diff --git a/CHANGES b/CHANGES index 7a7ca266e0a98f53eb92796746768b999610bc50..614348b8c4d532d7cb1f281d98570519ad194fd4 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 253cca7f59ba11094fb995f06b35b7ddd43ba466..250fd69a981b0a95913c39661c7e5394eb7bba1a 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 f0f80a72fc8d313bbc806d54e9b607e11fa87bb5..a4bbba0556c657314b2d6fb9e8dfca43e713b4db 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 b6146d75c4176d1956388d27b623ab12f3a9eb20..1f4a0a17952fa7cc03994bbc5d8f0f515ffe183a 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 952f37960e8c915ef50daa19e5c01167ab65c5e6..cc092d262dc313e827751990c3d42191b30bf954 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 309664d3829169e44fbcb3d6450a5e38443c5542..4cd293472ff2eb9571dd54f6a96f249f93a81f6d 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"},