dd493c8509d006895d1aa6b5c0570cb993af13e8
[openssl.git] / crypto / pem / pem_info.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/buffer.h>
13 #include <openssl/objects.h>
14 #include <openssl/evp.h>
15 #include <openssl/x509.h>
16 #include <openssl/pem.h>
17 #include <openssl/rsa.h>
18 #include <openssl/dsa.h>
19
20 #ifndef OPENSSL_NO_STDIO
21 STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
22                                         pem_password_cb *cb, void *u)
23 {
24     BIO *b;
25     STACK_OF(X509_INFO) *ret;
26
27     if ((b = BIO_new(BIO_s_file())) == NULL) {
28         PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
29         return (0);
30     }
31     BIO_set_fp(b, fp, BIO_NOCLOSE);
32     ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
33     BIO_free(b);
34     return (ret);
35 }
36 #endif
37
38 STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
39                                             pem_password_cb *cb, void *u)
40 {
41     X509_INFO *xi = NULL;
42     char *name = NULL, *header = NULL;
43     void *pp;
44     unsigned char *data = NULL;
45     const unsigned char *p;
46     long len, error = 0;
47     int ok = 0;
48     STACK_OF(X509_INFO) *ret = NULL;
49     unsigned int i, raw, ptype;
50     d2i_of_void *d2i = 0;
51
52     if (sk == NULL) {
53         if ((ret = sk_X509_INFO_new_null()) == NULL) {
54             PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
55             goto err;
56         }
57     } else
58         ret = sk;
59
60     if ((xi = X509_INFO_new()) == NULL)
61         goto err;
62     for (;;) {
63         raw = 0;
64         ptype = 0;
65         i = PEM_read_bio(bp, &name, &header, &data, &len);
66         if (i == 0) {
67             error = ERR_GET_REASON(ERR_peek_last_error());
68             if (error == PEM_R_NO_START_LINE) {
69                 ERR_clear_error();
70                 break;
71             }
72             goto err;
73         }
74  start:
75         if ((strcmp(name, PEM_STRING_X509) == 0) ||
76             (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
77             d2i = (D2I_OF(void)) d2i_X509;
78             if (xi->x509 != NULL) {
79                 if (!sk_X509_INFO_push(ret, xi))
80                     goto err;
81                 if ((xi = X509_INFO_new()) == NULL)
82                     goto err;
83                 goto start;
84             }
85             pp = &(xi->x509);
86         } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
87             d2i = (D2I_OF(void)) d2i_X509_AUX;
88             if (xi->x509 != NULL) {
89                 if (!sk_X509_INFO_push(ret, xi))
90                     goto err;
91                 if ((xi = X509_INFO_new()) == NULL)
92                     goto err;
93                 goto start;
94             }
95             pp = &(xi->x509);
96         } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
97             d2i = (D2I_OF(void)) d2i_X509_CRL;
98             if (xi->crl != NULL) {
99                 if (!sk_X509_INFO_push(ret, xi))
100                     goto err;
101                 if ((xi = X509_INFO_new()) == NULL)
102                     goto err;
103                 goto start;
104             }
105             pp = &(xi->crl);
106         } else
107 #ifndef OPENSSL_NO_RSA
108         if (strcmp(name, PEM_STRING_RSA) == 0) {
109             d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
110             if (xi->x_pkey != NULL) {
111                 if (!sk_X509_INFO_push(ret, xi))
112                     goto err;
113                 if ((xi = X509_INFO_new()) == NULL)
114                     goto err;
115                 goto start;
116             }
117
118             xi->enc_data = NULL;
119             xi->enc_len = 0;
120
121             xi->x_pkey = X509_PKEY_new();
122             if (xi->x_pkey == NULL)
123                 goto err;
124             ptype = EVP_PKEY_RSA;
125             pp = &xi->x_pkey->dec_pkey;
126             if ((int)strlen(header) > 10) /* assume encrypted */
127                 raw = 1;
128         } else
129 #endif
130 #ifndef OPENSSL_NO_DSA
131         if (strcmp(name, PEM_STRING_DSA) == 0) {
132             d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
133             if (xi->x_pkey != NULL) {
134                 if (!sk_X509_INFO_push(ret, xi))
135                     goto err;
136                 if ((xi = X509_INFO_new()) == NULL)
137                     goto err;
138                 goto start;
139             }
140
141             xi->enc_data = NULL;
142             xi->enc_len = 0;
143
144             xi->x_pkey = X509_PKEY_new();
145             if (xi->x_pkey == NULL)
146                 goto err;
147             ptype = EVP_PKEY_DSA;
148             pp = &xi->x_pkey->dec_pkey;
149             if ((int)strlen(header) > 10) /* assume encrypted */
150                 raw = 1;
151         } else
152 #endif
153 #ifndef OPENSSL_NO_EC
154         if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
155             d2i = (D2I_OF(void)) d2i_ECPrivateKey;
156             if (xi->x_pkey != NULL) {
157                 if (!sk_X509_INFO_push(ret, xi))
158                     goto err;
159                 if ((xi = X509_INFO_new()) == NULL)
160                     goto err;
161                 goto start;
162             }
163
164             xi->enc_data = NULL;
165             xi->enc_len = 0;
166
167             xi->x_pkey = X509_PKEY_new();
168             if (xi->x_pkey == NULL)
169                 goto err;
170             ptype = EVP_PKEY_EC;
171             pp = &xi->x_pkey->dec_pkey;
172             if ((int)strlen(header) > 10) /* assume encrypted */
173                 raw = 1;
174         } else
175 #endif
176         {
177             d2i = NULL;
178             pp = NULL;
179         }
180
181         if (d2i != NULL) {
182             if (!raw) {
183                 EVP_CIPHER_INFO cipher;
184
185                 if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
186                     goto err;
187                 if (!PEM_do_header(&cipher, data, &len, cb, u))
188                     goto err;
189                 p = data;
190                 if (ptype) {
191                     if (!d2i_PrivateKey(ptype, pp, &p, len)) {
192                         PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
193                         goto err;
194                     }
195                 } else if (d2i(pp, &p, len) == NULL) {
196                     PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
197                     goto err;
198                 }
199             } else {            /* encrypted RSA data */
200                 if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
201                     goto err;
202                 xi->enc_data = (char *)data;
203                 xi->enc_len = (int)len;
204                 data = NULL;
205             }
206         } else {
207             /* unknown */
208         }
209         OPENSSL_free(name);
210         name = NULL;
211         OPENSSL_free(header);
212         header = NULL;
213         OPENSSL_free(data);
214         data = NULL;
215     }
216
217     /*
218      * if the last one hasn't been pushed yet and there is anything in it
219      * then add it to the stack ...
220      */
221     if ((xi->x509 != NULL) || (xi->crl != NULL) ||
222         (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
223         if (!sk_X509_INFO_push(ret, xi))
224             goto err;
225         xi = NULL;
226     }
227     ok = 1;
228  err:
229     X509_INFO_free(xi);
230     if (!ok) {
231         for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
232             xi = sk_X509_INFO_value(ret, i);
233             X509_INFO_free(xi);
234         }
235         if (ret != sk)
236             sk_X509_INFO_free(ret);
237         ret = NULL;
238     }
239
240     OPENSSL_free(name);
241     OPENSSL_free(header);
242     OPENSSL_free(data);
243     return (ret);
244 }
245
246 /* A TJH addition */
247 int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
248                             unsigned char *kstr, int klen,
249                             pem_password_cb *cb, void *u)
250 {
251     int i, ret = 0;
252     unsigned char *data = NULL;
253     const char *objstr = NULL;
254     char buf[PEM_BUFSIZE];
255     unsigned char *iv = NULL;
256
257     if (enc != NULL) {
258         objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
259         if (objstr == NULL) {
260             PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
261             goto err;
262         }
263     }
264
265     /*
266      * now for the fun part ... if we have a private key then we have to be
267      * able to handle a not-yet-decrypted key being written out correctly ...
268      * if it is decrypted or it is non-encrypted then we use the base code
269      */
270     if (xi->x_pkey != NULL) {
271         if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
272             if (enc == NULL) {
273                 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL);
274                 goto err;
275             }
276
277             /* copy from weirdo names into more normal things */
278             iv = xi->enc_cipher.iv;
279             data = (unsigned char *)xi->enc_data;
280             i = xi->enc_len;
281
282             /*
283              * we take the encryption data from the internal stuff rather
284              * than what the user has passed us ... as we have to match
285              * exactly for some strange reason
286              */
287             objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
288             if (objstr == NULL) {
289                 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
290                        PEM_R_UNSUPPORTED_CIPHER);
291                 goto err;
292             }
293
294             /* create the right magic header stuff */
295             OPENSSL_assert(strlen(objstr) + 23
296                            + 2 * EVP_CIPHER_iv_length(enc) + 13 <=
297                            sizeof buf);
298             buf[0] = '\0';
299             PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
300             PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc),
301                          (char *)iv);
302
303             /* use the normal code to write things out */
304             i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
305             if (i <= 0)
306                 goto err;
307         } else {
308             /* Add DSA/DH */
309 #ifndef OPENSSL_NO_RSA
310             /* normal optionally encrypted stuff */
311             if (PEM_write_bio_RSAPrivateKey(bp,
312                                             EVP_PKEY_get0_RSA(xi->x_pkey->dec_pkey),
313                                             enc, kstr, klen, cb, u) <= 0)
314                 goto err;
315 #endif
316         }
317     }
318
319     /* if we have a certificate then write it out now */
320     if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
321         goto err;
322
323     /*
324      * we are ignoring anything else that is loaded into the X509_INFO
325      * structure for the moment ... as I don't need it so I'm not coding it
326      * here and Eric can do it when this makes it into the base library --tjh
327      */
328
329     ret = 1;
330
331  err:
332     OPENSSL_cleanse(buf, PEM_BUFSIZE);
333     return (ret);
334 }