Modify S/MIME application so the -signer option writes the signer(s)
to a file if we are verifying.
This commit is contained in:
parent
5a9a4b299c
commit
55ec5861c8
27
apps/smime.c
27
apps/smime.c
@ -70,6 +70,7 @@ static X509 *load_cert(char *file);
|
|||||||
static EVP_PKEY *load_key(char *file);
|
static EVP_PKEY *load_key(char *file);
|
||||||
static STACK_OF(X509) *load_certs(char *file);
|
static STACK_OF(X509) *load_certs(char *file);
|
||||||
static X509_STORE *setup_verify(char *CAfile, char *CApath);
|
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_OP 0x10
|
||||||
#define SMIME_ENCRYPT (1 | SMIME_OP)
|
#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))) {
|
if(!(signer = load_cert(signerfile))) {
|
||||||
BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
|
BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
|
||||||
goto end;
|
goto end;
|
||||||
@ -276,7 +277,7 @@ int MAIN(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(recipfile) {
|
if(recipfile && (operation == SMIME_DECRYPT)) {
|
||||||
if(!(recip = load_cert(recipfile))) {
|
if(!(recip = load_cert(recipfile))) {
|
||||||
BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
|
BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
|
||||||
ERR_print_errors(bio_err);
|
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");
|
BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
|
||||||
else ret = 0;
|
else ret = 0;
|
||||||
} else if(operation == SMIME_VERIFY) {
|
} 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)) {
|
if(PKCS7_verify(p7, other, store, indata, out, flags)) {
|
||||||
BIO_printf(bio_err, "Verification Successful\n");
|
BIO_printf(bio_err, "Verification Successful\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -348,6 +351,12 @@ int MAIN(int argc, char **argv)
|
|||||||
BIO_printf(bio_err, "Verification Failure\n");
|
BIO_printf(bio_err, "Verification Failure\n");
|
||||||
ret = 5;
|
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) {
|
} else if(operation == SMIME_PK7OUT) {
|
||||||
PEM_write_bio_PKCS7(out, p7);
|
PEM_write_bio_PKCS7(out, p7);
|
||||||
} else {
|
} else {
|
||||||
@ -444,3 +453,17 @@ static X509_STORE *setup_verify(char *CAfile, char *CApath)
|
|||||||
X509_STORE_free(store);
|
X509_STORE_free(store);
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -144,14 +144,13 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
|||||||
X509 *signer;
|
X509 *signer;
|
||||||
STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
|
STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
|
||||||
PKCS7_SIGNER_INFO *si;
|
PKCS7_SIGNER_INFO *si;
|
||||||
PKCS7_ISSUER_AND_SERIAL *ias;
|
|
||||||
X509_STORE_CTX cert_ctx;
|
X509_STORE_CTX cert_ctx;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
int i, j=0;
|
int i, j=0;
|
||||||
BIO *p7bio;
|
BIO *p7bio;
|
||||||
BIO *tmpout;
|
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);
|
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -176,34 +175,9 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!(signers = sk_X509_new(NULL))) {
|
signers = PKCS7_iget_signers(p7, certs, flags);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(!signers) return 0;
|
||||||
|
|
||||||
/* Now verify the certificates */
|
/* Now verify the certificates */
|
||||||
|
|
||||||
@ -281,6 +255,57 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
|||||||
return 0;
|
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 */
|
/* Build a complete PKCS#7 enveloped data */
|
||||||
|
|
||||||
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
|
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
|
||||||
|
@ -396,6 +396,7 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
|||||||
BIO *data, int flags);
|
BIO *data, int flags);
|
||||||
int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||||
BIO *indata, BIO *out, int flags);
|
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,
|
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
|
||||||
int flags);
|
int flags);
|
||||||
int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, 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_DATAVERIFY 107
|
||||||
#define PKCS7_F_PKCS7_DECRYPT 114
|
#define PKCS7_F_PKCS7_DECRYPT 114
|
||||||
#define PKCS7_F_PKCS7_ENCRYPT 115
|
#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_CIPHER 108
|
||||||
#define PKCS7_F_PKCS7_SET_CONTENT 109
|
#define PKCS7_F_PKCS7_SET_CONTENT 109
|
||||||
#define PKCS7_F_PKCS7_SET_TYPE 110
|
#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_MULTIPART_BOUNDARY 137
|
||||||
#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
|
#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
|
||||||
#define PKCS7_R_NO_SIGNATURES_ON_DATA 123
|
#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_NO_SIG_CONTENT_TYPE 138
|
||||||
#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
|
#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
|
||||||
#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
|
#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
|
||||||
|
@ -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_DATAVERIFY,0), "PKCS7_dataVerify"},
|
||||||
{ERR_PACK(0,PKCS7_F_PKCS7_DECRYPT,0), "PKCS7_decrypt"},
|
{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_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_CIPHER,0), "PKCS7_set_cipher"},
|
||||||
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
|
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
|
||||||
{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
|
{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_MULTIPART_BOUNDARY ,"no multipart boundary"},
|
||||||
{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
|
{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
|
||||||
{PKCS7_R_NO_SIGNATURES_ON_DATA ,"no signatures on data"},
|
{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_NO_SIG_CONTENT_TYPE ,"no sig content type"},
|
||||||
{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this 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"},
|
{PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR ,"pkcs7 add signature error"},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user