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 = 0, 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));