Upstream update.
[shishi.git] / asn1 / src / CertificateExample.c
blob2f3bf96d1cb82555df1e5604658a3d8dd89b8a55
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: CertificateExample.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"
33 char *
34 my_ltostr(long v,char *str)
36 long d,r;
37 char temp[20];
38 int count,k,start;
40 if(v<0){
41 str[0]='-';
42 start=1;
43 v=-v;
45 else start=0;
47 count=0;
48 do{
49 d=v/10;
50 r=v-d*10;
51 temp[start+count]='0'+(char)r;
52 count++;
53 v=d;
54 }while(v);
56 for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
57 str[count+start]=0;
58 return str;
61 /******************************************************/
62 /* Function : get_name_type */
63 /* Description: analyze a structure of type Name */
64 /* Parameters: */
65 /* char *root: the structure identifier */
66 /* char *answer: the string with elements like: */
67 /* "C=US O=gov" */
68 /******************************************************/
69 void
70 get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
72 int k,k2,result,len;
73 char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
74 ASN1_TYPE value=ASN1_TYPE_EMPTY;
75 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
77 answer[0]=0;
78 k=1;
79 do{
80 strcpy(name,root);
81 strcat(name,".rdnSequence.?");
82 my_ltostr(k,counter);
83 strcat(name,counter);
84 len = sizeof(str) - 1;
85 result=asn1_read_value(cert,name,str,&len);
86 if(result==ASN1_ELEMENT_NOT_FOUND) break;
87 k2=1;
88 do{
89 strcpy(name2,name);
90 strcat(name2,".?");
91 my_ltostr(k2,counter);
92 strcat(name2,counter);
93 len = sizeof(str) - 1;
94 result=asn1_read_value(cert,name2,str,&len);
95 if(result==ASN1_ELEMENT_NOT_FOUND) break;
96 strcpy(name3,name2);
97 strcat(name3,".type");
98 len = sizeof(str) - 1;
99 result=asn1_read_value(cert,name3,str,&len);
100 strcpy(name3,name2);
101 strcat(name3,".value");
102 if(result==ASN1_SUCCESS){
103 len = sizeof(str2) - 1;
104 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
105 str2,&len);
106 if(!strcmp(str,str2)){
107 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
108 &value);
109 len = sizeof(str) - 1;
110 asn1_read_value(cert,name3,str,&len);
111 asn1_der_decoding(&value,str,len,errorDescription);
112 len = sizeof(str) - 1;
113 asn1_read_value(value,"",str,&len); /* CHOICE */
114 strcpy(name3,str);
115 len = sizeof(str) - 1;
116 asn1_read_value(value,name3,str,&len);
117 str[len]=0;
118 strcat(answer," C=");
119 strcat(answer,str);
120 asn1_delete_structure(&value);
122 else{
123 len = sizeof(str2) - 1;
124 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
125 ,str2,&len);
126 if(!strcmp(str,str2)){
127 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
128 ,&value);
129 len = sizeof(str) - 1;
130 asn1_read_value(cert,name3,str,&len);
131 asn1_der_decoding(&value,str,len,errorDescription);
132 len = sizeof(str) - 1;
133 asn1_read_value(value,"",str,&len); /* CHOICE */
134 strcpy(name3,str);
135 len = sizeof(str) - 1;
136 asn1_read_value(value,name3,str,&len);
137 str[len]=0;
138 strcat(answer," O=");
139 strcat(answer,str);
140 asn1_delete_structure(&value);
142 else{
143 len = sizeof(str2) - 1;
144 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
145 if(!strcmp(str,str2)){
146 asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
147 len = sizeof(str) - 1;
148 asn1_read_value(cert,name3,str,&len);
149 asn1_der_decoding(&value,str,len,errorDescription);
150 len = sizeof(str) - 1;
151 asn1_read_value(value,"",str,&len); /* CHOICE */
152 strcpy(name3,str);
153 len = sizeof(str) - 1;
154 asn1_read_value(value,name3,str,&len);
155 str[len]=0;
156 strcat(answer," OU=");
157 strcat(answer,str);
158 asn1_delete_structure(&value);
163 k2++;
164 }while(1);
165 k++;
166 }while(1);
170 /******************************************************/
171 /* Function : create_certificate */
172 /* Description: creates a certificate named */
173 /* "certificate1". Values are the same */
174 /* as in rfc2459 Appendix D.1 */
175 /* Parameters: */
176 /* unsigned char *der: contains the der encoding */
177 /* int *der_len: number of bytes of der string */
178 /******************************************************/
179 void
180 create_certificate(node_asn *cert_def,unsigned char *der,int *der_len)
182 int result,k,len;
183 unsigned char str[1024],*str2;
184 ASN1_TYPE cert1=ASN1_TYPE_EMPTY;
185 ASN1_TYPE value=ASN1_TYPE_EMPTY;
186 ASN1_TYPE param=ASN1_TYPE_EMPTY;
187 ASN1_TYPE constr=ASN1_TYPE_EMPTY;
188 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
190 result=asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert1);
192 /* Use the next 3 lines to visit the empty certificate */
193 /* printf("-----------------\n");
194 asn1_visit_tree(cert1,"");
195 printf("-----------------\n"); */
197 /* version: v3(2) */
198 result=asn1_write_value(cert1,"tbsCertificate.version","v3",0);
200 /* serialNumber: 17 */
201 result=asn1_write_value(cert1,"tbsCertificate.serialNumber","17",0);
203 /* signature: dsa-with-sha1 */
204 len = sizeof(str) - 1;
205 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
206 result=asn1_write_value(cert1,"tbsCertificate.signature.algorithm",
207 str,1);
209 result=asn1_write_value(cert1,"tbsCertificate.signature.parameters",
210 NULL,0);
213 /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
214 result=asn1_write_value(cert1,"tbsCertificate.issuer","rdnSequence",12);
216 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
217 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
218 /* C */
219 len = sizeof(str) - 1;
220 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
221 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
222 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
223 &value);
224 result=asn1_write_value(value,"","US",2);
225 result=asn1_der_coding(value,"",der,der_len,errorDescription);
226 asn1_delete_structure(&value);
227 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
230 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
231 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
232 /* O */
233 len = sizeof(str) - 1;
234 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
235 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
236 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
237 &value);
238 result=asn1_write_value(value,"","printableString",1);
239 result=asn1_write_value(value,"printableString","gov",3);
240 result=asn1_der_coding(value,"",der,der_len,errorDescription);
241 asn1_delete_structure(&value);
242 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
245 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
246 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
248 /* OU */
249 len = sizeof(str) - 1;
250 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
251 str,&len);
252 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
253 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
254 result=asn1_write_value(value,"","printableString",1);
255 result=asn1_write_value(value,"printableString","nist",4);
256 result=asn1_der_coding(value,"",der,der_len,errorDescription);
257 asn1_delete_structure(&value);
258 result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
261 /* validity */
262 result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore","utcTime",1);
263 result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore.utcTime","970630000000Z",1);
265 result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter","utcTime",1);
266 result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter.utcTime","971231000000Z",1);
270 /* subject: Country="US" Organization="gov" OrganizationUnit="nist" */
271 result=asn1_write_value(cert1,"tbsCertificate.subject","rdnSequence",1);
273 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",1);
274 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
275 /* C */
276 len = sizeof(str) - 1;
277 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
278 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
279 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
280 &value);
281 result=asn1_write_value(value,"","US",2);
282 result=asn1_der_coding(value,"",der,der_len,errorDescription);
283 asn1_delete_structure(&value);
284 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
287 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
288 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
289 /* O */
290 len = sizeof(str) - 1;
291 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
292 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
293 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
294 &value);
295 result=asn1_write_value(value,"","printableString",1);
296 result=asn1_write_value(value,"printableString","gov",3);
297 result=asn1_der_coding(value,"",der,der_len,errorDescription);
298 asn1_delete_structure(&value);
299 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
302 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
303 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
304 /* OU */
305 len = sizeof(str) - 1;
306 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
307 str,&len);
308 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
309 result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
310 result=asn1_write_value(value,"","printableString",1);
311 result=asn1_write_value(value,"printableString","nist",4);
312 result=asn1_der_coding(value,"",der,der_len,errorDescription);
313 asn1_delete_structure(&value);
314 result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
317 /* subjectPublicKeyInfo: dsa with parameters=Dss-Parms */
318 len = sizeof(str) - 1;
319 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa",str,&len);
320 result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",str,1);
321 result=asn1_create_element(cert_def,"PKIX1Implicit88.Dss-Parms",&param);
322 str2="\xd4\x38"; /* only an example */
323 result=asn1_write_value(param,"p",str2,128);
324 str2="\xd4\x38"; /* only an example */
325 result=asn1_write_value(param,"q",str2,20);
326 str2="\xd4\x38"; /* only an example */
327 result=asn1_write_value(param,"g",str2,128);
328 result=asn1_der_coding(param,"",der,der_len,errorDescription);
329 asn1_delete_structure(&param);
330 result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len);
333 /* subjectPublicKey */
334 str2="\x02\x81"; /* only an example */
335 result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",str2,1048);
337 result=asn1_write_value(cert1,"tbsCertificate.issuerUniqueID",NULL,0); /* NO OPTION */
338 result=asn1_write_value(cert1,"tbsCertificate.subjectUniqueID",NULL,0); /* NO OPTION */
340 /* extensions */
341 result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1);
342 len = sizeof(str) - 1;
343 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-basicConstraints",
344 str,&len);
345 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /* basicConstraints */
346 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","TRUE",1);
347 result=asn1_create_element(cert_def,"PKIX1Implicit88.BasicConstraints",&constr);
348 result=asn1_write_value(constr,"cA","TRUE",1);
349 result=asn1_write_value(constr,"pathLenConstraint",NULL,0);
350 result=asn1_der_coding(constr,"",der,der_len,errorDescription);
351 result=asn1_delete_structure(&constr);
352 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",der,*der_len);
355 result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1);
356 len = sizeof(str) - 1;
357 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-subjectKeyIdentifier",
358 str,&len);
359 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /* subjectKeyIdentifier */
360 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","FALSE",1);
361 str2="\x04\x14\xe7\x26\xc5"; /* only an example */
362 result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",str2,22);
365 /* signatureAlgorithm: dsa-with-sha */
366 len = sizeof(str) - 1;
367 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
368 result=asn1_write_value(cert1,"signatureAlgorithm.algorithm",str,1);
369 result=asn1_write_value(cert1,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
372 /* signature */
373 result=asn1_der_coding(cert1,"tbsCertificate",der,der_len
374 ,errorDescription);
375 if(result!=ASN1_SUCCESS){
376 printf("\n'tbsCertificate' encoding creation: ERROR\n");
378 /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
379 result=asn1_write_value(cert1,"signature",str2,368); /* dsa-with-sha */
382 /* Use the next 3 lines to visit the certificate */
383 /* printf("-----------------\n");
384 asn1_visit_tree(cert1,"");
385 printf("-----------------\n"); */
388 result=asn1_der_coding(cert1,"",der,der_len,errorDescription);
389 if(result!=ASN1_SUCCESS){
390 printf("\n'certificate' encoding creation: ERROR\n");
391 return;
394 /* Print the 'Certificate1' DER encoding */
395 printf("-----------------\nCertificate Encoding:\nNumber of bytes=%i\n",*der_len);
396 for(k=0;k<*der_len;k++) printf("%02x ",der[k]);
397 printf("\n-----------------\n");
399 /* Clear the "certificate1" structure */
400 asn1_delete_structure(&cert1);
405 /******************************************************/
406 /* Function : get_certificate */
407 /* Description: creates a certificate named */
408 /* "certificate2" from a der encoding */
409 /* string */
410 /* Parameters: */
411 /* unsigned char *der: the encoding string */
412 /* int der_len: number of bytes of der string */
413 /******************************************************/
414 void
415 get_certificate(node_asn *cert_def,unsigned char *der,int der_len)
417 int result,len,start,end;
418 unsigned char str[1024],str2[1024];
419 ASN1_TYPE cert2=ASN1_TYPE_EMPTY;
420 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
422 asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert2);
424 result=asn1_der_decoding(&cert2,der,der_len,errorDescription);
426 if(result!=ASN1_SUCCESS){
427 printf("Problems with DER encoding\n");
428 return;
432 /* issuer */
433 get_Name_type(cert_def,cert2,"tbsCertificate.issuer",str);
434 printf("certificate:\nissuer :%s\n",str);
435 /* subject */
436 get_Name_type(cert_def,cert2,"tbsCertificate.subject",str);
437 printf("subject:%s\n",str);
440 /* Verify sign */
441 len = sizeof(str) - 1;
442 result=asn1_read_value(cert2,"signatureAlgorithm.algorithm"
443 ,str,&len);
445 len = sizeof(str2) - 1;
446 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
447 if(!strcmp(str,str2)){ /* dsa-with-sha */
449 result=asn1_der_decoding_startEnd(cert2,der,der_len,
450 "tbsCertificate",&start,&end);
452 /* add the lines to calculate the sha on der[start]..der[end] */
454 len = sizeof(str) - 1;
455 result=asn1_read_value(cert2,"signature",str,&len);
457 /* compare the previous value to signature ( with issuer public key) */
460 /* Use the next 3 lines to visit the certificate */
461 /* printf("-----------------\n");
462 asn1_visit_tree(cert2,"");
463 printf("-----------------\n"); */
466 /* Clear the "certificate2" structure */
467 asn1_delete_structure(&cert2);
470 #include "pkix_asn1_tab.c"
472 /********************************************************/
473 /* Function : main */
474 /* Description: reads the certificate description. */
475 /* Creates a certificate and calculate */
476 /* the der encoding. After that creates */
477 /* another certificate from der string */
478 /********************************************************/
480 main(int argc,char *argv[])
482 int result,der_len;
483 unsigned char der[1024];
484 ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
485 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
487 if(1)
488 result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription);
489 else
490 result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);
492 if(result != ASN1_SUCCESS){
493 libtasn1_perror(result);
494 printf("%s",errorDescription);
495 exit(1);
499 /* Use the following 3 lines to visit the PKIX1Implicit structures */
500 /* printf("-----------------\n");
501 asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88");
502 printf("-----------------\n"); */
505 create_certificate(PKIX1Implicit88,der,&der_len);
507 get_certificate(PKIX1Implicit88,der,der_len);
509 /* Clear the "PKIX1Implicit88" structures */
510 asn1_delete_structure(&PKIX1Implicit88);
512 return 0;