summaryrefslogtreecommitdiffstats
path: root/providers/common/keymgmt/dsa_kmgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'providers/common/keymgmt/dsa_kmgmt.c')
-rw-r--r--providers/common/keymgmt/dsa_kmgmt.c91
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 }
+};