summaryrefslogtreecommitdiffstats
path: root/providers
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-01-21 15:05:56 +0100
committerRichard Levitte <levitte@openssl.org>2020-01-28 08:08:22 +0100
commit505b41fc5a7a3cb255d2f62cf4902a1a5c1db2dd (patch)
tree5af49f556aaba41c16ad5f8ad5ddf32c0a5d76a4 /providers
parentd5aef5946bd9b113623ad778114768585a1f7a02 (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.c95
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