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 28 static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); 29 #ifndef OPENSSL_NO_DSA 30 static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); 31 #endif 32 33 #ifndef OPENSSL_NO_EC 34 static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); 35 #endif 36 37 IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) 38 39 IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) 40 IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) 41 IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) 42 IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) 43 44 IMPLEMENT_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 */ 53 static 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 69 RSA *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 79 RSA *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 88 IMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) 89 IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) 90 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) 91 #endif 92 #ifndef OPENSSL_NO_DSA 93 static 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 109 DSA *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 117 IMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) 118 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) 119 # ifndef OPENSSL_NO_STDIO 120 DSA *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 129 IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) 130 #endif 131 132 #ifndef OPENSSL_NO_DEPRECATED_3_0 133 # ifndef OPENSSL_NO_EC 134 static 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 150 EC_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 158 IMPLEMENT_PEM_rw(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, 159 ECPKParameters) 160 161 162 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, 163 ECPrivateKey) 164 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) 165 # ifndef OPENSSL_NO_STDIO 166 EC_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 179 IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) 180 IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) 181 182 /* Transparently read in PKCS#3 or X9.42 DH parameters */ 183 184 DH *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 209 DH *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 226 IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, pkey, PEM_STRING_PUBLIC, PUBKEY) 227