1/* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10/* 11 * DSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14#include "internal/deprecated.h" 15 16#include <stdio.h> 17#include "internal/cryptlib.h" 18#include <openssl/bio.h> 19#include <openssl/evp.h> 20#include <openssl/x509.h> 21#include <openssl/pkcs7.h> 22#include <openssl/pem.h> 23#include <openssl/rsa.h> 24#include <openssl/dsa.h> 25#include <openssl/dh.h> 26#include "pem_local.h" 27 28static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); 29#ifndef OPENSSL_NO_DSA 30static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); 31#endif 32 33#ifndef OPENSSL_NO_EC 34static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); 35#endif 36 37IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) 38 39IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) 40IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) 41IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) 42IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) 43 44IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, 45 PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) 46#ifndef OPENSSL_NO_DEPRECATED_3_0 47/* 48 * We treat RSA or DSA private keys as a special case. For private keys we 49 * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract 50 * the relevant private key: this means can handle "traditional" and PKCS#8 51 * formats transparently. 52 */ 53static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) 54{ 55 RSA *rtmp; 56 if (!key) 57 return NULL; 58 rtmp = EVP_PKEY_get1_RSA(key); 59 EVP_PKEY_free(key); 60 if (!rtmp) 61 return NULL; 62 if (rsa) { 63 RSA_free(*rsa); 64 *rsa = rtmp; 65 } 66 return rtmp; 67} 68 69RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, 70 void *u) 71{ 72 EVP_PKEY *pktmp; 73 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); 74 return pkey_get_rsa(pktmp, rsa); 75} 76 77# ifndef OPENSSL_NO_STDIO 78 79RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) 80{ 81 EVP_PKEY *pktmp; 82 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); 83 return pkey_get_rsa(pktmp, rsa); 84} 85 86# endif 87 88IMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) 89IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) 90IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) 91#endif 92#ifndef OPENSSL_NO_DSA 93static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) 94{ 95 DSA *dtmp; 96 if (!key) 97 return NULL; 98 dtmp = EVP_PKEY_get1_DSA(key); 99 EVP_PKEY_free(key); 100 if (!dtmp) 101 return NULL; 102 if (dsa) { 103 DSA_free(*dsa); 104 *dsa = dtmp; 105 } 106 return dtmp; 107} 108 109DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, 110 void *u) 111{ 112 EVP_PKEY *pktmp; 113 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); 114 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ 115} 116 117IMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) 118IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) 119# ifndef OPENSSL_NO_STDIO 120DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) 121{ 122 EVP_PKEY *pktmp; 123 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); 124 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ 125} 126 127# endif 128 129IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) 130#endif 131 132#ifndef OPENSSL_NO_DEPRECATED_3_0 133# ifndef OPENSSL_NO_EC 134static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) 135{ 136 EC_KEY *dtmp; 137 if (!key) 138 return NULL; 139 dtmp = EVP_PKEY_get1_EC_KEY(key); 140 EVP_PKEY_free(key); 141 if (!dtmp) 142 return NULL; 143 if (eckey) { 144 EC_KEY_free(*eckey); 145 *eckey = dtmp; 146 } 147 return dtmp; 148} 149 150EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, 151 void *u) 152{ 153 EVP_PKEY *pktmp; 154 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); 155 return pkey_get_eckey(pktmp, key); /* will free pktmp */ 156} 157 158IMPLEMENT_PEM_rw(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, 159 ECPKParameters) 160 161 162IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, 163 ECPrivateKey) 164IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) 165# ifndef OPENSSL_NO_STDIO 166EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, 167 void *u) 168{ 169 EVP_PKEY *pktmp; 170 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); 171 return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ 172} 173# endif 174# endif /* !OPENSSL_NO_EC */ 175#endif /* !OPENSSL_NO_DEPRECATED_3_0 */ 176 177#ifndef OPENSSL_NO_DH 178 179IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) 180IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) 181 182/* Transparently read in PKCS#3 or X9.42 DH parameters */ 183 184DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) 185{ 186 char *nm = NULL; 187 const unsigned char *p = NULL; 188 unsigned char *data = NULL; 189 long len; 190 DH *ret = NULL; 191 192 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) 193 return NULL; 194 p = data; 195 196 if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) 197 ret = d2i_DHxparams(x, &p, len); 198 else 199 ret = d2i_DHparams(x, &p, len); 200 201 if (ret == NULL) 202 ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); 203 OPENSSL_free(nm); 204 OPENSSL_free(data); 205 return ret; 206} 207 208# ifndef OPENSSL_NO_STDIO 209DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) 210{ 211 BIO *b; 212 DH *ret; 213 214 if ((b = BIO_new(BIO_s_file())) == NULL) { 215 ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); 216 return 0; 217 } 218 BIO_set_fp(b, fp, BIO_NOCLOSE); 219 ret = PEM_read_bio_DHparams(b, x, cb, u); 220 BIO_free(b); 221 return ret; 222} 223# endif 224 225#endif 226IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, pkey, PEM_STRING_PUBLIC, PUBKEY) 227