/src/openssl/crypto/pem/pem_all.c
Line | Count | Source (jump to first uncovered line) |
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/bio.h> |
19 | | #include <openssl/evp.h> |
20 | | #include <openssl/x509.h> |
21 | | #include <openssl/pkcs7.h> |
22 | | #include <openssl/pem.h> |
23 | | #include <openssl/rsa.h> |
24 | | #include <openssl/dsa.h> |
25 | | #include <openssl/dh.h> |
26 | | #include "pem_local.h" |
27 | | |
28 | | static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); |
29 | | #ifndef OPENSSL_NO_DSA |
30 | | static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); |
31 | | #endif |
32 | | |
33 | | #ifndef OPENSSL_NO_EC |
34 | | static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); |
35 | | #endif |
36 | | |
37 | | IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) |
38 | | |
39 | | IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) |
40 | | IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) |
41 | | IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) |
42 | | IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) |
43 | | |
44 | | IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, |
45 | | PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) |
46 | | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
47 | | /* |
48 | | * We treat RSA or DSA private keys as a special case. For private keys we |
49 | | * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract |
50 | | * the relevant private key: this means can handle "traditional" and PKCS#8 |
51 | | * formats transparently. |
52 | | */ |
53 | | static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) |
54 | 0 | { |
55 | 0 | RSA *rtmp; |
56 | 0 | if (!key) |
57 | 0 | return NULL; |
58 | 0 | rtmp = EVP_PKEY_get1_RSA(key); |
59 | 0 | EVP_PKEY_free(key); |
60 | 0 | if (!rtmp) |
61 | 0 | return NULL; |
62 | 0 | if (rsa) { |
63 | 0 | RSA_free(*rsa); |
64 | 0 | *rsa = rtmp; |
65 | 0 | } |
66 | 0 | return rtmp; |
67 | 0 | } |
68 | | |
69 | | RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, |
70 | | void *u) |
71 | 0 | { |
72 | 0 | EVP_PKEY *pktmp; |
73 | 0 | pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); |
74 | 0 | return pkey_get_rsa(pktmp, rsa); |
75 | 0 | } |
76 | | |
77 | | # ifndef OPENSSL_NO_STDIO |
78 | | |
79 | | RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) |
80 | 0 | { |
81 | 0 | EVP_PKEY *pktmp; |
82 | 0 | pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); |
83 | 0 | return pkey_get_rsa(pktmp, rsa); |
84 | 0 | } |
85 | | |
86 | | # endif |
87 | | |
88 | | IMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) |
89 | | IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) |
90 | | IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) |
91 | | #endif |
92 | | #ifndef OPENSSL_NO_DSA |
93 | | static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) |
94 | 0 | { |
95 | 0 | DSA *dtmp; |
96 | 0 | if (!key) |
97 | 0 | return NULL; |
98 | 0 | dtmp = EVP_PKEY_get1_DSA(key); |
99 | 0 | EVP_PKEY_free(key); |
100 | 0 | if (!dtmp) |
101 | 0 | return NULL; |
102 | 0 | if (dsa) { |
103 | 0 | DSA_free(*dsa); |
104 | 0 | *dsa = dtmp; |
105 | 0 | } |
106 | 0 | return dtmp; |
107 | 0 | } |
108 | | |
109 | | DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, |
110 | | void *u) |
111 | 0 | { |
112 | 0 | EVP_PKEY *pktmp; |
113 | 0 | pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); |
114 | 0 | return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ |
115 | 0 | } |
116 | | |
117 | | IMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) |
118 | | IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) |
119 | | # ifndef OPENSSL_NO_STDIO |
120 | | DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) |
121 | 0 | { |
122 | 0 | EVP_PKEY *pktmp; |
123 | 0 | pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); |
124 | 0 | return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ |
125 | 0 | } |
126 | | |
127 | | # endif |
128 | | |
129 | | IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) |
130 | | #endif |
131 | | |
132 | | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
133 | | # ifndef OPENSSL_NO_EC |
134 | | static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) |
135 | 0 | { |
136 | 0 | EC_KEY *dtmp; |
137 | 0 | if (!key) |
138 | 0 | return NULL; |
139 | 0 | dtmp = EVP_PKEY_get1_EC_KEY(key); |
140 | 0 | EVP_PKEY_free(key); |
141 | 0 | if (!dtmp) |
142 | 0 | return NULL; |
143 | 0 | if (eckey) { |
144 | 0 | EC_KEY_free(*eckey); |
145 | 0 | *eckey = dtmp; |
146 | 0 | } |
147 | 0 | return dtmp; |
148 | 0 | } |
149 | | |
150 | | EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, |
151 | | void *u) |
152 | 0 | { |
153 | 0 | EVP_PKEY *pktmp; |
154 | 0 | pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); |
155 | 0 | return pkey_get_eckey(pktmp, key); /* will free pktmp */ |
156 | 0 | } |
157 | | |
158 | | IMPLEMENT_PEM_rw(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, |
159 | | ECPKParameters) |
160 | | |
161 | | |
162 | | IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, |
163 | | ECPrivateKey) |
164 | | IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) |
165 | | # ifndef OPENSSL_NO_STDIO |
166 | | EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, |
167 | | void *u) |
168 | 0 | { |
169 | 0 | EVP_PKEY *pktmp; |
170 | 0 | pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); |
171 | 0 | return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ |
172 | 0 | } |
173 | | # endif |
174 | | # endif /* !OPENSSL_NO_EC */ |
175 | | #endif /* !OPENSSL_NO_DEPRECATED_3_0 */ |
176 | | |
177 | | #ifndef OPENSSL_NO_DH |
178 | | |
179 | | IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) |
180 | | IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) |
181 | | |
182 | | /* Transparently read in PKCS#3 or X9.42 DH parameters */ |
183 | | |
184 | | DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) |
185 | 0 | { |
186 | 0 | char *nm = NULL; |
187 | 0 | const unsigned char *p = NULL; |
188 | 0 | unsigned char *data = NULL; |
189 | 0 | long len; |
190 | 0 | DH *ret = NULL; |
191 | |
|
192 | 0 | if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) |
193 | 0 | return NULL; |
194 | 0 | p = data; |
195 | |
|
196 | 0 | if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) |
197 | 0 | ret = d2i_DHxparams(x, &p, len); |
198 | 0 | else |
199 | 0 | ret = d2i_DHparams(x, &p, len); |
200 | |
|
201 | 0 | if (ret == NULL) |
202 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); |
203 | 0 | OPENSSL_free(nm); |
204 | 0 | OPENSSL_free(data); |
205 | 0 | return ret; |
206 | 0 | } |
207 | | |
208 | | # ifndef OPENSSL_NO_STDIO |
209 | | DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) |
210 | 0 | { |
211 | 0 | BIO *b; |
212 | 0 | DH *ret; |
213 | |
|
214 | 0 | if ((b = BIO_new(BIO_s_file())) == NULL) { |
215 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); |
216 | 0 | return 0; |
217 | 0 | } |
218 | 0 | BIO_set_fp(b, fp, BIO_NOCLOSE); |
219 | 0 | ret = PEM_read_bio_DHparams(b, x, cb, u); |
220 | 0 | BIO_free(b); |
221 | 0 | return ret; |
222 | 0 | } |
223 | | # endif |
224 | | |
225 | | #endif |
226 | | IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, pkey, PEM_STRING_PUBLIC, PUBKEY) |