diff options
author | Richard Levitte <levitte@openssl.org> | 2020-01-21 15:05:56 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-01-28 08:08:22 +0100 |
commit | 505b41fc5a7a3cb255d2f62cf4902a1a5c1db2dd (patch) | |
tree | 5af49f556aaba41c16ad5f8ad5ddf32c0a5d76a4 /providers | |
parent | d5aef5946bd9b113623ad778114768585a1f7a02 (diff) |
PROV: Adapt the DSA signature implementation to provide Algorithmidentifiers
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10920)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/implementations/signature/dsa.c | 95 |
1 files changed, 86 insertions, 9 deletions
diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index 9892e6d5e4..e8d9cd0b81 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -7,13 +7,18 @@ * https://www.openssl.org/source/license.html */ +#include <string.h> + #include <openssl/crypto.h> #include <openssl/core_numbers.h> #include <openssl/core_names.h> +#include <openssl/err.h> #include <openssl/dsa.h> #include <openssl/params.h> #include <openssl/evp.h> +#include "internal/nelem.h" #include "internal/sizes.h" +#include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "crypto/dsa.h" @@ -51,6 +56,12 @@ typedef struct { DSA *dsa; size_t mdsize; char mdname[OSSL_MAX_NAME_SIZE]; + + /* The Algorithm Identifier of the combined signature agorithm */ + unsigned char aid[OSSL_MAX_ALGORITHM_ID_SIZE]; + size_t aid_len; + + /* main digest */ EVP_MD *md; EVP_MD_CTX *mdctx; } PROV_DSA_CTX; @@ -116,28 +127,88 @@ static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa); } +static int get_md_nid(const EVP_MD *md) +{ + /* + * Because the DSA library deals with NIDs, we need to translate. + * We do so using EVP_MD_is_a(), and therefore need a name to NID + * map. + */ + static const OSSL_ITEM name_to_nid[] = { + { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, + { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, + { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, + { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, + { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, + { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, + { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, + { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, + { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, + }; + size_t i; + int mdnid = NID_undef; + + if (md == NULL) + goto end; + + for (i = 0; i < OSSL_NELEM(name_to_nid); i++) { + if (EVP_MD_is_a(md, name_to_nid[i].ptr)) { + mdnid = (int)name_to_nid[i].id; + break; + } + } + + if (mdnid == NID_undef) + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + + end: + return mdnid; +} + static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, const char *props, void *vdsa) { PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; - EVP_MD *md; + size_t algorithmidentifier_len = 0; + const unsigned char *algorithmidentifier; + + EVP_MD_CTX_free(pdsactx->mdctx); + EVP_MD_free(pdsactx->md); + pdsactx->mdctx = NULL; + pdsactx->mdsize = 0; + pdsactx->md = NULL; if (!dsa_signature_init(vpdsactx, vdsa)) return 0; - md = EVP_MD_fetch(pdsactx->libctx, mdname, props); - if (md == NULL) - return 0; - pdsactx->md = md; - pdsactx->mdsize = EVP_MD_size(md); + pdsactx->md = EVP_MD_fetch(pdsactx->libctx, mdname, props); + algorithmidentifier = + dsa_algorithmidentifier_encoding(get_md_nid(pdsactx->md), + &algorithmidentifier_len); + + if (algorithmidentifier == NULL) + goto error; + + pdsactx->mdsize = EVP_MD_size(pdsactx->md); pdsactx->mdctx = EVP_MD_CTX_new(); if (pdsactx->mdctx == NULL) - return 0; + goto error; - if (!EVP_DigestInit_ex(pdsactx->mdctx, md, NULL)) - return 0; + memcpy(pdsactx->aid, algorithmidentifier, algorithmidentifier_len); + pdsactx->aid_len = algorithmidentifier_len; + + if (!EVP_DigestInit_ex(pdsactx->mdctx, pdsactx->md, NULL)) + goto error; return 1; + + error: + EVP_MD_CTX_free(pdsactx->mdctx); + EVP_MD_free(pdsactx->md); + pdsactx->mdctx = NULL; + pdsactx->mdsize = 0; + pdsactx->md = NULL; + return 0; } int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data, @@ -254,6 +325,11 @@ static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) if (pdsactx == NULL || params == NULL) return 0; + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); + if (p != NULL + && !OSSL_PARAM_set_octet_string(p, pdsactx->aid, pdsactx->aid_len)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize)) return 0; @@ -268,6 +344,7 @@ static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) } static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_END |