2 * Copyright (C) 2006 Free Software Foundation
3 * Copyright (C) 2000,2001 Fabio Fiorina
5 * This file is part of LIBTASN1.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 /*****************************************************/
25 /* File: CrlExample.c */
26 /* Description: An example on how to use the ASN1 */
27 /* parser with the Certificate.txt file */
28 /*****************************************************/
38 my_ltostr(long v
,char *str
)
55 temp
[start
+count
]='0'+(char)r
;
60 for(k
=0;k
<count
;k
++) str
[k
+start
]=temp
[start
+count
-k
-1];
66 /******************************************************/
67 /* Function : get_name_type */
68 /* Description: analyze a structure of type Name */
70 /* char *root: the structure identifier */
71 /* char *answer: the string with elements like: */
73 /******************************************************/
75 get_Name_type(node_asn
*cert_def
,node_asn
*cert
,char *root
, char *answer
)
78 char name
[128],str
[1024],str2
[1024],name2
[128],counter
[5],name3
[128];
79 ASN1_TYPE value
=ASN1_TYPE_EMPTY
;
80 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
86 strcat(name
,".rdnSequence.?");
91 result
=asn1_read_value(cert
,name
,str
,&len
);
92 if(result
==ASN1_ELEMENT_NOT_FOUND
) break;
97 my_ltostr(k2
,counter
);
98 strcat(name2
,counter
);
101 result
=asn1_read_value(cert
,name2
,str
,&len
);
102 if(result
==ASN1_ELEMENT_NOT_FOUND
) break;
104 strcat(name3
,".type");
107 result
=asn1_read_value(cert
,name3
,str
,&len
);
109 strcat(name3
,".value");
110 if(result
==ASN1_SUCCESS
){
112 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-countryName",
114 if(!strcmp(str
,str2
)){
115 asn1_create_element(cert_def
,"PKIX1Implicit88.X520OrganizationName",
118 asn1_read_value(cert
,name3
,str
,&len
);
119 result
=asn1_der_decoding(&value
,str
,len
,errorDescription
);
122 asn1_read_value(value
,"",str
,&len
); /* CHOICE */
127 asn1_read_value(value
,name3
,str
,&len
);
129 strcat(answer
," C=");
132 asn1_delete_structure(&value
);
136 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationName"
138 if(!strcmp(str
,str2
)){
139 asn1_create_element(cert_def
,"PKIX1Implicit88.X520OrganizationName"
143 asn1_read_value(cert
,name3
,str
,&len
);
144 asn1_der_decoding(&value
,str
,len
,errorDescription
);
146 asn1_read_value(value
,"",str
,&len
); /* CHOICE */
149 asn1_read_value(value
,name3
,str
,&len
);
151 strcat(answer
," O=");
153 asn1_delete_structure(&value
);
157 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationalUnitName",str2
,&len
);
158 if(!strcmp(str
,str2
)){
159 asn1_create_element(cert_def
,"PKIX1Implicit88.X520OrganizationalUnitName",&value
);
161 asn1_read_value(cert
,name3
,str
,&len
);
162 asn1_der_decoding(&value
,str
,len
,errorDescription
);
164 asn1_read_value(value
,"",str
,&len
); /* CHOICE */
167 asn1_read_value(value
,name3
,str
,&len
);
169 strcat(answer
," OU=");
171 asn1_delete_structure(&value
);
183 /******************************************************/
184 /* Function : create_certificate */
185 /* Description: creates a certificate named */
186 /* "certificate1". Values are the same */
187 /* as in rfc2459 Appendix D.1 */
189 /* unsigned char *der: contains the der encoding */
190 /* int *der_len: number of bytes of der string */
191 /******************************************************/
193 create_CRL(node_asn
*cert_def
, unsigned char *der
,int *der_len
)
196 unsigned char str
[1024],*str2
;
197 ASN1_TYPE crl
=ASN1_TYPE_EMPTY
;
198 ASN1_TYPE value
=ASN1_TYPE_EMPTY
;
199 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
204 result
=asn1_create_element(cert_def
,"PKIX1Implicit88.CertificateList",&crl
);
206 /* Use the next 3 lines to visit the empty certificate */
207 /* printf("-----------------\n");
208 asn1_visit_tree(crl,"");
209 printf("-----------------\n"); */
213 result
=asn1_write_value(crl
,"tbsCertList.version","v2",0);
216 /* signature: dsa-with-sha */
218 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str
,&len
);
219 result
=asn1_write_value(crl
,"tbsCertList.signature.algorithm",str
,1);
220 result
=asn1_write_value(crl
,"tbsCertList.signature.parameters",NULL
,0);
223 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
224 result
=asn1_write_value(crl
,"tbsCertList.issuer","rdnSequence",1);
226 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence","NEW",1);
227 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
230 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-countryName",str
,&len
);
231 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,1);
232 result
=asn1_create_element(cert_def
,"PKIX1Implicit88.X520countryName",
234 result
=asn1_write_value(value
,"","US",2);
236 result
=asn1_der_coding(value
,"",der
,der_len
,errorDescription
);
238 asn1_delete_structure(&value
);
239 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
242 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence","NEW",4);
243 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST","NEW",4);
246 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationName",str
,&len
);
247 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,8);
248 result
=asn1_create_element(cert_def
,"PKIX1Implicit88.X520OrganizationName",
250 result
=asn1_write_value(value
,"","printableString",1);
251 result
=asn1_write_value(value
,"printableString","gov",3);
253 result
=asn1_der_coding(value
,"",der
,der_len
,errorDescription
);
254 asn1_delete_structure(&value
);
255 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
258 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence","NEW",1);
259 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
262 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationalUnitName",
264 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,1);
265 result
=asn1_create_element(cert_def
,"PKIX1Implicit88.X520OrganizationalUnitName",&value
);
266 result
=asn1_write_value(value
,"","printableString",1);
267 result
=asn1_write_value(value
,"printableString","nist",4);
269 result
=asn1_der_coding(value
,"",der
,der_len
,errorDescription
);
270 asn1_delete_structure(&value
);
271 result
=asn1_write_value(crl
,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
275 result
=asn1_write_value(crl
,"tbsCertList.thisUpdate","utcTime",1);
276 result
=asn1_write_value(crl
,"tbsCertList.thisUpdate.utcTime","970801000000Z",1);
278 result
=asn1_write_value(crl
,"tbsCertList.nextUpdate","utcTime",1);
279 result
=asn1_write_value(crl
,"tbsCertList.nextUpdate.utcTime","970808000000Z",1);
282 /* revokedCertificates */
283 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates","NEW",1);
285 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.userCertificate",str
,1);
286 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.revocationDate","utcTime",1);
287 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.revocationDate.utcTime","970731000000Z",1);
289 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions","NEW",1);
291 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-ce-cRLReasons",
293 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnID",str
,1); /* reasonCode */
294 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.critical","FALSE",1);
296 result
=asn1_write_value(crl
,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2
,3);
300 result
=asn1_write_value(crl
,"tbsCertList.crlExtensions",NULL
,0);
303 /* signatureAlgorithm: dsa-with-sha */
305 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str
,&len
);
306 result
=asn1_write_value(crl
,"signatureAlgorithm.algorithm",str
,1);
307 result
=asn1_write_value(crl
,"signatureAlgorithm.parameters",NULL
,0); /* NO OPTION */
311 result
=asn1_der_coding(crl
,"tbsCertList",der
,der_len
,errorDescription
);
312 if(result
!=ASN1_SUCCESS
){
313 printf("\n'tbsCertList' encoding creation: ERROR\n");
317 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
318 result
=asn1_write_value(crl
,"signature",str2
,46*8);
321 /* Use the next 3 lines to visit the certificate */
322 /* printf("-----------------\n");
323 asn1_visit_tree(crl,"");
324 printf("-----------------\n"); */
327 result
=asn1_der_coding(crl
,"",der
,der_len
,errorDescription
);
328 if(result
!=ASN1_SUCCESS
){
329 printf("\n'crl1' encoding creation: ERROR\n");
333 /* Print the 'Certificate1' DER encoding */
334 printf("-----------------\nCrl1 Encoding:\nNumber of bytes=%i\n",*der_len
);
335 for(k
=0;k
<*der_len
;k
++) printf("%02x ",der
[k
]);
336 printf("\n-----------------\n");
338 /* Clear the "certificate1" structure */
339 asn1_delete_structure(&crl
);
344 /******************************************************/
345 /* Function : get_certificate */
346 /* Description: creates a certificate named */
347 /* "certificate2" from a der encoding */
350 /* unsigned char *der: the encoding string */
351 /* int der_len: number of bytes of der string */
352 /******************************************************/
354 get_CRL(node_asn
*cert_def
,unsigned char *der
,int der_len
)
356 int result
,len
,start
,end
;
357 unsigned char str
[1024],str2
[1024];
358 ASN1_TYPE crl2
=ASN1_TYPE_EMPTY
;
359 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
362 asn1_create_element(cert_def
,"PKIX1Implicit88.CertificateList",&crl2
);
364 result
=asn1_der_decoding(&crl2
,der
,der_len
,errorDescription
);
366 if(result
!=ASN1_SUCCESS
){
367 printf("Problems with DER encoding\n");
373 get_Name_type(cert_def
,crl2
,"tbsCertList.issuer",str
);
374 printf("crl2:\nissuer: %s\n",str
);
379 result
=asn1_read_value(crl2
,"signatureAlgorithm.algorithm",str
,&len
);
381 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str2
,&len
);
382 if(!strcmp(str
,str2
)){ /* dsa-with-sha */
384 result
=asn1_der_decoding_startEnd(crl2
,der
,der_len
,
385 "tbsCertList",&start
,&end
);
387 /* add the lines to calculate the sha on der[start]..der[end] */
389 result
=asn1_read_value(crl2
,"signature",str
,&len
);
391 /* compare the previous value to signature ( with issuer public key) */
394 /* Use the next 3 lines to visit the certificate */
395 /* printf("-----------------\n");
396 asn1_visit_tree(crl2,"");
397 printf("-----------------\n"); */
400 /* Clear the "crl2" structure */
401 asn1_delete_structure(&crl2
);
404 #include "pkix_asn1_tab.c"
406 /********************************************************/
407 /* Function : main */
408 /* Description: reads the certificate description. */
409 /* Creates a certificate and calculate */
410 /* the der encoding. After that creates */
411 /* another certificate from der string */
412 /********************************************************/
414 main(int argc
,char *argv
[])
417 unsigned char der
[1024];
418 ASN1_TYPE PKIX1Implicit88
=ASN1_TYPE_EMPTY
;
419 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
422 result
=asn1_array2tree(pkix_asn1_tab
,&PKIX1Implicit88
,errorDescription
);
424 result
=asn1_parser2tree("pkix.asn",&PKIX1Implicit88
,errorDescription
);
426 if(result
!= ASN1_SUCCESS
){
427 libtasn1_perror(result
);
428 printf("%s\n",errorDescription
);
432 /* Use the following 3 lines to visit the PKIX1Implicit structures */
433 /* printf("-----------------\n");
434 asn1_visit_tree(cert_def,"PKIX1Implicit88");
435 printf("-----------------\n"); */
438 create_CRL(PKIX1Implicit88
,der
,&der_len
);
441 get_CRL(PKIX1Implicit88
,der
,der_len
);
443 /* Clear the "PKIX1Implicit88" structures */
444 asn1_delete_structure(&PKIX1Implicit88
);