Remove link between digests and signature algorithms.
authorDr. Stephen Henson <steve@openssl.org>
Wed, 19 Apr 2006 17:05:59 +0000 (17:05 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 19 Apr 2006 17:05:59 +0000 (17:05 +0000)
Use cross reference table in ASN1_item_sign(), ASN1_item_verify() to eliminate
the need for algorithm specific code.

16 files changed:
CHANGES
apps/ca.c
apps/req.c
apps/x509.c
crypto/asn1/a_sign.c
crypto/asn1/a_verify.c
crypto/asn1/asn1.h
crypto/asn1/asn1_err.c
crypto/evp/evp.h
crypto/evp/m_dss.c
crypto/evp/m_dss1.c
crypto/evp/m_ecdsa.c
crypto/evp/m_sha1.c
crypto/evp/p_sign.c
crypto/evp/p_verify.c
crypto/rsa/rsa_ameth.c

diff --git a/CHANGES b/CHANGES
index d87e1eb..c74a02c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.8a and 0.9.9  [xx XXX xxxx]
 
+  *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New 
+     EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
+     signing method from the key type. This effectively removes the link
+     between digests and public key types.
+     [Steve Henson]
+
   *) Add an OID cross reference table and utility functions. Its purpose is to
      translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
      rsaEncryption. This will allow some of the algorithm specific hackery
index 9af7bab..f7532d2 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1412,6 +1412,7 @@ bad:
 
                /* we now have a CRL */
                if (verbose) BIO_printf(bio_err,"signing CRL\n");
+#if 0
 #ifndef OPENSSL_NO_DSA
                if (pkey->type == EVP_PKEY_DSA) 
                        dgst=EVP_dss1();
@@ -1420,6 +1421,7 @@ bad:
 #ifndef OPENSSL_NO_ECDSA
                if (pkey->type == EVP_PKEY_EC)
                        dgst=EVP_ecdsa();
+#endif
 #endif
 
                /* Add any extensions asked for */
index 14bb0e0..b9a3852 100644 (file)
@@ -894,6 +894,7 @@ loop:
                        BIO_printf(bio_err,"you need to specify a private key\n");
                        goto end;
                        }
+#if 0
 #ifndef OPENSSL_NO_DSA
                if (pkey->type == EVP_PKEY_DSA)
                        digest=EVP_dss1();
@@ -901,6 +902,7 @@ loop:
 #ifndef OPENSSL_NO_ECDSA
                if (pkey->type == EVP_PKEY_EC)
                        digest=EVP_ecdsa();
+#endif
 #endif
                if (req == NULL)
                        {
index 8d20681..e3a9738 100644 (file)
@@ -912,6 +912,7 @@ bad:
                                                passin, e, "Private key");
                                        if (Upkey == NULL) goto end;
                                        }
+#if 0
 #ifndef OPENSSL_NO_DSA
                                if (Upkey->type == EVP_PKEY_DSA)
                                        digest=EVP_dss1();
@@ -919,6 +920,7 @@ bad:
 #ifndef OPENSSL_NO_ECDSA
                                if (Upkey->type == EVP_PKEY_EC)
                                        digest=EVP_ecdsa();
+#endif
 #endif
 
                                assert(need_rand);
index 1081950..c98dc7c 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
+#include "asn1_locl.h"
 
 #ifndef NO_ASN1_OLD
 
@@ -218,45 +219,34 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        {
        EVP_MD_CTX ctx;
        unsigned char *buf_in=NULL,*buf_out=NULL;
-       int i,inl=0,outl=0,outll=0;
-       X509_ALGOR *a;
+       int inl=0,outl=0,outll=0;
+       int signid, paramtype;
 
-       EVP_MD_CTX_init(&ctx);
-       for (i=0; i<2; i++)
+       if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
                {
-               if (i == 0)
-                       a=algor1;
-               else
-                       a=algor2;
-               if (a == NULL) continue;
-                if (type->pkey_type == NID_dsaWithSHA1 ||
-                       type->pkey_type == NID_ecdsa_with_SHA1)
-                       {
-                       /* special case: RFC 3279 tells us to omit 'parameters'
-                        * with id-dsa-with-sha1 and ecdsa-with-SHA1 */
-                       ASN1_TYPE_free(a->parameter);
-                       a->parameter = NULL;
-                       }
-               else if ((a->parameter == NULL) || 
-                       (a->parameter->type != V_ASN1_NULL))
-                       {
-                       ASN1_TYPE_free(a->parameter);
-                       if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
-                       a->parameter->type=V_ASN1_NULL;
-                       }
-               ASN1_OBJECT_free(a->algorithm);
-               a->algorithm=OBJ_nid2obj(type->pkey_type);
-               if (a->algorithm == NULL)
-                       {
-                       ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
-                       goto err;
-                       }
-               if (a->algorithm->length == 0)
+               if (!pkey->ameth ||
+                       !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
+                                               pkey->ameth->pkey_id))
                        {
-                       ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
-                       goto err;
+                       ASN1err(ASN1_F_ASN1_ITEM_SIGN,
+                               ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+                       return 0;
                        }
                }
+       else
+               signid = type->pkey_type;
+
+       if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+               paramtype = V_ASN1_NULL;
+       else
+               paramtype = V_ASN1_UNDEF;
+
+       if (algor1)
+               X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+       if (algor2)
+               X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+       EVP_MD_CTX_init(&ctx);
        inl=ASN1_item_i2d(asn,&buf_in, it);
        outll=outl=EVP_PKEY_size(pkey);
        buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
index fdce6e4..4885539 100644 (file)
@@ -60,6 +60,7 @@
 #include <time.h>
 
 #include "cryptlib.h"
+#include "asn1_locl.h"
 
 #ifndef NO_SYS_TYPES_H
 # include <sys/types.h>
@@ -129,19 +130,34 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
             void *asn, EVP_PKEY *pkey)
        {
        EVP_MD_CTX ctx;
-       const EVP_MD *type;
+       const EVP_MD *type = NULL;
        unsigned char *buf_in=NULL;
-       int ret= -1,i,inl;
+       int ret= -1,inl;
 
-       EVP_MD_CTX_init(&ctx);
-       i=OBJ_obj2nid(a->algorithm);
-       type=EVP_get_digestbyname(OBJ_nid2sn(i));
+       int mdnid, pknid;
+
+       /* Convert signature OID into digest and public key OIDs */
+
+       if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
+               {
+               ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+               goto err;
+               }
+       type=EVP_get_digestbynid(mdnid);
        if (type == NULL)
                {
                ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
                goto err;
                }
 
+       /* Check public key OID matches public key type */
+       if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+               {
+               ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+               goto err;
+               }
+
+       EVP_MD_CTX_init(&ctx);
        if (!EVP_VerifyInit_ex(&ctx,type, NULL))
                {
                ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
index 8aa7d3b..ea57f77 100644 (file)
@@ -1176,6 +1176,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_DECODE_ERROR                             110
 #define ASN1_R_DECODING_ERROR                           111
 #define ASN1_R_DEPTH_EXCEEDED                           174
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED        198
 #define ASN1_R_ENCODE_ERROR                             112
 #define ASN1_R_ERROR_GETTING_TIME                       173
 #define ASN1_R_ERROR_LOADING_SECTION                    172
@@ -1251,6 +1252,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM                 161
 #define ASN1_R_UNKNOWN_OBJECT_TYPE                      162
 #define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE                  163
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM              199
 #define ASN1_R_UNKNOWN_TAG                              194
 #define ASN1_R_UNKOWN_FORMAT                            195
 #define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE          164
@@ -1258,6 +1260,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM                 166
 #define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE              167
 #define ASN1_R_UNSUPPORTED_TYPE                                 196
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE                    200
 #define ASN1_R_WRONG_TAG                                168
 #define ASN1_R_WRONG_TYPE                               169
 
index bef2519..8b1a651 100644 (file)
@@ -93,7 +93,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET),    "ASN1_GENERALIZEDTIME_set"},
 {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3),    "ASN1_generate_v3"},
 {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT),     "ASN1_get_object"},
-{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),     "ASN1_HEADER_new"},
+{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),     "ASN1_HEADER_NEW"},
 {ERR_FUNC(ASN1_F_ASN1_I2D_BIO),        "ASN1_i2d_bio"},
 {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
 {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET),    "ASN1_INTEGER_set"},
@@ -111,7 +111,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
 {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW),     "ASN1_OBJECT_new"},
 {ERR_FUNC(ASN1_F_ASN1_PACK_STRING),    "ASN1_pack_string"},
-{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),       "ASN1_PCTX_NEW"},
+{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),       "ASN1_PCTX_new"},
 {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET),  "ASN1_PKCS5_PBE_SET"},
 {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK),       "ASN1_seq_pack"},
 {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK),     "ASN1_seq_unpack"},
@@ -123,7 +123,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I),        "ASN1_TEMPLATE_EX_D2I"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW),   "ASN1_TEMPLATE_NEW"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I),     "ASN1_TEMPLATE_NOEXP_D2I"},
-{ERR_FUNC(ASN1_F_ASN1_TIME_SET),       "ASN1_TIME_set"},
+{ERR_FUNC(ASN1_F_ASN1_TIME_SET),       "ASN1_TIME_SET"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),       "ASN1_TYPE_get_int_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING),   "ASN1_TYPE_get_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING),  "ASN1_unpack_string"},
@@ -140,7 +140,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN),    "d2i_ASN1_BOOLEAN"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES),      "d2i_ASN1_bytes"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME),    "D2I_ASN1_GENERALIZEDTIME"},
-{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),     "d2i_ASN1_HEADER"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),     "D2I_ASN1_HEADER"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER),    "D2I_ASN1_INTEGER"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT),     "d2i_ASN1_OBJECT"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_SET),        "d2i_ASN1_SET"},
@@ -168,10 +168,10 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_OID_MODULE_INIT),     "OID_MODULE_INIT"},
 {ERR_FUNC(ASN1_F_PARSE_TAGGING),       "PARSE_TAGGING"},
 {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET),      "PKCS5_pbe2_set"},
-{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),       "PKCS5_pbe_set"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),       "PKCS5_PBE_SET"},
 {ERR_FUNC(ASN1_F_X509_CINF_NEW),       "X509_CINF_NEW"},
-{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),       "X509_CRL_add0_revoked"},
-{ERR_FUNC(ASN1_F_X509_INFO_NEW),       "X509_INFO_new"},
+{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),       "X509_CRL_ADD0_REVOKED"},
+{ERR_FUNC(ASN1_F_X509_INFO_NEW),       "X509_INFO_NEW"},
 {ERR_FUNC(ASN1_F_X509_NAME_ENCODE),    "X509_NAME_ENCODE"},
 {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I),    "X509_NAME_EX_D2I"},
 {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW),    "X509_NAME_EX_NEW"},
@@ -196,6 +196,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_DECODE_ERROR)         ,"decode error"},
 {ERR_REASON(ASN1_R_DECODING_ERROR)       ,"decoding error"},
 {ERR_REASON(ASN1_R_DEPTH_EXCEEDED)       ,"depth exceeded"},
+{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
 {ERR_REASON(ASN1_R_ENCODE_ERROR)         ,"encode error"},
 {ERR_REASON(ASN1_R_ERROR_GETTING_TIME)   ,"error getting time"},
 {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
@@ -271,6 +272,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  ,"unknown object type"},
 {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
+{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_TAG)          ,"unknown tag"},
 {ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unkown format"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
@@ -278,6 +280,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE)     ,"unsupported type"},
+{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
 {ERR_REASON(ASN1_R_WRONG_TAG)            ,"wrong tag"},
 {ERR_REASON(ASN1_R_WRONG_TYPE)           ,"wrong type"},
 {0,NULL}
index e054d21..6ec2fa7 100644 (file)
@@ -188,6 +188,15 @@ typedef int evp_verify_method(int type,const unsigned char *m,
 #define EVP_MD_FLAG_ONESHOT    0x0001 /* digest can only handle a single
                                        * block */
 
+#define EVP_MD_FLAG_PKEY_DIGEST        0x0002 /* digest is a "clone" digest used
+                                       * which is a copy of an existing
+                                       * one for a specific public key type.
+                                       * EVP_dss1() etc */
+
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE      0x0004
+
 #define EVP_PKEY_NULL_method   NULL,NULL,{0,0,0,0}
 
 #ifndef OPENSSL_NO_DSA
@@ -792,6 +801,7 @@ void EVP_PBE_cleanup(void);
 
 #define ASN1_PKEY_ALIAS                0x1
 #define ASN1_PKEY_DYNAMIC      0x2
+#define ASN1_PKEY_SIGPARAM_NULL        0x4
 
 #define ASN1_PKEY_CTRL_PKCS7_SIGN      0x1
 
index a948c77..48c2689 100644 (file)
@@ -81,7 +81,7 @@ static const EVP_MD dsa_md=
        NID_dsaWithSHA,
        NID_dsaWithSHA,
        SHA_DIGEST_LENGTH,
-       0,
+       EVP_MD_FLAG_PKEY_DIGEST,
        init,
        update,
        final,
index c12e139..4f03fb7 100644 (file)
@@ -82,7 +82,7 @@ static const EVP_MD dss1_md=
        NID_dsa,
        NID_dsaWithSHA1,
        SHA_DIGEST_LENGTH,
-       0,
+       EVP_MD_FLAG_PKEY_DIGEST,
        init,
        update,
        final,
index fad270f..8d87a49 100644 (file)
@@ -130,7 +130,7 @@ static const EVP_MD ecdsa_md=
        NID_ecdsa_with_SHA1,
        NID_ecdsa_with_SHA1,
        SHA_DIGEST_LENGTH,
-       0,
+       EVP_MD_FLAG_PKEY_DIGEST,
        init,
        update,
        final,
index 4679b1c..41c8d3d 100644 (file)
@@ -82,7 +82,7 @@ static const EVP_MD sha1_md=
        NID_sha1,
        NID_sha1WithRSAEncryption,
        SHA_DIGEST_LENGTH,
-       0,
+       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
        init,
        update,
        final,
index e4ae590..54ad0fc 100644 (file)
@@ -88,6 +88,28 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
        EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);   
        EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
        EVP_MD_CTX_cleanup(&tmp_ctx);
+
+       if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+               {
+               EVP_PKEY_CTX *pkctx = NULL;
+               int sltmp = EVP_PKEY_size(pkey);
+               i = 0;
+               pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+               if (!pkctx)
+                       goto err;
+               if (EVP_PKEY_sign_init(pkctx) <= 0)
+                       goto err;
+               if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+                       goto err;
+               if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+                       goto err;
+               *siglen = sltmp;
+               i = 1;
+               err:
+               EVP_PKEY_CTX_free(pkctx);
+               return i;
+               }
+
        for (i=0; i<4; i++)
                {
                v=ctx->digest->required_pkey_type[i];
@@ -103,6 +125,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
                EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
                return(0);
                }
+
        if (ctx->digest->sign == NULL)
                {
                EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
index 21a40a3..8db4641 100644 (file)
@@ -70,6 +70,28 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
        int i,ok=0,v;
        MS_STATIC EVP_MD_CTX tmp_ctx;
 
+       EVP_MD_CTX_init(&tmp_ctx);
+       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
+       EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+       EVP_MD_CTX_cleanup(&tmp_ctx);
+
+       if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+               {
+               EVP_PKEY_CTX *pkctx = NULL;
+               i = -1;
+               pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+               if (!pkctx)
+                       goto err;
+               if (EVP_PKEY_verify_init(pkctx) <= 0)
+                       goto err;
+               if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+                       goto err;
+               i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+               err:
+               EVP_PKEY_CTX_free(pkctx);
+               return i;
+               }
+
        for (i=0; i<4; i++)
                {
                v=ctx->digest->required_pkey_type[i];
@@ -85,10 +107,6 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
                return(-1);
                }
-       EVP_MD_CTX_init(&tmp_ctx);
-       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
-       EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
-       EVP_MD_CTX_cleanup(&tmp_ctx);
         if (ctx->digest->verify == NULL)
                 {
                EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
index 93b9f07..1f913d7 100644 (file)
@@ -289,7 +289,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
                {
                EVP_PKEY_RSA,
                EVP_PKEY_RSA,
-               0,
+               ASN1_PKEY_SIGPARAM_NULL,
 
                "RSA",
                "OpenSSL RSA method",