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
)
557 int is_err
= 1/*, buf_len, i, n*/;
558 /* char* base_buf; */
560 if ((ofstream
= fopen(path
, "wb")) == NULL
)
564 case X509_OUTPUT_DER
:
565 if (fwrite(node
->data
, 1, node
->len
, ofstream
)
570 case X509_OUTPUT_PEM:
571 if (fprintf(ofstream,pem_prolog)<0) {
576 buf_len = node->len << 1;
577 base_buf = (char*) malloc((size_t)buf_len);
578 memset(base_buf,0,buf_len);
579 if (base64_encode(base_buf, &buf_len, node->data,
580 (int) node->len) != 0) {
587 fprintf(ofstream,"%.64s\n",&base_buf[i]);
590 if (fprintf(ofstream, pem_epilog)<0) {
608 * add the owner public key to x509 certificate
610 int x509write_add_pubkey(x509_raw
*chain
, rsa_context
*pubkey
)
612 x509_node n_tmp
, n_tmp2
, *node
;
615 node
= &chain
->subpubkey
;
617 x509write_init_node(&n_tmp
);
618 x509write_init_node(&n_tmp2
);
621 * RSAPublicKey ::= SEQUENCE {
622 * modulus INTEGER, -- n
623 * publicExponent INTEGER -- e
626 if ((ret
= asn1_add_mpi(&pubkey
->N
, ASN1_INTEGER
, &n_tmp
)) != 0) {
627 x509write_free_node(&n_tmp
);
628 x509write_free_node(&n_tmp2
);
631 if ((ret
= asn1_add_mpi(&pubkey
->E
, ASN1_INTEGER
, &n_tmp
)) != 0) {
632 x509write_free_node(&n_tmp
);
633 x509write_free_node(&n_tmp2
);
636 if ((ret
= asn1_append_tag(&n_tmp
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
))
638 x509write_free_node(&n_tmp
);
639 x509write_free_node(&n_tmp2
);
644 * SubjectPublicKeyInfo ::= SEQUENCE {
645 * algorithm AlgorithmIdentifier,
646 * subjectPublicKey BIT STRING }
648 if ((ret
= asn1_append_tag(&n_tmp
, ASN1_BIT_STRING
)) != 0) {
649 x509write_free_node(&n_tmp
);
650 x509write_free_node(&n_tmp2
);
653 if ((ret
= asn1_add_oid(&n_tmp2
, (unsigned char*)OID_PKCS1_RSA
, 9,
654 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, ASN1_NULL
,
655 (unsigned char *)"", 0)) != 0) {
656 x509write_free_node(&n_tmp
);
657 x509write_free_node(&n_tmp2
);
661 if ((ret
= asn1_append_nodes(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, 2,
663 x509write_free_node(&n_tmp
);
664 x509write_free_node(&n_tmp2
);
668 x509write_free_node(&n_tmp
);
669 x509write_free_node(&n_tmp2
);
674 * RelativeDistinguishedName ::=
675 * SET OF AttributeTypeAndValue
677 * AttributeTypeAndValue ::= SEQUENCE {
678 * type AttributeType,
679 * value AttributeValue }
681 static int x509write_add_name(x509_node
*node
, unsigned char *oid
,
682 unsigned int oid_len
, unsigned char *value
, int len
, int value_tag
)
687 x509write_init_node(&n_tmp
);
689 if ((ret
= asn1_add_oid(&n_tmp
, oid
, oid_len
,
690 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, value_tag
,
692 x509write_free_node(&n_tmp
);
696 if ((asn1_append_nodes(node
, ASN1_CONSTRUCTED
| ASN1_SET
, 1, &n_tmp
))
698 x509write_free_node(&n_tmp
);
702 x509write_free_node(&n_tmp
);
707 * Parse the name string and add to node
709 static int x509write_parse_names(x509_node
*node
, unsigned char *names
)
711 unsigned char *sp
, *begin
= NULL
;
712 unsigned char oid
[3] = OID_X520
, tag
[4], *tag_sp
= tag
;
713 unsigned char *C
= NULL
, *CN
= NULL
, *O
= NULL
, *OU
= NULL
,
714 *ST
= NULL
, *L
= NULL
, *R
= NULL
;
715 int C_len
= 0, CN_len
= 0, O_len
= 0, OU_len
= 0, ST_len
= 0,
716 L_len
= 0, R_len
= 0;
717 int ret
, is_tag
= 1, is_begin
= -1, len
= 0;
720 for (sp
= names
; ; ++sp
) {
725 if (tag_sp
== &tag
[3])
726 return POLARSSL_ERR_X509_VALUE_TO_LENGTH
;
733 /* set len 0 (reset) */
736 /* tag hasn't ' '! */
745 /* set pointer of value begin */
751 /* is value at end? */
752 if (*sp
== ';' or *sp
== '\0') {
756 if (tag
[0] == 'C' and tag
[1] == 'N') {
761 } else if (tag
[0] == 'O' and tag
[1] == '\0') {
766 } else if (tag
[0] == 'C' and tag
[1] == '\0') {
770 /* organisation unit */
771 } else if (tag
[0] == 'O' and tag
[1] == 'U') {
776 } else if (tag
[0] == 'S' and tag
[1] == 'T') {
781 } else if (tag
[0] == 'L' and tag
[1] == '\0') {
786 } else if (tag
[0] == 'R' and tag
[1] == '\0') {
791 /* set tag poiner to begin */
795 if (*sp
== '\0' or *(sp
+1) == '\0')
809 oid
[2] = X520_COUNTRY
;
810 if ((ret
= x509write_add_name(node
, oid
, 3, C
, C_len
,
811 ASN1_PRINTABLE_STRING
)) != 0)
818 if ((ret
= x509write_add_name(node
, oid
, 3, ST
, ST_len
,
819 ASN1_PRINTABLE_STRING
)) != 0)
825 oid
[2] = X520_LOCALITY
;
826 if ((ret
= x509write_add_name(node
, oid
, 3, L
, L_len
,
827 ASN1_PRINTABLE_STRING
)) != 0)
833 oid
[2] = X520_ORGANIZATION
;
834 if ((ret
= x509write_add_name(node
, oid
, 3, O
, O_len
,
835 ASN1_PRINTABLE_STRING
)) != 0)
839 /* organisation unit */
841 oid
[2] = X520_ORG_UNIT
;
842 if ((ret
= x509write_add_name(node
, oid
, 3, OU
, OU_len
,
843 ASN1_PRINTABLE_STRING
)) != 0)
849 oid
[2] = X520_COMMON_NAME
;
850 if ((ret
= x509write_add_name(node
, oid
, 3, CN
, CN_len
,
851 ASN1_PRINTABLE_STRING
)) != 0)
857 if ((ret
= x509write_add_name(node
, (unsigned char*)OID_PKCS9_EMAIL
,
858 9, R
, R_len
, ASN1_IA5_STRING
)) != 0)
862 if ((asn1_append_tag(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
)) != 0)
869 * Copy raw data from orginal ca to node
871 static int x509write_copy_from_raw(x509_node
*node
, x509_buf
*raw
)
873 if (x509write_realloc_node(node
, raw
->len
) != 0)
876 memcpy(node
->p
, raw
->p
, (size_t)raw
->len
);
877 if ((node
->p
+= raw
->len
-1) != node
->end
)
878 return POLARSSL_ERR_X509_POINT_ERROR
;
887 int x509write_add_issuer(x509_raw
*crt
, unsigned char *issuer
)
889 return x509write_parse_names(&crt
->issuer
, issuer
);
895 int x509write_add_subject(x509_raw
*crt
, unsigned char *subject
)
897 return x509write_parse_names(&crt
->subject
, subject
);
901 * Copy issuer line from another cert to issuer
903 int x509write_copy_issuer(x509_raw
*crt
, x509_cert
*from_crt
)
905 return x509write_copy_from_raw(&crt
->issuer
, &from_crt
->issuer_raw
);
909 * Copy subject line from another cert
911 int x509write_copy_subject(x509_raw
*crt
, x509_cert
*from_crt
)
913 return x509write_copy_from_raw(&crt
->subject
, &from_crt
->subject_raw
);
917 * Copy subject line form antoher cert into issuer
919 int x509write_copy_issuer_form_subject(x509_raw
*crt
,
922 return x509write_copy_from_raw(&crt
->issuer
, &from_crt
->subject_raw
);
926 * Copy issuer line from another cert into subject
928 int x509write_copy_subject_from_issuer(x509_raw
*crt
,
929 x509_cert
* from_crt
)
931 return x509write_copy_from_raw(&crt
->subject
, &from_crt
->issuer_raw
);
935 * Validity ::= SEQUENCE {
941 * generalTime GeneralizedTime }
943 /* TODO: No handle GeneralizedTime! */
944 int x509write_add_validity(x509_raw
*chain
, unsigned char *befor
,
945 unsigned char *after
)
949 x509_node
*node
= &chain
->validity
;
952 if ((ret
= asn1_add_date_utc(befor
, node
)) != 0)
956 if ((ret
= asn1_add_date_utc(after
, node
)) != 0)
959 if ((ret
= asn1_append_tag(node
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
)) != 0)
966 * make hash from tbs and sign that with private key
968 static int x509write_make_sign(x509_raw
*chain
, rsa_context
*privkey
)
971 unsigned char hash
[20], *sign
;
972 size_t sign_len
= (size_t) mpi_size(&privkey
->N
);
975 sha1(chain
->tbs
.data
, chain
->tbs
.len
, hash
);
978 sign
= (unsigned char *) malloc(sign_len
);
982 if ((ret
= rsa_pkcs1_sign(privkey
, RSA_PRIVATE
, RSA_SHA1
, 20, hash
,
986 if ((ret
= asn1_add_obj(sign
, sign_len
, ASN1_BIT_STRING
,
991 * AlgorithmIdentifier ::= SEQUENCE {
992 * algorithm OBJECT IDENTIFIER,
993 * parameters ANY DEFINED BY algorithm OPTIONAL }
995 return asn1_add_oid(&chain
->signalg
, (unsigned char*)OID_PKCS1_RSA_SHA
, 9,
996 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
, ASN1_NULL
,
997 (unsigned char*)"", 0);
1001 * Create a self signed certificate
1003 int x509write_create_sign(x509_raw
*chain
, rsa_context
*privkey
)
1008 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1010 if ((ret
= asn1_add_int(2, &chain
->version
)) != 0)
1013 if ((ret
= asn1_append_tag(&chain
->version
, ASN1_CONTEXT_SPECIFIC
|
1014 ASN1_CONSTRUCTED
)) != 0)
1019 * CertificateSerialNumber ::= INTEGER
1021 srand((unsigned int) time(NULL
));
1023 if ((ret
= asn1_add_int(serial
, &chain
->serial
)) != 0)
1027 * AlgorithmIdentifier ::= SEQUENCE {
1028 * algorithm OBJECT IDENTIFIER,
1029 * parameters ANY DEFINED BY algorithm OPTIONAL }
1031 if ((ret
= asn1_add_oid(&chain
->tbs_signalg
,
1032 (unsigned char*)OID_PKCS1_RSA_SHA
, 9, ASN1_CONSTRUCTED
|
1033 ASN1_SEQUENCE
, ASN1_NULL
, (unsigned char*)"", 0)) != 0)
1039 if ((ret
= asn1_append_nodes(&chain
->tbs
, ASN1_CONSTRUCTED
|
1040 ASN1_SEQUENCE
, 7, &chain
->version
, &chain
->serial
,
1041 &chain
->tbs_signalg
, &chain
->issuer
, &chain
->validity
,
1042 &chain
->subject
, &chain
->subpubkey
)) != 0)
1046 if ((ret
= x509write_make_sign(chain
, privkey
)) != 0)
1050 if ((ret
= asn1_append_nodes(&chain
->raw
, ASN1_CONSTRUCTED
|
1051 ASN1_SEQUENCE
, 3, &chain
->tbs
, &chain
->signalg
,
1052 &chain
->sign
)) != 0)
1058 int x509write_create_selfsign(x509_raw
*chain
, rsa_context
*privkey
)
1061 * On self signed certificate are subject and issuer the same
1063 x509write_free_node(&chain
->issuer
);
1064 chain
->issuer
= chain
->subject
;
1065 return x509write_create_sign(chain
, privkey
);
1069 * CertificationRequestInfo ::= SEQUENCE {
1072 * subjectPublicKeyInfo SubjectPublicKeyInfo,
1073 * attributes [0] IMPLICIT Attributes }
1075 * CertificationRequest ::= SEQUENCE {
1076 * certificationRequestInfo CertificationRequestInfo,
1077 * signatureAlgorithm SignatureAlgorithmIdentifier,
1078 * signature Signature }
1080 * It use chain.serail for attributes!
1083 int x509write_create_csr(x509_raw
*chain
, rsa_context
*privkey
)
1087 /* version ::= INTEGER */
1088 if ((ret
= asn1_add_int(0, &chain
->version
)) != 0)
1091 /* write attributes */
1092 if ((ret
= asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC
|
1093 ASN1_CONSTRUCTED
, &chain
->serial
)) != 0)
1096 /* create CertificationRequestInfo */
1097 if ((ret
= asn1_append_nodes(&chain
->tbs
, ASN1_CONSTRUCTED
|
1098 ASN1_SEQUENCE
, 4, &chain
->version
, &chain
->subject
,
1099 &chain
->subpubkey
, &chain
->serial
)) != 0)
1103 if ((ret
= x509write_make_sign(chain
, privkey
)) != 0)
1107 if ((ret
= asn1_append_nodes(&chain
->raw
, ASN1_CONSTRUCTED
| ASN1_SEQUENCE
,
1108 3, &chain
->tbs
, &chain
->signalg
, &chain
->sign
)) != 0)
1117 void x509write_free_raw(x509_raw
*chain
)
1119 x509write_free_node(&chain
->raw
);
1120 x509write_free_node(&chain
->tbs
);
1121 x509write_free_node(&chain
->version
);
1122 x509write_free_node(&chain
->serial
);
1123 x509write_free_node(&chain
->tbs_signalg
);
1124 x509write_free_node(&chain
->issuer
);
1125 x509write_free_node(&chain
->validity
);
1126 if (chain
->subject
.data
!= chain
->issuer
.data
)
1127 x509write_free_node(&chain
->subject
);
1128 x509write_free_node(&chain
->subpubkey
);
1129 x509write_free_node(&chain
->signalg
);
1130 x509write_free_node(&chain
->sign
);
1133 void x509write_init_raw(x509_raw
*chain
)
1135 memset((void *) chain
, 0, sizeof(x509_raw
));