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