Modify S/MIME application so the -signer option writes the signer(s)
authorDr. Stephen Henson <steve@openssl.org>
Tue, 7 Dec 1999 02:35:52 +0000 (02:35 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 7 Dec 1999 02:35:52 +0000 (02:35 +0000)
to a file if we are verifying.

apps/smime.c
crypto/pkcs7/pk7_smime.c
crypto/pkcs7/pkcs7.h
crypto/pkcs7/pkcs7err.c

index 75087ea..0d713a5 100644 (file)
@@ -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;
+}
+       
index 58bf2d7..3f6cad4 100644 (file)
@@ -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,
index d30a05b..7369e32 100644 (file)
@@ -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
index a6c1ce9..d0a1f59 100644 (file)
@@ -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"},