diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 19:22:08 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 19:22:08 +0000 |
commit | 55fffa809312f6c0ae40528fd1ee66b7559c4650 (patch) | |
tree | bb6b3e63b35220d36bdc654f784a985e88ba1cd2 /src/lib/crypto/dsa_ossl.cpp | |
parent | Releasing progress-linux version 0.17.0-3~progress7.99u1. (diff) | |
download | rnp-55fffa809312f6c0ae40528fd1ee66b7559c4650.tar.xz rnp-55fffa809312f6c0ae40528fd1ee66b7559c4650.zip |
Merging upstream version 0.17.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/crypto/dsa_ossl.cpp')
-rw-r--r-- | src/lib/crypto/dsa_ossl.cpp | 174 |
1 files changed, 126 insertions, 48 deletions
diff --git a/src/lib/crypto/dsa_ossl.cpp b/src/lib/crypto/dsa_ossl.cpp index 1fb75b5..3f91b72 100644 --- a/src/lib/crypto/dsa_ossl.cpp +++ b/src/lib/crypto/dsa_ossl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, [Ribose Inc](https://www.ribose.com). + * Copyright (c) 2021, 2023 [Ribose Inc](https://www.ribose.com). * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -35,6 +35,10 @@ #include <openssl/dh.h> #include <openssl/err.h> #include <openssl/evp.h> +#if defined(CRYPTO_BACKEND_OPENSSL3) +#include <openssl/core_names.h> +#include <openssl/param_build.h> +#endif #define DSA_MAX_Q_BITLEN 256 @@ -83,66 +87,118 @@ done: return res; } +#if defined(CRYPTO_BACKEND_OPENSSL3) +static OSSL_PARAM * +dsa_build_params(bignum_t *p, bignum_t *q, bignum_t *g, bignum_t *y, bignum_t *x) +{ + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + if (!bld) { + return NULL; // LCOV_EXCL_LINE + } + if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p) || + !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q) || + !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g) || + !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, y) || + (x && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, x))) { + /* LCOV_EXCL_START */ + OSSL_PARAM_BLD_free(bld); + return NULL; + /* LCOV_EXCL_END */ + } + OSSL_PARAM *param = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + return param; +} +#endif + static EVP_PKEY * dsa_load_key(const pgp_dsa_key_t *key, bool secret = false) { - DSA * dsa = NULL; EVP_PKEY *evpkey = NULL; - bignum_t *p = mpi2bn(&key->p); - bignum_t *q = mpi2bn(&key->q); - bignum_t *g = mpi2bn(&key->g); - bignum_t *y = mpi2bn(&key->y); - bignum_t *x = secret ? mpi2bn(&key->x) : NULL; + rnp::bn p(mpi2bn(&key->p)); + rnp::bn q(mpi2bn(&key->q)); + rnp::bn g(mpi2bn(&key->g)); + rnp::bn y(mpi2bn(&key->y)); + rnp::bn x(secret ? mpi2bn(&key->x) : NULL); - if (!p || !q || !g || !y || (secret && !x)) { + if (!p.get() || !q.get() || !g.get() || !y.get() || (secret && !x.get())) { + /* LCOV_EXCL_START */ RNP_LOG("out of memory"); - goto done; + return NULL; + /* LCOV_EXCL_END */ } - dsa = DSA_new(); +#if defined(CRYPTO_BACKEND_OPENSSL3) + OSSL_PARAM *params = dsa_build_params(p.get(), q.get(), g.get(), y.get(), x.get()); + if (!params) { + /* LCOV_EXCL_START */ + RNP_LOG("failed to build dsa params"); + return NULL; + /* LCOV_EXCL_END */ + } + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if (!ctx) { + /* LCOV_EXCL_START */ + RNP_LOG("failed to create dsa context"); + OSSL_PARAM_free(params); + return NULL; + /* LCOV_EXCL_END */ + } + if ((EVP_PKEY_fromdata_init(ctx) != 1) || + (EVP_PKEY_fromdata( + ctx, &evpkey, secret ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, params) != 1)) { + RNP_LOG("failed to create key from data"); + evpkey = NULL; + } + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + return evpkey; +#else + DSA *dsa = DSA_new(); if (!dsa) { + /* LCOV_EXCL_START */ RNP_LOG("Out of memory"); goto done; + /* LCOV_EXCL_END */ } - if (DSA_set0_pqg(dsa, p, q, g) != 1) { + if (DSA_set0_pqg(dsa, p.own(), q.own(), g.own()) != 1) { + /* LCOV_EXCL_START */ RNP_LOG("Failed to set pqg. Error: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } - p = NULL; - q = NULL; - g = NULL; - if (DSA_set0_key(dsa, y, x) != 1) { + if (DSA_set0_key(dsa, y.own(), x.own()) != 1) { + /* LCOV_EXCL_START */ RNP_LOG("Secret key load error: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } - y = NULL; - x = NULL; evpkey = EVP_PKEY_new(); if (!evpkey) { + /* LCOV_EXCL_START */ RNP_LOG("allocation failed"); goto done; + /* LCOV_EXCL_END */ } if (EVP_PKEY_set1_DSA(evpkey, dsa) <= 0) { + /* LCOV_EXCL_START */ RNP_LOG("Failed to set key: %lu", ERR_peek_last_error()); EVP_PKEY_free(evpkey); evpkey = NULL; + /* LCOV_EXCL_END */ } done: DSA_free(dsa); - bn_free(p); - bn_free(q); - bn_free(g); - bn_free(y); - bn_free(x); return evpkey; +#endif } rnp_result_t dsa_validate_key(rnp::RNG *rng, const pgp_dsa_key_t *key, bool secret) { /* OpenSSL doesn't implement key checks for the DSA, however we may use DL via DH */ - EVP_PKEY *pkey = dl_load_key(key->p, &key->q, key->g, key->y, NULL); + EVP_PKEY *pkey = dl_load_key(key->p, &key->q, key->g, key->y, secret ? &key->x : NULL); if (!pkey) { RNP_LOG("Failed to load key"); return RNP_ERROR_BAD_PARAMETERS; @@ -175,8 +231,10 @@ dsa_sign(rnp::RNG * rng, /* init context and sign */ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(evpkey, NULL); if (!ctx) { + /* LCOV_EXCL_START */ RNP_LOG("Context allocation failed: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } if (EVP_PKEY_sign_init(ctx) <= 0) { RNP_LOG("Failed to initialize signing: %lu", ERR_peek_last_error()); @@ -216,8 +274,10 @@ dsa_verify(const pgp_dsa_signature_t *sig, /* init context and sign */ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(evpkey, NULL); if (!ctx) { + /* LCOV_EXCL_START */ RNP_LOG("Context allocation failed: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } if (EVP_PKEY_verify_init(ctx) <= 0) { RNP_LOG("Failed to initialize verify: %lu", ERR_peek_last_error()); @@ -238,6 +298,43 @@ done: return ret; } +static bool +dsa_extract_key(EVP_PKEY *pkey, pgp_dsa_key_t &key) +{ +#if defined(CRYPTO_BACKEND_OPENSSL3) + rnp::bn p; + rnp::bn q; + rnp::bn g; + rnp::bn y; + rnp::bn x; + + bool res = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_P, p.ptr()) && + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_Q, q.ptr()) && + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_G, g.ptr()) && + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, y.ptr()) && + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, x.ptr()); + return res && p.mpi(key.p) && q.mpi(key.q) && g.mpi(key.g) && y.mpi(key.y) && x.mpi(key.x); +#else + const DSA *dsa = EVP_PKEY_get0_DSA(pkey); + if (!dsa) { + RNP_LOG("Failed to retrieve DSA key: %lu", ERR_peek_last_error()); + return false; + } + + const bignum_t *p = DSA_get0_p(dsa); + const bignum_t *q = DSA_get0_q(dsa); + const bignum_t *g = DSA_get0_g(dsa); + const bignum_t *y = DSA_get0_pub_key(dsa); + const bignum_t *x = DSA_get0_priv_key(dsa); + + if (!p || !q || !g || !y || !x) { + return false; + } + return bn2mpi(p, &key.p) && bn2mpi(q, &key.q) && bn2mpi(g, &key.g) && bn2mpi(y, &key.y) && + bn2mpi(x, &key.x); +#endif +} + rnp_result_t dsa_generate(rnp::RNG *rng, pgp_dsa_key_t *key, size_t keylen, size_t qbits) { @@ -246,7 +343,6 @@ dsa_generate(rnp::RNG *rng, pgp_dsa_key_t *key, size_t keylen, size_t qbits) } rnp_result_t ret = RNP_ERROR_GENERIC; - const DSA * dsa = NULL; EVP_PKEY * pkey = NULL; EVP_PKEY * parmkey = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -254,12 +350,16 @@ dsa_generate(rnp::RNG *rng, pgp_dsa_key_t *key, size_t keylen, size_t qbits) /* Generate DSA params */ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); if (!ctx) { + /* LCOV_EXCL_START */ RNP_LOG("Failed to create ctx: %lu", ERR_peek_last_error()); return ret; + /* LCOV_EXCL_END */ } if (EVP_PKEY_paramgen_init(ctx) <= 0) { + /* LCOV_EXCL_START */ RNP_LOG("Failed to init keygen: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, keylen) <= 0) { RNP_LOG("Failed to set key bits: %lu", ERR_peek_last_error()); @@ -293,32 +393,10 @@ dsa_generate(rnp::RNG *rng, pgp_dsa_key_t *key, size_t keylen, size_t qbits) RNP_LOG("DSA keygen failed: %lu", ERR_peek_last_error()); goto done; } - dsa = EVP_PKEY_get0_DSA(pkey); - if (!dsa) { - RNP_LOG("Failed to retrieve DSA key: %lu", ERR_peek_last_error()); - goto done; - } - const bignum_t *p; - const bignum_t *q; - const bignum_t *g; - const bignum_t *y; - const bignum_t *x; - p = DSA_get0_p(dsa); - q = DSA_get0_q(dsa); - g = DSA_get0_g(dsa); - y = DSA_get0_pub_key(dsa); - x = DSA_get0_priv_key(dsa); - if (!p || !q || !g || !y || !x) { - ret = RNP_ERROR_BAD_STATE; - goto done; + if (dsa_extract_key(pkey, *key)) { + ret = RNP_SUCCESS; } - bn2mpi(p, &key->p); - bn2mpi(q, &key->q); - bn2mpi(g, &key->g); - bn2mpi(y, &key->y); - bn2mpi(x, &key->x); - ret = RNP_SUCCESS; done: EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(parmkey); |