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