2 * X.509 certificate and private key writing
4 * Copyright (C) 2006-2007 Pascal Vizeli <pvizeli@yahoo.de>
5 * Modifications (C) 2009 Steven Barth <steven@midlink.org>
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.
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.
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,
22 * The ITU-T X.509 standard defines a certificat format for PKI.
24 * http://www.ietf.org/rfc/rfc2459.txt
25 * http://www.ietf.org/rfc/rfc3279.txt
27 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
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
33 * http://www.faqs.org/rfcs/rfc2314.html
35 #include "polarssl/config.h"
36 #include "polarssl/x509.h"
37 #include "polarssl/base64.h"
38 #include "polarssl/sha1.h"
49 #if defined _MSC_VER && !defined snprintf
50 #define snprintf _snprintf
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
);
57 * evaluate how mani octet have this integer
59 static int asn1_eval_octet(unsigned int digit
)
63 for (byte
= 4, i
= 24; i
>= 0; i
-= 8, --byte
)
64 if (((digit
>> i
) & 0xFF) != 0)
71 * write the asn.1 lenght form into p
73 static int asn1_add_len(unsigned int size
, x509_node
*node
)
78 int byte
= asn1_eval_octet(size
);
81 *(node
->p
) = (0x80 | byte
) & 0xFF;
84 for (i
= byte
; i
> 0; --i
) {
86 *(node
->p
) = (size
>> ((i
- 1) * 8)) & 0xFF;
93 *(node
->p
) = size
& 0xFF;
102 * write a ans.1 object into p
104 static int asn1_add_obj(unsigned char *value
, unsigned int size
, int tag
,
109 if (tag
== ASN1_BIT_STRING
)
113 x509write_realloc_node(node
, (size_t) size
+ tl
+
114 asn1_eval_octet(size
));
116 x509write_realloc_node(node
, (size_t) size
+ tl
);
118 if (node
->data
== NULL
)
122 *(node
->p
) = tag
& 0xFF;
126 if (tag
== ASN1_BIT_STRING
) {
127 asn1_add_len((unsigned int) size
+ 1, node
);
131 asn1_add_len((unsigned int) size
, node
);
137 memcpy(node
->p
, value
, (size_t) size
);
138 if ((node
->p
+= size
-1) != node
->end
)
139 return POLARSSL_ERR_X509_POINT_ERROR
;
141 /* make nothing -> NULL */
148 * write a asn.1 conform integer object
150 static int asn1_add_int(signed int value
, x509_node
*node
)
152 signed int i
= 0, neg
= 1;
153 unsigned int byte
, u_val
= 0, tmp_val
= 0;
163 byte
= asn1_eval_octet(u_val
);
168 /* ASN.1 integer is signed! */
169 if (byte
< 4 and ((u_val
>> ((byte
-1) * 8)) & 0xFF) == 0x80)
172 if (x509write_realloc_node(node
, (size_t) byte
+ 2) != 0)
176 *(node
->p
) = ASN1_INTEGER
;
180 asn1_add_len(byte
, node
);
183 for (i
= byte
; i
> 0; --i
) {
185 tmp_val
= (u_val
>> ((i
- 1) * 8)) & 0xFF;
187 *(node
->p
) = tmp_val
;
189 *(node
->p
) = ~tmp_val
;
195 if (node
->p
!= node
->end
)
196 return POLARSSL_ERR_X509_POINT_ERROR
;
202 * write a asn.1 conform mpi object
204 static int asn1_add_mpi(mpi
*value
, int tag
, x509_node
*node
)
206 size_t size
= (mpi_msb(value
) / 8) + 1;
208 int buf_len
= (int) size
, tl
= 2;
210 if (tag
== ASN1_BIT_STRING
)
214 x509write_realloc_node(node
, size
+ (size_t) tl
+
215 asn1_eval_octet((unsigned int)size
));
217 x509write_realloc_node(node
, size
+ (size_t) tl
);
219 if (node
->data
== NULL
)
222 buf
= (unsigned char*) malloc(size
);
223 if (mpi_write_binary(value
, buf
, buf_len
) != 0)
224 return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL
;
227 *(node
->p
) = tag
& 0xFF;
231 if (tag
== ASN1_BIT_STRING
) {
232 asn1_add_len((unsigned int) size
+ 1, node
);
236 asn1_add_len((unsigned int) size
, node
);
240 memcpy(node
->p
, buf
, size
);
243 if ((node
->p
+= (int) size
-1) != node
->end
)
244 return POLARSSL_ERR_X509_POINT_ERROR
;
250 * write a node into asn.1 conform object
252 static int asn1_append_tag(x509_node
*node
, int tag
)
257 x509write_init_node(&tmp
);
259 if (tag
== ASN1_BIT_STRING
)
263 x509write_realloc_node(&tmp
, node
->len
+ (size_t) tl
+
264 asn1_eval_octet((unsigned int)node
->len
));
266 x509write_realloc_node(&tmp
, node
->len
+ (size_t) tl
);
268 if (tmp
.data
== NULL
) {
269 x509write_free_node(&tmp
);
274 *(tmp
.p
) = tag
& 0xFF;
278 if (tag
== ASN1_BIT_STRING
) {
279 asn1_add_len((unsigned int) node
->len
+ 1, &tmp
);
283 asn1_add_len((unsigned int) node
->len
, &tmp
);
287 memcpy(tmp
.p
, node
->data
, node
->len
);
290 if ((tmp
.p
+= (int) node
->len
-1) != tmp
.end
) {
291 x509write_free_node(&tmp
);
292 return POLARSSL_ERR_X509_POINT_ERROR
;
296 node
->data
= tmp
.data
;
305 * write nodes into a asn.1 object
307 static int asn1_append_nodes(x509_node
*node
, int tag
, int anz
, ...)
319 tmp
= va_arg(ap
, x509_node
*);
320 if (tmp
->data
!= NULL
)
325 if (x509write_realloc_node(node
, size
+ (size_t) 2 +
326 asn1_eval_octet(size
)) != 0)
329 if (x509write_realloc_node(node
, size
+ (size_t) 2) != 0)
334 *(node
->p
) = tag
& 0xFF;
338 asn1_add_len(size
, node
);
346 tmp
= va_arg(ap
, x509_node
*);
347 if (tmp
->data
!= NULL
) {
349 memcpy(node
->p
, tmp
->data
, tmp
->len
);
350 if ((node
->p
+= (int) tmp
->len
-1) != node
->end
)
360 * write a ASN.1 conform object identifiere include a "tag"
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
)
368 x509write_init_node(&tmp
);
370 /* OBJECT IDENTIFIER */
371 if ((ret
= asn1_add_obj(oid
, len
, ASN1_OID
, &tmp
)) != 0) {
372 x509write_free_node(&tmp
);
377 if ((ret
= asn1_add_obj(value
, val_len
, tag_val
, &tmp
)) != 0) {
378 x509write_free_node(&tmp
);
383 if ((ret
= asn1_append_nodes(node
, tag
, 1, &tmp
)) != 0) {
384 x509write_free_node(&tmp
);
388 x509write_free_node(&tmp
);
395 static int asn1_add_date_utc(unsigned char *time
, x509_node
*node
)
397 unsigned char date
[13], *sp
;
401 sscanf((char*)time
, "%d-%d-%d %d:%d:%d", &xtime
.year
, &xtime
.mon
,
402 &xtime
.day
, &xtime
.hour
, &xtime
.min
, &xtime
.sec
);
405 if (xtime
.year
> 2000)
410 snprintf((char*)date
, 13, "%2d%2d%2d%2d%2d%2d", xtime
.year
, xtime
.mon
, xtime
.day
,
411 xtime
.hour
, xtime
.min
, xtime
.sec
);
413 /* replace ' ' to '0' */
414 for (sp
= date
; *sp
!= '\0'; ++sp
)
420 if ((ret
= asn1_add_obj(date
, 13, ASN1_UTC_TIME
, node
)) != 0)
427 * serialize an rsa key into DER
430 int x509write_serialize_key(rsa_context
*rsa
, x509_node
*node
)
433 x509write_init_node(node
);
435 /*Â vers, n, e, d, p, q, dp, dq, pq */
436 if ((ret
= asn1_add_int(rsa
->ver
, node
)) != 0)
438 if ((ret
= asn1_add_mpi(&rsa
->N
, ASN1_INTEGER
, node
)) != 0)
440 if ((ret
= asn1_add_mpi(&rsa
->E
, ASN1_INTEGER
, node
)) != 0)
442 if ((ret
= asn1_add_mpi(&rsa
->D
, ASN1_INTEGER
, node
)) != 0)
444 if ((ret
= asn1_add_mpi(&rsa
->P
, ASN1_INTEGER
, node
)) != 0)
446 if ((ret
= asn1_add_mpi(&rsa
->Q
, ASN1_INTEGER
, node
)) != 0)
448 if ((ret
= asn1_add_mpi(&rsa
->DP
, ASN1_INTEGER
, node
)) != 0)
450 if ((ret
= asn1_add_mpi(&rsa
->DQ
, ASN1_INTEGER
, node
)) != 0)
452 if ((ret
= asn1_add_mpi(&rsa
->QP
, ASN1_INTEGER
, node
)) != 0)
454 if ((ret
= asn1_append_tag(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
)) != 0)
461 * write a der/pem encoded rsa private key into a file
463 int x509write_keyfile(rsa_context
*rsa
, char *path
, int out_flag
)
466 const char key_beg
[] = "-----BEGIN RSA PRIVATE KEY-----\n",
467 key_end
[] = "-----END RSA PRIVATE KEY-----\n";
470 x509write_init_node(&node
);
471 if ((ret
= x509write_serialize_key(rsa
,&node
)) != 0) {
472 x509write_free_node(&node
);
476 ret
= x509write_file(&node
,path
,out_flag
,key_beg
,key_end
);
477 x509write_free_node(&node
);
484 * reasize the memory for node
486 static int x509write_realloc_node(x509_node
*node
, size_t larger
)
489 if (node
->data
== NULL
) {
491 node
->data
= malloc(larger
);
492 if(node
->data
== NULL
)
496 if ((node
->data
= realloc(node
->data
, node
->len
+ larger
)) == NULL
)
501 node
->p
= &node
->data
[node
->len
];
503 node
->end
= &node
->data
[node
->len
-1];
511 void x509write_init_node(x509_node
*node
)
513 memset(node
, 0, sizeof(x509_node
));
519 void x509write_free_node(x509_node
*node
)
521 if (node
->data
!= NULL
)
529 * write a x509 certificate into file
531 int x509write_crtfile(x509_raw
*chain
, unsigned char *path
, int out_flag
)
533 const char cer_beg
[] = "-----BEGIN CERTIFICATE-----\n",
534 cer_end
[] = "-----END CERTIFICATE-----\n";
536 return x509write_file(&chain
->raw
, (char*)path
, out_flag
, cer_beg
, cer_end
);
540 * write a x509 certificate into file
542 int x509write_csrfile(x509_raw
*chain
, unsigned char *path
, int out_flag
)
544 const char cer_beg
[] = "-----BEGIN CERTIFICATE REQUEST-----\n",
545 cer_end
[] = "-----END CERTIFICATE REQUEST-----\n";
547 return x509write_file(&chain
->raw
, (char*)path
, out_flag
, cer_beg
, cer_end
);
553 static int x509write_file(x509_node
*node
, char *path
, int format
,
554 const char* pem_prolog
, const char* pem_epilog
)
556 FILE *ofstream
= stdout
;
557 int is_err
= 1, buf_len
, i
, n
;
558 unsigned char* base_buf
;
561 if ((ofstream
= fopen(path
, "wb")) == NULL
)
566 case X509_OUTPUT_DER
:
567 if (fwrite(node
->data
, 1, node
->len
, ofstream
)
572 case X509_OUTPUT_PEM
:
573 if (fprintf(ofstream
,pem_prolog
)<0) {
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) {
587 n
=strlen((char*)base_buf
);
589 fprintf(ofstream
,"%.64s\n",&base_buf
[i
]);
592 if (fprintf(ofstream
, pem_epilog
)<0) {
610 * add the owner public key to x509 certificate
612 int x509write_add_pubkey(x509_raw
*chain
, rsa_context
*pubkey
)
614 x509_node n_tmp
, n_tmp2
, *node
;
617 node
= &chain
->subpubkey
;
619 x509write_init_node(&n_tmp
);
620 x509write_init_node(&n_tmp2
);
623 * RSAPublicKey ::= SEQUENCE {
624 * modulus INTEGER, -- n
625 * publicExponent INTEGER -- e
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
);
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
);
638 if ((ret
= asn1_append_tag(&n_tmp
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
))
640 x509write_free_node(&n_tmp
);
641 x509write_free_node(&n_tmp2
);
646 * SubjectPublicKeyInfo ::= SEQUENCE {
647 * algorithm AlgorithmIdentifier,
648 * subjectPublicKey BIT STRING }
650 if ((ret
= asn1_append_tag(&n_tmp
, ASN1_BIT_STRING
)) != 0) {
651 x509write_free_node(&n_tmp
);
652 x509write_free_node(&n_tmp2
);
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
);
663 if ((ret
= asn1_append_nodes(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, 2,
665 x509write_free_node(&n_tmp
);
666 x509write_free_node(&n_tmp2
);
670 x509write_free_node(&n_tmp
);
671 x509write_free_node(&n_tmp2
);
676 * RelativeDistinguishedName ::=
677 * SET OF AttributeTypeAndValue
679 * AttributeTypeAndValue ::= SEQUENCE {
680 * type AttributeType,
681 * value AttributeValue }
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
)
689 x509write_init_node(&n_tmp
);
691 if ((ret
= asn1_add_oid(&n_tmp
, oid
, oid_len
,
692 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, value_tag
,
694 x509write_free_node(&n_tmp
);
698 if ((asn1_append_nodes(node
, ASN1_CONSTRUCTED
| ASN1_SET
, 1, &n_tmp
))
700 x509write_free_node(&n_tmp
);
704 x509write_free_node(&n_tmp
);
709 * Parse the name string and add to node
711 static int x509write_parse_names(x509_node
*node
, unsigned char *names
)
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;
722 for (sp
= names
; ; ++sp
) {
727 if (tag_sp
== &tag
[3])
728 return POLARSSL_ERR_X509_VALUE_TO_LENGTH
;
735 /* set len 0 (reset) */
738 /* tag hasn't ' '! */
747 /* set pointer of value begin */
753 /* is value at end? */
754 if (*sp
== ';' or *sp
== '\0') {
758 if (tag
[0] == 'C' and tag
[1] == 'N') {
763 } else if (tag
[0] == 'O' and tag
[1] == '\0') {
768 } else if (tag
[0] == 'C' and tag
[1] == '\0') {
772 /* organisation unit */
773 } else if (tag
[0] == 'O' and tag
[1] == 'U') {
778 } else if (tag
[0] == 'S' and tag
[1] == 'T') {
783 } else if (tag
[0] == 'L' and tag
[1] == '\0') {
788 } else if (tag
[0] == 'R' and tag
[1] == '\0') {
793 /* set tag poiner to begin */
797 if (*sp
== '\0' or *(sp
+1) == '\0')
811 oid
[2] = X520_COUNTRY
;
812 if ((ret
= x509write_add_name(node
, oid
, 3, C
, C_len
,
813 ASN1_PRINTABLE_STRING
)) != 0)
820 if ((ret
= x509write_add_name(node
, oid
, 3, ST
, ST_len
,
821 ASN1_PRINTABLE_STRING
)) != 0)
827 oid
[2] = X520_LOCALITY
;
828 if ((ret
= x509write_add_name(node
, oid
, 3, L
, L_len
,
829 ASN1_PRINTABLE_STRING
)) != 0)
835 oid
[2] = X520_ORGANIZATION
;
836 if ((ret
= x509write_add_name(node
, oid
, 3, O
, O_len
,
837 ASN1_PRINTABLE_STRING
)) != 0)
841 /* organisation unit */
843 oid
[2] = X520_ORG_UNIT
;
844 if ((ret
= x509write_add_name(node
, oid
, 3, OU
, OU_len
,
845 ASN1_PRINTABLE_STRING
)) != 0)
851 oid
[2] = X520_COMMON_NAME
;
852 if ((ret
= x509write_add_name(node
, oid
, 3, CN
, CN_len
,
853 ASN1_PRINTABLE_STRING
)) != 0)
859 if ((ret
= x509write_add_name(node
, (unsigned char*)OID_PKCS9_EMAIL
,
860 9, R
, R_len
, ASN1_IA5_STRING
)) != 0)
864 if ((asn1_append_tag(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
)) != 0)
871 * Copy raw data from orginal ca to node
873 static int x509write_copy_from_raw(x509_node
*node
, x509_buf
*raw
)
875 if (x509write_realloc_node(node
, raw
->len
) != 0)
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
;
889 int x509write_add_issuer(x509_raw
*crt
, unsigned char *issuer
)
891 return x509write_parse_names(&crt
->issuer
, issuer
);
897 int x509write_add_subject(x509_raw
*crt
, unsigned char *subject
)
899 return x509write_parse_names(&crt
->subject
, subject
);
903 * Copy issuer line from another cert to issuer
905 int x509write_copy_issuer(x509_raw
*crt
, x509_cert
*from_crt
)
907 return x509write_copy_from_raw(&crt
->issuer
, &from_crt
->issuer_raw
);
911 * Copy subject line from another cert
913 int x509write_copy_subject(x509_raw
*crt
, x509_cert
*from_crt
)
915 return x509write_copy_from_raw(&crt
->subject
, &from_crt
->subject_raw
);
919 * Copy subject line form antoher cert into issuer
921 int x509write_copy_issuer_form_subject(x509_raw
*crt
,
924 return x509write_copy_from_raw(&crt
->issuer
, &from_crt
->subject_raw
);
928 * Copy issuer line from another cert into subject
930 int x509write_copy_subject_from_issuer(x509_raw
*crt
,
931 x509_cert
* from_crt
)
933 return x509write_copy_from_raw(&crt
->subject
, &from_crt
->issuer_raw
);
937 * Validity ::= SEQUENCE {
943 * generalTime GeneralizedTime }
945 /* TODO: No handle GeneralizedTime! */
946 int x509write_add_validity(x509_raw
*chain
, unsigned char *befor
,
947 unsigned char *after
)
951 x509_node
*node
= &chain
->validity
;
954 if ((ret
= asn1_add_date_utc(befor
, node
)) != 0)
958 if ((ret
= asn1_add_date_utc(after
, node
)) != 0)
961 if ((ret
= asn1_append_tag(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
)) != 0)
968 * make hash from tbs and sign that with private key
970 static int x509write_make_sign(x509_raw
*chain
, rsa_context
*privkey
)
973 unsigned char hash
[20], *sign
;
974 size_t sign_len
= (size_t) mpi_size(&privkey
->N
);
977 sha1(chain
->tbs
.data
, chain
->tbs
.len
, hash
);
980 sign
= (unsigned char *) malloc(sign_len
);
984 if ((ret
= rsa_pkcs1_sign(privkey
, RSA_PRIVATE
, RSA_SHA1
, 20, hash
,
988 if ((ret
= asn1_add_obj(sign
, sign_len
, ASN1_BIT_STRING
,
993 * AlgorithmIdentifier ::= SEQUENCE {
994 * algorithm OBJECT IDENTIFIER,
995 * parameters ANY DEFINED BY algorithm OPTIONAL }
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);
1003 * Create a self signed certificate
1005 int x509write_create_sign(x509_raw
*chain
, rsa_context
*privkey
)
1010 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1012 if ((ret
= asn1_add_int(2, &chain
->version
)) != 0)
1015 if ((ret
= asn1_append_tag(&chain
->version
, ASN1_CONTEXT_SPECIFIC
|
1016 ASN1_CONSTRUCTED
)) != 0)
1021 * CertificateSerialNumber ::= INTEGER
1023 srand((unsigned int) time(NULL
));
1025 if ((ret
= asn1_add_int(serial
, &chain
->serial
)) != 0)
1029 * AlgorithmIdentifier ::= SEQUENCE {
1030 * algorithm OBJECT IDENTIFIER,
1031 * parameters ANY DEFINED BY algorithm OPTIONAL }
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)
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)
1048 if ((ret
= x509write_make_sign(chain
, privkey
)) != 0)
1052 if ((ret
= asn1_append_nodes(&chain
->raw
, ASN1_CONSTRUCTED
|
1053 ASN1_SEQUENCE
, 3, &chain
->tbs
, &chain
->signalg
,
1054 &chain
->sign
)) != 0)
1060 int x509write_create_selfsign(x509_raw
*chain
, rsa_context
*privkey
)
1063 * On self signed certificate are subject and issuer the same
1065 x509write_free_node(&chain
->issuer
);
1066 chain
->issuer
= chain
->subject
;
1067 return x509write_create_sign(chain
, privkey
);
1071 * CertificationRequestInfo ::= SEQUENCE {
1074 * subjectPublicKeyInfo SubjectPublicKeyInfo,
1075 * attributes [0] IMPLICIT Attributes }
1077 * CertificationRequest ::= SEQUENCE {
1078 * certificationRequestInfo CertificationRequestInfo,
1079 * signatureAlgorithm SignatureAlgorithmIdentifier,
1080 * signature Signature }
1082 * It use chain.serail for attributes!
1085 int x509write_create_csr(x509_raw
*chain
, rsa_context
*privkey
)
1089 /* version ::= INTEGER */
1090 if ((ret
= asn1_add_int(0, &chain
->version
)) != 0)
1093 /* write attributes */
1094 if ((ret
= asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC
|
1095 ASN1_CONSTRUCTED
, &chain
->serial
)) != 0)
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)
1105 if ((ret
= x509write_make_sign(chain
, privkey
)) != 0)
1109 if ((ret
= asn1_append_nodes(&chain
->raw
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
,
1110 3, &chain
->tbs
, &chain
->signalg
, &chain
->sign
)) != 0)
1119 void x509write_free_raw(x509_raw
*chain
)
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
);
1135 void x509write_init_raw(x509_raw
*chain
)
1137 memset((void *) chain
, 0, sizeof(x509_raw
));