1 /* 2 * Copyright 2020-2023 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 <openssl/core_names.h> 17 #include <openssl/err.h> 18 #ifndef FIPS_MODULE 19 # include <openssl/x509.h> 20 #endif 21 #include "crypto/dsa.h" 22 #include "dsa_local.h" 23 24 /* 25 * The intention with the "backend" source file is to offer backend support 26 * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider 27 * implementations alike. 28 */ 29 30 int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[], 31 int include_private) 32 { 33 const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; 34 BIGNUM *priv_key = NULL, *pub_key = NULL; 35 36 if (dsa == NULL) 37 return 0; 38 39 if (include_private) { 40 param_priv_key = 41 OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); 42 } 43 param_pub_key = 44 OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); 45 46 /* It's ok if neither half is present */ 47 if (param_priv_key == NULL && param_pub_key == NULL) 48 return 1; 49 50 if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) 51 goto err; 52 if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) 53 goto err; 54 55 if (!DSA_set0_key(dsa, pub_key, priv_key)) 56 goto err; 57 58 return 1; 59 60 err: 61 BN_clear_free(priv_key); 62 BN_free(pub_key); 63 return 0; 64 } 65 66 int ossl_dsa_is_foreign(const DSA *dsa) 67 { 68 #ifndef FIPS_MODULE 69 if (dsa->engine != NULL || DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) 70 return 1; 71 #endif 72 return 0; 73 } 74 75 static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) 76 { 77 if (f != NULL && (*out = BN_dup(f)) == NULL) 78 return 0; 79 return 1; 80 } 81 82 DSA *ossl_dsa_dup(const DSA *dsa, int selection) 83 { 84 DSA *dupkey = NULL; 85 86 /* Do not try to duplicate foreign DSA keys */ 87 if (ossl_dsa_is_foreign(dsa)) 88 return NULL; 89 90 if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) 91 return NULL; 92 93 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 94 && !ossl_ffc_params_copy(&dupkey->params, &dsa->params)) 95 goto err; 96 97 dupkey->flags = dsa->flags; 98 99 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 100 && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 101 || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key))) 102 goto err; 103 104 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 105 && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 106 || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key))) 107 goto err; 108 109 #ifndef FIPS_MODULE 110 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, 111 &dupkey->ex_data, &dsa->ex_data)) 112 goto err; 113 #endif 114 115 return dupkey; 116 117 err: 118 DSA_free(dupkey); 119 return NULL; 120 } 121 122 #ifndef FIPS_MODULE 123 DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, 124 OSSL_LIB_CTX *libctx, const char *propq) 125 { 126 const unsigned char *p, *pm; 127 int pklen, pmlen; 128 int ptype; 129 const void *pval; 130 const ASN1_STRING *pstr; 131 const X509_ALGOR *palg; 132 ASN1_INTEGER *privkey = NULL; 133 const BIGNUM *dsa_p, *dsa_g; 134 BIGNUM *dsa_pubkey = NULL, *dsa_privkey = NULL; 135 BN_CTX *ctx = NULL; 136 137 DSA *dsa = NULL; 138 139 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) 140 return 0; 141 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 142 143 if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) 144 goto decerr; 145 if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) 146 goto decerr; 147 148 pstr = pval; 149 pm = pstr->data; 150 pmlen = pstr->length; 151 if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) 152 goto decerr; 153 /* We have parameters now set private key */ 154 if ((dsa_privkey = BN_secure_new()) == NULL 155 || !ASN1_INTEGER_to_BN(privkey, dsa_privkey)) { 156 ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); 157 goto dsaerr; 158 } 159 /* Calculate public key */ 160 if ((dsa_pubkey = BN_new()) == NULL) { 161 ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 162 goto dsaerr; 163 } 164 if ((ctx = BN_CTX_new()) == NULL) { 165 ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 166 goto dsaerr; 167 } 168 169 dsa_p = DSA_get0_p(dsa); 170 dsa_g = DSA_get0_g(dsa); 171 BN_set_flags(dsa_privkey, BN_FLG_CONSTTIME); 172 if (!BN_mod_exp(dsa_pubkey, dsa_g, dsa_privkey, dsa_p, ctx)) { 173 ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); 174 goto dsaerr; 175 } 176 if (!DSA_set0_key(dsa, dsa_pubkey, dsa_privkey)) { 177 ERR_raise(ERR_LIB_DSA, ERR_R_INTERNAL_ERROR); 178 goto dsaerr; 179 } 180 181 goto done; 182 183 decerr: 184 ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); 185 dsaerr: 186 BN_free(dsa_privkey); 187 BN_free(dsa_pubkey); 188 DSA_free(dsa); 189 dsa = NULL; 190 done: 191 BN_CTX_free(ctx); 192 ASN1_STRING_clear_free(privkey); 193 return dsa; 194 } 195 #endif 196