Upstream sync.
[shishi.git] / asn1 / src / CrlExample.c
blob2eba8c9cdf84826ecbd6bc5cf0d11d376f911a3b
1 /*
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 /*****************************************************/
28 #include <stdio.h>
29 #include <string.h>
30 #include "libtasn1.h"
34 char *
35 my_ltostr(long v,char *str)
37 long d,r;
38 char temp[20];
39 int count,k,start;
41 if(v<0){
42 str[0]='-';
43 start=1;
44 v=-v;
46 else start=0;
48 count=0;
49 do{
50 d=v/10;
51 r=v-d*10;
52 temp[start+count]='0'+(char)r;
53 count++;
54 v=d;
55 }while(v);
57 for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
58 str[count+start]=0;
59 return str;
63 /******************************************************/
64 /* Function : get_name_type */
65 /* Description: analyze a structure of type Name */
66 /* Parameters: */
67 /* char *root: the structure identifier */
68 /* char *answer: the string with elements like: */
69 /* "C=US O=gov" */
70 /******************************************************/
71 void
72 get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
74 int k,k2,result,len;
75 char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
76 ASN1_TYPE value=ASN1_TYPE_EMPTY;
77 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
79 answer[0]=0;
80 k=1;
81 do{
82 strcpy(name,root);
83 strcat(name,".rdnSequence.?");
84 my_ltostr(k,counter);
85 strcat(name,counter);
87 len = sizeof(str)-1;
88 result=asn1_read_value(cert,name,str,&len);
89 if(result==ASN1_ELEMENT_NOT_FOUND) break;
90 k2=1;
91 do{
92 strcpy(name2,name);
93 strcat(name2,".?");
94 my_ltostr(k2,counter);
95 strcat(name2,counter);
97 len = sizeof(str)-1;
98 result=asn1_read_value(cert,name2,str,&len);
99 if(result==ASN1_ELEMENT_NOT_FOUND) break;
100 strcpy(name3,name2);
101 strcat(name3,".type");
103 len = sizeof(str)-1;
104 result=asn1_read_value(cert,name3,str,&len);
105 strcpy(name3,name2);
106 strcat(name3,".value");
107 if(result==ASN1_SUCCESS){
108 len = sizeof(str2);
109 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
110 str2,&len);
111 if(!strcmp(str,str2)){
112 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
113 &value);
114 len = sizeof(str)-1;
115 asn1_read_value(cert,name3,str,&len);
116 result=asn1_der_decoding(&value,str,len,errorDescription);
118 len = sizeof(str)-1;
119 asn1_read_value(value,"",str,&len); /* CHOICE */
121 strcpy(name3,str);
123 len = sizeof(str)-1;
124 asn1_read_value(value,name3,str,&len);
125 str[len]=0;
126 strcat(answer," C=");
127 strcat(answer,str);
129 asn1_delete_structure(&value);
131 else{
132 len = sizeof(str2);
133 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
134 ,str2,&len);
135 if(!strcmp(str,str2)){
136 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
137 ,&value);
139 len = sizeof(str)-1;
140 asn1_read_value(cert,name3,str,&len);
141 asn1_der_decoding(&value,str,len,errorDescription);
142 len = sizeof(str)-1;
143 asn1_read_value(value,"",str,&len); /* CHOICE */
144 strcpy(name3,str);
145 len = sizeof(str)-1;
146 asn1_read_value(value,name3,str,&len);
147 str[len]=0;
148 strcat(answer," O=");
149 strcat(answer,str);
150 asn1_delete_structure(&value);
152 else{
153 len = sizeof(str2);
154 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
155 if(!strcmp(str,str2)){
156 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
157 len = sizeof(str)-1;
158 asn1_read_value(cert,name3,str,&len);
159 asn1_der_decoding(&value,str,len,errorDescription);
160 len = sizeof(str)-1;
161 asn1_read_value(value,"",str,&len); /* CHOICE */
162 strcpy(name3,str);
163 len = sizeof(str)-1;
164 asn1_read_value(value,name3,str,&len);
165 str[len]=0;
166 strcat(answer," OU=");
167 strcat(answer,str);
168 asn1_delete_structure(&value);
173 k2++;
174 }while(1);
175 k++;
176 }while(1);
180 /******************************************************/
181 /* Function : create_certificate */
182 /* Description: creates a certificate named */
183 /* "certificate1". Values are the same */
184 /* as in rfc2459 Appendix D.1 */
185 /* Parameters: */
186 /* unsigned char *der: contains the der encoding */
187 /* int *der_len: number of bytes of der string */
188 /******************************************************/
189 void
190 create_CRL(node_asn *cert_def, unsigned char *der,int *der_len)
192 int result,k,len;
193 unsigned char str[1024],*str2;
194 ASN1_TYPE crl=ASN1_TYPE_EMPTY;
195 ASN1_TYPE value=ASN1_TYPE_EMPTY;
196 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
197 int max_len;
199 max_len=*der_len;
201 result=asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl);
203 /* Use the next 3 lines to visit the empty certificate */
204 /* printf("-----------------\n");
205 asn1_visit_tree(crl,"");
206 printf("-----------------\n"); */
209 /* version: v2(1) */
210 result=asn1_write_value(crl,"tbsCertList.version","v2",0);
213 /* signature: dsa-with-sha */
214 len = sizeof(str)-1;
215 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
216 result=asn1_write_value(crl,"tbsCertList.signature.algorithm",str,1);
217 result=asn1_write_value(crl,"tbsCertList.signature.parameters",NULL,0);
220 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
221 result=asn1_write_value(crl,"tbsCertList.issuer","rdnSequence",1);
223 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
224 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
225 /* C */
226 len = sizeof(str)-1;
227 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
228 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
229 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
230 &value);
231 result=asn1_write_value(value,"","US",2);
232 *der_len=max_len;
233 result=asn1_der_coding(value,"",der,der_len,errorDescription);
235 asn1_delete_structure(&value);
236 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
239 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",4);
240 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",4);
241 /* O */
242 len = sizeof(str)-1;
243 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
244 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,8);
245 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
246 &value);
247 result=asn1_write_value(value,"","printableString",1);
248 result=asn1_write_value(value,"printableString","gov",3);
249 *der_len=max_len;
250 result=asn1_der_coding(value,"",der,der_len,errorDescription);
251 asn1_delete_structure(&value);
252 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
255 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
256 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
257 /* OU */
258 len = sizeof(str)-1;
259 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
260 str,&len);
261 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
262 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
263 result=asn1_write_value(value,"","printableString",1);
264 result=asn1_write_value(value,"printableString","nist",4);
265 *der_len=max_len;
266 result=asn1_der_coding(value,"",der,der_len,errorDescription);
267 asn1_delete_structure(&value);
268 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
271 /* validity */
272 result=asn1_write_value(crl,"tbsCertList.thisUpdate","utcTime",1);
273 result=asn1_write_value(crl,"tbsCertList.thisUpdate.utcTime","970801000000Z",1);
275 result=asn1_write_value(crl,"tbsCertList.nextUpdate","utcTime",1);
276 result=asn1_write_value(crl,"tbsCertList.nextUpdate.utcTime","970808000000Z",1);
279 /* revokedCertificates */
280 result=asn1_write_value(crl,"tbsCertList.revokedCertificates","NEW",1);
281 str[0]=18;
282 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.userCertificate",str,1);
283 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate","utcTime",1);
284 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate.utcTime","970731000000Z",1);
286 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions","NEW",1);
287 len = sizeof(str)-1;
288 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-cRLReasons",
289 str,&len);
290 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnID",str,1); /* reasonCode */
291 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.critical","FALSE",1);
292 str2="\x0a\x01\x01";
293 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2,3);
296 /* crlExtensions */
297 result=asn1_write_value(crl,"tbsCertList.crlExtensions",NULL,0);
300 /* signatureAlgorithm: dsa-with-sha */
301 len = sizeof(str)-1;
302 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
303 result=asn1_write_value(crl,"signatureAlgorithm.algorithm",str,1);
304 result=asn1_write_value(crl,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
306 /* signature */
307 *der_len=max_len;
308 result=asn1_der_coding(crl,"tbsCertList",der,der_len,errorDescription);
309 if(result!=ASN1_SUCCESS){
310 printf("\n'tbsCertList' encoding creation: ERROR\n");
311 return;
314 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
315 result=asn1_write_value(crl,"signature",str2,46*8);
318 /* Use the next 3 lines to visit the certificate */
319 /* printf("-----------------\n");
320 asn1_visit_tree(crl,"");
321 printf("-----------------\n"); */
323 *der_len=max_len;
324 result=asn1_der_coding(crl,"",der,der_len,errorDescription);
325 if(result!=ASN1_SUCCESS){
326 printf("\n'crl1' encoding creation: ERROR\n");
327 return;
330 /* Print the 'Certificate1' DER encoding */
331 printf("-----------------\nCrl1 Encoding:\nNumber of bytes=%i\n",*der_len);
332 for(k=0;k<*der_len;k++) printf("%02x ",der[k]);
333 printf("\n-----------------\n");
335 /* Clear the "certificate1" structure */
336 asn1_delete_structure(&crl);
341 /******************************************************/
342 /* Function : get_certificate */
343 /* Description: creates a certificate named */
344 /* "certificate2" from a der encoding */
345 /* string */
346 /* Parameters: */
347 /* unsigned char *der: the encoding string */
348 /* int der_len: number of bytes of der string */
349 /******************************************************/
350 void
351 get_CRL(node_asn *cert_def,unsigned char *der,int der_len)
353 int result,len,start,end;
354 unsigned char str[1024],str2[1024];
355 ASN1_TYPE crl2=ASN1_TYPE_EMPTY;
356 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
359 asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl2);
361 result=asn1_der_decoding(&crl2,der,der_len,errorDescription);
363 if(result!=ASN1_SUCCESS){
364 printf("Problems with DER encoding\n");
365 return;
369 /* issuer */
370 get_Name_type(cert_def,crl2,"tbsCertList.issuer",str);
371 printf("crl2:\nissuer: %s\n",str);
374 /* Verify sign */
375 len = sizeof(str)-1;
376 result=asn1_read_value(crl2,"signatureAlgorithm.algorithm",str,&len);
378 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
379 if(!strcmp(str,str2)){ /* dsa-with-sha */
381 result=asn1_der_decoding_startEnd(crl2,der,der_len,
382 "tbsCertList",&start,&end);
384 /* add the lines to calculate the sha on der[start]..der[end] */
386 result=asn1_read_value(crl2,"signature",str,&len);
388 /* compare the previous value to signature ( with issuer public key) */
391 /* Use the next 3 lines to visit the certificate */
392 /* printf("-----------------\n");
393 asn1_visit_tree(crl2,"");
394 printf("-----------------\n"); */
397 /* Clear the "crl2" structure */
398 asn1_delete_structure(&crl2);
401 #include "pkix_asn1_tab.c"
403 /********************************************************/
404 /* Function : main */
405 /* Description: reads the certificate description. */
406 /* Creates a certificate and calculate */
407 /* the der encoding. After that creates */
408 /* another certificate from der string */
409 /********************************************************/
411 main(int argc,char *argv[])
413 int result,der_len;
414 unsigned char der[1024];
415 ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
416 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
418 if(1)
419 result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription);
420 else
421 result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);
423 if(result != ASN1_SUCCESS){
424 libtasn1_perror(result);
425 printf("%s\n",errorDescription);
426 exit(1);
429 /* Use the following 3 lines to visit the PKIX1Implicit structures */
430 /* printf("-----------------\n");
431 asn1_visit_tree(cert_def,"PKIX1Implicit88");
432 printf("-----------------\n"); */
434 der_len=1024;
435 create_CRL(PKIX1Implicit88,der,&der_len);
438 get_CRL(PKIX1Implicit88,der,der_len);
440 /* Clear the "PKIX1Implicit88" structures */
441 asn1_delete_structure(&PKIX1Implicit88);
443 return 0;