ath9k: make endian check optional
[openwrt.git] / 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
This page took 0.110536 seconds and 5 git commands to generate.