Remove link between digests and signature algorithms.

Use cross reference table in ASN1_item_sign(), ASN1_item_verify() to eliminate
the need for algorithm specific code.
上级 614b448a
......@@ -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
......
......@@ -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 */
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -123,6 +123,7 @@
#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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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}
......
......@@ -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
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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);
......
......@@ -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);
......
......@@ -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",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部