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