Merge defines.h into int.h.
[libtasn1.git] / src / CrlExample.c
blob80c30bb4c4fe02f70ec79a52aa142fa54efa905a
1 /*
2 * Copyright (C) 2006, 2007 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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU 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, see <http://www.gnu.org/licenses/>.
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 <stdlib.h>
31 #include "libtasn1.h"
35 char *
36 my_ltostr(long v,char *str)
38 long d,r;
39 char temp[20];
40 int count,k,start;
42 if(v<0){
43 str[0]='-';
44 start=1;
45 v=-v;
47 else start=0;
49 count=0;
50 do{
51 d=v/10;
52 r=v-d*10;
53 temp[start+count]='0'+(char)r;
54 count++;
55 v=d;
56 }while(v);
58 for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
59 str[count+start]=0;
60 return str;
64 /******************************************************/
65 /* Function : get_name_type */
66 /* Description: analyze a structure of type Name */
67 /* Parameters: */
68 /* char *root: the structure identifier */
69 /* char *answer: the string with elements like: */
70 /* "C=US O=gov" */
71 /******************************************************/
72 void
73 get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
75 int k,k2,result,len;
76 char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
77 ASN1_TYPE value=ASN1_TYPE_EMPTY;
78 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
80 answer[0]=0;
81 k=1;
82 do{
83 strcpy(name,root);
84 strcat(name,".rdnSequence.?");
85 my_ltostr(k,counter);
86 strcat(name,counter);
88 len = sizeof(str)-1;
89 result=asn1_read_value(cert,name,str,&len);
90 if(result==ASN1_ELEMENT_NOT_FOUND) break;
91 k2=1;
92 do{
93 strcpy(name2,name);
94 strcat(name2,".?");
95 my_ltostr(k2,counter);
96 strcat(name2,counter);
98 len = sizeof(str)-1;
99 result=asn1_read_value(cert,name2,str,&len);
100 if(result==ASN1_ELEMENT_NOT_FOUND) break;
101 strcpy(name3,name2);
102 strcat(name3,".type");
104 len = sizeof(str)-1;
105 result=asn1_read_value(cert,name3,str,&len);
106 strcpy(name3,name2);
107 strcat(name3,".value");
108 if(result==ASN1_SUCCESS){
109 len = sizeof(str2);
110 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
111 str2,&len);
112 if(!strcmp(str,str2)){
113 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
114 &value);
115 len = sizeof(str)-1;
116 asn1_read_value(cert,name3,str,&len);
117 result=asn1_der_decoding(&value,str,len,errorDescription);
119 len = sizeof(str)-1;
120 asn1_read_value(value,"",str,&len); /* CHOICE */
122 strcpy(name3,str);
124 len = sizeof(str)-1;
125 asn1_read_value(value,name3,str,&len);
126 str[len]=0;
127 strcat(answer," C=");
128 strcat(answer,str);
130 asn1_delete_structure(&value);
132 else{
133 len = sizeof(str2);
134 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
135 ,str2,&len);
136 if(!strcmp(str,str2)){
137 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
138 ,&value);
140 len = sizeof(str)-1;
141 asn1_read_value(cert,name3,str,&len);
142 asn1_der_decoding(&value,str,len,errorDescription);
143 len = sizeof(str)-1;
144 asn1_read_value(value,"",str,&len); /* CHOICE */
145 strcpy(name3,str);
146 len = sizeof(str)-1;
147 asn1_read_value(value,name3,str,&len);
148 str[len]=0;
149 strcat(answer," O=");
150 strcat(answer,str);
151 asn1_delete_structure(&value);
153 else{
154 len = sizeof(str2);
155 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
156 if(!strcmp(str,str2)){
157 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
158 len = sizeof(str)-1;
159 asn1_read_value(cert,name3,str,&len);
160 asn1_der_decoding(&value,str,len,errorDescription);
161 len = sizeof(str)-1;
162 asn1_read_value(value,"",str,&len); /* CHOICE */
163 strcpy(name3,str);
164 len = sizeof(str)-1;
165 asn1_read_value(value,name3,str,&len);
166 str[len]=0;
167 strcat(answer," OU=");
168 strcat(answer,str);
169 asn1_delete_structure(&value);
174 k2++;
175 }while(1);
176 k++;
177 }while(1);
181 /******************************************************/
182 /* Function : create_certificate */
183 /* Description: creates a certificate named */
184 /* "certificate1". Values are the same */
185 /* as in rfc2459 Appendix D.1 */
186 /* Parameters: */
187 /* unsigned char *der: contains the der encoding */
188 /* int *der_len: number of bytes of der string */
189 /******************************************************/
190 void
191 create_CRL(node_asn *cert_def, unsigned char *der,int *der_len)
193 int result,k,len;
194 unsigned char str[1024],*str2;
195 ASN1_TYPE crl=ASN1_TYPE_EMPTY;
196 ASN1_TYPE value=ASN1_TYPE_EMPTY;
197 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
198 int max_len;
200 max_len=*der_len;
202 result=asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl);
204 /* Use the next 3 lines to visit the empty certificate */
205 /* printf("-----------------\n");
206 asn1_visit_tree(crl,"");
207 printf("-----------------\n"); */
210 /* version: v2(1) */
211 result=asn1_write_value(crl,"tbsCertList.version","v2",0);
214 /* signature: dsa-with-sha */
215 len = sizeof(str)-1;
216 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
217 result=asn1_write_value(crl,"tbsCertList.signature.algorithm",str,1);
218 result=asn1_write_value(crl,"tbsCertList.signature.parameters",NULL,0);
221 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
222 result=asn1_write_value(crl,"tbsCertList.issuer","rdnSequence",1);
224 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
225 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
226 /* C */
227 len = sizeof(str)-1;
228 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
229 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
230 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
231 &value);
232 result=asn1_write_value(value,"","US",2);
233 *der_len=max_len;
234 result=asn1_der_coding(value,"",der,der_len,errorDescription);
236 asn1_delete_structure(&value);
237 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
240 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",4);
241 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",4);
242 /* O */
243 len = sizeof(str)-1;
244 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
245 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,8);
246 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
247 &value);
248 result=asn1_write_value(value,"","printableString",1);
249 result=asn1_write_value(value,"printableString","gov",3);
250 *der_len=max_len;
251 result=asn1_der_coding(value,"",der,der_len,errorDescription);
252 asn1_delete_structure(&value);
253 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
256 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence","NEW",1);
257 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST","NEW",1);
258 /* OU */
259 len = sizeof(str)-1;
260 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
261 str,&len);
262 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.type",str,1);
263 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
264 result=asn1_write_value(value,"","printableString",1);
265 result=asn1_write_value(value,"printableString","nist",4);
266 *der_len=max_len;
267 result=asn1_der_coding(value,"",der,der_len,errorDescription);
268 asn1_delete_structure(&value);
269 result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
272 /* validity */
273 result=asn1_write_value(crl,"tbsCertList.thisUpdate","utcTime",1);
274 result=asn1_write_value(crl,"tbsCertList.thisUpdate.utcTime","970801000000Z",1);
276 result=asn1_write_value(crl,"tbsCertList.nextUpdate","utcTime",1);
277 result=asn1_write_value(crl,"tbsCertList.nextUpdate.utcTime","970808000000Z",1);
280 /* revokedCertificates */
281 result=asn1_write_value(crl,"tbsCertList.revokedCertificates","NEW",1);
282 str[0]=18;
283 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.userCertificate",str,1);
284 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate","utcTime",1);
285 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.revocationDate.utcTime","970731000000Z",1);
287 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions","NEW",1);
288 len = sizeof(str)-1;
289 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-cRLReasons",
290 str,&len);
291 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnID",str,1); /* reasonCode */
292 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.critical","FALSE",1);
293 str2="\x0a\x01\x01";
294 result=asn1_write_value(crl,"tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2,3);
297 /* crlExtensions */
298 result=asn1_write_value(crl,"tbsCertList.crlExtensions",NULL,0);
301 /* signatureAlgorithm: dsa-with-sha */
302 len = sizeof(str)-1;
303 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
304 result=asn1_write_value(crl,"signatureAlgorithm.algorithm",str,1);
305 result=asn1_write_value(crl,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
307 /* signature */
308 *der_len=max_len;
309 result=asn1_der_coding(crl,"tbsCertList",der,der_len,errorDescription);
310 if(result!=ASN1_SUCCESS){
311 printf("\n'tbsCertList' encoding creation: ERROR\n");
312 return;
315 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
316 result=asn1_write_value(crl,"signature",str2,46*8);
319 /* Use the next 3 lines to visit the certificate */
320 /* printf("-----------------\n");
321 asn1_visit_tree(crl,"");
322 printf("-----------------\n"); */
324 *der_len=max_len;
325 result=asn1_der_coding(crl,"",der,der_len,errorDescription);
326 if(result!=ASN1_SUCCESS){
327 printf("\n'crl1' encoding creation: ERROR\n");
328 return;
331 /* Print the 'Certificate1' DER encoding */
332 printf("-----------------\nCrl1 Encoding:\nNumber of bytes=%i\n",*der_len);
333 for(k=0;k<*der_len;k++) printf("%02x ",der[k]);
334 printf("\n-----------------\n");
336 /* Clear the "certificate1" structure */
337 asn1_delete_structure(&crl);
342 /******************************************************/
343 /* Function : get_certificate */
344 /* Description: creates a certificate named */
345 /* "certificate2" from a der encoding */
346 /* string */
347 /* Parameters: */
348 /* unsigned char *der: the encoding string */
349 /* int der_len: number of bytes of der string */
350 /******************************************************/
351 void
352 get_CRL(node_asn *cert_def,unsigned char *der,int der_len)
354 int result,len,start,end;
355 unsigned char str[1024],str2[1024];
356 ASN1_TYPE crl2=ASN1_TYPE_EMPTY;
357 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
360 asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl2);
362 result=asn1_der_decoding(&crl2,der,der_len,errorDescription);
364 if(result!=ASN1_SUCCESS){
365 printf("Problems with DER encoding\n");
366 return;
370 /* issuer */
371 get_Name_type(cert_def,crl2,"tbsCertList.issuer",str);
372 printf("crl2:\nissuer: %s\n",str);
375 /* Verify sign */
376 len = sizeof(str)-1;
377 result=asn1_read_value(crl2,"signatureAlgorithm.algorithm",str,&len);
379 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
380 if(!strcmp(str,str2)){ /* dsa-with-sha */
382 result=asn1_der_decoding_startEnd(crl2,der,der_len,
383 "tbsCertList",&start,&end);
385 /* add the lines to calculate the sha on der[start]..der[end] */
387 result=asn1_read_value(crl2,"signature",str,&len);
389 /* compare the previous value to signature ( with issuer public key) */
392 /* Use the next 3 lines to visit the certificate */
393 /* printf("-----------------\n");
394 asn1_visit_tree(crl2,"");
395 printf("-----------------\n"); */
398 /* Clear the "crl2" structure */
399 asn1_delete_structure(&crl2);
402 #include "pkix_asn1_tab.c"
404 /********************************************************/
405 /* Function : main */
406 /* Description: reads the certificate description. */
407 /* Creates a certificate and calculate */
408 /* the der encoding. After that creates */
409 /* another certificate from der string */
410 /********************************************************/
412 main(int argc,char *argv[])
414 int result,der_len;
415 unsigned char der[1024];
416 ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
417 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
419 if(1)
420 result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription);
421 else
422 result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);
424 if(result != ASN1_SUCCESS){
425 libtasn1_perror(result);
426 printf("%s\n",errorDescription);
427 exit(1);
430 /* Use the following 3 lines to visit the PKIX1Implicit structures */
431 /* printf("-----------------\n");
432 asn1_visit_tree(cert_def,"PKIX1Implicit88");
433 printf("-----------------\n"); */
435 der_len=1024;
436 create_CRL(PKIX1Implicit88,der,&der_len);
439 get_CRL(PKIX1Implicit88,der,der_len);
441 /* Clear the "PKIX1Implicit88" structures */
442 asn1_delete_structure(&PKIX1Implicit88);
444 return 0;