Fix some obvious bugs in the PKCS#7 library handling. It didn't try to

find the right RecipientInfo based on the recipient certificate (so would
fail a lot of the time) and fixup cipher structures to correctly (maybe)
modify the AlgorithmIdentifiers.  Largely untested at present... this will be
fixed in due course. Well the stuff was broken to begin with so if its broken
now then you haven't lost anything :-)
This commit is contained in:
Dr. Stephen Henson
1999-05-16 00:25:36 +00:00
parent a74c55cd8f
commit 84fa704c6f
9 changed files with 62 additions and 60 deletions

View File

@@ -88,23 +88,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
case NID_pkcs7_signedAndEnveloped:
rsk=p7->d.signed_and_enveloped->recipientinfo;
md_sk=p7->d.signed_and_enveloped->md_algs;
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.signed_and_enveloped->enc_data->algorithm->algorithm)));
xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
if (evp_cipher == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATAINIT,
PKCS7_R_CIPHER_NOT_INITIALIZED);
goto err;
}
xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
break;
case NID_pkcs7_enveloped:
rsk=p7->d.enveloped->recipientinfo;
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.enveloped->enc_data->algorithm->algorithm)));
xalg=p7->d.enveloped->enc_data->algorithm;
evp_cipher=p7->d.enveloped->enc_data->cipher;
if (evp_cipher == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATAINIT,
PKCS7_R_CIPHER_NOT_INITIALIZED);
goto err;
}
xalg=p7->d.enveloped->enc_data->algorithm;
break;
default:
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
@@ -146,24 +148,28 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
int keylen,ivlen;
int jj,max;
unsigned char *tmp;
EVP_CIPHER_CTX *ctx;
if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
goto err;
}
BIO_get_cipher_ctx(btmp, &ctx);
keylen=EVP_CIPHER_key_length(evp_cipher);
ivlen=EVP_CIPHER_iv_length(evp_cipher);
RAND_bytes(key,keylen);
EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
memset(key, 0, keylen);
xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
if (ivlen > 0) {
EVP_CIPHER_CTX *ctx;
BIO_get_cipher_ctx(btmp, &ctx);
RAND_bytes(iv,ivlen);
if (xalg->parameter == NULL)
xalg->parameter=ASN1_TYPE_new();
if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
goto err;
}
RAND_bytes(key,keylen);
/* Lets do the pub key stuff :-) */
max=0;
@@ -201,8 +207,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
}
Free(tmp);
BIO_set_cipher(btmp,evp_cipher,key,iv,1);
if (out == NULL)
out=btmp;
else
@@ -249,8 +253,7 @@ err:
}
/* int */
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
X509_STORE *xs)
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
{
int i,j;
BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
@@ -286,7 +289,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
if (evp_cipher == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
@@ -298,13 +301,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
if (evp_cipher == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
xalg=p7->d.enveloped->enc_data->algorithm;
break;
default:
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
goto err;
}
@@ -316,7 +319,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
xa=(X509_ALGOR *)sk_value(md_sk,i);
if ((btmp=BIO_new(BIO_f_md())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
goto err;
}
@@ -324,7 +327,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
if (evp_md == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
goto err;
}
@@ -351,50 +354,36 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
goto err;
}
/* It was encrypted, we need to decrypt the secret key
* with the private key */
/* We need to find a private key for one of the people in the
* recipentinfo list */
if (rsk == NULL)
return(NULL);
/* FIXME: this assumes that the passed private key
* corresponds to the first RecipientInfo. This in
* general is not true
/* Find the recipientInfo which matches the passed certificate
* (if any)
*/
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0);
#if 0
X509_STORE_CTX_init(&s_ctx,xs,NULL,NULL);
for (i=0; i<sk_num(rsk); i++)
{
for (i=0; i<sk_num(rsk); i++) {
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,i);
uf (X509_STORE_get_by_issuer_serial(&s_ctx,
X509_LU_PKEY,
ri->issuer_and_serial->issuer,
ri->issuer_and_serial->serial,
&ret))
break;
if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
pcert->cert_info->issuer) &&
!ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
ri->issuer_and_serial->serial)) break;
ri=NULL;
}
if (ri == NULL) return(NULL);
pkey=ret.data.pkey;
#endif
if (pkey == NULL)
{
}
if (ri == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
return(NULL);
}
}
jj=EVP_PKEY_size(pkey);
tmp=Malloc(jj+10);
if (tmp == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_MALLOC_FAILURE);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -404,7 +393,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
pkey);
if (jj <= 0)
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_EVP_LIB);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
goto err;
}
@@ -416,7 +405,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
if (jj != EVP_CIPHER_CTX_key_length(evp_ctx))
{
PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
goto err;
}
EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0);