Line data Source code
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 0 : IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
141 :
142 0 : IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
143 0 : IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
144 0 : IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
145 :
146 0 : 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 12 : static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
156 : {
157 : RSA *rtmp;
158 12 : if (!key)
159 : return NULL;
160 12 : rtmp = EVP_PKEY_get1_RSA(key);
161 12 : EVP_PKEY_free(key);
162 12 : if (!rtmp)
163 : return NULL;
164 12 : if (rsa) {
165 0 : RSA_free(*rsa);
166 0 : *rsa = rtmp;
167 : }
168 12 : return rtmp;
169 : }
170 :
171 12 : RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
172 : void *u)
173 : {
174 : EVP_PKEY *pktmp;
175 12 : pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
176 12 : return pkey_get_rsa(pktmp, rsa);
177 : }
178 :
179 : # ifndef OPENSSL_NO_FP_API
180 :
181 0 : RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
182 : {
183 : EVP_PKEY *pktmp;
184 0 : pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
185 0 : return pkey_get_rsa(pktmp, rsa);
186 : }
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 0 : IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
239 : RSAPrivateKey)
240 : # endif
241 0 : IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
242 0 : RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
243 : PEM_STRING_PUBLIC,
244 : RSA_PUBKEY)
245 : #endif
246 : #ifndef OPENSSL_NO_DSA
247 0 : static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
248 : {
249 : DSA *dtmp;
250 0 : if (!key)
251 : return NULL;
252 0 : dtmp = EVP_PKEY_get1_DSA(key);
253 0 : EVP_PKEY_free(key);
254 0 : if (!dtmp)
255 : return NULL;
256 0 : if (dsa) {
257 0 : DSA_free(*dsa);
258 0 : *dsa = dtmp;
259 : }
260 0 : return dtmp;
261 : }
262 :
263 0 : DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
264 : void *u)
265 : {
266 : 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 : }
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 0 : IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
318 : DSAPrivateKey)
319 : # endif
320 0 : IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
321 : # ifndef OPENSSL_NO_FP_API
322 0 : DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
323 : {
324 : 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 : }
328 :
329 : # endif
330 :
331 0 : IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
332 : #endif
333 : #ifndef OPENSSL_NO_EC
334 0 : static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
335 : {
336 : EC_KEY *dtmp;
337 0 : if (!key)
338 : return NULL;
339 0 : dtmp = EVP_PKEY_get1_EC_KEY(key);
340 0 : EVP_PKEY_free(key);
341 0 : if (!dtmp)
342 : return NULL;
343 0 : if (eckey) {
344 0 : EC_KEY_free(*eckey);
345 0 : *eckey = dtmp;
346 : }
347 0 : return dtmp;
348 : }
349 :
350 0 : EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
351 : void *u)
352 : {
353 : 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 : }
357 :
358 0 : 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 0 : IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
406 : ECPrivateKey)
407 : # endif
408 0 : IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
409 : # ifndef OPENSSL_NO_FP_API
410 0 : EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
411 : void *u)
412 : {
413 : 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 : }
417 :
418 : # endif
419 :
420 : #endif
421 :
422 : #ifndef OPENSSL_NO_DH
423 :
424 0 : IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
425 0 : IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
426 : #endif
427 0 : IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
|