summaryrefslogtreecommitdiffstats
path: root/crypto/dsa
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2019-08-30 13:33:37 +0100
committerMatt Caswell <matt@openssl.org>2019-09-09 14:00:00 +0100
commit4889dadcb8511176c30888c748f1981adc38451d (patch)
treeb27f1a2529e512f43344d7a62d89daa1bcc2407d /crypto/dsa
parentdfcb5d29b525f5d2b6bd80602dca5efe5fca77bb (diff)
Implement DSA in the default provider
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9753)
Diffstat (limited to 'crypto/dsa')
-rw-r--r--crypto/dsa/dsa_ameth.c71
-rw-r--r--crypto/dsa/dsa_gen.c2
-rw-r--r--crypto/dsa/dsa_key.c1
-rw-r--r--crypto/dsa/dsa_lib.c2
-rw-r--r--crypto/dsa/dsa_locl.h3
5 files changed, 76 insertions, 3 deletions
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index ef6fc7632a..4e0ed01970 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -8,14 +8,16 @@
*/
#include <stdio.h>
-#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
-#include "dsa_locl.h"
#include <openssl/bn.h>
#include <openssl/cms.h>
+#include <openssl/core_names.h>
+#include "internal/cryptlib.h"
#include "internal/asn1_int.h"
#include "internal/evp_int.h"
+#include "internal/param_build.h"
+#include "dsa_locl.h"
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
@@ -63,6 +65,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
goto err;
}
+ dsa->dirty_cnt++;
ASN1_INTEGER_free(public_key);
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
@@ -185,6 +188,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
goto dsaerr;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
ret = 1;
@@ -300,6 +304,7 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
return 0;
BN_free(to->pkey.dsa->g);
to->pkey.dsa->g = a;
+ to->pkey.dsa->dirty_cnt++;
return 1;
}
@@ -381,6 +386,7 @@ static int dsa_param_decode(EVP_PKEY *pkey,
DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
return 0;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}
@@ -417,6 +423,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey,
DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
return 0;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}
@@ -514,6 +521,56 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
}
+static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
+{
+ return pkey->pkey.dsa->dirty_cnt;
+}
+
+static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+{
+ DSA *dsa = pk->pkey.dsa;
+ OSSL_PARAM_BLD tmpl;
+ const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
+ const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
+ const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
+ OSSL_PARAM *params;
+ void *provkey = NULL;
+
+ if (p == NULL || q == NULL || g == NULL)
+ return NULL;
+
+ ossl_param_bld_init(&tmpl);
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
+ return NULL;
+
+ /*
+ * This may be used to pass domain parameters only without any key data -
+ * so "pub_key" is optional. We can never have a "priv_key" without a
+ * corresponding "pub_key" though.
+ */
+ if (pub_key != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
+ pub_key))
+ return NULL;
+
+ if (priv_key != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
+ priv_key))
+ return NULL;
+ }
+ }
+
+ params = ossl_param_bld_to_param(&tmpl);
+
+ /* We export, the provider imports */
+ provkey = evp_keymgmt_importkey(keymgmt, params);
+
+ ossl_param_bld_free(params);
+ return provkey;
+}
+
/* NB these are sorted in pkey_id order, lowest first */
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
@@ -570,5 +627,13 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
int_dsa_free,
dsa_pkey_ctrl,
old_dsa_priv_decode,
- old_dsa_priv_encode}
+ old_dsa_priv_encode,
+
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+
+ dsa_pkey_dirty_cnt,
+ dsa_pkey_export_to
+ }
};
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index 858f127315..14cb8e9f53 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -281,6 +281,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
ret->p = BN_dup(p);
ret->q = BN_dup(q);
ret->g = BN_dup(g);
+ ret->dirty_cnt++;
if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
ok = 0;
goto err;
@@ -598,6 +599,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
ok = -1;
goto err;
}
+ ret->dirty_cnt++;
if (counter_ret != NULL)
*counter_ret = counter;
if (h_ret != NULL)
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 333bff959e..86f79b804e 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -65,6 +65,7 @@ static int dsa_builtin_keygen(DSA *dsa)
dsa->priv_key = priv_key;
dsa->pub_key = pub_key;
+ dsa->dirty_cnt++;
ok = 1;
err:
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index 1068f1da77..034300fc7e 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -273,6 +273,7 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
BN_free(d->g);
d->g = g;
}
+ d->dirty_cnt++;
return 1;
}
@@ -303,6 +304,7 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
BN_free(d->priv_key);
d->priv_key = priv_key;
}
+ d->dirty_cnt++;
return 1;
}
diff --git a/crypto/dsa/dsa_locl.h b/crypto/dsa/dsa_locl.h
index 5c464e7c25..e56ff06977 100644
--- a/crypto/dsa/dsa_locl.h
+++ b/crypto/dsa/dsa_locl.h
@@ -31,6 +31,9 @@ struct dsa_st {
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
CRYPTO_RWLOCK *lock;
+
+ /* Provider data */
+ size_t dirty_cnt; /* If any key material changes, increment this */
};
struct DSA_SIG_st {