summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2005-08-04 22:15:22 +0000
committerDr. Stephen Henson <steve@openssl.org>2005-08-04 22:15:22 +0000
commit8f2e4fdf860705a0d6868daba187e055781f7755 (patch)
tree06480b418e5bcdebb679dc169642099232bcd0b8
parent11de71b04c750e6be6f5e8ac875655a2a67efaf7 (diff)
Allow PKCS7_decrypt() to work if no cert supplied.
-rw-r--r--CHANGES5
-rw-r--r--apps/smime.c4
-rw-r--r--crypto/pkcs7/pk7_doit.c74
-rw-r--r--crypto/pkcs7/pk7_smime.c2
-rw-r--r--crypto/pkcs7/pkcs7.h1
-rw-r--r--crypto/pkcs7/pkcs7err.c1
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 <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include <openssl/err.h>
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; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
- ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
- if(!X509_NAME_cmp(ri->issuer_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; 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) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+ goto err;
+ }
}
jj=EVP_PKEY_size(pkey);
@@ -439,12 +451,40 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
goto err;
}
- jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_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; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+ {
+ ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+ jj=EVP_PKEY_decrypt(tmp,
+ M_ASN1_STRING_data(ri->enc_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"},