pem_all.c revision 142425
155714Skris/* crypto/pem/pem_all.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#undef SSLEAY_MACROS
6155714Skris#include "cryptlib.h"
6255714Skris#include <openssl/bio.h>
6355714Skris#include <openssl/evp.h>
6455714Skris#include <openssl/x509.h>
6555714Skris#include <openssl/pkcs7.h>
6655714Skris#include <openssl/pem.h>
67142425Snectar#include <openssl/fips.h>
6855714Skris
69109998Smarkm#ifndef OPENSSL_NO_RSA
7059191Skrisstatic RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
7159191Skris#endif
72109998Smarkm#ifndef OPENSSL_NO_DSA
7359191Skrisstatic DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
7459191Skris#endif
7559191Skris
7655714SkrisIMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
7755714Skris
7859191SkrisIMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
7959191Skris
8055714SkrisIMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
8155714Skris
8255714SkrisIMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
8355714Skris
8455714SkrisIMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
8555714Skris					PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
8655714Skris
8755714Skris
88109998Smarkm#ifndef OPENSSL_NO_RSA
8955714Skris
9059191Skris/* We treat RSA or DSA private keys as a special case.
9159191Skris *
9259191Skris * For private keys we read in an EVP_PKEY structure with
9359191Skris * PEM_read_bio_PrivateKey() and extract the relevant private
9459191Skris * key: this means can handle "traditional" and PKCS#8 formats
9559191Skris * transparently.
9659191Skris */
9755714Skris
9859191Skrisstatic RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
9959191Skris{
10059191Skris	RSA *rtmp;
10159191Skris	if(!key) return NULL;
10259191Skris	rtmp = EVP_PKEY_get1_RSA(key);
10359191Skris	EVP_PKEY_free(key);
10459191Skris	if(!rtmp) return NULL;
10559191Skris	if(rsa) {
10659191Skris		RSA_free(*rsa);
10759191Skris		*rsa = rtmp;
10859191Skris	}
10959191Skris	return rtmp;
11059191Skris}
11159191Skris
11259191SkrisRSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
11359191Skris								void *u)
11459191Skris{
11559191Skris	EVP_PKEY *pktmp;
11659191Skris	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
11759191Skris	return pkey_get_rsa(pktmp, rsa);
11859191Skris}
11959191Skris
120109998Smarkm#ifndef OPENSSL_NO_FP_API
12159191Skris
12259191SkrisRSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
12359191Skris								void *u)
12459191Skris{
12559191Skris	EVP_PKEY *pktmp;
12659191Skris	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
12759191Skris	return pkey_get_rsa(pktmp, rsa);
12859191Skris}
12959191Skris
13059191Skris#endif
13159191Skris
132142425Snectar#ifdef OPENSSL_FIPS
133142425Snectar
134142425Snectarint PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
135142425Snectar                                               unsigned char *kstr, int klen,
136142425Snectar                                               pem_password_cb *cb, void *u)
137142425Snectar{
138142425Snectar	EVP_PKEY *k;
139142425Snectar	int ret;
140142425Snectar	k = EVP_PKEY_new();
141142425Snectar	if (!k)
142142425Snectar		return 0;
143142425Snectar	EVP_PKEY_set1_RSA(k, x);
144142425Snectar
145142425Snectar	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
146142425Snectar	EVP_PKEY_free(k);
147142425Snectar	return ret;
148142425Snectar}
149142425Snectar
150142425Snectar#ifndef OPENSSL_NO_FP_API
151142425Snectarint PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
152142425Snectar                                               unsigned char *kstr, int klen,
153142425Snectar                                               pem_password_cb *cb, void *u)
154142425Snectar{
155142425Snectar	EVP_PKEY *k;
156142425Snectar	int ret;
157142425Snectar	k = EVP_PKEY_new();
158142425Snectar	if (!k)
159142425Snectar		return 0;
160142425Snectar
161142425Snectar	EVP_PKEY_set1_RSA(k, x);
162142425Snectar
163142425Snectar	ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
164142425Snectar	EVP_PKEY_free(k);
165142425Snectar	return ret;
166142425Snectar}
167142425Snectar#endif
168142425Snectar
169142425Snectar#else
170142425Snectar
17159191SkrisIMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
172142425Snectar
173142425Snectar#endif
174142425Snectar
17555714SkrisIMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
17659191SkrisIMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
17755714Skris
17855714Skris#endif
17955714Skris
180109998Smarkm#ifndef OPENSSL_NO_DSA
18155714Skris
18259191Skrisstatic DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
18359191Skris{
18459191Skris	DSA *dtmp;
18559191Skris	if(!key) return NULL;
18659191Skris	dtmp = EVP_PKEY_get1_DSA(key);
18759191Skris	EVP_PKEY_free(key);
18859191Skris	if(!dtmp) return NULL;
18959191Skris	if(dsa) {
19059191Skris		DSA_free(*dsa);
19159191Skris		*dsa = dtmp;
19259191Skris	}
19359191Skris	return dtmp;
19459191Skris}
19555714Skris
19659191SkrisDSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
19759191Skris								void *u)
19859191Skris{
19959191Skris	EVP_PKEY *pktmp;
20059191Skris	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
20159191Skris	return pkey_get_dsa(pktmp, dsa);
20259191Skris}
20359191Skris
204142425Snectar
205142425Snectar#ifdef OPENSSL_FIPS
206142425Snectar
207142425Snectarint PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
208142425Snectar                                               unsigned char *kstr, int klen,
209142425Snectar                                               pem_password_cb *cb, void *u)
210142425Snectar{
211142425Snectar	EVP_PKEY *k;
212142425Snectar	int ret;
213142425Snectar	k = EVP_PKEY_new();
214142425Snectar	if (!k)
215142425Snectar		return 0;
216142425Snectar	EVP_PKEY_set1_DSA(k, x);
217142425Snectar
218142425Snectar	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
219142425Snectar	EVP_PKEY_free(k);
220142425Snectar	return ret;
221142425Snectar}
222142425Snectar
223142425Snectar#ifndef OPENSSL_NO_FP_API
224142425Snectarint PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
225142425Snectar                                               unsigned char *kstr, int klen,
226142425Snectar                                               pem_password_cb *cb, void *u)
227142425Snectar{
228142425Snectar	EVP_PKEY *k;
229142425Snectar	int ret;
230142425Snectar	k = EVP_PKEY_new();
231142425Snectar	if (!k)
232142425Snectar		return 0;
233142425Snectar	EVP_PKEY_set1_DSA(k, x);
234142425Snectar	ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
235142425Snectar	EVP_PKEY_free(k);
236142425Snectar	return ret;
237142425Snectar}
238142425Snectar#endif
239142425Snectar
240142425Snectar#else
241142425Snectar
24259191SkrisIMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
243142425Snectar
244142425Snectar#endif
245142425Snectar
24659191SkrisIMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
24759191Skris
248109998Smarkm#ifndef OPENSSL_NO_FP_API
24959191Skris
25059191SkrisDSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
25159191Skris								void *u)
25259191Skris{
25359191Skris	EVP_PKEY *pktmp;
25459191Skris	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
25559191Skris	return pkey_get_dsa(pktmp, dsa);
25659191Skris}
25759191Skris
25859191Skris#endif
25959191Skris
26055714SkrisIMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
26155714Skris
26255714Skris#endif
26355714Skris
264109998Smarkm#ifndef OPENSSL_NO_DH
26555714Skris
26655714SkrisIMPLEMENT_PEM_rw(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
26755714Skris
26855714Skris#endif
26955714Skris
27055714Skris
27155714Skris/* The PrivateKey case is not that straightforward.
27255714Skris *   IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
27355714Skris * does not work, RSA and DSA keys have specific strings.
27455714Skris * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything
27555714Skris * appropriate.)
27655714Skris */
277142425Snectar
278142425Snectar#ifdef OPENSSL_FIPS
279142425Snectar
280142425Snectarint PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
281142425Snectar                                               unsigned char *kstr, int klen,
282142425Snectar                                               pem_password_cb *cb, void *u)
283142425Snectar	{
284142425Snectar		if (FIPS_mode())
285142425Snectar			return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
286142425Snectar						(char *)kstr, klen, cb, u);
287142425Snectar		else
288142425Snectar                	return PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,
289142425Snectar                (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),
290142425Snectar                        bp,(char *)x,enc,kstr,klen,cb,u);
291142425Snectar	}
292142425Snectar
293142425Snectar#ifndef OPENSSL_NO_FP_API
294142425Snectarint PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
295142425Snectar                                               unsigned char *kstr, int klen,
296142425Snectar                                               pem_password_cb *cb, void *u)
297142425Snectar	{
298142425Snectar		if (FIPS_mode())
299142425Snectar			return PEM_write_PKCS8PrivateKey(fp, x, enc,
300142425Snectar						(char *)kstr, klen, cb, u);
301142425Snectar		else
302142425Snectar                	return PEM_ASN1_write((int (*)())i2d_PrivateKey,
303142425Snectar                (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),
304142425Snectar                        fp,(char *)x,enc,kstr,klen,cb,u);
305142425Snectar	}
306142425Snectar#endif
307142425Snectar
308142425Snectar#else
309142425Snectar
31055714SkrisIMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA), PrivateKey)
31159191Skris
312142425Snectar#endif
313142425Snectar
31459191SkrisIMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
315109998Smarkm
316