2 * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
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
11 * DSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
16 #include <openssl/core_names.h>
17 #include <openssl/err.h>
19 # include <openssl/x509.h>
21 #include "crypto/dsa.h"
22 #include "dsa_local.h"
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.
30 int ossl_dsa_key_fromdata(DSA
*dsa
, const OSSL_PARAM params
[],
33 const OSSL_PARAM
*param_priv_key
= NULL
, *param_pub_key
;
34 BIGNUM
*priv_key
= NULL
, *pub_key
= NULL
;
39 if (include_private
) {
41 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PRIV_KEY
);
44 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PUB_KEY
);
46 /* It's ok if neither half is present */
47 if (param_priv_key
== NULL
&& param_pub_key
== NULL
)
50 if (param_pub_key
!= NULL
&& !OSSL_PARAM_get_BN(param_pub_key
, &pub_key
))
52 if (param_priv_key
!= NULL
&& !OSSL_PARAM_get_BN(param_priv_key
, &priv_key
))
55 if (!DSA_set0_key(dsa
, pub_key
, priv_key
))
61 BN_clear_free(priv_key
);
66 int ossl_dsa_is_foreign(const DSA
*dsa
)
69 if (dsa
->engine
!= NULL
|| DSA_get_method((DSA
*)dsa
) != DSA_OpenSSL())
75 static ossl_inline
int dsa_bn_dup_check(BIGNUM
**out
, const BIGNUM
*f
)
77 if (f
!= NULL
&& (*out
= BN_dup(f
)) == NULL
)
82 DSA
*ossl_dsa_dup(const DSA
*dsa
, int selection
)
86 /* Do not try to duplicate foreign DSA keys */
87 if (ossl_dsa_is_foreign(dsa
))
90 if ((dupkey
= ossl_dsa_new(dsa
->libctx
)) == NULL
)
93 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0
94 && !ossl_ffc_params_copy(&dupkey
->params
, &dsa
->params
))
97 dupkey
->flags
= dsa
->flags
;
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
)))
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
)))
110 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA
,
111 &dupkey
->ex_data
, &dsa
->ex_data
))
123 DSA
*ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO
*p8inf
,
124 OSSL_LIB_CTX
*libctx
, const char *propq
)
126 const unsigned char *p
, *pm
;
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
;
139 if (!PKCS8_pkey_get0(NULL
, &p
, &pklen
, &palg
, p8inf
))
141 X509_ALGOR_get0(NULL
, &ptype
, &pval
, palg
);
143 if ((privkey
= d2i_ASN1_INTEGER(NULL
, &p
, pklen
)) == NULL
)
145 if (privkey
->type
== V_ASN1_NEG_INTEGER
|| ptype
!= V_ASN1_SEQUENCE
)
150 pmlen
= pstr
->length
;
151 if ((dsa
= d2i_DSAparams(NULL
, &pm
, pmlen
)) == NULL
)
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
);
159 /* Calculate public key */
160 if ((dsa_pubkey
= BN_new()) == NULL
) {
161 ERR_raise(ERR_LIB_DSA
, ERR_R_MALLOC_FAILURE
);
164 if ((ctx
= BN_CTX_new()) == NULL
) {
165 ERR_raise(ERR_LIB_DSA
, ERR_R_MALLOC_FAILURE
);
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
);
176 DSA_set0_key(dsa
, dsa_pubkey
, dsa_privkey
);
181 ERR_raise(ERR_LIB_DSA
, DSA_R_DECODE_ERROR
);
183 BN_free(dsa_privkey
);
189 ASN1_STRING_clear_free(privkey
);