diff options
-rw-r--r-- | apps/smime.c | 27 | ||||
-rw-r--r-- | crypto/pkcs7/pk7_smime.c | 83 | ||||
-rw-r--r-- | crypto/pkcs7/pkcs7.h | 3 | ||||
-rw-r--r-- | crypto/pkcs7/pkcs7err.c | 2 |
4 files changed, 84 insertions, 31 deletions
diff --git a/apps/smime.c b/apps/smime.c index 75087ea68f..0d713a52b5 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -70,6 +70,7 @@ static X509 *load_cert(char *file); static EVP_PKEY *load_key(char *file); static STACK_OF(X509) *load_certs(char *file); static X509_STORE *setup_verify(char *CAfile, char *CApath); +static int save_certs(char *signerfile, STACK_OF(X509) *signers); #define SMIME_OP 0x10 #define SMIME_ENCRYPT (1 | SMIME_OP) @@ -261,7 +262,7 @@ int MAIN(int argc, char **argv) } } - if(signerfile) { + if(signerfile && (operation == SMIME_SIGN)) { if(!(signer = load_cert(signerfile))) { BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); goto end; @@ -276,7 +277,7 @@ int MAIN(int argc, char **argv) } } - if(recipfile) { + if(recipfile && (operation == SMIME_DECRYPT)) { if(!(recip = load_cert(recipfile))) { BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); ERR_print_errors(bio_err); @@ -341,6 +342,8 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); else ret = 0; } else if(operation == SMIME_VERIFY) { + STACK_OF(X509) *signers; + signers = PKCS7_iget_signers(p7, other, flags); if(PKCS7_verify(p7, other, store, indata, out, flags)) { BIO_printf(bio_err, "Verification Successful\n"); ret = 0; @@ -348,6 +351,12 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Verification Failure\n"); ret = 5; } + if(!save_certs(signerfile, signers)) { + BIO_printf(bio_err, "Error writing signers to %s\n", + signerfile); + ret = 2; + } + sk_X509_free(signers); } else if(operation == SMIME_PK7OUT) { PEM_write_bio_PKCS7(out, p7); } else { @@ -444,3 +453,17 @@ static X509_STORE *setup_verify(char *CAfile, char *CApath) X509_STORE_free(store); return NULL; } + +int save_certs(char *signerfile, STACK_OF(X509) *signers) +{ + int i; + BIO *tmp; + if(!signerfile) return 1; + tmp = BIO_new_file(signerfile, "w"); + if(!tmp) return 0; + for(i = 0; i < sk_X509_num(signers); i++) + PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); + BIO_free(tmp); + return 1; +} + diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 58bf2d7d28..3f6cad44f8 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -144,14 +144,13 @@ 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) { + if(!PKCS7_type_is_signed(p7)) { PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); return 0; } @@ -176,34 +175,9 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, } - if(!(signers = sk_X509_new(NULL))) { - PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); - 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 +255,57 @@ 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(!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, diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h index d30a05bd2e..7369e324d7 100644 --- a/crypto/pkcs7/pkcs7.h +++ b/crypto/pkcs7/pkcs7.h @@ -396,6 +396,7 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_iget_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher, int flags); int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); @@ -431,6 +432,7 @@ int SMIME_text(BIO *in, BIO *out); #define PKCS7_F_PKCS7_DATAVERIFY 107 #define PKCS7_F_PKCS7_DECRYPT 114 #define PKCS7_F_PKCS7_ENCRYPT 115 +#define PKCS7_F_PKCS7_IGET_SIGNERS 124 #define PKCS7_F_PKCS7_SET_CIPHER 108 #define PKCS7_F_PKCS7_SET_CONTENT 109 #define PKCS7_F_PKCS7_SET_TYPE 110 @@ -463,6 +465,7 @@ int SMIME_text(BIO *in, BIO *out); #define PKCS7_R_NO_MULTIPART_BOUNDARY 137 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 #define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +#define PKCS7_R_NO_SIGNERS 142 #define PKCS7_R_NO_SIG_CONTENT_TYPE 138 #define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 #define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c index a6c1ce98fe..d0a1f599ab 100644 --- a/crypto/pkcs7/pkcs7err.c +++ b/crypto/pkcs7/pkcs7err.c @@ -79,6 +79,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]= {ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"}, {ERR_PACK(0,PKCS7_F_PKCS7_DECRYPT,0), "PKCS7_decrypt"}, {ERR_PACK(0,PKCS7_F_PKCS7_ENCRYPT,0), "PKCS7_encrypt"}, +{ERR_PACK(0,PKCS7_F_PKCS7_IGET_SIGNERS,0), "PKCS7_iget_signers"}, {ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"}, {ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"}, {ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"}, @@ -114,6 +115,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {PKCS7_R_NO_MULTIPART_BOUNDARY ,"no multipart boundary"}, {PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"}, {PKCS7_R_NO_SIGNATURES_ON_DATA ,"no signatures on data"}, +{PKCS7_R_NO_SIGNERS ,"no signers"}, {PKCS7_R_NO_SIG_CONTENT_TYPE ,"no sig content type"}, {PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"}, {PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR ,"pkcs7 add signature error"}, |