Allow PKCS7_decrypt() to work if no cert supplied.
This commit is contained in:
parent
984aefe0e8
commit
1682e8fb12
6 changed files with 66 additions and 21 deletions
5
CHANGES
5
CHANGES
|
@ -4,7 +4,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]
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"},
|
||||
|
|
Loading…
Reference in a new issue