From 8f2e4fdf860705a0d6868daba187e055781f7755 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 4 Aug 2005 22:15:22 +0000 Subject: [PATCH] Allow PKCS7_decrypt() to work if no cert supplied. --- CHANGES | 5 ++- apps/smime.c | 4 +-- crypto/pkcs7/pk7_doit.c | 74 +++++++++++++++++++++++++++++++--------- crypto/pkcs7/pk7_smime.c | 2 +- crypto/pkcs7/pkcs7.h | 1 + crypto/pkcs7/pkcs7err.c | 1 + 6 files changed, 66 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 7a7ca266e0..614348b8c4 100644 --- a/CHANGES +++ b/CHANGES @@ -14,7 +14,10 @@ Changes between 0.9.8 and 0.9.8a [XX xxx XXXX] - *) + *) Make PKCS7_decrypt() work even if no certificate is supplied by + attempting to decrypt each encrypted key in turn. Add support to + smime utility. + [Steve Henson] Changes between 0.9.7h and 0.9.8 [05 Jul 2005] diff --git a/apps/smime.c b/apps/smime.c index 253cca7f59..250fd69a98 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -384,9 +384,9 @@ int MAIN(int argc, char **argv) } else if (operation == SMIME_DECRYPT) { - if (!recipfile) + if (!recipfile && !keyfile) { - BIO_printf(bio_err, "No recipient certificate and key specified\n"); + BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index f0f80a72fc..a4bbba0556 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -62,6 +62,7 @@ #include #include #include +#include static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value); @@ -307,6 +308,17 @@ err: return(out); } +static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) + { + int ret; + ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, + pcert->cert_info->issuer); + if (ret) + return ret; + return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + ri->issuer_and_serial->serial); + } + /* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { @@ -417,18 +429,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) * (if any) */ - for (i=0; iissuer_and_serial->issuer, - pcert->cert_info->issuer) && - !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, - ri->issuer_and_serial->serial)) break; - ri=NULL; - } - if (ri == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); - goto err; + if (pcert) { + for (i=0; ienc_key), - M_ASN1_STRING_length(ri->enc_key), pkey); - if (jj <= 0) + /* If we haven't got a certificate try each ri in turn */ + + if (pcert == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); - goto err; + for (i=0; ienc_key), + M_ASN1_STRING_length(ri->enc_key), + pkey); + if (jj > 0) + break; + ERR_clear_error(); + ri = NULL; + } + if (ri == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_NO_RECIPIENT_MATCHES_KEY); + goto err; + } + } + else + { + jj=EVP_PKEY_decrypt(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); + goto err; + } } evp_ctx=NULL; diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index b6146d75c4..1f4a0a1795 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -441,7 +441,7 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) return 0; } - if(!X509_check_private_key(cert, pkey)) { + if(cert && !X509_check_private_key(cert, pkey)) { PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return 0; diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h index 952f37960e..cc092d262d 100644 --- a/crypto/pkcs7/pkcs7.h +++ b/crypto/pkcs7/pkcs7.h @@ -432,6 +432,7 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 #define PKCS7_R_NO_MULTIPART_BOUNDARY 137 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 #define PKCS7_R_NO_SIGNATURES_ON_DATA 123 #define PKCS7_R_NO_SIGNERS 142 #define PKCS7_R_NO_SIG_CONTENT_TYPE 138 diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c index 309664d382..4cd293472f 100644 --- a/crypto/pkcs7/pkcs7err.c +++ b/crypto/pkcs7/pkcs7err.c @@ -124,6 +124,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"}, +{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY),"no recipient matches key"}, {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA),"no signatures on data"}, {ERR_REASON(PKCS7_R_NO_SIGNERS) ,"no signers"}, {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"}, -- 2.34.1