[openssl] master update

Richard Levitte levitte at openssl.org
Tue Jan 28 07:10:12 UTC 2020


The branch master has been updated
       via  0cb3f4f985aa52688ddc90075f480ba612d34fe3 (commit)
       via  505b41fc5a7a3cb255d2f62cf4902a1a5c1db2dd (commit)
       via  d5aef5946bd9b113623ad778114768585a1f7a02 (commit)
      from  2ee4a50ab92020dc49383d5aa644397edac4a59a (commit)


- Log -----------------------------------------------------------------
commit 0cb3f4f985aa52688ddc90075f480ba612d34fe3
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jan 22 20:59:56 2020 +0100

    test_evp_extra_test.c: don't rely on exact parameter position
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10920)

commit 505b41fc5a7a3cb255d2f62cf4902a1a5c1db2dd
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jan 21 15:05:56 2020 +0100

    PROV: Adapt the DSA signature implementation to provide Algorithmidentifiers
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10920)

commit d5aef5946bd9b113623ad778114768585a1f7a02
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jan 21 14:56:13 2020 +0100

    Adapt ASN1_item_sign_ctx() for use with provided keypairs
    
    The mechanism to do this is to ask the signature operation for the DER
    encoded AlgorithmIdentifier that corresponds to the combination of
    signature algorithm and digest algorithm.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10920)

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/a_sign.c                      | 51 +++++++++++++++--
 crypto/dsa/build.info                     |  2 +-
 crypto/dsa/dsa_aid.c                      | 65 +++++++++++++++++++++
 include/crypto/dsa.h                      |  2 +
 include/internal/sizes.h                  |  1 +
 include/openssl/core_names.h              | 18 +++++-
 providers/implementations/signature/dsa.c | 95 ++++++++++++++++++++++++++++---
 test/evp_extra_test.c                     | 23 ++++----
 8 files changed, 226 insertions(+), 31 deletions(-)
 create mode 100644 crypto/dsa/dsa_aid.c

diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 564a500cf4..0089ce29dd 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -18,6 +18,7 @@
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
+#include <openssl/core_names.h>
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
 
@@ -156,11 +157,51 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
     }
 
     if (pkey->ameth == NULL) {
-        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
-        goto err;
-    }
+        EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
+        OSSL_PARAM params[2];
+        unsigned char aid[128];
+        size_t aid_len = 0;
+
+        if (pctx == NULL
+            || !EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) {
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+            goto err;
+        }
+
+        params[0] =
+            OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID,
+                                              aid, sizeof(aid));
+        params[1] = OSSL_PARAM_construct_end();
+
+        if (EVP_PKEY_CTX_get_params(pctx, params) <= 0)
+            goto err;
+
+        if ((aid_len = params[0].return_size) == 0) {
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+                    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+            goto err;
+        }
+
+        if (algor1 != NULL) {
+            const unsigned char *pp = aid;
+
+            if (d2i_X509_ALGOR(&algor1, &pp, aid_len) == NULL) {
+                ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+        }
+
+        if (algor2 != NULL) {
+            const unsigned char *pp = aid;
+
+            if (d2i_X509_ALGOR(&algor2, &pp, aid_len) == NULL) {
+                ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+        }
 
-    if (pkey->ameth->item_sign) {
+        rv = 3;
+    } else if (pkey->ameth->item_sign) {
         rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
         if (rv == 1)
             outl = signature->length;
@@ -189,7 +230,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
 #ifndef OPENSSL_NO_SM2
             EVP_PKEY_id(pkey) == NID_sm2 ? NID_sm2 :
 #endif
-        pkey->ameth->pkey_id;
+            pkey->ameth->pkey_id;
 
         if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) {
             ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info
index 309fda323e..2cbea9b961 100644
--- a/crypto/dsa/build.info
+++ b/crypto/dsa/build.info
@@ -1,6 +1,6 @@
 LIBS=../../libcrypto
 
-$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c
+$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c
 
 SOURCE[../../libcrypto]=$COMMON\
         dsa_gen.c dsa_key.c dsa_asn1.c \
diff --git a/crypto/dsa/dsa_aid.c b/crypto/dsa/dsa_aid.c
new file mode 100644
index 0000000000..759e5c90e1
--- /dev/null
+++ b/crypto/dsa/dsa_aid.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 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 <stdlib.h>
+
+#include <openssl/objects.h>
+#include "crypto/dsa.h"
+
+#define ASN1_SEQUENCE 0x30
+#define ASN1_OID 0x06
+
+/* dsaWithSHA OIDs are of the form: (1 3 14 3 2 |n|) */
+#define ENCODE_ALGORITHMIDENTIFIER_SHA(name, n)                         \
+    static const unsigned char algorithmidentifier_##name##_der[] = {   \
+        ASN1_SEQUENCE, 0x07,                                            \
+          ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, n                       \
+}
+
+ENCODE_ALGORITHMIDENTIFIER_SHA(sha, 13);
+ENCODE_ALGORITHMIDENTIFIER_SHA(sha1, 27);
+
+/* dsaWithSHA OIDs are of the form: (2 16 840 1 101 3 4 3 |n|) */
+#define ENCODE_ALGORITHMIDENTIFIER_SHAx(name, n)                        \
+    static const unsigned char algorithmidentifier_##name##_der[] = {   \
+        ASN1_SEQUENCE, 0x0b,                                            \
+          ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n   \
+}
+
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha224, 1);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha256, 2);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha384, 3);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha512, 4);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_224, 5);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_256, 6);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_384, 7);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_512, 8);
+
+#define MD_CASE(name)                                                   \
+    case NID_##name:                                                    \
+        *len = sizeof(algorithmidentifier_##name##_der);                \
+        return algorithmidentifier_##name##_der
+
+const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
+{
+    switch (md_nid) {
+        MD_CASE(sha);
+        MD_CASE(sha1);
+        MD_CASE(sha224);
+        MD_CASE(sha256);
+        MD_CASE(sha384);
+        MD_CASE(sha512);
+        MD_CASE(sha3_224);
+        MD_CASE(sha3_256);
+        MD_CASE(sha3_384);
+        MD_CASE(sha3_512);
+    default:
+        return NULL;
+    }
+}
diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h
index 9afae37d2a..041ebd4f7f 100644
--- a/include/crypto/dsa.h
+++ b/include/crypto/dsa.h
@@ -11,3 +11,5 @@
 
 int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
                  int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);
+
+const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len);
diff --git a/include/internal/sizes.h b/include/internal/sizes.h
index fab5cbdec7..00a5d3e88e 100644
--- a/include/internal/sizes.h
+++ b/include/internal/sizes.h
@@ -16,5 +16,6 @@
  */
 # define OSSL_MAX_NAME_SIZE           50 /* Algorithm name */
 # define OSSL_MAX_PROPQUERY_SIZE     256 /* Property query strings */
+# define OSSL_MAX_ALGORITHM_ID_SIZE  256 /* AlgorithmIdentifier DER */
 
 #endif
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 195fe6ed38..cd701ab937 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -87,7 +87,16 @@ extern "C" {
 #define OSSL_DIGEST_PARAM_FLAGS      "flags"     /* ulong */
 
 /* Known DIGEST names (not a complete list) */
-#define OSSL_DIGEST_NAME_MD5 "MD5"
+#define OSSL_DIGEST_NAME_MD5            "MD5"
+#define OSSL_DIGEST_NAME_SHA1           "SHA1"
+#define OSSL_DIGEST_NAME_SHA2_224       "SHA2-224"
+#define OSSL_DIGEST_NAME_SHA2_256       "SHA2-256"
+#define OSSL_DIGEST_NAME_SHA2_384       "SHA2-384"
+#define OSSL_DIGEST_NAME_SHA2_512       "SHA2-512"
+#define OSSL_DIGEST_NAME_SHA3_224       "SHA3-224"
+#define OSSL_DIGEST_NAME_SHA3_256       "SHA3-256"
+#define OSSL_DIGEST_NAME_SHA3_384       "SHA3-384"
+#define OSSL_DIGEST_NAME_SHA3_512       "SHA3-512"
 #define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128"
 #define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256"
 
@@ -158,6 +167,8 @@ extern "C" {
 #define OSSL_PKEY_PARAM_BITS                "bits" /* integer */
 #define OSSL_PKEY_PARAM_MAX_SIZE            "max-size" /* integer */
 #define OSSL_PKEY_PARAM_SECURITY_BITS       "security-bits" /* integer */
+#define OSSL_PKEY_PARAM_DIGEST              OSSL_ALG_PARAM_DIGEST
+#define OSSL_PKEY_PARAM_DIGEST_SIZE         "digest-size"
 #define OSSL_PKEY_PARAM_DEFAULT_DIGEST      "default-digest" /* utf8 string */
 #define OSSL_PKEY_PARAM_MANDATORY_DIGEST    "mandatory-digest" /* utf8 string */
 
@@ -200,8 +211,9 @@ extern "C" {
 #define OSSL_EXCHANGE_PARAM_PAD      "pad" /* uint */
 
 /* Signature parameters */
-#define OSSL_SIGNATURE_PARAM_DIGEST         OSSL_ALG_PARAM_DIGEST
-#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE    "digest-size"
+#define OSSL_SIGNATURE_PARAM_ALGORITHM_ID       "algorithm-id"
+#define OSSL_SIGNATURE_PARAM_DIGEST             OSSL_PKEY_PARAM_DIGEST
+#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE        OSSL_PKEY_PARAM_DIGEST_SIZE
 
 /* Asym cipher parameters */
 #define OSSL_ASYM_CIPHER_PARAM_PAD_MODE                 "pad-mode"
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
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 5f2bcc1a51..57f5010381 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -1288,23 +1288,20 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
      */
     params = EVP_PKEY_CTX_settable_params(ctx);
     if (!TEST_ptr(params)
-            || !TEST_int_eq(strcmp(params[0].key,
-                            OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
-            || !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
-                            0)
-               /* The final key should be NULL */
-            || !TEST_ptr_null(params[2].key))
+        || !TEST_ptr(OSSL_PARAM_locate_const(params,
+                                             OSSL_SIGNATURE_PARAM_DIGEST_SIZE))
+        || !TEST_ptr(OSSL_PARAM_locate_const(params,
+                                             OSSL_SIGNATURE_PARAM_DIGEST)))
         goto err;
 
-    /* Gettable params are the same as the settable ones */
     params = EVP_PKEY_CTX_gettable_params(ctx);
     if (!TEST_ptr(params)
-            || !TEST_int_eq(strcmp(params[0].key,
-                            OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
-            || !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
-                            0)
-               /* The final key should be NULL */
-            || !TEST_ptr_null(params[2].key))
+        || !TEST_ptr(OSSL_PARAM_locate_const(params,
+                                             OSSL_SIGNATURE_PARAM_ALGORITHM_ID))
+        || !TEST_ptr(OSSL_PARAM_locate_const(params,
+                                             OSSL_SIGNATURE_PARAM_DIGEST_SIZE))
+        || !TEST_ptr(OSSL_PARAM_locate_const(params,
+                                             OSSL_SIGNATURE_PARAM_DIGEST)))
         goto err;
 
     /*


More information about the openssl-commits mailing list