summaryrefslogtreecommitdiffstats
path: root/crypto/pkcs7
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-05-08 16:38:19 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-05-08 16:38:19 +0000
commit7144c4212a18e01bf805169ad1f3fdd885975759 (patch)
tree1d4bdb9c3e7b8347bb610b361aa437174cbd345a /crypto/pkcs7
parent399a6f0bd179960209df83b548ba5869acfdab86 (diff)
Update PKCS#7 decrypt routines to use new API.
Diffstat (limited to 'crypto/pkcs7')
-rw-r--r--crypto/pkcs7/pk7_doit.c110
-rw-r--r--crypto/pkcs7/pkcs7.h1
-rw-r--r--crypto/pkcs7/pkcs7err.c1
3 files changed, 78 insertions, 34 deletions
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 026dd540d6..a3c8baf466 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -197,6 +197,61 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
}
+int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
+ PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+ {
+ EVP_PKEY_CTX *pctx = NULL;
+ unsigned char *ek = NULL;
+ int eklen;
+
+ int ret = 0;
+
+ pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!pctx)
+ return 0;
+
+ if (EVP_PKEY_decrypt_init(pctx) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+ EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
+ goto err;
+ }
+
+ if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+ ri->enc_key->data, ri->enc_key->length) <= 0)
+ goto err;
+
+ ek = OPENSSL_malloc(eklen);
+
+ if (ek == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+ ri->enc_key->data, ri->enc_key->length) <= 0)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ ret = 1;
+
+ *pek = ek;
+ *peklen = eklen;
+
+ err:
+ if (pctx)
+ EVP_PKEY_CTX_free(pctx);
+ if (!ret && ek)
+ OPENSSL_free(ek);
+
+ return ret;
+ }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
@@ -347,7 +402,6 @@ 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;
- unsigned char *tmp=NULL;
X509_ALGOR *xa;
ASN1_OCTET_STRING *data_body=NULL;
const EVP_MD *evp_md;
@@ -437,7 +491,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
int max;
X509_OBJECT ret;
#endif
- int jj;
+ unsigned char *ek = NULL;
+ int eklen;
if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
{
@@ -452,26 +507,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
* (if any)
*/
- if (pcert) {
- for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ if (pcert)
+ {
+ for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+ {
ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
if (!pkcs7_cmp_ri(ri, pcert))
break;
ri=NULL;
- }
- if (ri == NULL) {
+ }
+ if (ri == NULL)
+ {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
goto err;
- }
- }
-
- jj=EVP_PKEY_size(pkey);
- tmp=(unsigned char *)OPENSSL_malloc(jj+10);
- if (tmp == NULL)
- {
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
- goto err;
+ }
}
/* If we haven't got a certificate try each ri in turn */
@@ -481,11 +531,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
{
ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
- jj=EVP_PKEY_decrypt_old(tmp,
- M_ASN1_STRING_data(ri->enc_key),
- M_ASN1_STRING_length(ri->enc_key),
- pkey);
- if (jj > 0)
+ if (pkcs7_decrypt_rinfo(&ek, &eklen,
+ ri, pkey) > 0)
break;
ERR_clear_error();
ri = NULL;
@@ -499,15 +546,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
}
else
{
- jj=EVP_PKEY_decrypt_old(tmp,
- M_ASN1_STRING_data(ri->enc_key),
- M_ASN1_STRING_length(ri->enc_key), pkey);
- if (jj <= 0)
- {
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
- ERR_R_EVP_LIB);
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
goto err;
- }
}
evp_ctx=NULL;
@@ -517,22 +557,26 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
goto err;
- if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+ if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
/* Some S/MIME clients don't use the same key
* and effective key length. The key length is
* determined by the size of the decrypted RSA key.
*/
- if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
+ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
{
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
goto err;
}
}
- if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
+ if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
goto err;
- OPENSSL_cleanse(tmp,jj);
+ if (ek)
+ {
+ OPENSSL_cleanse(ek,eklen);
+ OPENSSL_free(ek);
+ }
if (out == NULL)
out=etmp;
@@ -578,8 +622,6 @@ err:
if (bio != NULL) BIO_free_all(bio);
out=NULL;
}
- if (tmp != NULL)
- OPENSSL_free(tmp);
return(out);
}
diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
index 9867753fea..398c527606 100644
--- a/crypto/pkcs7/pkcs7.h
+++ b/crypto/pkcs7/pkcs7.h
@@ -404,6 +404,7 @@ void ERR_load_PKCS7_strings(void);
#define PKCS7_F_PKCS7_DATASIGN 106
#define PKCS7_F_PKCS7_DATAVERIFY 107
#define PKCS7_F_PKCS7_DECRYPT 114
+#define PKCS7_F_PKCS7_DECRYPT_RINFO 133
#define PKCS7_F_PKCS7_ENCODE_RINFO 132
#define PKCS7_F_PKCS7_ENCRYPT 115
#define PKCS7_F_PKCS7_FIND_DIGEST 127
diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c
index e6eb206d02..198a149fc1 100644
--- a/crypto/pkcs7/pkcs7err.c
+++ b/crypto/pkcs7/pkcs7err.c
@@ -86,6 +86,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"},
{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
+{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"},
{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"},
{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"},