Allow digests to supply S/MIME micalg values from a ctrl.
Send ctrls to EVP_PKEY_METHOD during signing of PKCS7 structure so customisation is possible.
This commit is contained in:
parent
0ee2166cc5
commit
b7683e3a5d
10 changed files with 83 additions and 40 deletions
10
CHANGES
10
CHANGES
|
@ -4,6 +4,16 @@
|
|||
|
||||
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Allow digests to supply their own micalg string for S/MIME type using
|
||||
the ctrl EVP_MD_CTRL_MICALG.
|
||||
[Steve Henson]
|
||||
|
||||
*) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
|
||||
EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
|
||||
ctrl. It can then customise the structure before and/or after signing
|
||||
if necessary.
|
||||
[Steve Henson]
|
||||
|
||||
*) New function OBJ_add_sigid() to allow application defined signature OIDs
|
||||
to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
|
||||
to free up any added signature OIDs.
|
||||
|
|
|
@ -169,6 +169,9 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
dctx->md = p2;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_PKCS7_SIGN:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
|
||||
case EVP_PKEY_CTRL_PEER_KEY:
|
||||
/* Default behaviour is OK */
|
||||
case EVP_PKEY_CTRL_PKCS7_SIGN:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
|
|
@ -332,6 +332,8 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
|
|||
OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
|
||||
OPENSSL_free(ctx->md_data);
|
||||
}
|
||||
if (ctx->pctx)
|
||||
EVP_PKEY_CTX_free(ctx->pctx);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if(ctx->engine)
|
||||
/* The EVP_MD we used belongs to an ENGINE, release the
|
||||
|
|
|
@ -218,6 +218,7 @@ typedef int evp_verify_method(int type,const unsigned char *m,
|
|||
/* Digest ctrls */
|
||||
|
||||
#define EVP_MD_CTRL_DIGALGID 0x1
|
||||
#define EVP_MD_CTRL_MICALG 0x2
|
||||
|
||||
/* Minimum Algorithm specific ctrl value */
|
||||
|
||||
|
@ -455,6 +456,9 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
|
|||
#define EVP_SignDigestUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
|
||||
#define EVP_VerifyDigestUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
|
||||
|
||||
#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
|
||||
#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
|
||||
|
||||
#ifdef CONST_STRICT
|
||||
void BIO_set_md(BIO *,const EVP_MD *md);
|
||||
#else
|
||||
|
@ -981,10 +985,12 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
|||
EVP_PKEY_CTRL_MD, 0, (void *)md)
|
||||
|
||||
#define EVP_PKEY_CTRL_MD 1
|
||||
#define EVP_PKEY_CTRL_PEER_KEY 2
|
||||
#define EVP_PKEY_CTRL_PEER_KEY 2
|
||||
|
||||
#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3
|
||||
#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4
|
||||
#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3
|
||||
#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4
|
||||
|
||||
#define EVP_PKEY_CTRL_PKCS7_SIGN 5
|
||||
|
||||
#define EVP_PKEY_ALG_CTRL 0x1000
|
||||
|
||||
|
|
|
@ -826,6 +826,7 @@ err:
|
|||
int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
{
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
unsigned char *abuf = NULL;
|
||||
int alen;
|
||||
unsigned int siglen;
|
||||
|
@ -836,21 +837,38 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
|||
return 0;
|
||||
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
if (!EVP_SignInit_ex(&mctx,md,NULL))
|
||||
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_PKCS7_SIGN, 0, si) <= 0)
|
||||
{
|
||||
PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
|
||||
ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
|
||||
if(!abuf)
|
||||
goto err;
|
||||
if (!EVP_SignUpdate(&mctx,abuf,alen))
|
||||
if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
|
||||
goto err;
|
||||
OPENSSL_free(abuf);
|
||||
abuf = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
|
||||
if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
|
||||
goto err;
|
||||
abuf = OPENSSL_malloc(siglen);
|
||||
if(!abuf)
|
||||
goto err;
|
||||
if (!EVP_SignFinal(&mctx, abuf, &siglen, si->pkey))
|
||||
if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
|
||||
EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
|
||||
{
|
||||
PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
|
||||
ASN1_STRING_set0(si->enc_digest, abuf, siglen);
|
||||
|
@ -864,10 +882,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
|||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
|
||||
PKCS7 *p7, PKCS7_SIGNER_INFO *si)
|
||||
|
|
|
@ -149,52 +149,65 @@ static PKCS7 *B64_read_PKCS7(BIO *bio)
|
|||
static int pk7_write_micalg(BIO *out, PKCS7 *p7)
|
||||
{
|
||||
STACK_OF(X509_ALGOR) *mdalgs;
|
||||
STACK *mic_sk;
|
||||
int i, have_unknown = 0, ret = 0;
|
||||
const EVP_MD *md;
|
||||
int i, have_unknown = 0, write_comma, ret = 0, md_nid;
|
||||
mdalgs = p7->d.sign->md_algs;
|
||||
mic_sk = sk_new_null();
|
||||
if (!mic_sk)
|
||||
goto err;
|
||||
have_unknown = 0;
|
||||
write_comma = 0;
|
||||
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
|
||||
{
|
||||
switch(OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm))
|
||||
if (write_comma)
|
||||
BIO_write(out, ",", 1);
|
||||
write_comma = 1;
|
||||
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
|
||||
md = EVP_get_digestbynid(md_nid);
|
||||
if (md && md->md_ctrl)
|
||||
{
|
||||
int rv;
|
||||
char *micstr;
|
||||
rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
|
||||
if (rv > 0)
|
||||
{
|
||||
BIO_puts(out, micstr);
|
||||
OPENSSL_free(micstr);
|
||||
continue;
|
||||
}
|
||||
if (rv != -2)
|
||||
goto err;
|
||||
}
|
||||
switch(md_nid)
|
||||
{
|
||||
case NID_sha1:
|
||||
if (!sk_push(mic_sk, "sha1"))
|
||||
goto err;
|
||||
BIO_puts(out, "sha1");
|
||||
break;
|
||||
|
||||
case NID_md5:
|
||||
if (!sk_push(mic_sk, "md5"))
|
||||
goto err;
|
||||
BIO_puts(out, "md5");
|
||||
break;
|
||||
|
||||
case NID_sha256:
|
||||
if (!sk_push(mic_sk, "sha-256"))
|
||||
goto err;
|
||||
BIO_puts(out, "sha-256");
|
||||
break;
|
||||
|
||||
case NID_sha384:
|
||||
if (!sk_push(mic_sk, "sha-384"))
|
||||
goto err;
|
||||
BIO_puts(out, "sha-384");
|
||||
break;
|
||||
|
||||
case NID_sha512:
|
||||
if (!sk_push(mic_sk, "sha-512"))
|
||||
goto err;
|
||||
BIO_puts(out, "sha-512");
|
||||
break;
|
||||
|
||||
case NID_id_GostR3411_94:
|
||||
if (!sk_push(mic_sk, "gostr3411-94"))
|
||||
BIO_puts(out, "gostr3411-94");
|
||||
goto err;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!have_unknown)
|
||||
if (have_unknown)
|
||||
write_comma = 0;
|
||||
else
|
||||
{
|
||||
if (!sk_push(mic_sk, "unknown"))
|
||||
goto err;
|
||||
BIO_puts(out, "unknown");
|
||||
have_unknown = 1;
|
||||
}
|
||||
break;
|
||||
|
@ -202,18 +215,9 @@ static int pk7_write_micalg(BIO *out, PKCS7 *p7)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_num(mic_sk); i++)
|
||||
{
|
||||
BIO_puts(out, sk_value(mic_sk, i));
|
||||
if (i > 0)
|
||||
BIO_write(out, ",", 1);
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
|
||||
if (mic_sk)
|
||||
sk_free(mic_sk);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
|
@ -435,6 +435,7 @@ void ERR_load_PKCS7_strings(void);
|
|||
#define PKCS7_F_PKCS7_SIGN 116
|
||||
#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
|
||||
#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
|
||||
#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139
|
||||
#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137
|
||||
#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
|
||||
#define PKCS7_F_PKCS7_VERIFY 117
|
||||
|
|
|
@ -103,6 +103,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
|
|||
{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
|
||||
|
|
|
@ -438,6 +438,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
|
||||
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
|
||||
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
|
||||
case EVP_PKEY_CTRL_PKCS7_SIGN:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue