diff options
author | Eduardo Chappa <chappa@washington.edu> | 2014-05-02 19:04:29 -0600 |
---|---|---|
committer | Eduardo Chappa <chappa@washington.edu> | 2014-05-02 19:04:29 -0600 |
commit | 223b392e8d40a0622936403d1da5eaf0cdd54d60 (patch) | |
tree | 05858ceae7dea53c9e97c205ce524a112f41723e | |
parent | 0d1e49834f4c3005b2b92a4ce8a03bd395d2fb1e (diff) | |
download | alpine-223b392e8d40a0622936403d1da5eaf0cdd54d60.tar.xz |
* Create help for explaining how encrypted password file support
works.
* When a message is sent encrypted, add the sender certificate so that
the sender can decrypt it too.
* When a message is signed and encrypted, first sign it and then encrypt
it. This changes the usual order of encrypting and then signing, and it has
the shortcoming of making bigger messages. However, this is the way that
most clients work with S/MIME, and so for compatibility with other programs,
we will send signed, then encrypted, instead of encrypted, then signed.
Hmm... should we sign the encrypted part?
* Avoid the first RSET smtp command, as this causes delays in some evily
managed servers.
-rw-r--r-- | imap/src/c-client/smtp.c | 5 | ||||
-rw-r--r-- | pith/pine.hlp | 125 | ||||
-rw-r--r-- | pith/send.c | 8 | ||||
-rw-r--r-- | pith/smime.c | 206 | ||||
-rw-r--r-- | po/Makefile.in | 2 |
5 files changed, 294 insertions, 52 deletions
diff --git a/imap/src/c-client/smtp.c b/imap/src/c-client/smtp.c index 47c7e5a6..1c72670c 100644 --- a/imap/src/c-client/smtp.c +++ b/imap/src/c-client/smtp.c @@ -437,10 +437,11 @@ long smtp_mail (SENDSTREAM *stream,char *type,ENVELOPE *env,BODY *body) (stream->netstream->dtb == (NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL)) ? "/ssl" : ""); - do { /* make sure stream is in good shape */ - smtp_send (stream,"RSET",NIL); + do { if (retry) { /* need to retry with authentication? */ NETMBX mb; + /* make sure stream is in good shape */ + smtp_send (stream,"RSET",NIL); /* yes, build remote name for authentication */ mail_valid_net_parse (smtpserver,&mb); if (!smtp_auth (stream,&mb,smtpserver)) return NIL; diff --git a/pith/pine.hlp b/pith/pine.hlp index 3e713d7d..b296f024 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 60 2014-04-25 18:02:23 +Alpine Commit 61 2014-05-02 18:29:37 ============= h_news ================= <HTML> <HEAD> @@ -184,17 +184,25 @@ Additions include: <LI> Upgrade UW-IMAP to Panda IMAP from <A HREF="https://github.com/jonabbey/panda-imap">https://github.com/jonabbey/panda-imap</A>. <LI> S/MIME: Add screen to manage certificates. - <LI> S/MIME: sign messages using intermediate certificates when needed and possible. - <LI> S/MIME: validation of certificates for servers that modify signed content. + <LI> S/MIME: sign messages using intermediate certificates when needed + and possible. + <LI> S/MIME: validation of certificates for servers that modify signed + content. + <LI> S/MIME: signed and encrypted messages will be signed first and + encrypted second, so that they can be decoded by other clients. + <LI> S/MIME: add the sender certificate to the list of certificates in + encrypted messages to make it possible for the sender to decrypt + the message they sent. <LI> Add support to selective expunge through a subcommand of the select-apply commands. Read more in the <A HREF="h_index_cmd_expunge">help</A> for the expunge command. <LI> Pico: New subcommand of the search command, allows to reverse the direction of search. - <LI> If a password file is defined, and S/MIME is enabled, the key and - certificate used to encrypt the password file are saved in - the ~/.alpine-smime/.pwd directory, or in the directory specified - by the -pwdcertdir command line option. + <LI> Unix Alpine: If a password file is defined, and S/MIME is enabled, + the key and certificate used to encrypt the password file are saved + in the ~/.alpine-smime/.pwd directory, or in the directory specified + by the -pwdcertdir command line option. + <A HREF="h_password_file_support">Learn more</A>. <LI> Add /tls1, /tls1_1, /tls1_2 and /dtls1 to the definition of a server to use different ways to connect using ssl, for example {server.com/tls1} will attempt to connect to @@ -217,6 +225,9 @@ Additions include: <LI> Experimental: Write the content-type of a message in lowercase, as some non-compliant servers do not understand uppercase content-type, such as those of GMX.de. + <LI> Experimental: Do not send the RSET command before attempting + to send a message, as this causes a delay in some evily managed + servers. <LI> Opening a folder updates recent count in maildrops (this already works for other types of folders) <LI> Automatically redraw screen after opening an attachment @@ -283,7 +294,7 @@ Bugs that have been addressed include: $alpine_TCLINC instead of $alpine_TCLINC/tcl.h. Reported and fixed by Werner Scheinast. <LI> Move SSL configurations from UW-IMAP to configure script, and - update OpenSSL configuration for mac OSX. + update OpenSSL configuration for Mac OSX. <LI> Remove -lregex from linker flags when building --with-supplied-regex. </UL> <P> @@ -719,6 +730,104 @@ or instead you can find the Apache License, version 2.0 at the web URL: <End of Release Notes> </BODY> </HTML> +====== h_password_file_support ====== +<HTML> +<HEAD> +<TITLE>Encryption for Password File Support Explained</TITLE> +</HEAD> +<BODY> +<H1>Encryption for Password File Support Explained</H1> + +Index<BR> +<OL> +<LI><A HREF="#content">Explanation</A> +<LI><A HREF="#example">Example</A> +</OL> + +<P><A NAME="content">Unix Alpine Only.</A> + +<P> If your version of Alpine has been built with password file support +then you can use a special file to save your passwords, and avoid typing +them every time you open a connection to a remote server. + +<P> If your version of Alpine was built with SMIME support, and you have a +public certificate/private key pair, then Alpine will use such pair to +encrypt your password file. If you have more than one key/certificate +pair, Alpine will pick the first pair that it finds that works. You can also +select a pair, and the way to do this is explained below. + +<P> Once a pair has been chosen, it will be copied to the directory +~/.alpine-smime/.pwd, and from then on, Alpine will use the pair found in +that directory. The first time this process is done, this directory will +be created, a key/certificate pair will be copied to it, and this pair +will be used in the future to encrypt and decrypt your password file. You +can create this directory and copy any key/certificate pair there. You +can add a self-signed certificate there, if you like, and you can let +this certificate expire. This will not affect the encryption and decryption +of the password file. + +<P> If you prefer not to use the directory ~/.alpine-smime/.pwd to save +your key/certificate pair, you can specify a different one with the +-pwdcertdir command line option in Alpine. If the directory specified by +this option is not found or there is no valid key/certificate pair there, +Alpine will fail to encrypt and decrypt your password file. In other words, +Alpine will not initialize this directory for you. + +<P> Alpine does not care about the names of the key and certificates in +this directory, but the private key must have ".key" extension +and your public certificate must have the ".crt" extension. The +name of the private key will be used in the prompt when you are asked +to unlock your key to decrypt your password. + +<P><A NAME="example">An example follows</A> + +<P>Assume you have a private key called peter@address.com.key in your, +~/.alpine-smime/private directory, and a public certificate called +peter@address.com.crt in your ~/.alpine-smime/public directory, and these +are your only key/certificate pair. + +<P> When Alpine starts for the first time, without command line options, +it will check if the directory ~/.alpine-smime/.pwd exists, and if not, +it will create it. Then it will go through your keys and certificates and +find a pair that it can use, and copy the files peter@address.com.key, +and peter@address.com.crt to the ~/.alpine-smime/.pwd directory. Alternatively +you can do the same by copying these files by yourself. This can be done +with the sequence of commands + +<PRE> +mkdir ~/.alpine-smime/.pwd +cp ~/.alpine-smime/private/peter@address.com.key ~/.alpine-smime/.pwd +cp ~/.alpine-smime/public/peter@address.com.crt ~/.alpine-smime/.pwd +</PRE> + +<P> When Alpine starts, you will be asked the password to unlock your +private key with the prompt. + +<PRE> +Enter password of key <peter@address.com> to unlock password file: +</PRE> + +<P> If you prefer to use different names for your private and public keys +in the ~/.alpine-smime/.pwd directory, you can do so, but you must +preserve the extension of the files. For example, you can use the names +private_key.key and public_cert.crt instead. In this case, the prompt you +will see when you are asked to unlock your private key will read + +<PRE> +Enter password of key <private_key> to unlock password file: +</PRE> + +<P>Observe that you do not need to use an existing key/certificate pair, +and that you can create a new private key/public certificate pair to +encrypt and decrypt your password. However, once one is used, Alpine does +not provide a mechanism to switch the encryption and decryption files to +another key/certificate pair. This will be implemented in a future +release of Alpine. + +<P> +<End of help> +</BODY> +</HTML> ====== h_tls_failure_details ====== <HTML> <HEAD> diff --git a/pith/send.c b/pith/send.c index bd99d49a..4620d1aa 100644 --- a/pith/send.c +++ b/pith/send.c @@ -1768,12 +1768,12 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve result = 1; - if(ps_global->smime->do_encrypt) - result = encrypt_outgoing_message(header, &body); + if(ps_global->smime->do_sign) + result = sign_outgoing_message(header, &body, 0); /* need to free new body from encrypt if sign fails? */ - if(result && ps_global->smime->do_sign) - result = sign_outgoing_message(header, &body, ps_global->smime->do_encrypt); + if(result && ps_global->smime->do_encrypt) + result = encrypt_outgoing_message(header, &body); lmc.so = so; diff --git a/pith/smime.c b/pith/smime.c index 566e2be5..ce7b6a70 100644 --- a/pith/smime.c +++ b/pith/smime.c @@ -56,18 +56,19 @@ static int load_private_key(PERSONAL_CERT *pcert); static void create_local_cache(char *h, char *base, BODY *b, int type); static long rfc822_output_func(void *b, char *string); static void setup_pkcs7_body_for_signature(BODY *b, char *description, - char *type, char *filename); + char *type, char *filename, char *smime_type); static BIO *body_to_bio(BODY *body); static BIO *bio_from_store(STORE_S *store); static STORE_S *get_part_contents(long msgno, const char *section); static PKCS7 *get_pkcs7_from_part(long msgno, const char *section); static int do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent); -static int do_detached_signature_verify(BODY *b, long msgno, char *section); +int do_detached_signature_verify(BODY *b, long msgno, char *section); static PERSONAL_CERT *find_certificate_matching_pkcs7(PKCS7 *p7); static int do_decoding(BODY *b, long msgno, const char *section); static void free_smime_struct(SMIME_STUFF_S **smime); static void setup_storage_locations(void); 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); @@ -89,6 +90,36 @@ static X509_STORE *s_cert_store; static int seeded = 0; static int egdsocket = 0; +typedef enum {P7Type, CharType, SizedText} SpareType; + +typedef struct smime_sparep_t { + SpareType sptype; + void *data; +} SMIME_SPARE_S; + +void * +create_smime_sparep(SpareType stype, void *s) +{ + SMIME_SPARE_S *rv; + + rv = fs_get(sizeof(SMIME_SPARE_S)); + rv->sptype = stype; + rv->data = s; + return (void *) rv; +} + +SpareType +get_smime_sparep_type(void *s) +{ + return ((SMIME_SPARE_S *)s)->sptype; +} + +void * +get_smime_sparep_data(void *s) +{ + return ((SMIME_SPARE_S *)s)->data; +} + #ifdef PASSFILE /* @@ -2041,7 +2072,7 @@ load_private_key(PERSONAL_CERT *pcert) static void -setup_pkcs7_body_for_signature(BODY *b, char *description, char *type, char *filename) +setup_pkcs7_body_for_signature(BODY *b, char *description, char *type, char *filename, char *smime_type) { b->type = TYPEAPPLICATION; b->subtype = cpystr(type); @@ -2052,6 +2083,8 @@ setup_pkcs7_body_for_signature(BODY *b, char *description, char *type, char *fil set_parameter(&b->disposition.parameter, "filename", filename); set_parameter(&b->parameter, "name", filename); + if(smime_type && *smime_type) + set_parameter(&b->parameter, "smime-type", smime_type); } @@ -2238,6 +2271,8 @@ encrypt_outgoing_message(METAENV *header, BODY **bodyP) BODY *body = *bodyP; BODY *newBody = NULL; int result = 0; + X509 *cert; + char buf[MAXPATH]; dprint((9, "encrypt_outgoing_message()")); smime_init(); @@ -2250,13 +2285,9 @@ encrypt_outgoing_message(METAENV *header, BODY **bodyP) for(pf = header->local; pf && pf->name; pf = pf->next) if(pf->type == Address && pf->rcptto && pf->addr && *pf->addr){ for(a=*pf->addr; a; a=a->next){ - X509 *cert; - char buf[MAXPATH]; - snprintf(buf, sizeof(buf), "%s@%s", a->mailbox, a->host); - cert = get_cert_for(buf, Public); - if(cert) + if((cert = get_cert_for(buf, Public)) != NULL) sk_X509_push(encerts,cert); else{ q_status_message2(SM_ORDER, 1, 1, @@ -2267,6 +2298,14 @@ encrypt_outgoing_message(METAENV *header, BODY **bodyP) } } + /* add the sender's certificate so that they can decrypt the message too */ + for(a=header->env->from; a ; a = a->next){ + snprintf(buf, sizeof(buf), "%s@%s", a->mailbox, a->host); + + if((cert = get_cert_for(buf, Public)) != NULL + && sk_X509_find(encerts, cert) == -1) + sk_X509_push(encerts,cert); + } in = body_to_bio(body); @@ -2491,12 +2530,74 @@ do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent) void free_smime_body_sparep(void **sparep) { + char *s; + SIZEDTEXT *st; if(sparep && *sparep){ - PKCS7_free((PKCS7 *) (*sparep)); - *sparep = NULL; + switch(get_smime_sparep_type(*sparep)){ + case P7Type: PKCS7_free((PKCS7 *) get_smime_sparep_data(*sparep)); + break; + case CharType: s = (char *)get_smime_sparep_data(*sparep); + fs_give((void **) &s); + break; + case SizedText : st = (SIZEDTEXT *)get_smime_sparep_data(*sparep); + fs_give((void **) &st->data); + fs_give((void **) &st); + break; + default : break; + } + ((SMIME_SPARE_S *)(*sparep))->data = NULL; + fs_give(sparep); } } +/* return the mime header for this body part. Memory freed by caller */ +char * +smime_fetch_mime(BODY *b, MAILSTREAM *stream, long msgno, char * section, + unsigned long *mimelen) +{ + char *rv; + char newSec[100]; + + if(b->type == TYPEMULTIPART) + snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : ""); + else + strncpy(newSec, section, sizeof(newSec)); + newSec[sizeof(newSec)-1] = '\0'; + rv = mail_fetch_mime(stream, msgno, newSec, mimelen, 0); + return rv ? cpystr(rv) : NULL; +} + + +void +smime_write_body_header(BODY *b, MAILSTREAM *stream, long msgno, char *section, soutr_t f, void *s) +{ + char *rv; + char newSec[100]; + + if(b->nested.part == NULL) + return; + + if(b->nested.part->body.type == TYPEMULTIPART) + snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : ""); + else + strncpy(newSec, section, sizeof(newSec)); + newSec[sizeof(newSec)-1] = '\0'; + rv = mail_fetch_mime(stream, msgno, newSec, NULL, 0); + if(f && rv != NULL) + (*f)(s, rv); +} + +int +write_signed_body(BODY *b, MAILSTREAM *stream, long msgno, char *section, BIO *in) +{ + + smime_write_body_header(b, stream, msgno, section, rfc822_output_func, in); + + +} + + + /* Big comment, explaining the mess that exists out there, and how we deal with it, and also how we solve the problems that are created this way. @@ -2569,7 +2670,7 @@ free_smime_body_sparep(void **sparep) * Given a multipart body of type multipart/signed, attempt to verify it. * Returns non-zero if the body was changed. */ -static int +int do_detached_signature_verify(BODY *b, long msgno, char *section) { PKCS7 *p7 = NULL; @@ -2579,29 +2680,44 @@ do_detached_signature_verify(BODY *b, long msgno, char *section) unsigned long mimelen, bodylen; char newSec[100], *mimetext, *bodytext; char *what_we_did; + SIZEDTEXT *st; dprint((9, "do_detached_signature_verify(msgno=%ld type=%d subtype=%s section=%s)", msgno, b->type, b->subtype ? b->subtype : "NULL", (section && *section) ? section : (section != NULL) ? "Top" : "NULL")); smime_init(); - snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : ""); - - mimetext = mail_fetch_mime(ps_global->mail_stream, msgno, (char*) newSec, &mimelen, 0); - - if(mimetext) - bodytext = mail_fetch_body (ps_global->mail_stream, msgno, (char*) newSec, &bodylen, 0); + /* if it was signed and then encrypted, use the decrypted text + * to check the validity of the signature + */ + if(b->sparep){ + if(get_smime_sparep_type(b->sparep) == SizedText){ + /* bodytext includes mimetext */ + st = (SIZEDTEXT *) get_smime_sparep_data(b->sparep); + bodytext = st->data; + bodylen = st->size; + mimetext = NULL; + mimelen = 0L; + } + } + else{ + snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : ""); + mimetext = mail_fetch_mime(ps_global->mail_stream, msgno, (char*) newSec, &mimelen, 0); + if(mimetext) + bodytext = mail_fetch_body (ps_global->mail_stream, msgno, (char*) newSec, &bodylen, 0); - if (mimetext == NULL || bodytext == NULL) - return modified_the_body; + if(mimetext == NULL || bodytext == NULL) + return modified_the_body; + } snprintf(newSec, sizeof(newSec), "%s%s2", section ? section : "", (section && *section) ? "." : ""); - if((p7 = get_pkcs7_from_part(msgno, newSec)) == NULL - || (in = BIO_new(BIO_s_mem())) == NULL) - return modified_the_body; + if((p7 = get_pkcs7_from_part(msgno, newSec)) == NULL + || (in = BIO_new(BIO_s_mem())) == NULL) + return modified_the_body; (void) BIO_reset(in); - BIO_write(in, mimetext, mimelen); + if(mimetext != NULL) + BIO_write(in, mimetext, mimelen); BIO_write(in, bodytext, bodylen); /* Try compatibility with the past and check if this message @@ -2623,6 +2739,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section) * it by hand. */ if((result = do_signature_verify(p7, in, NULL, 1)) == 0 + && mimelen > 0 /* do not do this for encrypted messages */ && IS_REMOTE(ps_global->mail_stream->mailbox)){ char *fetch; unsigned long hlen, tlen; @@ -2645,7 +2762,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section) bstart += 4; INIT(&bs, mail_string, bstart, tlen); - rfc822_parse_msg_full(&env, &body, h, (bstart-h), &bs, BADHOST, 0, 0); + rfc822_parse_msg_full(&env, &body, h, bstart-h, &bs, BADHOST, 0, 0); mail_free_envelope(&env); mail_free_body_part(&b->nested.part); @@ -2654,6 +2771,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section) modified_the_body = 1; snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : ""); + mimetext = mail_fetch_mime(ps_global->mail_stream, msgno, (char*) newSec, &mimelen, 0); if(mimetext) @@ -2701,7 +2819,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section) b->description = cpystr(what_we_did); - b->sparep = p7; + b->sparep = create_smime_sparep(P7Type, p7); p = b->nested.part; @@ -2844,11 +2962,11 @@ do_decoding(BODY *b, long msgno, const char *section) * Extract binary data from part to an in-memory store */ - if(b->sparep){ /* already done */ - p7 = (PKCS7*) b->sparep; + if(b->sparep){ + if(get_smime_sparep_type(b->sparep) == P7Type) + p7 = (PKCS7*) get_smime_sparep_data(b->sparep); } else{ - p7 = get_pkcs7_from_part(msgno, section && *section ? section : "1"); if(!p7){ q_status_message1(SM_ORDER, 2, 2, "Couldn't load PKCS7 object: %s", @@ -2860,7 +2978,7 @@ do_decoding(BODY *b, long msgno, const char *section) * Save the PKCS7 object for later dealings by the user interface. * It will be cleaned up when the body is garbage collected. */ - b->sparep = p7; + b->sparep = create_smime_sparep(P7Type, p7); } dprint((1, "type_is_signed = %d, type_is_enveloped = %d", PKCS7_type_is_signed(p7), PKCS7_type_is_enveloped(p7))); @@ -2927,8 +3045,7 @@ do_decoding(BODY *b, long msgno, const char *section) if(!decrypt_result){ q_status_message1(SM_ORDER, 1, 1, _("Error decrypting: %s"), (char*) openssl_error_string()); - goto end; - } + goto end; } BIO_write(out, null, 1); } @@ -2957,12 +3074,24 @@ do_decoding(BODY *b, long msgno, const char *section) q_status_message(SM_ORDER, 3, 3, _("Encrypted data couldn't be parsed.")); } else{ + SIZEDTEXT *st; bstart += 4; /* skip over CRLF*2 */ INIT(&s, mail_string, bstart, strlen(bstart)); - rfc822_parse_msg_full(&env, &body, h, (bstart-h)-2, &s, BADHOST, 0, 0); + rfc822_parse_msg_full(&env, &body, h, bstart-h-2, &s, BADHOST, 0, 0); mail_free_envelope(&env); /* Don't care about this */ + if(body->type == TYPEMULTIPART + && !strucmp(body->subtype, "SIGNED")){ + char *cookie = NULL; + PARAMETER *param; + for (param = body->parameter; param && !cookie; param = param->next) + if (!strucmp (param->attribute,"BOUNDARY")) cookie = param->value; + st = fs_get(sizeof(SIZEDTEXT)); + st->data = (void *) cpystr(bstart + strlen(cookie)+4); /* 4 = strlen("--\r\n") */ + st->size = body->nested.part->next->body.mime.offset - 2*(strlen(cookie) + 4); + body->sparep = create_smime_sparep(SizedText, (void *)st); + } body->mime.offset = 0; body->mime.text.size = 0; @@ -3094,7 +3223,6 @@ do_fiddle_smime_message(BODY *b, long msgno, char *section) else{ for(p=b->nested.part,partNum=1; p; p=p->next,partNum++){ - /* Append part number to the section string */ snprintf(newSec, sizeof(newSec), "%s%s%d", section, *section ? "." : "", partNum); @@ -3141,6 +3269,7 @@ get_chain_for_cert(X509 *cert, int *error) X509_STORE_CTX *ctx; X509 *x, *xtmp; int rc; /* return code */ + int level = -1; *error = 0; ERR_clear_error(); @@ -3150,7 +3279,8 @@ get_chain_for_cert(X509 *cert, int *error) *error = X509_STORE_CTX_get_error(ctx); else if((chain = sk_X509_new_null()) != NULL){ for(x = cert; ; x = xtmp){ - sk_X509_push(chain, X509_dup(x)); + if(++level > 0) + sk_X509_push(chain, X509_dup(x)); rc = X509_STORE_CTX_get1_issuer(&xtmp, ctx, x); if(rc < 0) *error = 1; @@ -3160,8 +3290,10 @@ get_chain_for_cert(X509 *cert, int *error) break; } } - if(*error && chain != NULL) + if((*error && chain != NULL) || level == 0){ sk_X509_pop_free(chain, X509_free); + chain = NULL; + } X509_STORE_CTX_free(ctx); } return chain; @@ -3248,7 +3380,7 @@ sign_outgoing_message(METAENV *header, BODY **bodyP, int dont_detach) newBody = mail_newbody(); - setup_pkcs7_body_for_signature(newBody, "S/MIME Cryptographically Signed Message", "pkcs7-mime", "smime.p7m"); + setup_pkcs7_body_for_signature(newBody, "S/MIME Cryptographically Signed Message", "pkcs7-mime", "smime.p7m", "signed-data"); newBody->contents.text.data = (unsigned char *) outs; *bodyP = newBody; @@ -3288,7 +3420,7 @@ sign_outgoing_message(METAENV *header, BODY **bodyP, int dont_detach) p1->next = p2; - setup_pkcs7_body_for_signature(&p2->body, "S/MIME Cryptographic Signature", "pkcs7-signature", "smime.p7s"); + setup_pkcs7_body_for_signature(&p2->body, "S/MIME Cryptographic Signature", "pkcs7-signature", "smime.p7s", NULL); p2->body.contents.text.data = (unsigned char *) outs; newBody->nested.part = p1; diff --git a/po/Makefile.in b/po/Makefile.in index 0f400a12..cc1c5abc 100644 --- a/po/Makefile.in +++ b/po/Makefile.in @@ -11,7 +11,7 @@ # Origin: gettext-0.16 PACKAGE = alpine -VERSION = 2.19.99 +VERSION = 2.19.991 PACKAGE_BUGREPORT = chappa@washington.edu SHELL = /bin/sh |