Optimized memory handling in the record protocol.
[gnutls.git] / src / CrlExample.c
blobc187f07af1d4cf53415fbc66ccf1eb61df2b82c6
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 "../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 */
38 /* Parameters: */
39 /* char *root: the structure identifier */
40 /* char *answer: the string with elements like: */
41 /* "C=US O=gov" */
42 /******************************************************/
43 void
44 get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
46 int k,k2,result,len;
47 char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
48 node_asn *value;
50 answer[0]=0;
51 k=1;
52 do{
53 strcpy(name,root);
54 strcat(name,".rdnSequence.?");
55 _asn1_ltostr(k,counter);
56 strcat(name,counter);
58 len = sizeof(str)-1;
59 result=asn1_read_value(cert,name,str,&len);
60 if(result==ASN_ELEMENT_NOT_FOUND) break;
61 k2=1;
62 do{
63 strcpy(name2,name);
64 strcat(name2,".?");
65 _asn1_ltostr(k2,counter);
66 strcat(name2,counter);
68 len = sizeof(str)-1;
69 result=asn1_read_value(cert,name2,str,&len);
70 if(result==ASN_ELEMENT_NOT_FOUND) break;
71 strcpy(name3,name2);
72 strcat(name3,".type");
74 len = sizeof(str)-1;
75 result=asn1_read_value(cert,name3,str,&len);
76 strcpy(name3,name2);
77 strcat(name3,".value");
78 if(result==ASN_OK){
79 len = sizeof(str2);
80 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
81 str2,&len);
82 if(!strcmp(str,str2)){
83 asn1_create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName",
84 &value,"certificate2-subject-C");
85 len = sizeof(str)-1;
86 asn1_read_value(cert,name3,str,&len);
87 asn1_get_der(value,str,len);
88 strcpy(name3,"certificate2-subject-C");
90 len = sizeof(str)-1;
91 asn1_read_value(value,name3,str,&len); /* CHOICE */
92 strcat(name3,".");
93 strcat(name3,str);
95 len = sizeof(str)-1;
96 asn1_read_value(value,name3,str,&len);
97 str[len]=0;
98 strcat(answer," C=");
99 strcat(answer,str);
100 asn1_delete_structure(value);
102 else{
103 len = sizeof(str2);
104 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
105 ,str2,&len);
106 if(!strcmp(str,str2)){
107 asn1_create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName"
108 ,&value,"certificate2-subject-O");
110 len = sizeof(str)-1;
111 asn1_read_value(cert,name3,str,&len);
112 asn1_get_der(value,str,len);
113 strcpy(name3,"certificate2-subject-O");
114 len = sizeof(str)-1;
115 asn1_read_value(value,name3,str,&len); /* CHOICE */
116 strcat(name3,".");
117 strcat(name3,str);
118 len = sizeof(str)-1;
119 asn1_read_value(value,name3,str,&len);
120 str[len]=0;
121 strcat(answer," O=");
122 strcat(answer,str);
123 asn1_delete_structure(value);
125 else{
126 len = sizeof(str2);
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");
130 len = sizeof(str)-1;
131 asn1_read_value(cert,name3,str,&len);
132 asn1_get_der(value,str,len);
133 strcpy(name3,"certificate2-subject-OU");
134 len = sizeof(str)-1;
135 asn1_read_value(value,name3,str,&len); /* CHOICE */
136 strcat(name3,".");
137 strcat(name3,str);
138 len = sizeof(str)-1;
139 asn1_read_value(value,name3,str,&len);
140 str[len]=0;
141 strcat(answer," OU=");
142 strcat(answer,str);
143 asn1_delete_structure(value);
148 k2++;
149 }while(1);
150 k++;
151 }while(1);
155 /******************************************************/
156 /* Function : create_certificate */
157 /* Description: creates a certificate named */
158 /* "certificate1". Values are the same */
159 /* as in rfc2459 Appendix D.1 */
160 /* Parameters: */
161 /* unsigned char *der: contains the der encoding */
162 /* int *der_len: number of bytes of der string */
163 /******************************************************/
164 void
165 create_CRL(node_asn *cert_def, unsigned char *der,int *der_len)
167 int result,k,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"); */
179 /* version: v2(1) */
180 result=asn1_write_value(crl,"crl1.tbsCertList.version","v2",0);
182 /* signature: dsa-with-sha */
183 len = sizeof(str)-1;
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);
195 /* C */
196 len = sizeof(str)-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);
209 /* O */
210 len = sizeof(str)-1;
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",
214 &value,"OrgName");
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);
224 /* OU */
225 len = sizeof(str)-1;
226 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
227 str,&len);
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);
237 /* validity */
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);
247 str[0]=18;
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);
253 len = sizeof(str)-1;
254 result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-cRLReasons",
255 str,&len);
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);
258 str2="\x0a\x01\x01";
259 result=asn1_write_value(crl,"crl1.tbsCertList.revokedCertificates.?LAST.crlEntryExtensions.?LAST.extnValue",str2,3);
262 /* crlExtensions */
263 result=asn1_write_value(crl,"crl1.tbsCertList.crlExtensions",NULL,0);
266 /* signatureAlgorithm: dsa-with-sha */
267 len = sizeof(str)-1;
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 */
272 /* signature */
273 result=asn1_create_der(crl,"crl1.tbsCertList",der,der_len);
274 if(result!=ASN_OK){
275 printf("\n'tbsCertList' encoding creation: ERROR\n");
276 return;
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);
290 if(result!=ASN_OK){
291 printf("\n'crl1' encoding creation: ERROR\n");
292 return;
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 */
310 /* string */
311 /* Parameters: */
312 /* unsigned char *der: the encoding string */
313 /* int der_len: number of bytes of der string */
314 /******************************************************/
315 void
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];
320 node_asn *crl2;
323 asn1_create_structure(cert_def,"PKIX1Implicit88.CertificateList",&crl2,"crl2");
325 result=asn1_get_der(crl2,der,der_len);
327 if(result!=ASN_OK){
328 printf("Problems with DER encoding\n");
329 return;
333 /* issuer */
334 get_Name_type(cert_def,crl2,"crl2.tbsCertList.issuer",str);
335 printf("crl2:\nissuer =%s\n",str);
338 /* Verify sign */
339 len = sizeof(str)-1;
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[])
376 int result,der_len;
377 unsigned char der[1024];
378 char file_name[128];
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");
385 return;
387 else if(result==ASN_SYNTAX_ERROR){
388 printf("PARSE ERROR\n");
389 return;
391 else if(result==ASN_IDENTIFIER_NOT_FOUND){
392 printf("IDENTIFIER NOT FOUND\n");
393 return;
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);
410 return;