Look for *.m4 in gl/m4/.
[libtasn1.git] / src / CrlExample.c
blobe9a9fdf1cb9f58cb5fc1a891f2c9c60dee14d7d2
1 /*
2 * Copyright (C) 2000,2001 Fabio Fiorina
4 * This file is part of LIBTASN1.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: CrlExample.c */
25 /* Description: An example on how to use the ASN1 */
26 /* parser with the Certificate.txt file */
27 /*****************************************************/
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include "libtasn1.h"
36 char *
37 my_ltostr(long v,char *str)
39 long d,r;
40 char temp[20];
41 int count,k,start;
43 if(v<0){
44 str[0]='-';
45 start=1;
46 v=-v;
48 else start=0;
50 count=0;
51 do{
52 d=v/10;
53 r=v-d*10;
54 temp[start+count]='0'+(char)r;
55 count++;
56 v=d;
57 }while(v);
59 for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
60 str[count+start]=0;
61 return str;
65 /******************************************************/
66 /* Function : get_name_type */
67 /* Description: analyze a structure of type Name */
68 /* Parameters: */
69 /* char *root: the structure identifier */
70 /* char *answer: the string with elements like: */
71 /* "C=US O=gov" */
72 /******************************************************/
73 void
74 get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
76 int k,k2,result,len;
77 char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
78 ASN1_TYPE value=ASN1_TYPE_EMPTY;
79 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
81 answer[0]=0;
82 k=1;
83 do{
84 strcpy(name,root);
85 strcat(name,".rdnSequence.?");
86 my_ltostr(k,counter);
87 strcat(name,counter);
89 len = sizeof(str)-1;
90 result=asn1_read_value(cert,name,str,&len);
91 if(result==ASN1_ELEMENT_NOT_FOUND) break;
92 k2=1;
93 do{
94 strcpy(name2,name);
95 strcat(name2,".?");
96 my_ltostr(k2,counter);
97 strcat(name2,counter);
99 len = sizeof(str)-1;
100 result=asn1_read_value(cert,name2,str,&len);
101 if(result==ASN1_ELEMENT_NOT_FOUND) break;
102 strcpy(name3,name2);
103 strcat(name3,".type");
105 len = sizeof(str)-1;
106 result=asn1_read_value(cert,name3,str,&len);
107 strcpy(name3,name2);
108 strcat(name3,".value");
109 if(result==ASN1_SUCCESS){
110 len = sizeof(str2);
111 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
112 str2,&len);
113 if(!strcmp(str,str2)){
114 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
115 &value);
116 len = sizeof(str)-1;
117 asn1_read_value(cert,name3,str,&len);
118 result=asn1_der_decoding(&value,str,len,errorDescription);
120 len = sizeof(str)-1;
121 asn1_read_value(value,"",str,&len); /* CHOICE */
123 strcpy(name3,str);
125 len = sizeof(str)-1;
126 asn1_read_value(value,name3,str,&len);
127 str[len]=0;
128 strcat(answer," C=");
129 strcat(answer,str);
131 asn1_delete_structure(&value);
133 else{
134 len = sizeof(str2);
135 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
136 ,str2,&len);
137 if(!strcmp(str,str2)){
138 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
139 ,&value);
141 len = sizeof(str)-1;
142 asn1_read_value(cert,name3,str,&len);
143 asn1_der_decoding(&value,str,len,errorDescription);
144 len = sizeof(str)-1;
145 asn1_read_value(value,"",str,&len); /* CHOICE */
146 strcpy(name3,str);
147 len = sizeof(str)-1;
148 asn1_read_value(value,name3,str,&len);
149 str[len]=0;
150 strcat(answer," O=");
151 strcat(answer,str);
152 asn1_delete_structure(&value);
154 else{
155 len = sizeof(str2);
156 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
157 if(!strcmp(str,str2)){
158 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
159 len = sizeof(str)-1;
160 asn1_read_value(cert,name3,str,&len);
161 asn1_der_decoding(&value,str,len,errorDescription);
162 len = sizeof(str)-1;
163 asn1_read_value(value,"",str,&len); /* CHOICE */
164 strcpy(name3,str);
165 len = sizeof(str)-1;
166 asn1_read_value(value,name3,str,&len);
167 str[len]=0;
168 strcat(answer," OU=");
169 strcat(answer,str);
170 asn1_delete_structure(&value);
175 k2++;
176 }while(1);
177 k++;
178 }while(1);
182 /******************************************************/
183 /* Function : create_certificate */
184 /* Description: creates a certificate named */
185 /* "certificate1". Values are the same */
186 /* as in rfc2459 Appendix D.1 */
187 /* Parameters: */
188 /* unsigned char *der: contains the der encoding */
189 /* int *der_len: number of bytes of der string */
190 /******************************************************/
191 void
192 create_CRL(node_asn *cert_def, unsigned char *der,int *der_len)
194 int result,k,len;
195 unsigned char str[1024],*str2;
196 ASN1_TYPE crl=ASN1_TYPE_EMPTY;
197 ASN1_TYPE value=ASN1_TYPE_EMPTY;
198 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
199 int max_len;
201 max_len=*der_len;
203 result=asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl);
205 /* Use the next 3 lines to visit the empty certificate */
206 /* printf("-----------------\n");
207 asn1_visit_tree(crl,"");
208 printf("-----------------\n"); */
211 /* version: v2(1) */
212 result=asn1_write_value(crl,"tbsCertList.version","v2",0);
215 /* signature: dsa-with-sha */
216 len = sizeof(str)-1;
217 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
218 result=asn1_write_value(crl,"tbsCertList.signature.algorithm",str,1);
219 result=asn1_write_value(crl,"tbsCertList.signature.parameters",NULL,0);
222 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
223 result=asn1_write_value(crl,"tbsCertList.issuer","rdnSequence",1);
225 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
226 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
227 /* C */
228 len = sizeof(str)-1;
229 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
230 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
231 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
232 &value);
233 result=asn1_write_value(value,"","US",2);
234 *der_len=max_len;
235 result=asn1_der_coding(value,"",der,der_len,errorDescription);
237 asn1_delete_structure(&value);
238 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
241 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",4);
242 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",4);
243 /* O */
244 len = sizeof(str)-1;
245 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
246 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,8);
247 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
248 &value);
249 result=asn1_write_value(value,"","printableString",1);
250 result=asn1_write_value(value,"printableString","gov",3);
251 *der_len=max_len;
252 result=asn1_der_coding(value,"",der,der_len,errorDescription);
253 asn1_delete_structure(&value);
254 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
257 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
258 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
259 /* OU */
260 len = sizeof(str)-1;
261 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
262 str,&len);
263 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
264 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
265 result=asn1_write_value(value,"","printableString",1);
266 result=asn1_write_value(value,"printableString","nist",4);
267 *der_len=max_len;
268 result=asn1_der_coding(value,"",der,der_len,errorDescription);
269 asn1_delete_structure(&value);
270 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
273 /* validity */
274 result=asn1_write_value(crl,"tbsCertList.thisUpdate","utcTime",1);
275 result=asn1_write_value(crl,"tbsCertList.thisUpdate.utcTime","970801000000Z",1);
277 result=asn1_write_value(crl,"tbsCertList.nextUpdate","utcTime",1);
278 result=asn1_write_value(crl,"tbsCertList.nextUpdate.utcTime","970808000000Z",1);
281 /* revokedCertificates */
282 result=asn1_write_value(crl,"tbsCertList.revokedCertificates","NEW",1);
283 str[0]=18;
284 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.userCertificate",str,1);
285 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate","utcTime",1);
286 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate.utcTime","970731000000Z",1);
288 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions","NEW",1);
289 len = sizeof(str)-1;
290 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-cRLReasons",
291 str,&len);
292 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnID",str,1); /* reasonCode */
293 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.critical","FALSE",1);
294 str2="\x0a\x01\x01";
295 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2,3);
298 /* crlExtensions */
299 result=asn1_write_value(crl,"tbsCertList.crlExtensions",NULL,0);
302 /* signatureAlgorithm: dsa-with-sha */
303 len = sizeof(str)-1;
304 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
305 result=asn1_write_value(crl,"signatureAlgorithm.algorithm",str,1);
306 result=asn1_write_value(crl,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
308 /* signature */
309 *der_len=max_len;
310 result=asn1_der_coding(crl,"tbsCertList",der,der_len,errorDescription);
311 if(result!=ASN1_SUCCESS){
312 printf("\n'tbsCertList' encoding creation: ERROR\n");
313 return;
316 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
317 result=asn1_write_value(crl,"signature",str2,46*8);
320 /* Use the next 3 lines to visit the certificate */
321 /* printf("-----------------\n");
322 asn1_visit_tree(crl,"");
323 printf("-----------------\n"); */
325 *der_len=max_len;
326 result=asn1_der_coding(crl,"",der,der_len,errorDescription);
327 if(result!=ASN1_SUCCESS){
328 printf("\n'crl1' encoding creation: ERROR\n");
329 return;
332 /* Print the 'Certificate1' DER encoding */
333 printf("-----------------\nCrl1 Encoding:\nNumber of bytes=%i\n",*der_len);
334 for(k=0;k<*der_len;k++) printf("%02x ",der[k]);
335 printf("\n-----------------\n");
337 /* Clear the "certificate1" structure */
338 asn1_delete_structure(&crl);
343 /******************************************************/
344 /* Function : get_certificate */
345 /* Description: creates a certificate named */
346 /* "certificate2" from a der encoding */
347 /* string */
348 /* Parameters: */
349 /* unsigned char *der: the encoding string */
350 /* int der_len: number of bytes of der string */
351 /******************************************************/
352 void
353 get_CRL(node_asn *cert_def,unsigned char *der,int der_len)
355 int result,len,start,end;
356 unsigned char str[1024],str2[1024];
357 ASN1_TYPE crl2=ASN1_TYPE_EMPTY;
358 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
361 asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl2);
363 result=asn1_der_decoding(&crl2,der,der_len,errorDescription);
365 if(result!=ASN1_SUCCESS){
366 printf("Problems with DER encoding\n");
367 return;
371 /* issuer */
372 get_Name_type(cert_def,crl2,"tbsCertList.issuer",str);
373 printf("crl2:\nissuer: %s\n",str);
376 /* Verify sign */
377 len = sizeof(str)-1;
378 result=asn1_read_value(crl2,"signatureAlgorithm.algorithm",str,&len);
380 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
381 if(!strcmp(str,str2)){ /* dsa-with-sha */
383 result=asn1_der_decoding_startEnd(crl2,der,der_len,
384 "tbsCertList",&start,&end);
386 /* add the lines to calculate the sha on der[start]..der[end] */
388 result=asn1_read_value(crl2,"signature",str,&len);
390 /* compare the previous value to signature ( with issuer public key) */
393 /* Use the next 3 lines to visit the certificate */
394 /* printf("-----------------\n");
395 asn1_visit_tree(crl2,"");
396 printf("-----------------\n"); */
399 /* Clear the "crl2" structure */
400 asn1_delete_structure(&crl2);
403 #include "pkix_asn1_tab.c"
405 /********************************************************/
406 /* Function : main */
407 /* Description: reads the certificate description. */
408 /* Creates a certificate and calculate */
409 /* the der encoding. After that creates */
410 /* another certificate from der string */
411 /********************************************************/
413 main(int argc,char *argv[])
415 int result,der_len;
416 unsigned char der[1024];
417 ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
418 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
420 if(1)
421 result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription);
422 else
423 result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);
425 if(result != ASN1_SUCCESS){
426 libtasn1_perror(result);
427 printf("%s\n",errorDescription);
428 exit(1);
431 /* Use the following 3 lines to visit the PKIX1Implicit structures */
432 /* printf("-----------------\n");
433 asn1_visit_tree(cert_def,"PKIX1Implicit88");
434 printf("-----------------\n"); */
436 der_len=1024;
437 create_CRL(PKIX1Implicit88,der,&der_len);
440 get_CRL(PKIX1Implicit88,der,der_len);
442 /* Clear the "PKIX1Implicit88" structures */
443 asn1_delete_structure(&PKIX1Implicit88);
445 return 0;