Convert to Unix EOLs.
[platform/upstream/libtasn1.git] / src / CertificateExample.c
1 /*
2  *      Copyright (C) 2006 Free Software Foundation
3  *      Copyright (C) 2000,2001 Fabio Fiorina
4  *
5  * This file is part of LIBTASN1.
6  *
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.
11  *
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.
16  *
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
20  * 02110-1301, USA
21  */
22
23
24 /*****************************************************/
25 /* File: CertificateExample.c                        */
26 /* Description: An example on how to use the ASN1    */
27 /*              parser with the Certificate.txt file */   
28 /*****************************************************/
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include "libtasn1.h"
34
35
36 char *
37 my_ltostr(long v,char *str)
38 {
39   long d,r;
40   char temp[20];
41   int count,k,start;
42
43   if(v<0){
44     str[0]='-';
45     start=1;
46     v=-v;
47   }
48   else start=0;
49
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);
58
59   for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
60   str[count+start]=0;
61   return str;
62 }
63
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)
74 {
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];
79
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);
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);
96       len = sizeof(str) - 1;
97       result=asn1_read_value(cert,name2,str,&len);
98       if(result==ASN1_ELEMENT_NOT_FOUND) break;
99       strcpy(name3,name2);
100       strcat(name3,".type");
101       len = sizeof(str) - 1;
102       result=asn1_read_value(cert,name3,str,&len);
103       strcpy(name3,name2);
104       strcat(name3,".value");
105       if(result==ASN1_SUCCESS){
106         len = sizeof(str2) - 1;
107         result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
108                           str2,&len);
109         if(!strcmp(str,str2)){
110           asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
111                            &value);
112           len = sizeof(str) - 1;
113           asn1_read_value(cert,name3,str,&len);
114           asn1_der_decoding(&value,str,len,errorDescription);
115           len = sizeof(str) - 1;
116           asn1_read_value(value,"",str,&len);  /* CHOICE */
117           strcpy(name3,str);
118           len = sizeof(str) - 1;
119           asn1_read_value(value,name3,str,&len);
120           str[len]=0;
121           strcat(answer," C=");
122           strcat(answer,str);
123           asn1_delete_structure(&value);
124         }
125         else{
126           len = sizeof(str2) - 1;
127           result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
128                             ,str2,&len);
129           if(!strcmp(str,str2)){
130             asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
131                              ,&value);
132             len = sizeof(str) - 1;
133             asn1_read_value(cert,name3,str,&len);         
134             asn1_der_decoding(&value,str,len,errorDescription);
135             len = sizeof(str) - 1;
136             asn1_read_value(value,"",str,&len);  /* CHOICE */
137             strcpy(name3,str);
138             len = sizeof(str) - 1;
139             asn1_read_value(value,name3,str,&len);
140             str[len]=0;
141             strcat(answer," O=");
142             strcat(answer,str);
143             asn1_delete_structure(&value);
144           }
145           else{
146             len = sizeof(str2) - 1;
147             result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
148             if(!strcmp(str,str2)){
149               asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
150               len = sizeof(str) - 1;
151               asn1_read_value(cert,name3,str,&len);
152               asn1_der_decoding(&value,str,len,errorDescription);
153               len = sizeof(str) - 1;
154               asn1_read_value(value,"",str,&len);  /* CHOICE */
155               strcpy(name3,str);
156               len = sizeof(str) - 1;
157               asn1_read_value(value,name3,str,&len);
158               str[len]=0;
159               strcat(answer," OU=");
160               strcat(answer,str);
161               asn1_delete_structure(&value);
162             }
163           }
164         }
165       }
166       k2++;
167     }while(1);
168     k++;
169   }while(1);
170 }
171
172
173 /******************************************************/
174 /* Function : create_certificate                      */
175 /* Description: creates a certificate named           */
176 /*              "certificate1". Values are the same   */
177 /*              as in rfc2459 Appendix D.1            */
178 /* Parameters:                                        */
179 /*   unsigned char *der: contains the der encoding    */
180 /*   int *der_len: number of bytes of der string      */ 
181 /******************************************************/
182 void
183 create_certificate(node_asn *cert_def,unsigned char *der,int *der_len)
184 {
185   int result,k,len;
186   unsigned char str[1024],*str2;
187   ASN1_TYPE cert1=ASN1_TYPE_EMPTY;
188   ASN1_TYPE value=ASN1_TYPE_EMPTY;
189   ASN1_TYPE param=ASN1_TYPE_EMPTY;
190   ASN1_TYPE constr=ASN1_TYPE_EMPTY;
191   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
192   int max_len;
193
194   max_len=*der_len;
195
196   result=asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert1);
197  
198   /* Use the next 3 lines to visit the empty certificate */
199   /* printf("-----------------\n");
200      asn1_visit_tree(cert1,"");   
201      printf("-----------------\n"); */
202
203   /* version: v3(2) */  
204   result=asn1_write_value(cert1,"tbsCertificate.version","v3",0); 
205
206   /* serialNumber: 17 */    
207   result=asn1_write_value(cert1,"tbsCertificate.serialNumber","17",0); 
208
209   /* signature: dsa-with-sha1 */
210   len = sizeof(str) - 1;
211   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
212   result=asn1_write_value(cert1,"tbsCertificate.signature.algorithm",
213                      str,1);    
214   
215   result=asn1_write_value(cert1,"tbsCertificate.signature.parameters",
216                      NULL,0);
217
218
219   /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
220   result=asn1_write_value(cert1,"tbsCertificate.issuer","rdnSequence",12);
221
222   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
223   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
224   /* C */
225   len = sizeof(str) - 1;
226   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
227   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
228   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
229                           &value);
230   result=asn1_write_value(value,"","US",2);
231   *der_len = max_len;
232   result=asn1_der_coding(value,"",der,der_len,errorDescription);
233   asn1_delete_structure(&value);
234   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
235
236
237   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
238   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
239   /* O */
240   len = sizeof(str) - 1;
241   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
242   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
243   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
244                           &value);
245   result=asn1_write_value(value,"","printableString",1);
246   result=asn1_write_value(value,"printableString","gov",3);
247   *der_len = max_len;
248   result=asn1_der_coding(value,"",der,der_len,errorDescription);
249   asn1_delete_structure(&value);
250   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
251
252
253   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
254   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
255
256   /* OU */
257   len = sizeof(str) - 1;
258   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
259                     str,&len);
260   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
261   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
262   result=asn1_write_value(value,"","printableString",1);
263   result=asn1_write_value(value,"printableString","nist",4);
264   *der_len = max_len;
265   result=asn1_der_coding(value,"",der,der_len,errorDescription);
266   asn1_delete_structure(&value);
267   result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
268
269
270   /* validity */
271   result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore","utcTime",1);
272   result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore.utcTime","970630000000Z",1);
273
274   result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter","utcTime",1);
275   result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter.utcTime","971231000000Z",1);
276
277
278
279   /* subject: Country="US" Organization="gov" OrganizationUnit="nist" */
280   result=asn1_write_value(cert1,"tbsCertificate.subject","rdnSequence",1);
281
282   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",1);
283   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
284   /* C */
285   len = sizeof(str) - 1;
286   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
287   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
288   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
289                           &value);
290   result=asn1_write_value(value,"","US",2);
291   *der_len = max_len;
292   result=asn1_der_coding(value,"",der,der_len,errorDescription);
293   asn1_delete_structure(&value);
294   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
295
296
297   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
298   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
299   /* O */
300   len = sizeof(str) - 1;
301   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
302   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
303   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
304                           &value);
305   result=asn1_write_value(value,"","printableString",1);
306   result=asn1_write_value(value,"printableString","gov",3);
307   *der_len = max_len;
308   result=asn1_der_coding(value,"",der,der_len,errorDescription);
309   asn1_delete_structure(&value);
310   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
311
312
313   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
314   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
315   /* OU */
316   len = sizeof(str) - 1;
317   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
318                     str,&len);
319   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
320   result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
321   result=asn1_write_value(value,"","printableString",1);
322   result=asn1_write_value(value,"printableString","nist",4);
323   *der_len = max_len;
324   result=asn1_der_coding(value,"",der,der_len,errorDescription);
325   asn1_delete_structure(&value);
326   result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
327
328
329   /* subjectPublicKeyInfo: dsa with parameters=Dss-Parms */
330   len = sizeof(str) - 1;
331   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa",str,&len);
332   result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",str,1); 
333   result=asn1_create_element(cert_def,"PKIX1Implicit88.Dss-Parms",&param);
334   str2="\xd4\x38"; /* only an example */
335   result=asn1_write_value(param,"p",str2,128);
336   str2="\xd4\x38"; /* only an example */
337   result=asn1_write_value(param,"q",str2,20);
338   str2="\xd4\x38"; /* only an example */
339   result=asn1_write_value(param,"g",str2,128);
340   *der_len = max_len;
341   result=asn1_der_coding(param,"",der,der_len,errorDescription);
342   asn1_delete_structure(&param);
343   result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len); 
344
345
346   /* subjectPublicKey */
347   str2="\x02\x81"; /* only an example */
348   result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",str2,1048);
349
350   result=asn1_write_value(cert1,"tbsCertificate.issuerUniqueID",NULL,0);  /* NO OPTION */
351   result=asn1_write_value(cert1,"tbsCertificate.subjectUniqueID",NULL,0); /* NO OPTION */
352
353   /* extensions */
354   result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1); 
355   len = sizeof(str) - 1;
356   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-basicConstraints",
357                     str,&len);
358   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /*   basicConstraints */  
359   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","TRUE",1); 
360   result=asn1_create_element(cert_def,"PKIX1Implicit88.BasicConstraints",&constr);
361   result=asn1_write_value(constr,"cA","TRUE",1); 
362   result=asn1_write_value(constr,"pathLenConstraint",NULL,0); 
363   *der_len = max_len; 
364   result=asn1_der_coding(constr,"",der,der_len,errorDescription);
365   result=asn1_delete_structure(&constr);
366   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",der,*der_len); 
367
368
369   result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1); 
370   len = sizeof(str) - 1;
371   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-subjectKeyIdentifier",
372                     str,&len);
373   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /* subjectKeyIdentifier */ 
374   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","FALSE",1); 
375   str2="\x04\x14\xe7\x26\xc5"; /* only an example */
376   result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",str2,22); 
377
378
379   /* signatureAlgorithm: dsa-with-sha  */
380   len = sizeof(str) - 1;
381   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
382   result=asn1_write_value(cert1,"signatureAlgorithm.algorithm",str,1); 
383   result=asn1_write_value(cert1,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */  
384
385
386   /* signature */
387   *der_len = max_len;
388   result=asn1_der_coding(cert1,"tbsCertificate",der,der_len
389                          ,errorDescription);
390   if(result!=ASN1_SUCCESS){
391     printf("\n'tbsCertificate' encoding creation: ERROR\n");
392   }
393   /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
394   result=asn1_write_value(cert1,"signature",str2,368); /* dsa-with-sha */ 
395   
396
397   /* Use the next 3 lines to visit the certificate */
398   /* printf("-----------------\n");   
399      asn1_visit_tree(cert1,"");  
400      printf("-----------------\n"); */
401
402   *der_len = max_len;
403   result=asn1_der_coding(cert1,"",der,der_len,errorDescription);
404   if(result!=ASN1_SUCCESS){
405     printf("\n'certificate' encoding creation: ERROR\n");
406     return;
407   }
408
409   /* Print the 'Certificate1' DER encoding */ 
410   printf("-----------------\nCertificate Encoding:\nNumber of bytes=%i\n",*der_len);
411   for(k=0;k<*der_len;k++) printf("%02x ",der[k]);  
412   printf("\n-----------------\n");
413
414   /* Clear the "certificate1" structure */
415   asn1_delete_structure(&cert1);
416 }
417
418
419
420 /******************************************************/
421 /* Function : get_certificate                         */
422 /* Description: creates a certificate named           */
423 /*              "certificate2" from a der encoding    */
424 /*              string                                */
425 /* Parameters:                                        */
426 /*   unsigned char *der: the encoding string          */
427 /*   int der_len: number of bytes of der string      */ 
428 /******************************************************/
429 void
430 get_certificate(node_asn *cert_def,unsigned char *der,int der_len)
431 {
432   int result,len,start,end;
433   unsigned char str[1024],str2[1024];
434   ASN1_TYPE cert2=ASN1_TYPE_EMPTY;
435   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
436
437   asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert2);
438
439   result=asn1_der_decoding(&cert2,der,der_len,errorDescription);
440
441   if(result!=ASN1_SUCCESS){
442     printf("Problems with DER encoding\n");
443     return;
444   }
445    
446
447   /* issuer */
448   get_Name_type(cert_def,cert2,"tbsCertificate.issuer",str);
449   printf("certificate:\nissuer :%s\n",str);
450   /* subject */
451   get_Name_type(cert_def,cert2,"tbsCertificate.subject",str);
452   printf("subject:%s\n",str);
453
454
455   /* Verify sign */
456   len = sizeof(str) - 1;
457   result=asn1_read_value(cert2,"signatureAlgorithm.algorithm"
458                     ,str,&len);
459
460   len = sizeof(str2) - 1;
461   result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
462   if(!strcmp(str,str2)){  /* dsa-with-sha */
463
464     result=asn1_der_decoding_startEnd(cert2,der,der_len,
465                              "tbsCertificate",&start,&end);
466
467     /* add the lines to calculate the sha on der[start]..der[end] */
468
469     len = sizeof(str) - 1;
470     result=asn1_read_value(cert2,"signature",str,&len);
471
472     /* compare the previous value to signature ( with issuer public key) */ 
473   }
474
475   /* Use the next 3 lines to visit the certificate */
476   /*   printf("-----------------\n");   
477      asn1_visit_tree(cert2,"");  
478      printf("-----------------\n"); */
479
480
481   /* Clear the "certificate2" structure */
482   asn1_delete_structure(&cert2);
483 }
484
485 #include "pkix_asn1_tab.c"
486
487 /********************************************************/
488 /* Function : main                                      */
489 /* Description: reads the certificate description.      */
490 /*              Creates a certificate and calculate     */
491 /*              the der encoding. After that creates    */  
492 /*              another certificate from der string     */
493 /********************************************************/
494 int
495 main(int argc,char *argv[])
496 {
497   int result,der_len;
498   unsigned char der[1024];
499   ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
500   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
501
502   if(1)
503     result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription); 
504   else
505     result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);
506
507   if(result != ASN1_SUCCESS){
508     libtasn1_perror(result);
509     printf("%s",errorDescription);
510     exit(1);
511   }
512
513   
514   /* Use the following 3 lines to visit the PKIX1Implicit structures */
515   /* printf("-----------------\n");
516      asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88");   
517      printf("-----------------\n"); */
518
519   der_len=1024;
520   create_certificate(PKIX1Implicit88,der,&der_len);
521
522   get_certificate(PKIX1Implicit88,der,der_len);
523
524   /* Clear the "PKIX1Implicit88" structures */
525   asn1_delete_structure(&PKIX1Implicit88);
526
527   return 0;
528 }
529
530
531
532
533
534
535
536
537