summaryrefslogtreecommitdiff
path: root/pith
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2015-12-05 02:14:13 -0700
committerEduardo Chappa <chappa@washington.edu>2015-12-05 02:14:13 -0700
commitc77ba26762d2f2fc9a978420ecd90cfafd50269e (patch)
treed6b5b0af730de62ba326e3c7b677d8d502d44a97 /pith
parent01170cfd3d5b6e5dfdc11c75f6e6740e8f938109 (diff)
downloadalpine-c77ba26762d2f2fc9a978420ecd90cfafd50269e.tar.xz
* Alpine will ask users if they wish to save S/MIME certificates included
in signatures, when the option "Validate Using Certificate Store Only" is enabled. If the user does not wish to save it, validation will fail.
Diffstat (limited to 'pith')
-rw-r--r--pith/options.h6
-rw-r--r--pith/pine.hlp14
-rw-r--r--pith/smime.c29
3 files changed, 37 insertions, 12 deletions
diff --git a/pith/options.h b/pith/options.h
index f35bcfa3..bdaa252c 100644
--- a/pith/options.h
+++ b/pith/options.h
@@ -234,4 +234,10 @@ extern int (*pith_smime_import_certificate)(char *, char *, size_t);
*/
extern int (*pith_smime_enter_password)(char *, char *, size_t);
+/*
+ * required call to ask the user to confirm to save a certificate in the
+ * store
+ */
+extern int (*pith_smime_confirm_save)(char *);
+
#endif /* PITH_OPTIONS_INCLUDED */
diff --git a/pith/pine.hlp b/pith/pine.hlp
index 64216fcb..b5507329 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any
reasonable place to be called from.
Dummy change to get revision in pine.hlp
============= h_revision =================
-Alpine Commit 112 2015-11-18 09:02:07
+Alpine Commit 113 2015-12-05 02:13:57
============= h_news =================
<HTML>
<HEAD>
@@ -221,6 +221,11 @@ Additions include:
<LI> SMIME: sort certificates by some type of alphabetical order in the
displayed name.
+ <LI> SMIME: Alpine will ask users if they wish to save S/MIME
+ certificates included in signatures, when the option "Validate
+ Using Certificate Store Only" is enabled. If the user does not wish
+ to save it, validation will fail.
+
<LI> HTML: Add support for decoding entities in hexadecimal notation.
Suggested by Tulip&aacute;nt Gergely.
@@ -34953,7 +34958,12 @@ either use the certificates that come in the message, or the ones that
you have personally stored. If this feature is enabled (the default) then
Alpine will use certificates that you have already saved in your store
and not those that come in the message to validate the sender of the
-message. This behavior helps you prevent against impersonation, because
+message. In particular, the first time that you receive a signed message
+from a sender, and their certificate does not validate against your
+store, then you will be asked if you wish to save such certificate. If
+you do not wish to save the certificate, then Alpine will fail to validate
+the signature of the message. Otherwise, Alpine will proceed to validate
+the signature of the message. This behavior helps you prevent against impersonation, because
it is assumed that you trust the certificates that you have saved, and
might not trust those that came with the message that you are validating.
<P>
diff --git a/pith/smime.c b/pith/smime.c
index 01e0df09..30f42a22 100644
--- a/pith/smime.c
+++ b/pith/smime.c
@@ -71,7 +71,7 @@ static int copy_container_to_dir(WhichCerts which);
static int do_fiddle_smime_message(BODY *b, long msgno, char *section);
void setup_privatekey_storage(void);
int smime_path(char *rpath, char *fpath, size_t len);
-int smime_extract_and_save_cert(PKCS7 *p7);
+int smime_extract_and_save_cert(PKCS7 *p7, int check_cert);
int same_cert(X509 *, X509 *);
CertList * certlist_from_personal_certs(PERSONAL_CERT *pc);
#ifdef PASSFILE
@@ -85,6 +85,7 @@ int smime_validate_extra_test(char *mimetext, unsigned long mimelen, char
int (*pith_opt_smime_get_passphrase)(void);
int (*pith_smime_import_certificate)(char *, char *, size_t);
int (*pith_smime_enter_password)(char *prompt, char *, size_t);
+int (*pith_smime_confirm_save)(char *email);
static X509_STORE *s_cert_store;
@@ -2478,12 +2479,13 @@ int same_cert(X509 *x, X509 *cert)
* < 0 - certificate error is not recoverable, don't even think about it.
*/
-int smime_extract_and_save_cert(PKCS7 *p7)
+int smime_extract_and_save_cert(PKCS7 *p7, int check_cert)
{
STACK_OF(X509) *signers;
X509 *x, *cert;
char **email;
int i, j;
+ long error;
if((signers = PKCS7_get0_signers(p7, NULL, 0)) == NULL)
return -1;
@@ -2495,10 +2497,15 @@ int smime_extract_and_save_cert(PKCS7 *p7)
if((email = get_x509_subject_email(x)) != NULL){
for(j = 0; email[j] != NULL; j++){
if((cert = get_cert_for(email[j], Public)) == NULL
- || same_cert(x, cert) == 0)
- save_cert_for(email[j], x, Public);
- X509_free(cert);
- fs_give((void **) &email[i]);
+ || same_cert(x, cert) == 0){
+ if(check_cert == 0
+ || smime_validate_cert(x, &error) == 0
+ || (*pith_smime_confirm_save)(email[j]) == 1)
+ save_cert_for(email[j], x, Public);
+ }
+ if(cert != NULL)
+ X509_free(cert);
+ fs_give((void **) &email[j]);
}
fs_give((void **) email);
}
@@ -2521,8 +2528,7 @@ do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent)
{
STACK_OF(X509) *otherCerts = NULL;
CertList *cl;
- int result;
- int flags;
+ int result, flags;
const char *data;
long err;
@@ -2533,8 +2539,6 @@ do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent)
return -1;
}
- smime_extract_and_save_cert(p7);
-
flags = F_ON(F_USE_CERT_STORE_ONLY, ps_global) ? PKCS7_NOINTERN : 0;
if(ps_global->smime->publiccertlist == NULL){
@@ -2773,6 +2777,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
PART *p;
int result, modified_the_body = 0;
int flag; /* 1 silent, 0 not silent */
+ int saved = 0;
unsigned long mimelen, bodylen;
char newSec[100], *mimetext, *bodytext;
char *what_we_did;
@@ -2816,6 +2821,10 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
BIO_write(in, mimetext, mimelen);
BIO_write(in, bodytext, bodylen);
+ saved = smime_extract_and_save_cert(p7, F_ON(F_USE_CERT_STORE_ONLY, ps_global));
+ if(saved < 0 && F_ON(F_USE_CERT_STORE_ONLY, ps_global))
+ return modified_the_body;
+
if((result = do_signature_verify(p7, in, NULL, 1)) == 0){
flag = (mimelen == 0 || !IS_REMOTE(ps_global->mail_stream->mailbox))
? 0 : 1;