diff options
Diffstat (limited to 'providers/common/keymgmt/dsa_kmgmt.c')
-rw-r--r-- | providers/common/keymgmt/dsa_kmgmt.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/providers/common/keymgmt/dsa_kmgmt.c b/providers/common/keymgmt/dsa_kmgmt.c new file mode 100644 index 0000000000..a53c0b212c --- /dev/null +++ b/providers/common/keymgmt/dsa_kmgmt.c @@ -0,0 +1,91 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/core_numbers.h> +#include <openssl/core_names.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/params.h> +#include "internal/provider_algs.h" + +static OSSL_OP_keymgmt_importkey_fn dsa_importkey; + +static int params_to_key(DSA *dsa, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *param_p, *param_q, *param_g, *param_priv_key; + const OSSL_PARAM *param_pub_key; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL; + + if (dsa == NULL) + return 0; + + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); + param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q); + param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); + param_priv_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY); + param_pub_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PUB_KEY); + + /* + * DSA documentation says that a public key must be present if a private key + * is. + */ + if (param_priv_key != NULL && param_pub_key == NULL) + return 0; + + if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p)) + || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q)) + || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)) + || (param_priv_key != NULL + && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) + || (param_pub_key != NULL + && !OSSL_PARAM_get_BN(param_pub_key, &pub_key))) + goto err; + + if (!DSA_set0_pqg(dsa, p, q, g)) + goto err; + p = q = g = NULL; + + if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key)) + goto err; + priv_key = pub_key = NULL; + + return 1; + + err: + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(priv_key); + BN_free(pub_key); + return 0; +} + +static void *dsa_importkey(void *provctx, const OSSL_PARAM params[]) +{ + DSA *dsa; + + if ((dsa = DSA_new()) == NULL + || !params_to_key(dsa, params)) { + DSA_free(dsa); + dsa = NULL; + } + return dsa; +} + +const OSSL_DISPATCH dsa_keymgmt_functions[] = { + /* + * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also + * implement OSSL_FUNC_KEYMGMT_EXPORTKEY. + */ + { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dsa_importkey }, + { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DSA_free }, + { 0, NULL } +}; |