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 d87e1ebbdd7c1d7a5559aba23e27ad6fd5c73ea5..c74a02c367b130a93217319d2a8afe9c3d9d4e32 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 9af7bab20bb27ad8ff054fabaa382623462bb716..f7532d21b56c3ae34e0116484e667f058f5ea815 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 14bb0e0d03bee3946f40e03abdb1c75a3b21fe2b..b9a3852cfce5bcfc9311f3a02b6cab698c692428 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 8d20681ec3b476e3ad0c698d2209c4f859f4a24e..e3a97383a6cd37a031a884d3b4df589c3fd1fd02 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 1081950518c7b7fdea470c876523f58ace22124b..c98dc7c332fe4a8d9b7fbb0555171fb0bf8cf2e8 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 fdce6e4380b6534a782717c87fd8c1564ef4fb48..4885539c262ef95a2ae56c1de8722d6a9c7d8c6a 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 8aa7d3b09d9713b888b2b45c54e5276580a3227a..ea57f77861e6bc22b1267f4ef007316ac84ef0b2 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 bef2519e65a6371062baa77804f684f23c166924..8b1a651a92153833cb1a83ca625cdb88ad66c018 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 e054d211f6b8c24a8cca35a72253362df8141ecf..6ec2fa798a8176a8efdcbd2371a11d5549d8fd4a 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 a948c77fa497a2bf8fc35f574ea333c1fbd0cd9f..48c2689504821fdeeaef5f3f0b06118eab40725e 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 c12e13972b501d98cd35456733ce3915ad000e3a..4f03fb70e0263e84566c24d333ddd06b7cee71ce 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 fad270faca2b39e3d8087bdabc6fec9fb4fea10c..8d87a49ebe9af85ca213f8f3ff67fb6b31d2407c 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 4679b1c4638c18d1e0d8c6edc8c1d86f14fff28d..41c8d3dfe2591569de1aef020a61ced1f310b449 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 e4ae5906f5578238654dcdf940d150da994f1411..54ad0fc7f74da3b06eff08887647b06541099a99 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 21a40a375e1b71b6e3a2c17bd0a8ee840cde1ec2..8db46412f3771720b9afde5faa46a4dcfc133dc9 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 93b9f075c4bc8d098deab0cd9d857c4d50e119a5..1f913d79dc7dcb3779214abf24fb5a03c9593ba2 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",