X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_smime.c;h=04489380b8f22d0634958ab91ca9fd52f518bcd4;hp=58bf2d7d288cdd994dba02032fcfa9aeff286ec1;hb=b216664f666fa6c6371d1de0f6dd6292472e7f1e;hpb=5a9a4b299c0140ccdd5cc61fef701935a5931842 diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 58bf2d7d28..04489380b8 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -115,12 +115,16 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, } #ifndef NO_DES PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1); - PKCS7_simple_smimecap (smcap, NID_des_cbc, -1); #endif #ifndef NO_RC2 - PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40); PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128); PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64); +#endif +#ifndef NO_DES + PKCS7_simple_smimecap (smcap, NID_des_cbc, -1); +#endif +#ifndef NO_RC2 + PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40); #endif PKCS7_add_attrib_smimecap (si, smcap); sk_pop_free(smcap, X509_ALGOR_free); @@ -144,21 +148,25 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, X509 *signer; STACK_OF(PKCS7_SIGNER_INFO) *sinfos; PKCS7_SIGNER_INFO *si; - PKCS7_ISSUER_AND_SERIAL *ias; X509_STORE_CTX cert_ctx; char buf[4096]; int i, j=0; BIO *p7bio; BIO *tmpout; - if(OBJ_obj2nid(p7->type) != NID_pkcs7_signed) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); + if(!p7) { + PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if(!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); return 0; } /* Check for no data and no content: no data to verify signature */ if(PKCS7_get_detached(p7) && !indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT); + PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT); return 0; } @@ -171,39 +179,14 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, sinfos = PKCS7_get_signer_info(p7); if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA); - return 0; - } - - - if(!(signers = sk_X509_new(NULL))) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); + PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA); return 0; } - /* Collect all the signers together */ - - for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) - { - si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); - ias = si->issuer_and_serial; - signer = NULL; - /* If any certificates passed they take priority */ - if (certs) signer = X509_find_by_issuer_and_serial (certs, - ias->issuer, ias->serial); - if (!signer && !(flags & PKCS7_NOINTERN) - && p7->d.sign->cert) signer = - X509_find_by_issuer_and_serial (p7->d.sign->cert, - ias->issuer, ias->serial); - if (!signer) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); - sk_X509_free(signers); - return 0; - } - sk_X509_push(signers, signer); - } + signers = PKCS7_iget_signers(p7, certs, flags); + if(!signers) return 0; /* Now verify the certificates */ @@ -281,6 +264,62 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, return 0; } +STACK_OF(X509) *PKCS7_iget_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) +{ + STACK_OF(X509) *signers; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + PKCS7_ISSUER_AND_SERIAL *ias; + X509 *signer; + int i; + + if(!p7) { + PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if(!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); + return NULL; + } + if(!(signers = sk_X509_new(NULL))) { + PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Collect all the signers together */ + + sinfos = PKCS7_get_signer_info(p7); + + if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { + PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_NO_SIGNERS); + return 0; + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) + { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + ias = si->issuer_and_serial; + signer = NULL; + /* If any certificates passed they take priority */ + if (certs) signer = X509_find_by_issuer_and_serial (certs, + ias->issuer, ias->serial); + if (!signer && !(flags & PKCS7_NOINTERN) + && p7->d.sign->cert) signer = + X509_find_by_issuer_and_serial (p7->d.sign->cert, + ias->issuer, ias->serial); + if (!signer) { + PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); + sk_X509_free(signers); + return 0; + } + + sk_X509_push(signers, signer); + } + return signers; +} + + /* Build a complete PKCS#7 enveloped data */ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher, @@ -351,10 +390,17 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) BIO *tmpmem; int ret, i; char buf[4096]; + + if(!p7) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + if(!PKCS7_type_is_enveloped(p7)) { PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE); return 0; } + if(!X509_check_private_key(cert, pkey)) { PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);