Algorithm specific ASN1 signing functions.

This commit is contained in:
Dr. Stephen Henson 2010-03-11 13:32:38 +00:00
parent 31d66c2a98
commit 85522a074c
5 changed files with 84 additions and 35 deletions

View File

@ -4,6 +4,12 @@
Changes between 1.0.0 and 1.1.0 [xx XXX xxxx] Changes between 1.0.0 and 1.1.0 [xx XXX xxxx]
*) Support for companion algorithm specific ASN1 signing routines.
New function ASN1_item_sign_ctx() signs a pre-initialised
EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
the appropriate parameters.
[Steve Henson]
*) Add new algorithm specific ASN1 verification initialisation function *) Add new algorithm specific ASN1 verification initialisation function
to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1 to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
handling will be the same no matter what EVP_PKEY_METHOD is used. handling will be the same no matter what EVP_PKEY_METHOD is used.

View File

@ -218,30 +218,66 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
const EVP_MD *type) const EVP_MD *type)
{ {
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
{
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
return ASN1_item_sign_ctx(&ctx, it, algor1, algor2, signature, asn);
}
int ASN1_item_sign_ctx(EVP_MD_CTX *ctx,
const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn)
{
const EVP_MD *type;
EVP_PKEY *pkey;
unsigned char *buf_in=NULL,*buf_out=NULL; unsigned char *buf_in=NULL,*buf_out=NULL;
size_t inl=0,outl=0,outll=0; size_t inl=0,outl=0,outll=0;
int signid, paramtype; int signid, paramtype;
int rv;
if (type == NULL) type = EVP_MD_CTX_md(ctx);
{ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
int def_nid;
if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
type = EVP_get_digestbynid(def_nid);
}
if (type == NULL) if (!type || !pkey)
{ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST); ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
return 0; return 0;
} }
if (pkey->ameth->item_sign)
{
rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
signature);
if (rv == 1)
outl = signature->length;
/* Return value meanings:
* <=0: error.
* 1: method does everything.
* 2: carry on as normal.
* 3: ASN1 method sets algorithm identifiers: just sign.
*/
if (rv <= 0)
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
if (rv <= 1)
goto err;
}
else
rv = 2;
if (rv == 2)
{
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{ {
if (!pkey->ameth || if (!pkey->ameth ||
!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), !OBJ_find_sigid_by_algs(&signid,
EVP_MD_nid(type),
pkey->ameth->pkey_id)) pkey->ameth->pkey_id))
{ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0; return 0;
} }
@ -259,23 +295,23 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
if (algor2) if (algor2)
X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
EVP_MD_CTX_init(&ctx); }
inl=ASN1_item_i2d(asn,&buf_in, it); inl=ASN1_item_i2d(asn,&buf_in, it);
outll=outl=EVP_PKEY_size(pkey); outll=outl=EVP_PKEY_size(pkey);
buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); buf_out=OPENSSL_malloc((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL)) if ((buf_in == NULL) || (buf_out == NULL))
{ {
outl=0; outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE); ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
goto err; goto err;
} }
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey) if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
|| !EVP_DigestSignUpdate(&ctx, buf_in, inl) || !EVP_DigestSignFinal(ctx, buf_out, &outl))
|| !EVP_DigestSignFinal(&ctx, buf_out, &outl))
{ {
outl=0; outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB); ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
goto err; goto err;
} }
if (signature->data != NULL) OPENSSL_free(signature->data); if (signature->data != NULL) OPENSSL_free(signature->data);
@ -288,7 +324,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err: err:
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL) if (buf_in != NULL)
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
if (buf_out != NULL) if (buf_out != NULL)

View File

@ -1193,6 +1193,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_ASN1_ITEM_I2D_FP 193 #define ASN1_F_ASN1_ITEM_I2D_FP 193
#define ASN1_F_ASN1_ITEM_PACK 198 #define ASN1_F_ASN1_ITEM_PACK 198
#define ASN1_F_ASN1_ITEM_SIGN 195 #define ASN1_F_ASN1_ITEM_SIGN 195
#define ASN1_F_ASN1_ITEM_SIGN_CTX 220
#define ASN1_F_ASN1_ITEM_UNPACK 199 #define ASN1_F_ASN1_ITEM_UNPACK 199
#define ASN1_F_ASN1_ITEM_VERIFY 197 #define ASN1_F_ASN1_ITEM_VERIFY 197
#define ASN1_F_ASN1_MBSTRING_NCOPY 122 #define ASN1_F_ASN1_MBSTRING_NCOPY 122
@ -1291,6 +1292,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
#define ASN1_R_BUFFER_TOO_SMALL 107 #define ASN1_R_BUFFER_TOO_SMALL 107
#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 #define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108
#define ASN1_R_CONTEXT_NOT_INITIALISED 217
#define ASN1_R_DATA_IS_WRONG 109 #define ASN1_R_DATA_IS_WRONG 109
#define ASN1_R_DECODE_ERROR 110 #define ASN1_R_DECODE_ERROR 110
#define ASN1_R_DECODING_ERROR 111 #define ASN1_R_DECODING_ERROR 111

View File

@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */ /* crypto/asn1/asn1_err.c */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -107,6 +107,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
@ -208,6 +209,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"}, {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"}, {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"},
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"}, {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
{ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"}, {ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"},
{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"}, {ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"},

View File

@ -119,6 +119,9 @@ struct evp_pkey_asn1_method_st
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *a, ASN1_BIT_STRING *sig, X509_ALGOR *a, ASN1_BIT_STRING *sig,
EVP_PKEY *pkey); EVP_PKEY *pkey);
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
ASN1_BIT_STRING *sig);
} /* EVP_PKEY_ASN1_METHOD */; } /* EVP_PKEY_ASN1_METHOD */;