diff options
Diffstat (limited to 'crypto/pkcs7')
-rw-r--r-- | crypto/pkcs7/pk7_doit.c | 1 | ||||
-rw-r--r-- | crypto/pkcs7/pk7_mime.c | 2 | ||||
-rw-r--r-- | crypto/pkcs7/pk7_smime.c | 45 | ||||
-rw-r--r-- | crypto/pkcs7/pkcs7.h | 3 | ||||
-rw-r--r-- | crypto/pkcs7/pkcs7err.c | 2 |
5 files changed, 51 insertions, 2 deletions
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 0b441fe071..157cf193bd 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -854,7 +854,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) EVP_MD_CTX_cleanup(&mctx); ASN1_STRING_set0(si->enc_digest, abuf, siglen); - abuf = NULL; return 1; diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c index 134746c186..c0edb07861 100644 --- a/crypto/pkcs7/pk7_mime.c +++ b/crypto/pkcs7/pk7_mime.c @@ -204,7 +204,7 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) msg_type = "enveloped-data"; else if (PKCS7_type_is_signed(p7)) { - /* If we have any signers it is signed-data othewise + /* If we have any signers it is signed-data otherwise * certs-only. */ STACK_OF(PKCS7_SIGNER_INFO) *sinfos; diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index e09fb38dc5..28ec531dca 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -63,6 +63,8 @@ #include <openssl/x509.h> #include <openssl/x509v3.h> +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); + PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags) { @@ -198,6 +200,14 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, || !PKCS7_add_attrib_smimecap (si, smcap)) goto err; sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + smcap = NULL; + } + if (flags & PKCS7_REUSE_DIGEST) + { + if (!pkcs7_copy_existing_digest(p7, si)) + goto err; + if (!PKCS7_SIGNER_INFO_sign(si)) + goto err; } } return si; @@ -209,6 +219,41 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, return NULL; } +/* Search for a digest matching SignerInfo digest type and if found + * copy across. + */ + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) + { + int i; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *sitmp; + ASN1_OCTET_STRING *osdig = NULL; + sinfos = PKCS7_get_signer_info(p7); + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) + { + sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + if (si == sitmp) + break; + if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) + continue; + if (!OBJ_cmp(si->digest_alg->algorithm, + sitmp->digest_alg->algorithm)) + { + osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); + break; + } + + } + + if (osdig) + return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); + + PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, + PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + return 0; + } + int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags) { diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h index 7d31b689a7..581dfb13cc 100644 --- a/crypto/pkcs7/pkcs7.h +++ b/crypto/pkcs7/pkcs7.h @@ -270,6 +270,7 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_STREAM 0x1000 #define PKCS7_NOCRL 0x2000 #define PKCS7_PARTIAL 0x4000 +#define PKCS7_REUSE_DIGEST 0x8000 /* Flags: for compatibility with older code */ @@ -412,6 +413,7 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_F_PKCS7_ADD_SIGNATURE 131 #define PKCS7_F_PKCS7_ADD_SIGNER 103 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 #define PKCS7_F_PKCS7_CTRL 104 #define PKCS7_F_PKCS7_DATADECODE 112 #define PKCS7_F_PKCS7_DATAFINAL 128 @@ -462,6 +464,7 @@ void ERR_load_PKCS7_strings(void); #define PKCS7_R_NO_CONTENT 122 #define PKCS7_R_NO_CONTENT_TYPE 135 #define PKCS7_R_NO_DEFAULT_DIGEST 151 +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 #define PKCS7_R_NO_MULTIPART_BOUNDARY 137 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c index 9b2bec9650..e1e9add19a 100644 --- a/crypto/pkcs7/pkcs7err.c +++ b/crypto/pkcs7/pkcs7err.c @@ -81,6 +81,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]= {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"}, {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, +{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), "PKCS7_COPY_EXISTING_DIGEST"}, {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_CTRL"}, {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, @@ -134,6 +135,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"}, {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"}, {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) ,"no default digest"}, +{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"}, {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"}, |