CMS public key parameter support.
Add support for customisation of CMS handling of signed and enveloped data from custom public key parameters. This will provide support for RSA-PSS and RSA-OAEP but could also be applied to other algorithms.
This commit is contained in:
parent
211a14f627
commit
e365352d6a
6 changed files with 212 additions and 75 deletions
|
@ -112,6 +112,7 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
|
|||
#define CMS_REUSE_DIGEST 0x8000
|
||||
#define CMS_USE_KEYID 0x10000
|
||||
#define CMS_DEBUG_DECRYPT 0x20000
|
||||
#define CMS_KEY_PARAM 0x40000
|
||||
|
||||
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
|
||||
|
||||
|
@ -190,6 +191,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
|
|||
|
||||
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
|
||||
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
|
||||
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
|
||||
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||
X509 *recip, unsigned int flags);
|
||||
|
@ -256,6 +258,8 @@ int CMS_SignedData_init(CMS_ContentInfo *cms);
|
|||
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
|
||||
unsigned int flags);
|
||||
EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
|
||||
EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
|
||||
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
|
||||
|
||||
void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
|
||||
|
@ -374,6 +378,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_F_CMS_ENVELOPEDDATA_CREATE 124
|
||||
#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125
|
||||
#define CMS_F_CMS_ENVELOPED_DATA_INIT 126
|
||||
#define CMS_F_CMS_ENV_ASN1_CTRL 171
|
||||
#define CMS_F_CMS_FINAL 127
|
||||
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128
|
||||
#define CMS_F_CMS_GET0_CONTENT 129
|
||||
|
@ -399,6 +404,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144
|
||||
#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168
|
||||
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145
|
||||
#define CMS_F_CMS_SD_ASN1_CTRL 170
|
||||
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146
|
||||
#define CMS_F_CMS_SET_DETACHED 147
|
||||
#define CMS_F_CMS_SIGN 148
|
||||
|
|
|
@ -97,6 +97,8 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
|||
EVP_PKEY_free(si->pkey);
|
||||
if (si->signer)
|
||||
X509_free(si->signer);
|
||||
if (si->pctx)
|
||||
EVP_MD_CTX_cleanup(&si->mctx);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -227,6 +229,8 @@ static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
|||
EVP_PKEY_free(ktri->pkey);
|
||||
if (ktri->recip)
|
||||
X509_free(ktri->recip);
|
||||
if (ktri->pctx)
|
||||
EVP_PKEY_CTX_free(ktri->pctx);
|
||||
}
|
||||
else if (ri->type == CMS_RECIPINFO_KEK)
|
||||
{
|
||||
|
|
|
@ -103,6 +103,27 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
|
|||
return cms_get0_enveloped(cms);
|
||||
}
|
||||
|
||||
static int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
|
||||
{
|
||||
EVP_PKEY *pkey = ri->d.ktri->pkey;
|
||||
int i;
|
||||
if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
|
||||
return 1;
|
||||
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
|
||||
if (i == -2)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
return 0;
|
||||
}
|
||||
if (i <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_EnvelopedData *env;
|
||||
|
@ -117,6 +138,13 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
|
|||
return ri->type;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
|
||||
{
|
||||
if (ri->type == CMS_RECIPINFO_TRANS)
|
||||
return ri->d.ktri->pctx;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
|
@ -151,7 +179,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
|||
CMS_KeyTransRecipientInfo *ktri;
|
||||
CMS_EnvelopedData *env;
|
||||
EVP_PKEY *pk = NULL;
|
||||
int i, type;
|
||||
int type;
|
||||
env = cms_get0_enveloped(cms);
|
||||
if (!env)
|
||||
goto err;
|
||||
|
@ -200,23 +228,16 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
|||
if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
|
||||
goto err;
|
||||
|
||||
if (pk->ameth && pk->ameth->pkey_ctrl)
|
||||
if (flags & CMS_KEY_PARAM)
|
||||
{
|
||||
i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
|
||||
0, ri);
|
||||
if (i == -2)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
if (!ktri->pctx)
|
||||
return 0;
|
||||
if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (i <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
|
||||
CMS_R_CTRL_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (!cms_env_asn1_ctrl(ri, 0))
|
||||
goto err;
|
||||
|
||||
if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
|
||||
goto merr;
|
||||
|
@ -302,7 +323,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
|
|||
{
|
||||
CMS_KeyTransRecipientInfo *ktri;
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
unsigned char *ek = NULL;
|
||||
size_t eklen;
|
||||
|
||||
|
@ -317,12 +338,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
|
|||
ktri = ri->d.ktri;
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
if (!pctx)
|
||||
return 0;
|
||||
pctx = ktri->pctx;
|
||||
|
||||
if (EVP_PKEY_encrypt_init(pctx) <= 0)
|
||||
goto err;
|
||||
if (pctx)
|
||||
{
|
||||
if (!cms_env_asn1_ctrl(ri, 0))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
if (!pctx)
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_encrypt_init(pctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
|
||||
EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
|
||||
|
@ -353,7 +384,10 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
|
|||
|
||||
err:
|
||||
if (pctx)
|
||||
{
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
ktri->pctx = NULL;
|
||||
}
|
||||
if (ek)
|
||||
OPENSSL_free(ek);
|
||||
return ret;
|
||||
|
@ -366,7 +400,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
|||
CMS_RecipientInfo *ri)
|
||||
{
|
||||
CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = ktri->pkey;
|
||||
unsigned char *ek = NULL;
|
||||
size_t eklen;
|
||||
int ret = 0;
|
||||
|
@ -380,21 +414,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
|||
return 0;
|
||||
}
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
if (!pctx)
|
||||
ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (!ktri->pctx)
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_decrypt_init(pctx) <= 0)
|
||||
if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
|
||||
if (!cms_env_asn1_ctrl(ri, 1))
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
|
||||
EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
|
||||
if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
|
||||
ktri->encryptedKey->data,
|
||||
ktri->encryptedKey->length) <= 0)
|
||||
goto err;
|
||||
|
@ -408,7 +445,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_decrypt(pctx, ek, &eklen,
|
||||
if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
|
||||
ktri->encryptedKey->data,
|
||||
ktri->encryptedKey->length) <= 0)
|
||||
{
|
||||
|
@ -428,8 +465,11 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
|||
ec->keylen = eklen;
|
||||
|
||||
err:
|
||||
if (pctx)
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
if (ktri->pctx)
|
||||
{
|
||||
EVP_PKEY_CTX_free(ktri->pctx);
|
||||
ktri->pctx = NULL;
|
||||
}
|
||||
if (!ret && ek)
|
||||
OPENSSL_free(ek);
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), "cms_EnvelopedData_init_bio"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "CMS_ENV_ASN1_CTRL"},
|
||||
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
|
||||
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
|
||||
{ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
|
||||
|
@ -128,6 +129,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), "CMS_RecipientInfo_set0_key"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), "CMS_RecipientInfo_set0_password"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), "CMS_RecipientInfo_set0_pkey"},
|
||||
{ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "CMS_SD_ASN1_CTRL"},
|
||||
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
|
||||
{ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
|
||||
{ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
|
||||
|
|
|
@ -140,6 +140,9 @@ struct CMS_SignerInfo_st
|
|||
/* Signing certificate and key */
|
||||
X509 *signer;
|
||||
EVP_PKEY *pkey;
|
||||
/* Digest and public key context for alternative parameters */
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
};
|
||||
|
||||
struct CMS_SignerIdentifier_st
|
||||
|
@ -202,6 +205,8 @@ struct CMS_KeyTransRecipientInfo_st
|
|||
/* Recipient Key and cert */
|
||||
X509 *recip;
|
||||
EVP_PKEY *pkey;
|
||||
/* Public key context for this operation */
|
||||
EVP_PKEY_CTX *pctx;
|
||||
};
|
||||
|
||||
struct CMS_KeyAgreeRecipientInfo_st
|
||||
|
|
|
@ -297,6 +297,27 @@ int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
|
||||
{
|
||||
EVP_PKEY *pkey = si->pkey;
|
||||
int i;
|
||||
if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
|
||||
return 1;
|
||||
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
|
||||
if (i == -2)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SD_ASN1_CTRL,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
return 0;
|
||||
}
|
||||
if (i <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
|
||||
unsigned int flags)
|
||||
|
@ -324,6 +345,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
|||
|
||||
si->pkey = pk;
|
||||
si->signer = signer;
|
||||
EVP_MD_CTX_init(&si->mctx);
|
||||
si->pctx = NULL;
|
||||
|
||||
if (flags & CMS_USE_KEYID)
|
||||
{
|
||||
|
@ -385,23 +408,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
|||
}
|
||||
}
|
||||
|
||||
if (pk->ameth && pk->ameth->pkey_ctrl)
|
||||
{
|
||||
i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
|
||||
0, si);
|
||||
if (i == -2)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ADD1_SIGNER,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (i <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
|
||||
goto err;
|
||||
if (!(flags & CMS_NOATTR))
|
||||
{
|
||||
/* Initialialize signed attributes strutucture so other
|
||||
|
@ -429,7 +437,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
|||
{
|
||||
if (!cms_copy_messageDigest(cms, si))
|
||||
goto err;
|
||||
if (!(flags & CMS_PARTIAL) &&
|
||||
if (!(flags & (CMS_PARTIAL|CMS_KEY_PARAM)) &&
|
||||
!CMS_SignerInfo_sign(si))
|
||||
goto err;
|
||||
}
|
||||
|
@ -442,6 +450,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
|||
goto merr;
|
||||
}
|
||||
|
||||
if (flags & CMS_KEY_PARAM)
|
||||
{
|
||||
if (flags & CMS_NOATTR)
|
||||
{
|
||||
si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
|
||||
if (!si->pctx)
|
||||
goto err;
|
||||
if (EVP_PKEY_sign_init(si->pctx) <= 0)
|
||||
goto err;
|
||||
if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
|
||||
goto err;
|
||||
}
|
||||
else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!sd->signerInfos)
|
||||
sd->signerInfos = sk_CMS_SignerInfo_new_null();
|
||||
if (!sd->signerInfos ||
|
||||
|
@ -489,6 +513,16 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
|
|||
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
|
||||
{
|
||||
return si->pctx;
|
||||
}
|
||||
|
||||
EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
|
||||
{
|
||||
return &si->mctx;
|
||||
}
|
||||
|
||||
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_SignedData *sd;
|
||||
|
@ -621,9 +655,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
|||
{
|
||||
EVP_MD_CTX mctx;
|
||||
int r = 0;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
|
||||
if (!si->pkey)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
|
||||
|
@ -632,6 +666,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
|||
|
||||
if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
|
||||
goto err;
|
||||
/* Set SignerInfo algortihm details if we used custom parametsr */
|
||||
if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
|
||||
goto err;
|
||||
|
||||
/* If any signed attributes calculate and add messageDigest attribute */
|
||||
|
||||
|
@ -654,6 +691,26 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
|||
if (!CMS_SignerInfo_sign(si))
|
||||
goto err;
|
||||
}
|
||||
else if (si->pctx)
|
||||
{
|
||||
unsigned char *sig;
|
||||
size_t siglen;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int mdlen;
|
||||
pctx = si->pctx;
|
||||
if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
|
||||
goto err;
|
||||
sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
|
||||
if (!sig)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0)
|
||||
goto err;
|
||||
ASN1_STRING_set0(si->signature, sig, siglen);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *sig;
|
||||
|
@ -679,6 +736,8 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
|||
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
if (pctx)
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
@ -701,7 +760,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
|
|||
|
||||
int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
||||
{
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_MD_CTX *mctx = &si->mctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
unsigned char *abuf = NULL;
|
||||
int alen;
|
||||
|
@ -712,7 +771,6 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
|||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
|
||||
{
|
||||
|
@ -720,8 +778,14 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
|
||||
goto err;
|
||||
if (si->pctx)
|
||||
pctx = si->pctx;
|
||||
else
|
||||
{
|
||||
EVP_MD_CTX_init(mctx);
|
||||
if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
|
||||
EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
|
||||
|
@ -734,15 +798,15 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
|||
ASN1_ITEM_rptr(CMS_Attributes_Sign));
|
||||
if(!abuf)
|
||||
goto err;
|
||||
if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
|
||||
if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
|
||||
if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
|
||||
goto err;
|
||||
OPENSSL_free(abuf);
|
||||
abuf = OPENSSL_malloc(siglen);
|
||||
if(!abuf)
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
|
||||
if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
|
||||
|
@ -752,7 +816,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
|||
goto err;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_MD_CTX_cleanup(mctx);
|
||||
|
||||
ASN1_STRING_set0(si->signature, abuf, siglen);
|
||||
|
||||
|
@ -761,15 +825,14 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
|||
err:
|
||||
if (abuf)
|
||||
OPENSSL_free(abuf);
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_MD_CTX_cleanup(mctx);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
||||
{
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
EVP_MD_CTX *mctx = &si->mctx;
|
||||
unsigned char *abuf = NULL;
|
||||
int alen, r = -1;
|
||||
const EVP_MD *md = NULL;
|
||||
|
@ -783,27 +846,30 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
|||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
if (md == NULL)
|
||||
return -1;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
|
||||
EVP_MD_CTX_init(mctx);
|
||||
if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
|
||||
goto err;
|
||||
|
||||
if (!cms_sd_asn1_ctrl(si, 1))
|
||||
goto err;
|
||||
|
||||
alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
|
||||
ASN1_ITEM_rptr(CMS_Attributes_Verify));
|
||||
if(!abuf)
|
||||
goto err;
|
||||
r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
|
||||
r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
|
||||
OPENSSL_free(abuf);
|
||||
if (r <= 0)
|
||||
{
|
||||
r = -1;
|
||||
goto err;
|
||||
}
|
||||
r = EVP_DigestVerifyFinal(&mctx,
|
||||
r = EVP_DigestVerifyFinal(mctx,
|
||||
si->signature->data, si->signature->length);
|
||||
if (r <= 0)
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_MD_CTX_cleanup(mctx);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -843,7 +909,10 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
|||
{
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
int r = -1;
|
||||
unsigned char mval[EVP_MAX_MD_SIZE];
|
||||
unsigned int mlen;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
/* If we have any signed attributes look for messageDigest value */
|
||||
if (CMS_signed_get_attr_count(si) >= 0)
|
||||
|
@ -862,18 +931,17 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
|||
if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
|
||||
goto err;
|
||||
|
||||
if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If messageDigest found compare it */
|
||||
|
||||
if (os)
|
||||
{
|
||||
unsigned char mval[EVP_MAX_MD_SIZE];
|
||||
unsigned int mlen;
|
||||
if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
|
||||
goto err;
|
||||
}
|
||||
if (mlen != (unsigned int)os->length)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
|
@ -892,8 +960,18 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
|||
}
|
||||
else
|
||||
{
|
||||
r = EVP_VerifyFinal(&mctx, si->signature->data,
|
||||
si->signature->length, si->pkey);
|
||||
const EVP_MD *md = EVP_MD_CTX_md(&mctx);
|
||||
pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
|
||||
if (EVP_PKEY_verify_init(pkctx) <= 0)
|
||||
goto err;
|
||||
if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
|
||||
goto err;
|
||||
si->pctx = pkctx;
|
||||
if (!cms_sd_asn1_ctrl(si, 1))
|
||||
goto err;
|
||||
r = EVP_PKEY_verify(pkctx, si->signature->data,
|
||||
si->signature->length,
|
||||
mval, mlen);
|
||||
if (r <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
|
@ -903,6 +981,8 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
|||
}
|
||||
|
||||
err:
|
||||
if (pkctx)
|
||||
EVP_PKEY_CTX_free(pkctx);
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
return r;
|
||||
|
||||
|
|
Loading…
Reference in a new issue