/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) |