Adapt ASN1_item_sign_ctx() for use with provided keypairs
authorRichard Levitte <levitte@openssl.org>
Tue, 21 Jan 2020 13:56:13 +0000 (14:56 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 28 Jan 2020 07:06:01 +0000 (08:06 +0100)
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@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10920)

crypto/asn1/a_sign.c
include/openssl/core_names.h

index 564a500cf427e46a61258122d62e51cfd37e0c7f..0089ce29dd5c928810457e8cba8ce69270ced173 100644 (file)
@@ -18,6 +18,7 @@
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
 #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"
 
 #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) {
     }
 
     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;
         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
 #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,
 
         if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) {
             ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
index 195fe6ed38ad698dcbd52a699e8b199eb700ca64..20b06ff96b49d9db60282f05abb8a17a6742eeae 100644 (file)
@@ -158,6 +158,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_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 */
 
 #define OSSL_PKEY_PARAM_DEFAULT_DIGEST      "default-digest" /* utf8 string */
 #define OSSL_PKEY_PARAM_MANDATORY_DIGEST    "mandatory-digest" /* utf8 string */
 
@@ -200,8 +202,9 @@ extern "C" {
 #define OSSL_EXCHANGE_PARAM_PAD      "pad" /* uint */
 
 /* Signature parameters */
 #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"
 
 /* Asym cipher parameters */
 #define OSSL_ASYM_CIPHER_PARAM_PAD_MODE                 "pad-mode"