fabee20ea65a7f5eb16fdf86201b350cb6ed574d
[project/luci.git] / contrib / package / px5g / src / library / x509write.c
1 /*
2  *  X.509 certificate and private key writing
3  *
4  *  Copyright (C) 2006-2007  Pascal Vizeli <pvizeli@yahoo.de>
5  *  Modifications (C) 2009 Steven Barth <steven@midlink.org>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License, version 2.1 as published by the Free Software Foundation.
10  *
11  *  This library 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 GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA  02110-1301  USA
20  */
21 /*
22  *  The ITU-T X.509 standard defines a certificat format for PKI.
23  *
24  *  http://www.ietf.org/rfc/rfc2459.txt
25  *  http://www.ietf.org/rfc/rfc3279.txt
26  *
27  *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
28  *
29  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
30  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
31  *
32  *  For CRS:
33  *  http://www.faqs.org/rfcs/rfc2314.html
34  */
35 #include "polarssl/config.h"
36 #include "polarssl/x509.h"
37 #include "polarssl/base64.h"
38 #include "polarssl/sha1.h"
39
40 #include <string.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <stdarg.h>
44 #include <time.h>
45
46 #define and &&
47 #define or ||
48
49 #if defined _MSC_VER && !defined snprintf
50 #define snprintf _snprintf
51 #endif
52
53 static int x509write_realloc_node(x509_node *node, size_t larger);
54 static int x509write_file(x509_node *node, char *path, int format, const char* pem_prolog, const char* pem_epilog);
55
56 /*
57  * evaluate how mani octet have this integer
58  */
59 static int asn1_eval_octet(unsigned int digit)
60 {
61     int i, byte;
62
63     for (byte = 4, i = 24; i >= 0; i -= 8, --byte)
64         if (((digit >> i) & 0xFF) != 0)
65             return byte;
66
67     return 0;
68 }
69
70 /*
71  * write the asn.1 lenght form into p
72  */
73 static int asn1_add_len(unsigned int size, x509_node *node)
74 {
75     if (size > 127) {
76
77         /* long size */
78         int byte = asn1_eval_octet(size);
79         int i = 0;
80
81         *(node->p) = (0x80 | byte) & 0xFF;
82         ++node->p;
83
84         for (i = byte; i > 0; --i) {
85
86             *(node->p) = (size >> ((i - 1) * 8)) & 0xFF;
87             ++node->p;
88         }
89
90     } else {
91
92         /* short size */
93         *(node->p) = size & 0xFF;
94         if (size != 0)
95             ++node->p;
96     }
97
98     return 0;
99 }
100
101 /*
102  * write a ans.1 object into p
103  */
104 static int asn1_add_obj(unsigned char *value, unsigned int size, int tag,
105         x509_node *node)
106 {
107     int tl = 2;
108
109     if (tag == ASN1_BIT_STRING)
110         ++tl;
111
112     if (size > 127)
113         x509write_realloc_node(node, (size_t) size + tl +
114                 asn1_eval_octet(size));
115     else
116         x509write_realloc_node(node, (size_t) size + tl);
117
118     if (node->data == NULL)
119         return 1;
120
121     /* tag */
122     *(node->p) = tag & 0xFF;
123     ++node->p;
124
125     /* len */
126     if (tag == ASN1_BIT_STRING) {
127         asn1_add_len((unsigned int) size + 1, node);
128         *(node->p) = 0x00;
129         ++node->p;
130     } else {
131         asn1_add_len((unsigned int) size, node);
132     }
133
134     /* value */
135     if (size > 0) {
136
137         memcpy(node->p, value, (size_t) size);
138         if ((node->p += size -1) != node->end)
139             return POLARSSL_ERR_X509_POINT_ERROR;
140     } else {
141         /* make nothing -> NULL */
142     }
143
144     return 0;
145 }
146
147 /*
148  * write a asn.1 conform integer object
149  */
150 static int asn1_add_int(signed int value, x509_node *node)
151 {
152     signed int i = 0, neg = 1;
153     unsigned int byte, u_val = 0, tmp_val = 0;
154
155     /* if negate? */
156     if (value < 0) {
157         neg = -1;
158         u_val = ~value;
159     } else {
160         u_val = value;
161     }
162
163     byte = asn1_eval_octet(u_val);
164     /* 0 isn't NULL */
165     if (byte == 0)
166         byte = 1;
167
168     /* ASN.1 integer is signed! */
169     if (byte < 4 and ((u_val >> ((byte -1) * 8)) & 0xFF) == 0x80)
170         byte += 1;
171
172     if (x509write_realloc_node(node, (size_t) byte + 2) != 0)
173         return 1;
174
175     /* tag */
176     *(node->p) = ASN1_INTEGER;
177     ++node->p;
178
179     /* len */
180     asn1_add_len(byte, node);
181
182     /* value */
183     for (i = byte; i > 0; --i) {
184
185         tmp_val = (u_val >> ((i - 1) * 8)) & 0xFF;
186         if (neg == 1)
187             *(node->p) = tmp_val;
188         else
189             *(node->p) = ~tmp_val;
190
191         if (i > 1)
192           ++node->p;
193     }
194
195     if (node->p != node->end)
196         return POLARSSL_ERR_X509_POINT_ERROR;
197
198     return 0;
199 }
200
201 /*
202  * write a asn.1 conform mpi object
203  */
204 static int asn1_add_mpi(mpi *value, int tag, x509_node *node)
205 {
206     size_t size = (mpi_msb(value) / 8) + 1;
207     unsigned char *buf;
208     int buf_len = (int) size, tl = 2;
209
210     if (tag == ASN1_BIT_STRING)
211         ++tl;
212
213     if (size > 127)
214         x509write_realloc_node(node, size + (size_t) tl +
215             asn1_eval_octet((unsigned int)size));
216     else
217         x509write_realloc_node(node, size + (size_t) tl);
218
219     if (node->data == NULL)
220         return 1;
221
222     buf = (unsigned char*) malloc(size);
223     if (mpi_write_binary(value, buf, buf_len) != 0)
224         return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL;
225
226     /* tag */
227     *(node->p) = tag & 0xFF;
228     ++node->p;
229
230     /* len */
231     if (tag == ASN1_BIT_STRING) {
232         asn1_add_len((unsigned int) size + 1, node);
233         *(node->p) = 0x00;
234         ++node->p;
235     } else {
236         asn1_add_len((unsigned int) size, node);
237     }
238
239     /* value */
240     memcpy(node->p, buf, size);
241     free(buf);
242
243     if ((node->p += (int) size -1) != node->end)
244         return POLARSSL_ERR_X509_POINT_ERROR;
245
246     return 0;
247 }
248
249 /*
250  * write a node into asn.1 conform object
251  */
252 static int asn1_append_tag(x509_node *node, int tag)
253 {
254     int tl = 2;
255
256     x509_node tmp;
257     x509write_init_node(&tmp);
258
259     if (tag == ASN1_BIT_STRING)
260         ++tl;
261
262     if (node->len > 127)
263         x509write_realloc_node(&tmp, node->len + (size_t) tl +
264             asn1_eval_octet((unsigned int)node->len));
265     else
266         x509write_realloc_node(&tmp, node->len + (size_t) tl);
267
268     if (tmp.data == NULL) {
269         x509write_free_node(&tmp);
270         return 1;
271     }
272
273     /* tag */
274     *(tmp.p) = tag & 0xFF;
275     ++tmp.p;
276
277     /* len */
278     if (tag == ASN1_BIT_STRING) {
279         asn1_add_len((unsigned int) node->len + 1, &tmp);
280         *(tmp.p) = 0x00;
281         ++tmp.p;
282     } else {
283         asn1_add_len((unsigned int) node->len, &tmp);
284     }
285
286     /* value */
287     memcpy(tmp.p, node->data, node->len);
288
289     /* good? */
290     if ((tmp.p += (int) node->len -1) != tmp.end) {
291         x509write_free_node(&tmp);
292         return POLARSSL_ERR_X509_POINT_ERROR;
293     }
294
295     free(node->data);
296     node->data = tmp.data;
297     node->p = tmp.p;
298     node->end = tmp.end;
299     node->len = tmp.len;
300
301     return 0;
302 }
303
304 /*
305  * write nodes into a asn.1 object
306  */
307 static int asn1_append_nodes(x509_node *node, int tag, int anz, ...)
308 {
309     va_list ap;
310     size_t size = 0;
311     x509_node *tmp;
312     int count;
313
314     va_start(ap, anz);
315     count = anz;
316
317     while (count--) {
318
319         tmp = va_arg(ap, x509_node*);
320         if (tmp->data != NULL)
321             size += tmp->len;
322     }
323
324     if ( size > 127) {
325         if (x509write_realloc_node(node, size + (size_t) 2 +
326                     asn1_eval_octet(size)) != 0)
327             return 1;
328     } else {
329         if (x509write_realloc_node(node, size + (size_t) 2) != 0)
330             return 1;
331     }
332
333     /* tag */
334     *(node->p) = tag & 0xFF;
335     ++node->p;
336
337     /* len */
338     asn1_add_len(size, node);
339
340     /* value */
341     va_start(ap, anz);
342     count = anz;
343
344     while (count--) {
345
346         tmp = va_arg(ap, x509_node*);
347         if (tmp->data != NULL) {
348
349             memcpy(node->p, tmp->data, tmp->len);
350             if ((node->p += (int) tmp->len -1) != node->end)
351                 ++node->p;
352         }
353     }
354
355     va_end(ap);
356     return 0;
357 }
358
359 /*
360  * write a ASN.1 conform object identifiere include a "tag"
361  */
362 static int asn1_add_oid(x509_node *node, unsigned char *oid, size_t len,
363         int tag, int tag_val, unsigned char *value, size_t val_len)
364 {
365     int ret;
366     x509_node tmp;
367
368     x509write_init_node(&tmp);
369
370     /* OBJECT IDENTIFIER */
371     if ((ret = asn1_add_obj(oid, len, ASN1_OID, &tmp)) != 0) {
372         x509write_free_node(&tmp);
373         return ret;
374     }
375
376     /* value */
377     if ((ret = asn1_add_obj(value, val_len, tag_val, &tmp)) != 0) {
378         x509write_free_node(&tmp);
379         return ret;
380     }
381
382     /* SET/SEQUENCE */
383     if ((ret = asn1_append_nodes(node, tag, 1, &tmp)) != 0) {
384         x509write_free_node(&tmp);
385         return ret;
386     }
387
388     x509write_free_node(&tmp);
389     return 0;
390 }
391
392 /*
393  *  utcTime        UTCTime
394  */
395 static int asn1_add_date_utc(unsigned char *time, x509_node *node)
396 {
397     unsigned char date[13], *sp;
398     x509_time xtime;
399     int ret;
400
401     sscanf((char*)time, "%d-%d-%d %d:%d:%d", &xtime.year, &xtime.mon,
402         &xtime.day, &xtime.hour, &xtime.min, &xtime.sec);
403
404     /* convert to YY */
405     if (xtime.year > 2000)
406         xtime.year -= 2000;
407     else
408         xtime.year -= 1900;
409
410     snprintf((char*)date, 13, "%2d%2d%2d%2d%2d%2d", xtime.year, xtime.mon, xtime.day,
411         xtime.hour, xtime.min, xtime.sec);
412
413     /* replace ' ' to '0' */
414     for (sp = date; *sp != '\0'; ++sp)
415         if (*sp == '\x20')
416             *sp = '\x30';
417
418     date[12] = 'Z';
419
420     if ((ret = asn1_add_obj(date, 13, ASN1_UTC_TIME, node)) != 0)
421         return ret;
422
423     return 0;
424 }
425
426 /*
427  * serialize an rsa key into DER
428  */
429
430 int x509write_serialize_key(rsa_context *rsa, x509_node *node)
431 {
432     int ret = 0;
433     x509write_init_node(node);
434
435     /* vers, n, e, d, p, q, dp, dq, pq */
436     if ((ret = asn1_add_int(rsa->ver, node)) != 0)
437         return ret;
438     if ((ret = asn1_add_mpi(&rsa->N, ASN1_INTEGER, node)) != 0)
439         return ret;
440     if ((ret = asn1_add_mpi(&rsa->E, ASN1_INTEGER, node)) != 0)
441         return ret;
442     if ((ret = asn1_add_mpi(&rsa->D, ASN1_INTEGER, node)) != 0)
443         return ret;
444     if ((ret = asn1_add_mpi(&rsa->P, ASN1_INTEGER, node)) != 0)
445         return ret;
446     if ((ret = asn1_add_mpi(&rsa->Q, ASN1_INTEGER, node)) != 0)
447         return ret;
448     if ((ret = asn1_add_mpi(&rsa->DP, ASN1_INTEGER, node)) != 0)
449         return ret;
450     if ((ret = asn1_add_mpi(&rsa->DQ, ASN1_INTEGER, node)) != 0)
451         return ret;
452     if ((ret = asn1_add_mpi(&rsa->QP, ASN1_INTEGER, node)) != 0)
453         return ret;
454     if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
455         return ret;
456
457     return 0;
458 }
459
460 /*
461  * write a der/pem encoded rsa private key into a file
462  */
463 int x509write_keyfile(rsa_context *rsa, char *path, int out_flag)
464 {
465     int ret = 0;
466     const char  key_beg[] = "-----BEGIN RSA PRIVATE KEY-----\n",
467                 key_end[] = "-----END RSA PRIVATE KEY-----\n";
468     x509_node node;
469
470     x509write_init_node(&node);
471     if ((ret = x509write_serialize_key(rsa,&node)) != 0) {
472         x509write_free_node(&node);
473               return ret;
474     }
475
476     ret = x509write_file(&node,path,out_flag,key_beg,key_end);
477     x509write_free_node(&node);
478
479     return ret;
480 }
481
482
483 /*
484  * reasize the memory for node
485  */
486 static int x509write_realloc_node(x509_node *node, size_t larger)
487 {
488     /* init len */
489     if (node->data == NULL) {
490         node->len = 0;
491         node->data = malloc(larger);
492         if(node->data == NULL)
493             return 1;
494     } else {
495         /* realloc memory */
496         if ((node->data = realloc(node->data, node->len + larger)) == NULL)
497             return 1;
498     }
499
500     /* init pointer */
501     node->p = &node->data[node->len];
502     node->len += larger;
503     node->end = &node->data[node->len -1];
504
505     return 0;
506 }
507
508 /*
509  * init node
510  */
511 void x509write_init_node(x509_node *node)
512 {
513     memset(node, 0, sizeof(x509_node));
514 }
515
516 /*
517  * clean memory
518  */
519 void x509write_free_node(x509_node *node)
520 {
521     if (node->data != NULL)
522         free(node->data);
523     node->p = NULL;
524     node->end = NULL;
525     node->len = 0;
526 }
527
528 /*
529  * write a x509 certificate into file
530  */
531 int x509write_crtfile(x509_raw *chain, unsigned char *path, int out_flag)
532 {
533     const char  cer_beg[] = "-----BEGIN CERTIFICATE-----\n",
534                 cer_end[] = "-----END CERTIFICATE-----\n";
535
536     return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end);
537 }
538
539 /*
540  * write a x509 certificate into file
541  */
542 int x509write_csrfile(x509_raw *chain, unsigned char *path, int out_flag)
543 {
544     const char  cer_beg[] = "-----BEGIN CERTIFICATE REQUEST-----\n",
545                 cer_end[] = "-----END CERTIFICATE REQUEST-----\n";
546
547     return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end);
548 }
549
550 /*
551  * write an x509 file
552  */
553 static int x509write_file(x509_node *node, char *path, int format,
554         const char* pem_prolog, const char* pem_epilog)
555 {
556     FILE *ofstream = stdout;
557     int is_err = 1, buf_len, i, n;
558     unsigned char* base_buf;
559
560     if (path) {
561         if ((ofstream = fopen(path, "wb")) == NULL)
562                 return 1;
563     }
564
565     switch (format) {
566         case X509_OUTPUT_DER:
567             if (fwrite(node->data, 1, node->len, ofstream)
568                 != node->len)
569                 is_err = -1;
570             break;
571
572         case X509_OUTPUT_PEM:
573             if (fprintf(ofstream,pem_prolog)<0) {
574                 is_err = -1;
575                 break;
576             }
577
578             buf_len = node->len << 1;
579             base_buf = (unsigned char*) malloc((size_t)buf_len);
580             memset(base_buf,0,buf_len);
581             if (base64_encode(base_buf, &buf_len, node->data,
582                         (int) node->len) != 0) {
583                 is_err = -1;
584                 break;
585             }
586
587             n=strlen((char*)base_buf);
588             for(i=0;i<n;i+=64) {
589                 fprintf(ofstream,"%.64s\n",&base_buf[i]);
590             }
591
592             if (fprintf(ofstream, pem_epilog)<0) {
593                 is_err = -1;
594                 break;
595             }
596
597             free(base_buf);
598     }
599
600     fclose(ofstream);
601
602     if (is_err == -1)
603         return 1;
604
605     return 0;
606 }
607
608
609 /*
610  * add the owner public key to x509 certificate
611  */
612 int x509write_add_pubkey(x509_raw *chain, rsa_context *pubkey)
613 {
614     x509_node n_tmp, n_tmp2, *node;
615     int ret;
616
617     node = &chain->subpubkey;
618
619     x509write_init_node(&n_tmp);
620     x509write_init_node(&n_tmp2);
621
622     /*
623     *  RSAPublicKey ::= SEQUENCE {
624     *      modulus           INTEGER,  -- n
625     *      publicExponent    INTEGER   -- e
626     *  }
627     */
628     if ((ret = asn1_add_mpi(&pubkey->N, ASN1_INTEGER, &n_tmp)) != 0) {
629         x509write_free_node(&n_tmp);
630         x509write_free_node(&n_tmp2);
631         return ret;
632     }
633     if ((ret = asn1_add_mpi(&pubkey->E, ASN1_INTEGER, &n_tmp)) != 0) {
634         x509write_free_node(&n_tmp);
635         x509write_free_node(&n_tmp2);
636         return ret;
637     }
638     if ((ret = asn1_append_tag(&n_tmp, ASN1_CONSTRUCTED | ASN1_SEQUENCE))
639             != 0) {
640         x509write_free_node(&n_tmp);
641         x509write_free_node(&n_tmp2);
642         return ret;
643     }
644
645     /*
646      *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
647      *       algorithm            AlgorithmIdentifier,
648      *       subjectPublicKey     BIT STRING }
649      */
650     if ((ret = asn1_append_tag(&n_tmp, ASN1_BIT_STRING)) != 0) {
651         x509write_free_node(&n_tmp);
652         x509write_free_node(&n_tmp2);
653        return ret;
654     }
655     if ((ret = asn1_add_oid(&n_tmp2, (unsigned char*)OID_PKCS1_RSA, 9,
656                   ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL,
657                   (unsigned char *)"", 0)) != 0) {
658         x509write_free_node(&n_tmp);
659         x509write_free_node(&n_tmp2);
660         return ret;
661     }
662
663     if ((ret = asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 2,
664                    &n_tmp2, &n_tmp))) {
665         x509write_free_node(&n_tmp);
666         x509write_free_node(&n_tmp2);
667         return ret;
668     }
669
670     x509write_free_node(&n_tmp);
671     x509write_free_node(&n_tmp2);
672     return 0;
673 }
674
675 /*
676  *  RelativeDistinguishedName ::=
677  *    SET OF AttributeTypeAndValue
678  *
679  *  AttributeTypeAndValue ::= SEQUENCE {
680  *    type     AttributeType,
681  *    value    AttributeValue }
682  */
683 static int x509write_add_name(x509_node *node, unsigned char *oid,
684         unsigned int oid_len, unsigned char *value, int len, int value_tag)
685 {
686     int ret;
687     x509_node n_tmp;
688
689     x509write_init_node(&n_tmp);
690
691     if ((ret = asn1_add_oid(&n_tmp, oid, oid_len,
692                 ASN1_CONSTRUCTED | ASN1_SEQUENCE, value_tag,
693                 value, len))) {
694         x509write_free_node(&n_tmp);
695         return ret;
696     }
697
698     if ((asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SET, 1, &n_tmp))
699             != 0) {
700         x509write_free_node(&n_tmp);
701         return ret;
702     }
703
704     x509write_free_node(&n_tmp);
705     return 0;
706 }
707
708 /*
709  * Parse the name string and add to node
710  */
711 static int x509write_parse_names(x509_node *node, unsigned char *names)
712 {
713     unsigned char *sp, *begin = NULL;
714     unsigned char oid[3] = OID_X520, tag[4], *tag_sp = tag;
715     unsigned char *C = NULL, *CN = NULL, *O = NULL, *OU = NULL,
716                   *ST = NULL, *L = NULL, *R = NULL;
717     int C_len = 0, CN_len = 0, O_len = 0, OU_len = 0, ST_len = 0,
718                 L_len = 0, R_len = 0;
719     int ret = 0, is_tag = 1, is_begin = -1, len = 0;
720
721
722     for (sp = names; ; ++sp) {
723
724         /* filter tag */
725         if (is_tag == 1) {
726
727             if (tag_sp == &tag[3])
728                 return POLARSSL_ERR_X509_VALUE_TO_LENGTH;
729
730             /* is tag end? */
731             if (*sp == '=') {
732                 is_tag = -1;
733                 *tag_sp = '\0';
734                 is_begin = 1;
735                 /* set len 0 (reset) */
736                 len = 0;
737             } else {
738                 /* tag hasn't ' '! */
739                 if (*sp != ' ') {
740                     *tag_sp = *sp;
741                     ++tag_sp;
742                 }
743             }
744         /* filter value */
745         } else {
746
747             /* set pointer of value begin */
748             if (is_begin == 1) {
749                 begin = sp;
750                 is_begin = -1;
751             }
752
753             /* is value at end? */
754             if (*sp == ';' or *sp == '\0') {
755                 is_tag = 1;
756
757                 /* common name */
758                 if (tag[0] == 'C' and tag[1] == 'N') {
759                     CN = begin;
760                     CN_len = len;
761
762                 /* organization */
763                 } else if (tag[0] == 'O' and tag[1] == '\0') {
764                     O = begin;
765                     O_len = len;
766
767                 /* country */
768                 } else if (tag[0] == 'C' and tag[1] == '\0') {
769                     C = begin;
770                     C_len = len;
771
772                 /* organisation unit */
773                 } else if (tag[0] == 'O' and tag[1] == 'U') {
774                     OU = begin;
775                     OU_len = len;
776
777                 /* state */
778                 } else if (tag[0] == 'S' and tag[1] == 'T') {
779                     ST = begin;
780                     ST_len = len;
781
782                 /* locality */
783                 } else if (tag[0] == 'L' and tag[1] == '\0') {
784                     L = begin;
785                     L_len = len;
786
787                 /* email */
788                 } else if (tag[0] == 'R' and tag[1] == '\0') {
789                     R = begin;
790                     R_len = len;
791                 }
792
793                 /* set tag poiner to begin */
794                 tag_sp = tag;
795
796                 /* is at end? */
797                 if (*sp == '\0' or *(sp +1) == '\0')
798                     break;
799             } else {
800                 ++len;
801             }
802         }
803
804         /* make saver */
805         if (*sp == '\0')
806           break;
807     } /* end for */
808
809     /* country */
810     if (C != NULL) {
811         oid[2] = X520_COUNTRY;
812         if ((ret = x509write_add_name(node, oid, 3, C, C_len,
813                         ASN1_PRINTABLE_STRING)) != 0)
814             return ret;
815     }
816
817     /* state */
818     if (ST != NULL) {
819         oid[2] = X520_STATE;
820         if ((ret = x509write_add_name(node, oid, 3, ST, ST_len,
821                         ASN1_PRINTABLE_STRING)) != 0)
822             return ret;
823     }
824
825     /* locality */
826     if (L != NULL) {
827         oid[2] = X520_LOCALITY;
828         if ((ret = x509write_add_name(node, oid, 3, L, L_len,
829                         ASN1_PRINTABLE_STRING)) != 0)
830             return ret;
831     }
832
833     /* organization */
834     if (O != NULL) {
835         oid[2] = X520_ORGANIZATION;
836         if ((ret = x509write_add_name(node, oid, 3, O, O_len,
837                         ASN1_PRINTABLE_STRING)) != 0)
838             return ret;
839     }
840
841     /* organisation unit */
842     if (OU != NULL) {
843         oid[2] = X520_ORG_UNIT;
844         if ((ret = x509write_add_name(node, oid, 3, OU, OU_len,
845                         ASN1_PRINTABLE_STRING)) != 0)
846             return ret;
847     }
848
849     /* common name */
850     if (CN != NULL) {
851         oid[2] = X520_COMMON_NAME;
852         if ((ret = x509write_add_name(node, oid, 3, CN, CN_len,
853                         ASN1_PRINTABLE_STRING)) != 0)
854             return ret;
855     }
856
857     /* email */
858     if (R != NULL) {
859         if ((ret = x509write_add_name(node, (unsigned char*)OID_PKCS9_EMAIL,
860                         9, R, R_len, ASN1_IA5_STRING)) != 0)
861             return ret;
862     }
863
864     if ((asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
865         return ret;
866
867     return 0;
868 }
869
870 /*
871  * Copy raw data from orginal ca to node
872  */
873 static int x509write_copy_from_raw(x509_node *node, x509_buf *raw)
874 {
875     if (x509write_realloc_node(node, raw->len) != 0)
876         return 1;
877
878     memcpy(node->p, raw->p, (size_t)raw->len);
879     if ((node->p += raw->len -1) != node->end)
880         return POLARSSL_ERR_X509_POINT_ERROR;
881
882     return 0;
883 }
884
885 /*
886  * Add the issuer
887  */
888
889 int x509write_add_issuer(x509_raw *crt, unsigned char *issuer)
890 {
891     return x509write_parse_names(&crt->issuer, issuer);
892 }
893
894 /*
895  * Add the subject
896  */
897 int x509write_add_subject(x509_raw *crt, unsigned char *subject)
898 {
899     return x509write_parse_names(&crt->subject, subject);
900 }
901
902 /*
903  * Copy issuer line from another cert to issuer
904  */
905 int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt)
906 {
907     return x509write_copy_from_raw(&crt->issuer, &from_crt->issuer_raw);
908 }
909
910 /*
911  * Copy subject line from another cert
912  */
913 int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt)
914 {
915     return x509write_copy_from_raw(&crt->subject, &from_crt->subject_raw);
916 }
917
918 /*
919  * Copy subject line form antoher cert into issuer
920  */
921 int x509write_copy_issuer_form_subject(x509_raw *crt,
922         x509_cert *from_crt)
923 {
924     return x509write_copy_from_raw(&crt->issuer, &from_crt->subject_raw);
925 }
926
927 /*
928  * Copy issuer line from another cert into subject
929  */
930 int x509write_copy_subject_from_issuer(x509_raw *crt,
931         x509_cert * from_crt)
932 {
933     return x509write_copy_from_raw(&crt->subject, &from_crt->issuer_raw);
934 }
935
936 /*
937  *  Validity ::= SEQUENCE {
938  *       notBefore      Time,
939  *       notAfter       Time }
940  *
941  *  Time ::= CHOICE {
942  *       utcTime        UTCTime,
943  *       generalTime    GeneralizedTime }
944  */
945 /* TODO: No handle GeneralizedTime! */
946 int x509write_add_validity(x509_raw *chain, unsigned char *befor,
947         unsigned char *after)
948 {
949     int ret;
950
951     x509_node *node = &chain->validity;
952
953     /* notBefore */
954     if ((ret = asn1_add_date_utc(befor, node)) != 0)
955         return ret;
956
957     /* notAfter */
958     if ((ret = asn1_add_date_utc(after, node)) != 0)
959         return ret;
960
961     if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
962         return ret;
963
964     return 0;
965 }
966
967 /*
968  * make hash from tbs and sign that with private key
969  */
970 static int x509write_make_sign(x509_raw *chain, rsa_context *privkey)
971 {
972     int ret;
973     unsigned char hash[20], *sign;
974     size_t sign_len = (size_t) mpi_size(&privkey->N);
975
976     /* make hash */
977     sha1(chain->tbs.data, chain->tbs.len, hash);
978
979     /* create sign */
980     sign = (unsigned char *) malloc(sign_len);
981     if (sign == NULL)
982         return 1;
983
984     if ((ret = rsa_pkcs1_sign(privkey, RSA_PRIVATE, RSA_SHA1, 20, hash,
985                     sign)) != 0)
986         return ret;
987
988     if ((ret = asn1_add_obj(sign, sign_len, ASN1_BIT_STRING,
989                     &chain->sign)) != 0)
990         return ret;
991
992     /*
993      *  AlgorithmIdentifier  ::=  SEQUENCE  {
994      *       algorithm               OBJECT IDENTIFIER,
995      *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
996      */
997     return asn1_add_oid(&chain->signalg, (unsigned char*)OID_PKCS1_RSA_SHA, 9,
998                   ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL,
999                   (unsigned char*)"", 0);
1000 }
1001
1002 /*
1003  * Create a self signed certificate
1004  */
1005 int x509write_create_sign(x509_raw *chain, rsa_context *privkey)
1006 {
1007     int ret, serial;
1008
1009     /*
1010      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
1011      */
1012     if ((ret = asn1_add_int(2, &chain->version)) != 0)
1013         return ret;
1014
1015     if ((ret = asn1_append_tag(&chain->version, ASN1_CONTEXT_SPECIFIC |
1016                     ASN1_CONSTRUCTED)) != 0)
1017         return ret;
1018
1019
1020     /*
1021      *  CertificateSerialNumber  ::=  INTEGER
1022      */
1023     srand((unsigned int) time(NULL));
1024     serial = rand();
1025     if ((ret = asn1_add_int(serial, &chain->serial)) != 0)
1026         return ret;
1027
1028     /*
1029      *  AlgorithmIdentifier  ::=  SEQUENCE  {
1030      *       algorithm               OBJECT IDENTIFIER,
1031      *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
1032      */
1033     if ((ret = asn1_add_oid(&chain->tbs_signalg,
1034                                 (unsigned char*)OID_PKCS1_RSA_SHA, 9, ASN1_CONSTRUCTED |
1035                                 ASN1_SEQUENCE, ASN1_NULL, (unsigned char*)"", 0)) != 0)
1036         return ret;
1037
1038    /*
1039     *  Create the tbs
1040     */
1041     if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED |
1042                     ASN1_SEQUENCE, 7, &chain->version, &chain->serial,
1043                     &chain->tbs_signalg, &chain->issuer, &chain->validity,
1044                     &chain->subject, &chain->subpubkey)) != 0)
1045         return ret;
1046
1047     /* make signing */
1048     if ((ret = x509write_make_sign(chain, privkey)) != 0)
1049         return ret;
1050
1051     /* finishing */
1052     if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED |
1053                     ASN1_SEQUENCE, 3, &chain->tbs, &chain->signalg,
1054                     &chain->sign)) != 0)
1055         return ret;
1056
1057     return 0;
1058 }
1059
1060 int x509write_create_selfsign(x509_raw *chain, rsa_context *privkey)
1061 {
1062     /*
1063      * On self signed certificate are subject and issuer the same
1064      */
1065     x509write_free_node(&chain->issuer);
1066     chain->issuer = chain->subject;
1067     return x509write_create_sign(chain, privkey);
1068 }
1069
1070 /*
1071  * CertificationRequestInfo ::= SEQUENCE                    {
1072  *    version                       Version,
1073  *    subject                       Name,
1074  *    subjectPublicKeyInfo          SubjectPublicKeyInfo,
1075  *    attributes                    [0] IMPLICIT Attributes }
1076  *
1077  * CertificationRequest ::=   SEQUENCE                      {
1078  *    certificationRequestInfo  CertificationRequestInfo,
1079  *    signatureAlgorithm        SignatureAlgorithmIdentifier,
1080  *    signature                 Signature                   }
1081  *
1082  * It use chain.serail for attributes!
1083  *
1084  */
1085 int x509write_create_csr(x509_raw *chain, rsa_context *privkey)
1086 {
1087     int ret;
1088
1089     /* version ::= INTEGER */
1090     if ((ret = asn1_add_int(0, &chain->version)) != 0)
1091         return ret;
1092
1093     /* write attributes */
1094     if ((ret = asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC |
1095                     ASN1_CONSTRUCTED, &chain->serial)) != 0)
1096         return ret;
1097
1098     /* create CertificationRequestInfo */
1099     if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED |
1100                     ASN1_SEQUENCE, 4, &chain->version, &chain->subject,
1101                     &chain->subpubkey, &chain->serial)) != 0)
1102         return ret;
1103
1104     /* make signing */
1105     if ((ret = x509write_make_sign(chain, privkey)) != 0)
1106         return ret;
1107
1108     /* finish */
1109     if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | ASN1_SEQUENCE,
1110                     3, &chain->tbs, &chain->signalg, &chain->sign)) != 0)
1111         return ret;
1112
1113     return ret;
1114 }
1115
1116 /*
1117  * Free memory
1118  */
1119 void x509write_free_raw(x509_raw *chain)
1120 {
1121     x509write_free_node(&chain->raw);
1122     x509write_free_node(&chain->tbs);
1123     x509write_free_node(&chain->version);
1124     x509write_free_node(&chain->serial);
1125     x509write_free_node(&chain->tbs_signalg);
1126     x509write_free_node(&chain->issuer);
1127     x509write_free_node(&chain->validity);
1128     if (chain->subject.data != chain->issuer.data)
1129         x509write_free_node(&chain->subject);
1130     x509write_free_node(&chain->subpubkey);
1131     x509write_free_node(&chain->signalg);
1132     x509write_free_node(&chain->sign);
1133 }
1134
1135 void x509write_init_raw(x509_raw *chain)
1136 {
1137     memset((void *) chain, 0, sizeof(x509_raw));
1138 }
1139