10Sstevel@tonic-gate /* crypto/pem/pem_all.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
58*2139Sjp161948 /* ====================================================================
59*2139Sjp161948 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
60*2139Sjp161948 *
61*2139Sjp161948 * Redistribution and use in source and binary forms, with or without
62*2139Sjp161948 * modification, are permitted provided that the following conditions
63*2139Sjp161948 * are met:
64*2139Sjp161948 *
65*2139Sjp161948 * 1. Redistributions of source code must retain the above copyright
66*2139Sjp161948 * notice, this list of conditions and the following disclaimer.
67*2139Sjp161948 *
68*2139Sjp161948 * 2. Redistributions in binary form must reproduce the above copyright
69*2139Sjp161948 * notice, this list of conditions and the following disclaimer in
70*2139Sjp161948 * the documentation and/or other materials provided with the
71*2139Sjp161948 * distribution.
72*2139Sjp161948 *
73*2139Sjp161948 * 3. All advertising materials mentioning features or use of this
74*2139Sjp161948 * software must display the following acknowledgment:
75*2139Sjp161948 * "This product includes software developed by the OpenSSL Project
76*2139Sjp161948 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77*2139Sjp161948 *
78*2139Sjp161948 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79*2139Sjp161948 * endorse or promote products derived from this software without
80*2139Sjp161948 * prior written permission. For written permission, please contact
81*2139Sjp161948 * openssl-core@openssl.org.
82*2139Sjp161948 *
83*2139Sjp161948 * 5. Products derived from this software may not be called "OpenSSL"
84*2139Sjp161948 * nor may "OpenSSL" appear in their names without prior written
85*2139Sjp161948 * permission of the OpenSSL Project.
86*2139Sjp161948 *
87*2139Sjp161948 * 6. Redistributions of any form whatsoever must retain the following
88*2139Sjp161948 * acknowledgment:
89*2139Sjp161948 * "This product includes software developed by the OpenSSL Project
90*2139Sjp161948 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91*2139Sjp161948 *
92*2139Sjp161948 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93*2139Sjp161948 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94*2139Sjp161948 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95*2139Sjp161948 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96*2139Sjp161948 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97*2139Sjp161948 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98*2139Sjp161948 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99*2139Sjp161948 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100*2139Sjp161948 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101*2139Sjp161948 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102*2139Sjp161948 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103*2139Sjp161948 * OF THE POSSIBILITY OF SUCH DAMAGE.
104*2139Sjp161948 * ====================================================================
105*2139Sjp161948 *
106*2139Sjp161948 * This product includes cryptographic software written by Eric Young
107*2139Sjp161948 * (eay@cryptsoft.com). This product includes software written by Tim
108*2139Sjp161948 * Hudson (tjh@cryptsoft.com).
109*2139Sjp161948 *
110*2139Sjp161948 */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate #include <stdio.h>
1130Sstevel@tonic-gate #undef SSLEAY_MACROS
1140Sstevel@tonic-gate #include "cryptlib.h"
1150Sstevel@tonic-gate #include <openssl/bio.h>
1160Sstevel@tonic-gate #include <openssl/evp.h>
1170Sstevel@tonic-gate #include <openssl/x509.h>
1180Sstevel@tonic-gate #include <openssl/pkcs7.h>
1190Sstevel@tonic-gate #include <openssl/pem.h>
120*2139Sjp161948 #ifndef OPENSSL_NO_RSA
121*2139Sjp161948 #include <openssl/rsa.h>
122*2139Sjp161948 #endif
123*2139Sjp161948 #ifndef OPENSSL_NO_DSA
124*2139Sjp161948 #include <openssl/dsa.h>
125*2139Sjp161948 #endif
126*2139Sjp161948 #ifndef OPENSSL_NO_DH
127*2139Sjp161948 #include <openssl/dh.h>
128*2139Sjp161948 #endif
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1310Sstevel@tonic-gate static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
1320Sstevel@tonic-gate #endif
1330Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
1340Sstevel@tonic-gate static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
1350Sstevel@tonic-gate #endif
1360Sstevel@tonic-gate
137*2139Sjp161948 #ifndef OPENSSL_NO_EC
138*2139Sjp161948 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
139*2139Sjp161948 #endif
140*2139Sjp161948
IMPLEMENT_PEM_rw(X509_REQ,X509_REQ,PEM_STRING_X509_REQ,X509_REQ)1410Sstevel@tonic-gate IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
1500Sstevel@tonic-gate PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate /* We treat RSA or DSA private keys as a special case.
1560Sstevel@tonic-gate *
1570Sstevel@tonic-gate * For private keys we read in an EVP_PKEY structure with
1580Sstevel@tonic-gate * PEM_read_bio_PrivateKey() and extract the relevant private
1590Sstevel@tonic-gate * key: this means can handle "traditional" and PKCS#8 formats
1600Sstevel@tonic-gate * transparently.
1610Sstevel@tonic-gate */
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate RSA *rtmp;
1660Sstevel@tonic-gate if(!key) return NULL;
1670Sstevel@tonic-gate rtmp = EVP_PKEY_get1_RSA(key);
1680Sstevel@tonic-gate EVP_PKEY_free(key);
1690Sstevel@tonic-gate if(!rtmp) return NULL;
1700Sstevel@tonic-gate if(rsa) {
1710Sstevel@tonic-gate RSA_free(*rsa);
1720Sstevel@tonic-gate *rsa = rtmp;
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate return rtmp;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate
PEM_read_bio_RSAPrivateKey(BIO * bp,RSA ** rsa,pem_password_cb * cb,void * u)1770Sstevel@tonic-gate RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
1780Sstevel@tonic-gate void *u)
1790Sstevel@tonic-gate {
1800Sstevel@tonic-gate EVP_PKEY *pktmp;
1810Sstevel@tonic-gate pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
1820Sstevel@tonic-gate return pkey_get_rsa(pktmp, rsa);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
1860Sstevel@tonic-gate
PEM_read_RSAPrivateKey(FILE * fp,RSA ** rsa,pem_password_cb * cb,void * u)1870Sstevel@tonic-gate RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
1880Sstevel@tonic-gate void *u)
1890Sstevel@tonic-gate {
1900Sstevel@tonic-gate EVP_PKEY *pktmp;
1910Sstevel@tonic-gate pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
1920Sstevel@tonic-gate return pkey_get_rsa(pktmp, rsa);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate #endif
1960Sstevel@tonic-gate
IMPLEMENT_PEM_write_cb_const(RSAPrivateKey,RSA,PEM_STRING_RSA,RSAPrivateKey)197*2139Sjp161948 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
198*2139Sjp161948 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
1990Sstevel@tonic-gate IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate #endif
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
2060Sstevel@tonic-gate {
2070Sstevel@tonic-gate DSA *dtmp;
2080Sstevel@tonic-gate if(!key) return NULL;
2090Sstevel@tonic-gate dtmp = EVP_PKEY_get1_DSA(key);
2100Sstevel@tonic-gate EVP_PKEY_free(key);
2110Sstevel@tonic-gate if(!dtmp) return NULL;
2120Sstevel@tonic-gate if(dsa) {
2130Sstevel@tonic-gate DSA_free(*dsa);
2140Sstevel@tonic-gate *dsa = dtmp;
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate return dtmp;
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate
PEM_read_bio_DSAPrivateKey(BIO * bp,DSA ** dsa,pem_password_cb * cb,void * u)2190Sstevel@tonic-gate DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
2200Sstevel@tonic-gate void *u)
2210Sstevel@tonic-gate {
2220Sstevel@tonic-gate EVP_PKEY *pktmp;
2230Sstevel@tonic-gate pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
2240Sstevel@tonic-gate return pkey_get_dsa(pktmp, dsa);
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
IMPLEMENT_PEM_write_cb_const(DSAPrivateKey,DSA,PEM_STRING_DSA,DSAPrivateKey)227*2139Sjp161948 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
2280Sstevel@tonic-gate IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
2330Sstevel@tonic-gate void *u)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate EVP_PKEY *pktmp;
2360Sstevel@tonic-gate pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
2370Sstevel@tonic-gate return pkey_get_dsa(pktmp, dsa);
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate #endif
2410Sstevel@tonic-gate
IMPLEMENT_PEM_rw_const(DSAparams,DSA,PEM_STRING_DSAPARAMS,DSAparams)242*2139Sjp161948 IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
243*2139Sjp161948
244*2139Sjp161948 #endif
245*2139Sjp161948
246*2139Sjp161948
247*2139Sjp161948 #ifndef OPENSSL_NO_EC
248*2139Sjp161948 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
249*2139Sjp161948 {
250*2139Sjp161948 EC_KEY *dtmp;
251*2139Sjp161948 if(!key) return NULL;
252*2139Sjp161948 dtmp = EVP_PKEY_get1_EC_KEY(key);
253*2139Sjp161948 EVP_PKEY_free(key);
254*2139Sjp161948 if(!dtmp) return NULL;
255*2139Sjp161948 if(eckey)
256*2139Sjp161948 {
257*2139Sjp161948 EC_KEY_free(*eckey);
258*2139Sjp161948 *eckey = dtmp;
259*2139Sjp161948 }
260*2139Sjp161948 return dtmp;
261*2139Sjp161948 }
262*2139Sjp161948
PEM_read_bio_ECPrivateKey(BIO * bp,EC_KEY ** key,pem_password_cb * cb,void * u)263*2139Sjp161948 EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
264*2139Sjp161948 void *u)
265*2139Sjp161948 {
266*2139Sjp161948 EVP_PKEY *pktmp;
267*2139Sjp161948 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
268*2139Sjp161948 return pkey_get_eckey(pktmp, key);
269*2139Sjp161948 }
270*2139Sjp161948
IMPLEMENT_PEM_rw_const(ECPKParameters,EC_GROUP,PEM_STRING_ECPARAMETERS,ECPKParameters)271*2139Sjp161948 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
272*2139Sjp161948
273*2139Sjp161948 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
274*2139Sjp161948
275*2139Sjp161948 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
276*2139Sjp161948
277*2139Sjp161948 #ifndef OPENSSL_NO_FP_API
278*2139Sjp161948
279*2139Sjp161948 EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
280*2139Sjp161948 void *u)
281*2139Sjp161948 {
282*2139Sjp161948 EVP_PKEY *pktmp;
283*2139Sjp161948 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
284*2139Sjp161948 return pkey_get_eckey(pktmp, eckey);
285*2139Sjp161948 }
286*2139Sjp161948
287*2139Sjp161948 #endif
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate #endif
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
2920Sstevel@tonic-gate
293*2139Sjp161948 IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate #endif
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate /* The PrivateKey case is not that straightforward.
2990Sstevel@tonic-gate * IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
3000Sstevel@tonic-gate * does not work, RSA and DSA keys have specific strings.
3010Sstevel@tonic-gate * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything
3020Sstevel@tonic-gate * appropriate.)
3030Sstevel@tonic-gate */
304*2139Sjp161948 IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\
305*2139Sjp161948 (x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey)
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
3080Sstevel@tonic-gate
309