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 
 144 IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
 145 
 146 IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
 147 
 148 IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
 149                                         PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
 150 
 151 
 152 #ifndef OPENSSL_NO_RSA
 153 
 154 /* We treat RSA or DSA private keys as a special case.
 155  *
 156  * For private keys we read in an EVP_PKEY structure with
 157  * PEM_read_bio_PrivateKey() and extract the relevant private
 158  * key: this means can handle "traditional" and PKCS#8 formats
 159  * transparently.
 160  */
 161 
 162 static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
 163 {
 164         RSA *rtmp;
 165         if(!key) return NULL;
 166         rtmp = EVP_PKEY_get1_RSA(key);
 167         EVP_PKEY_free(key);
 168         if(!rtmp) return NULL;
 169         if(rsa) {
 170                 RSA_free(*rsa);
 171                 *rsa = rtmp;
 172         }
 173         return rtmp;
 174 }
 175 
 176 RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
 177                                                                 void *u)
 178 {
 179         EVP_PKEY *pktmp;
 180         pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
 181         return pkey_get_rsa(pktmp, rsa);
 182 }
 183 
 184 #ifndef OPENSSL_NO_FP_API
 185 
 186 RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
 187                                                                 void *u)
 188 {
 189         EVP_PKEY *pktmp;
 190         pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
 191         return pkey_get_rsa(pktmp, rsa);
 192 }
 193 
 194 #endif
 195 
 196 #ifdef OPENSSL_FIPS
 197 
 198 int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
 199                                                unsigned char *kstr, int klen,
 200                                                pem_password_cb *cb, void *u)
 201 {
 202         if (FIPS_mode())
 203                 {
 204                 EVP_PKEY *k;
 205                 int ret;
 206                 k = EVP_PKEY_new();
 207                 if (!k)
 208                         return 0;
 209                 EVP_PKEY_set1_RSA(k, x);
 210 
 211                 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
 212                 EVP_PKEY_free(k);
 213                 return ret;
 214                 }
 215         else
 216                 return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
 217                                         PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
 218 }
 219 
 220 #ifndef OPENSSL_NO_FP_API
 221 int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
 222                                                unsigned char *kstr, int klen,
 223                                                pem_password_cb *cb, void *u)
 224 {
 225         if (FIPS_mode())
 226                 {
 227                 EVP_PKEY *k;
 228                 int ret;
 229                 k = EVP_PKEY_new();
 230                 if (!k)
 231                         return 0;
 232 
 233                 EVP_PKEY_set1_RSA(k, x);
 234 
 235                 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
 236                 EVP_PKEY_free(k);
 237                 return ret;
 238                 }
 239         else
 240                 return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
 241                                         PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
 242 }
 243 #endif
 244 
 245 #else
 246 
 247 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
 248 
 249 #endif
 250 
 251 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 252 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 253 
 254 #endif
 255 
 256 #ifndef OPENSSL_NO_DSA
 257 
 258 static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
 259 {
 260         DSA *dtmp;
 261         if(!key) return NULL;
 262         dtmp = EVP_PKEY_get1_DSA(key);
 263         EVP_PKEY_free(key);
 264         if(!dtmp) return NULL;
 265         if(dsa) {
 266                 DSA_free(*dsa);
 267                 *dsa = dtmp;
 268         }
 269         return dtmp;
 270 }
 271 
 272 DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
 273                                                                 void *u)
 274 {
 275         EVP_PKEY *pktmp;
 276         pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
 277         return pkey_get_dsa(pktmp, dsa);        /* will free pktmp */
 278 }
 279 
 280 #ifdef OPENSSL_FIPS
 281 
 282 int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
 283                                                unsigned char *kstr, int klen,
 284                                                pem_password_cb *cb, void *u)
 285 {
 286         if (FIPS_mode())
 287                 {
 288                 EVP_PKEY *k;
 289                 int ret;
 290                 k = EVP_PKEY_new();
 291                 if (!k)
 292                         return 0;
 293                 EVP_PKEY_set1_DSA(k, x);
 294 
 295                 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
 296                 EVP_PKEY_free(k);
 297                 return ret;
 298                 }
 299         else
 300                 return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
 301                                         PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
 302 }
 303 
 304 #ifndef OPENSSL_NO_FP_API
 305 int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
 306                                                unsigned char *kstr, int klen,
 307                                                pem_password_cb *cb, void *u)
 308 {
 309         if (FIPS_mode())
 310                 {
 311                 EVP_PKEY *k;
 312                 int ret;
 313                 k = EVP_PKEY_new();
 314                 if (!k)
 315                         return 0;
 316                 EVP_PKEY_set1_DSA(k, x);
 317                 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
 318                 EVP_PKEY_free(k);
 319                 return ret;
 320                 }
 321         else
 322                 return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
 323                                         PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
 324 }
 325 #endif
 326 
 327 #else
 328 
 329 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
 330 
 331 #endif
 332 
 333 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
 334 
 335 #ifndef OPENSSL_NO_FP_API
 336 
 337 DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
 338                                                                 void *u)
 339 {
 340         EVP_PKEY *pktmp;
 341         pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
 342         return pkey_get_dsa(pktmp, dsa);        /* will free pktmp */
 343 }
 344 
 345 #endif
 346 
 347 IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
 348 
 349 #endif
 350 
 351 
 352 #ifndef OPENSSL_NO_EC
 353 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
 354 {
 355         EC_KEY *dtmp;
 356         if(!key) return NULL;
 357         dtmp = EVP_PKEY_get1_EC_KEY(key);
 358         EVP_PKEY_free(key);
 359         if(!dtmp) return NULL;
 360         if(eckey)
 361         {
 362                 EC_KEY_free(*eckey);
 363                 *eckey = dtmp;
 364         }
 365         return dtmp;
 366 }
 367 
 368 EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
 369                                                         void *u)
 370 {
 371         EVP_PKEY *pktmp;
 372         pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
 373         return pkey_get_eckey(pktmp, key);      /* will free pktmp */
 374 }
 375 
 376 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
 377 
 378 
 379 
 380 #ifdef OPENSSL_FIPS
 381 
 382 int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
 383                                                unsigned char *kstr, int klen,
 384                                                pem_password_cb *cb, void *u)
 385 {
 386         if (FIPS_mode())
 387                 {
 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 
 395                 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
 396                 EVP_PKEY_free(k);
 397                 return ret;
 398                 }
 399         else
 400                 return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
 401                                                 PEM_STRING_ECPRIVATEKEY,
 402                                                 bp,x,enc,kstr,klen,cb,u);
 403 }
 404 
 405 #ifndef OPENSSL_NO_FP_API
 406 int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
 407                                                unsigned char *kstr, int klen,
 408                                                pem_password_cb *cb, void *u)
 409 {
 410         if (FIPS_mode())
 411                 {
 412                 EVP_PKEY *k;
 413                 int ret;
 414                 k = EVP_PKEY_new();
 415                 if (!k)
 416                         return 0;
 417                 EVP_PKEY_set1_EC_KEY(k, x);
 418                 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
 419                 EVP_PKEY_free(k);
 420                 return ret;
 421                 }
 422         else
 423                 return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
 424                                                 PEM_STRING_ECPRIVATEKEY,
 425                                                 fp,x,enc,kstr,klen,cb,u);
 426 }
 427 #endif
 428 
 429 #else
 430 
 431 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
 432 
 433 #endif
 434 
 435 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 436 
 437 #ifndef OPENSSL_NO_FP_API
 438 
 439 EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
 440                                                                 void *u)
 441 {
 442         EVP_PKEY *pktmp;
 443         pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
 444         return pkey_get_eckey(pktmp, eckey);    /* will free pktmp */
 445 }
 446 
 447 #endif
 448 
 449 #endif
 450 
 451 #ifndef OPENSSL_NO_DH
 452 
 453 IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
 454 
 455 #endif
 456 
 457 IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)