2 * Copyright (C) 2000,2001 Fabio Fiorina
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 /*****************************************************/
23 /* File: CrlExample.c */
24 /* Description: An example on how to use the ASN1 */
25 /* parser with the Certificate.txt file */
26 /*****************************************************/
30 #include "../lib/gnutls.h"
31 #include "../lib/x509_der.h"
33 extern static_asn pkix_asn1_tab
[];
35 /******************************************************/
36 /* Function : get_name_type */
37 /* Description: analyze a structure of type Name */
39 /* char *root: the structure identifier */
40 /* char *answer: the string with elements like: */
42 /******************************************************/
44 get_Name_type(node_asn
*cert_def
,node_asn
*cert
,char *root
, char *answer
)
47 char name
[128],str
[1024],str2
[1024],name2
[128],counter
[5],name3
[128];
54 strcat(name
,".rdnSequence.?");
55 _asn1_ltostr(k
,counter
);
59 result
=asn1_read_value(cert
,name
,str
,&len
);
60 if(result
==ASN_ELEMENT_NOT_FOUND
) break;
65 _asn1_ltostr(k2
,counter
);
66 strcat(name2
,counter
);
69 result
=asn1_read_value(cert
,name2
,str
,&len
);
70 if(result
==ASN_ELEMENT_NOT_FOUND
) break;
72 strcat(name3
,".type");
75 result
=asn1_read_value(cert
,name3
,str
,&len
);
77 strcat(name3
,".value");
80 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-countryName",
82 if(!strcmp(str
,str2
)){
83 asn1_create_structure(cert_def
,"PKIX1Implicit88.X520OrganizationName",
84 &value
,"certificate2-subject-C");
86 asn1_read_value(cert
,name3
,str
,&len
);
87 asn1_get_der(value
,str
,len
);
88 strcpy(name3
,"certificate2-subject-C");
91 asn1_read_value(value
,name3
,str
,&len
); /* CHOICE */
96 asn1_read_value(value
,name3
,str
,&len
);
100 asn1_delete_structure(value
);
104 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationName"
106 if(!strcmp(str
,str2
)){
107 asn1_create_structure(cert_def
,"PKIX1Implicit88.X520OrganizationName"
108 ,&value
,"certificate2-subject-O");
111 asn1_read_value(cert
,name3
,str
,&len
);
112 asn1_get_der(value
,str
,len
);
113 strcpy(name3
,"certificate2-subject-O");
115 asn1_read_value(value
,name3
,str
,&len
); /* CHOICE */
119 asn1_read_value(value
,name3
,str
,&len
);
121 strcat(answer
," O=");
123 asn1_delete_structure(value
);
127 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationalUnitName",str2
,&len
);
128 if(!strcmp(str
,str2
)){
129 asn1_create_structure(cert_def
,"PKIX1Implicit88.X520OrganizationalUnitName",&value
,"certificate2-subject-OU");
131 asn1_read_value(cert
,name3
,str
,&len
);
132 asn1_get_der(value
,str
,len
);
133 strcpy(name3
,"certificate2-subject-OU");
135 asn1_read_value(value
,name3
,str
,&len
); /* CHOICE */
139 asn1_read_value(value
,name3
,str
,&len
);
141 strcat(answer
," OU=");
143 asn1_delete_structure(value
);
155 /******************************************************/
156 /* Function : create_certificate */
157 /* Description: creates a certificate named */
158 /* "certificate1". Values are the same */
159 /* as in rfc2459 Appendix D.1 */
161 /* unsigned char *der: contains the der encoding */
162 /* int *der_len: number of bytes of der string */
163 /******************************************************/
165 create_CRL(node_asn
*cert_def
, unsigned char *der
,int *der_len
)
168 unsigned char str
[1024],*str2
;
169 node_asn
*crl
,*value
;
171 result
=asn1_create_structure(cert_def
,"PKIX1Implicit88.CertificateList",&crl
,"crl1");
173 /* Use the next 3 lines to visit the empty certificate */
174 /* printf("-----------------\n");
175 asn1_visit_tree(crl,"crl1");
176 printf("-----------------\n"); */
180 result
=asn1_write_value(crl
,"crl1.tbsCertList.version","v2",0);
182 /* signature: dsa-with-sha */
184 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str
,&len
);
185 result
=asn1_write_value(crl
,"crl1.tbsCertList.signature.algorithm",str
,1);
187 result
=asn1_write_value(crl
,"crl1.tbsCertList.signature.parameters",NULL
,0);
190 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
191 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer","rdnSequence",1);
193 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence","NEW",1);
194 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
197 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-countryName",str
,&len
);
198 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,1);
199 result
=asn1_create_structure(cert_def
,"PKIX1Implicit88.X520countryName",
200 &value
,"countryName");
201 result
=asn1_write_value(value
,"countryName","US",2);
202 result
=asn1_create_der(value
,"countryName",der
,der_len
);
203 asn1_delete_structure(value
);
204 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
207 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence","NEW",4);
208 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST","NEW",4);
211 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationName",str
,&len
);
212 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,8);
213 result
=asn1_create_structure(cert_def
,"PKIX1Implicit88.X520OrganizationName",
215 result
=asn1_write_value(value
,"OrgName","printableString",1);
216 result
=asn1_write_value(value
,"OrgName.printableString","gov",3);
217 result
=asn1_create_der(value
,"OrgName",der
,der_len
);
218 asn1_delete_structure(value
);
219 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
222 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence","NEW",1);
223 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
226 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-at-organizationalUnitName",
228 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str
,1);
229 result
=asn1_create_structure(cert_def
,"PKIX1Implicit88.X520OrganizationalUnitName",&value
,"OrgUnitName");
230 result
=asn1_write_value(value
,"OrgUnitName","printableString",1);
231 result
=asn1_write_value(value
,"OrgUnitName.printableString","nist",4);
232 result
=asn1_create_der(value
,"OrgUnitName",der
,der_len
);
233 asn1_delete_structure(value
);
234 result
=asn1_write_value(crl
,"crl1.tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der
,*der_len
);
238 result
=asn1_write_value(crl
,"crl1.tbsCertList.thisUpdate","utcTime",1);
239 result
=asn1_write_value(crl
,"crl1.tbsCertList.thisUpdate.utcTime","970801000000Z",1);
241 result
=asn1_write_value(crl
,"crl1.tbsCertList.nextUpdate","utcTime",1);
242 result
=asn1_write_value(crl
,"crl1.tbsCertList.nextUpdate.utcTime","970808000000Z",1);
245 /* revokedCertificates */
246 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates","NEW",1);
248 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.userCertificate",str
,1);
249 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.revocationDate","utcTime",1);
250 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.revocationDate.utcTime","970731000000Z",1);
252 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.crlEntryExtensions","NEW",1);
254 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-ce-cRLReasons",
256 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnID",str
,1); /* reasonCode */
257 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.critical","FALSE",1);
259 result
=asn1_write_value(crl
,"crl1.tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2
,3);
263 result
=asn1_write_value(crl
,"crl1.tbsCertList.crlExtensions",NULL
,0);
266 /* signatureAlgorithm: dsa-with-sha */
268 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str
,&len
);
269 result
=asn1_write_value(crl
,"crl1.signatureAlgorithm.algorithm",str
,1);
270 result
=asn1_write_value(crl
,"crl1.signatureAlgorithm.parameters",NULL
,0); /* NO OPTION */
273 result
=asn1_create_der(crl
,"crl1.tbsCertList",der
,der_len
);
275 printf("\n'tbsCertList' encoding creation: ERROR\n");
279 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
280 result
=asn1_write_value(crl
,"crl1.signature",str2
,46*8);
283 /* Use the next 3 lines to visit the certificate */
284 /* printf("-----------------\n");
285 asn1_visit_tree(crl,"crl1");
286 printf("-----------------\n"); */
289 result
=asn1_create_der(crl
,"crl1",der
,der_len
);
291 printf("\n'crl1' encoding creation: ERROR\n");
295 /* Print the 'Certificate1' DER encoding */
296 printf("-----------------\nCrl1 Encoding:\nNumber of bytes=%i\n",*der_len
);
297 for(k
=0;k
<*der_len
;k
++) printf("%02x ",der
[k
]);
298 printf("\n-----------------\n");
300 /* Clear the "certificate1" structure */
301 asn1_delete_structure(crl
);
306 /******************************************************/
307 /* Function : get_certificate */
308 /* Description: creates a certificate named */
309 /* "certificate2" from a der encoding */
312 /* unsigned char *der: the encoding string */
313 /* int der_len: number of bytes of der string */
314 /******************************************************/
316 get_CRL(node_asn
*cert_def
,unsigned char *der
,int der_len
)
318 int result
,len
,start
,end
;
319 unsigned char str
[1024],str2
[1024];
323 asn1_create_structure(cert_def
,"PKIX1Implicit88.CertificateList",&crl2
,"crl2");
325 result
=asn1_get_der(crl2
,der
,der_len
);
328 printf("Problems with DER encoding\n");
334 get_Name_type(cert_def
,crl2
,"crl2.tbsCertList.issuer",str
);
335 printf("crl2:\nissuer =%s\n",str
);
340 result
=asn1_read_value(crl2
,"crl2.signatureAlgorithm.algorithm",str
,&len
);
342 result
=asn1_read_value(cert_def
,"PKIX1Implicit88.id-dsa-with-sha1",str2
,&len
);
343 if(!strcmp(str
,str2
)){ /* dsa-with-sha */
345 result
=asn1_get_start_end_der(crl2
,der
,der_len
,
346 "crl2.tbsCertList",&start
,&end
);
348 /* add the lines to calculate the sha on der[start]..der[end] */
350 result
=asn1_read_value(crl2
,"crl2.signature",str
,&len
);
352 /* compare the previous value to signature ( with issuer public key) */
355 /* Use the next 3 lines to visit the certificate */
356 /* printf("-----------------\n");
357 asn1_visit_tree(crl2,"crl2");
358 printf("-----------------\n"); */
361 /* Clear the "crl2" structure */
362 asn1_delete_structure(crl2
);
366 /********************************************************/
367 /* Function : main */
368 /* Description: reads the certificate description. */
369 /* Creates a certificate and calculate */
370 /* the der encoding. After that creates */
371 /* another certificate from der string */
372 /********************************************************/
374 main(int argc
,char *argv
[])
377 unsigned char der
[1024];
379 node_asn
*PKIX1Implicit88
;
381 result
=asn1_create_tree(pkix_asn1_tab
,&PKIX1Implicit88
);
383 if(result
==ASN_FILE_NOT_FOUND
){
384 printf("FILE NOT FOUND\n");
387 else if(result
==ASN_SYNTAX_ERROR
){
388 printf("PARSE ERROR\n");
391 else if(result
==ASN_IDENTIFIER_NOT_FOUND
){
392 printf("IDENTIFIER NOT FOUND\n");
397 /* Use the following 3 lines to visit the PKIX1Implicit structures */
398 /* printf("-----------------\n");
399 asn1_visit_tree(cert_def,"PKIX1Implicit88");
400 printf("-----------------\n"); */
403 create_CRL(PKIX1Implicit88
,der
,&der_len
);
405 get_CRL(PKIX1Implicit88
,der
,der_len
);
407 /* Clear the "PKIX1Implicit88" structures */
408 asn1_delete_structure(PKIX1Implicit88
);