Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/pem/pem_all.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/pem/pem_all.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
/* ====================================================================
59
 * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
60
 *
61
 * Redistribution and use in source and binary forms, with or without
62
 * modification, are permitted provided that the following conditions
63
 * are met:
64
 *
65
 * 1. Redistributions of source code must retain the above copyright
66
 *    notice, this list of conditions and the following disclaimer.
67
 *
68
 * 2. Redistributions in binary form must reproduce the above copyright
69
 *    notice, this list of conditions and the following disclaimer in
70
 *    the documentation and/or other materials provided with the
71
 *    distribution.
72
 *
73
 * 3. All advertising materials mentioning features or use of this
74
 *    software must display the following acknowledgment:
75
 *    "This product includes software developed by the OpenSSL Project
76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77
 *
78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79
 *    endorse or promote products derived from this software without
80
 *    prior written permission. For written permission, please contact
81
 *    openssl-core@openssl.org.
82
 *
83
 * 5. Products derived from this software may not be called "OpenSSL"
84
 *    nor may "OpenSSL" appear in their names without prior written
85
 *    permission of the OpenSSL Project.
86
 *
87
 * 6. Redistributions of any form whatsoever must retain the following
88
 *    acknowledgment:
89
 *    "This product includes software developed by the OpenSSL Project
90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91
 *
92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
104
 * ====================================================================
105
 *
106
 * This product includes cryptographic software written by Eric Young
107
 * (eay@cryptsoft.com).  This product includes software written by Tim
108
 * Hudson (tjh@cryptsoft.com).
109
 *
110
 */
111
112
#include <stdio.h>
113
#include "cryptlib.h"
114
#include <openssl/bio.h>
115
#include <openssl/evp.h>
116
#include <openssl/x509.h>
117
#include <openssl/pkcs7.h>
118
#include <openssl/pem.h>
119
#ifndef OPENSSL_NO_RSA
120
# include <openssl/rsa.h>
121
#endif
122
#ifndef OPENSSL_NO_DSA
123
# include <openssl/dsa.h>
124
#endif
125
#ifndef OPENSSL_NO_DH
126
# include <openssl/dh.h>
127
#endif
128
129
#ifndef OPENSSL_NO_RSA
130
static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
131
#endif
132
#ifndef OPENSSL_NO_DSA
133
static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
134
#endif
135
136
#ifndef OPENSSL_NO_EC
137
static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
138
#endif
139
140
IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
141
142
IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
143
IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
144
IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
145
146
IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
147
                 PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
148
#ifndef OPENSSL_NO_RSA
149
/*
150
 * We treat RSA or DSA private keys as a special case. For private keys we
151
 * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
152
 * the relevant private key: this means can handle "traditional" and PKCS#8
153
 * formats transparently.
154
 */
155
static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
156
0
{
157
0
    RSA *rtmp;
158
0
    if (!key)
159
0
        return NULL;
160
0
    rtmp = EVP_PKEY_get1_RSA(key);
161
0
    EVP_PKEY_free(key);
162
0
    if (!rtmp)
163
0
        return NULL;
164
0
    if (rsa) {
165
0
        RSA_free(*rsa);
166
0
        *rsa = rtmp;
167
0
    }
168
0
    return rtmp;
169
0
}
170
171
RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
172
                                void *u)
173
0
{
174
0
    EVP_PKEY *pktmp;
175
0
    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
176
0
    return pkey_get_rsa(pktmp, rsa);
177
0
}
178
179
# ifndef OPENSSL_NO_FP_API
180
181
RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
182
0
{
183
0
    EVP_PKEY *pktmp;
184
0
    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
185
0
    return pkey_get_rsa(pktmp, rsa);
186
0
}
187
188
# endif
189
190
# ifdef OPENSSL_FIPS
191
192
int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
193
                                unsigned char *kstr, int klen,
194
                                pem_password_cb *cb, void *u)
195
{
196
    if (FIPS_mode()) {
197
        EVP_PKEY *k;
198
        int ret;
199
        k = EVP_PKEY_new();
200
        if (!k)
201
            return 0;
202
        EVP_PKEY_set1_RSA(k, x);
203
204
        ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
205
        EVP_PKEY_free(k);
206
        return ret;
207
    } else
208
        return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
209
                                  PEM_STRING_RSA, bp, x, enc, kstr, klen, cb,
210
                                  u);
211
}
212
213
#  ifndef OPENSSL_NO_FP_API
214
int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
215
                            unsigned char *kstr, int klen,
216
                            pem_password_cb *cb, void *u)
217
{
218
    if (FIPS_mode()) {
219
        EVP_PKEY *k;
220
        int ret;
221
        k = EVP_PKEY_new();
222
        if (!k)
223
            return 0;
224
225
        EVP_PKEY_set1_RSA(k, x);
226
227
        ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
228
        EVP_PKEY_free(k);
229
        return ret;
230
    } else
231
        return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
232
                              PEM_STRING_RSA, fp, x, enc, kstr, klen, cb, u);
233
}
234
#  endif
235
236
# else
237
238
IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
239
                             RSAPrivateKey)
240
# endif
241
IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
242
                       RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
243
                                                      PEM_STRING_PUBLIC,
244
                                                      RSA_PUBKEY)
245
#endif
246
#ifndef OPENSSL_NO_DSA
247
static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
248
0
{
249
0
    DSA *dtmp;
250
0
    if (!key)
251
0
        return NULL;
252
0
    dtmp = EVP_PKEY_get1_DSA(key);
253
0
    EVP_PKEY_free(key);
254
0
    if (!dtmp)
255
0
        return NULL;
256
0
    if (dsa) {
257
0
        DSA_free(*dsa);
258
0
        *dsa = dtmp;
259
0
    }
260
0
    return dtmp;
261
0
}
262
263
DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
264
                                void *u)
265
0
{
266
0
    EVP_PKEY *pktmp;
267
0
    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
268
0
    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
269
0
}
270
271
# ifdef OPENSSL_FIPS
272
273
int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
274
                                unsigned char *kstr, int klen,
275
                                pem_password_cb *cb, void *u)
276
{
277
    if (FIPS_mode()) {
278
        EVP_PKEY *k;
279
        int ret;
280
        k = EVP_PKEY_new();
281
        if (!k)
282
            return 0;
283
        EVP_PKEY_set1_DSA(k, x);
284
285
        ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
286
        EVP_PKEY_free(k);
287
        return ret;
288
    } else
289
        return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
290
                                  PEM_STRING_DSA, bp, x, enc, kstr, klen, cb,
291
                                  u);
292
}
293
294
#  ifndef OPENSSL_NO_FP_API
295
int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
296
                            unsigned char *kstr, int klen,
297
                            pem_password_cb *cb, void *u)
298
{
299
    if (FIPS_mode()) {
300
        EVP_PKEY *k;
301
        int ret;
302
        k = EVP_PKEY_new();
303
        if (!k)
304
            return 0;
305
        EVP_PKEY_set1_DSA(k, x);
306
        ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
307
        EVP_PKEY_free(k);
308
        return ret;
309
    } else
310
        return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
311
                              PEM_STRING_DSA, fp, x, enc, kstr, klen, cb, u);
312
}
313
#  endif
314
315
# else
316
317
IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
318
                             DSAPrivateKey)
319
# endif
320
    IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
321
# ifndef OPENSSL_NO_FP_API
322
DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
323
0
{
324
0
    EVP_PKEY *pktmp;
325
0
    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
326
0
    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
327
0
}
328
329
# endif
330
331
IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
332
#endif
333
#ifndef OPENSSL_NO_EC
334
static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
335
0
{
336
0
    EC_KEY *dtmp;
337
0
    if (!key)
338
0
        return NULL;
339
0
    dtmp = EVP_PKEY_get1_EC_KEY(key);
340
0
    EVP_PKEY_free(key);
341
0
    if (!dtmp)
342
0
        return NULL;
343
0
    if (eckey) {
344
0
        EC_KEY_free(*eckey);
345
0
        *eckey = dtmp;
346
0
    }
347
0
    return dtmp;
348
0
}
349
350
EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
351
                                  void *u)
352
0
{
353
0
    EVP_PKEY *pktmp;
354
0
    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
355
0
    return pkey_get_eckey(pktmp, key); /* will free pktmp */
356
0
}
357
358
IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS,
359
                       ECPKParameters)
360
# ifdef OPENSSL_FIPS
361
int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
362
                               unsigned char *kstr, int klen,
363
                               pem_password_cb *cb, void *u)
364
{
365
    if (FIPS_mode()) {
366
        EVP_PKEY *k;
367
        int ret;
368
        k = EVP_PKEY_new();
369
        if (!k)
370
            return 0;
371
        EVP_PKEY_set1_EC_KEY(k, x);
372
373
        ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
374
        EVP_PKEY_free(k);
375
        return ret;
376
    } else
377
        return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
378
                                  PEM_STRING_ECPRIVATEKEY,
379
                                  bp, x, enc, kstr, klen, cb, u);
380
}
381
382
#  ifndef OPENSSL_NO_FP_API
383
int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
384
                           unsigned char *kstr, int klen,
385
                           pem_password_cb *cb, void *u)
386
{
387
    if (FIPS_mode()) {
388
        EVP_PKEY *k;
389
        int ret;
390
        k = EVP_PKEY_new();
391
        if (!k)
392
            return 0;
393
        EVP_PKEY_set1_EC_KEY(k, x);
394
        ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
395
        EVP_PKEY_free(k);
396
        return ret;
397
    } else
398
        return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
399
                              PEM_STRING_ECPRIVATEKEY,
400
                              fp, x, enc, kstr, klen, cb, u);
401
}
402
#  endif
403
404
# else
405
    IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
406
                       ECPrivateKey)
407
# endif
408
IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
409
# ifndef OPENSSL_NO_FP_API
410
EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
411
                              void *u)
412
0
{
413
0
    EVP_PKEY *pktmp;
414
0
    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
415
0
    return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
416
0
}
417
418
# endif
419
420
#endif
421
422
#ifndef OPENSSL_NO_DH
423
424
IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
425
    IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
426
#endif
427
IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)