Fix the PKCS#7 stuff: signature verify could fail if attributes reordered, the
detached data encoding was wrong and free up public keys.
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -5,6 +5,12 @@
|
|||||||
|
|
||||||
Changes between 0.9.1c and 0.9.2
|
Changes between 0.9.1c and 0.9.2
|
||||||
|
|
||||||
|
*) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
|
||||||
|
signed attributes when verifying signatures (this would break them),
|
||||||
|
the detached data encoding was wrong and public keys obtained using
|
||||||
|
X509_get_pubkey() weren't freed.
|
||||||
|
[Steve Henson]
|
||||||
|
|
||||||
*) Add text documentation for the BUFFER functions. Also added a work around
|
*) Add text documentation for the BUFFER functions. Also added a work around
|
||||||
to a Win95 console bug. This was triggered by the password read stuff: the
|
to a Win95 console bug. This was triggered by the password read stuff: the
|
||||||
last character typed gets carried over to the next fread(). If you were
|
last character typed gets carried over to the next fread(). If you were
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ char **str2;
|
|||||||
OBJ_create("1.9.9999","OID_example","Our example OID");
|
OBJ_create("1.9.9999","OID_example","Our example OID");
|
||||||
/* To retrieve */
|
/* To retrieve */
|
||||||
so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
|
so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
|
||||||
if (so->type == V_ASN1_SEQUENCE)
|
if (so && (so->type == V_ASN1_SEQUENCE))
|
||||||
{
|
{
|
||||||
ASN1_CTX c;
|
ASN1_CTX c;
|
||||||
ASN1_STRING *s;
|
ASN1_STRING *s;
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ BIO *bio;
|
|||||||
}
|
}
|
||||||
pkey=X509_get_pubkey(ri->cert);
|
pkey=X509_get_pubkey(ri->cert);
|
||||||
jj=EVP_PKEY_size(pkey);
|
jj=EVP_PKEY_size(pkey);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
if (max < jj) max=jj;
|
if (max < jj) max=jj;
|
||||||
}
|
}
|
||||||
if ((tmp=(unsigned char *)Malloc(max)) == NULL)
|
if ((tmp=(unsigned char *)Malloc(max)) == NULL)
|
||||||
@@ -197,6 +198,7 @@ BIO *bio;
|
|||||||
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,i);
|
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,i);
|
||||||
pkey=X509_get_pubkey(ri->cert);
|
pkey=X509_get_pubkey(ri->cert);
|
||||||
jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
|
jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
if (jj <= 0)
|
if (jj <= 0)
|
||||||
{
|
{
|
||||||
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
|
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
|
||||||
@@ -503,6 +505,11 @@ BIO *bio;
|
|||||||
case NID_pkcs7_signed:
|
case NID_pkcs7_signed:
|
||||||
si_sk=p7->d.sign->signer_info;
|
si_sk=p7->d.sign->signer_info;
|
||||||
os=p7->d.sign->contents->d.data;
|
os=p7->d.sign->contents->d.data;
|
||||||
|
/* If detached data then the content is excluded */
|
||||||
|
if(p7->detached) {
|
||||||
|
ASN1_OCTET_STRING_free(os);
|
||||||
|
p7->d.sign->contents->d.data = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,9 +615,7 @@ BIO *bio;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p7->detached)
|
if (!p7->detached)
|
||||||
ASN1_OCTET_STRING_set(os,(unsigned char *)"",0);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
btmp=BIO_find_type(bio,BIO_TYPE_MEM);
|
btmp=BIO_find_type(bio,BIO_TYPE_MEM);
|
||||||
if (btmp == NULL)
|
if (btmp == NULL)
|
||||||
@@ -648,6 +653,7 @@ PKCS7_SIGNER_INFO *si;
|
|||||||
STACK *sk,*cert;
|
STACK *sk,*cert;
|
||||||
BIO *btmp;
|
BIO *btmp;
|
||||||
X509 *x509;
|
X509 *x509;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
|
||||||
if (PKCS7_type_is_signed(p7))
|
if (PKCS7_type_is_signed(p7))
|
||||||
{
|
{
|
||||||
@@ -742,22 +748,27 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));
|
EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));
|
||||||
|
/* Note: when forming the encoding of the attributes we
|
||||||
|
* shouldn't reorder them or this will break the signature.
|
||||||
|
* This is done by using the IS_SEQUENCE flag.
|
||||||
|
*/
|
||||||
i=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE,
|
i=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE,
|
||||||
V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);
|
V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
|
||||||
pp=(unsigned char *)Malloc(i);
|
pp=(unsigned char *)Malloc(i);
|
||||||
p=pp;
|
p=pp;
|
||||||
i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
|
i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
|
||||||
V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);
|
V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
|
||||||
EVP_VerifyUpdate(&mdc_tmp,pp,i);
|
EVP_VerifyUpdate(&mdc_tmp,pp,i);
|
||||||
|
|
||||||
Free(pp);
|
Free(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
os=si->enc_digest;
|
os=si->enc_digest;
|
||||||
if (X509_get_pubkey(x509)->type == EVP_PKEY_DSA)
|
pkey = X509_get_pubkey(x509);
|
||||||
mdc_tmp.digest=EVP_dss1();
|
if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
|
||||||
|
|
||||||
i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length,
|
i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
|
||||||
X509_get_pubkey(x509));
|
EVP_PKEY_free(pkey);
|
||||||
if (i <= 0)
|
if (i <= 0)
|
||||||
{
|
{
|
||||||
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);
|
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);
|
||||||
|
|||||||
Reference in New Issue
Block a user