1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ TLS/SSL functions. TODO this needs an overhaul -- there _are_ stack leaks!?
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
9 * Gunnar Ritter. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Gunnar Ritter
22 * and his contributors.
23 * 4. Neither the name of Gunnar Ritter nor the names of his contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #ifndef HAVE_AMALGAMATION
48 #include <sys/socket.h>
50 #include <openssl/crypto.h>
51 #include <openssl/err.h>
52 #include <openssl/evp.h>
53 #include <openssl/opensslv.h>
54 #include <openssl/pem.h>
55 #include <openssl/rand.h>
56 #include <openssl/ssl.h>
57 #include <openssl/x509v3.h>
58 #include <openssl/x509.h>
60 #ifdef HAVE_XSSL_CONFIG
61 # include <openssl/conf.h>
64 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
69 * OpenSSL client implementation according to: John Viega, Matt Messier,
70 * Pravir Chandra: Network Security with OpenSSL. Sebastopol, CA 2002.
73 /* Update manual on changes (for all those)! */
74 #define n_XSSL_DISABLED_PROTOCOLS "-SSLv2"
76 #ifndef HAVE_XSSL_CONF_CTX
77 # ifndef SSL_OP_NO_SSLv2
78 # define SSL_OP_NO_SSLv2 0
80 # ifndef SSL_OP_NO_SSLv3
81 # define SSL_OP_NO_SSLv3 0
83 # ifndef SSL_OP_NO_TLSv1
84 # define SSL_OP_NO_TLSv1 0
86 # ifndef SSL_OP_NO_TLSv1_1
87 # define SSL_OP_NO_TLSv1_1 0
89 # ifndef SSL_OP_NO_TLSv1_2
90 # define SSL_OP_NO_TLSv1_2 0
93 /* SSL_CONF_CTX and _OP_NO_SSL_MASK were both introduced with 1.0.2!?! */
94 # ifndef SSL_OP_NO_SSL_MASK
95 # define SSL_OP_NO_SSL_MASK \
96 (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |\
97 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2)
101 #ifdef HAVE_XSSL_STACK_OF
102 # define n_XSSL_STACKOF(X) STACK_OF(X)
104 # define n_XSSL_STACKOF(X) /*X*/STACK
107 #if OPENSSL_VERSION_NUMBER + 0 >= 0x0090581fL
108 # define a_XSSL_RAND_LOAD_FILE_MAXBYTES -1
110 # define a_XSSL_RAND_LOAD_FILE_MAXBYTES 1024
113 /* Compatibility sighs (that sigh is _really_ a cute one) */
114 #if HAVE_XSSL_OPENSSL >= 0x10100
115 # define a_xssl_X509_get_notBefore X509_get0_notBefore
116 # define a_xssl_X509_get_notAfter X509_get0_notAfter
118 # define a_xssl_X509_get_notBefore X509_get_notBefore
119 # define a_xssl_X509_get_notAfter X509_get_notAfter
122 /* X509_STORE_set_flags */
123 #undef a_XSSL_X509_V_ANY
124 #ifndef X509_V_FLAG_NO_ALT_CHAINS
125 # define X509_V_FLAG_NO_ALT_CHAINS -1
127 # undef a_XSSL_X509_V_ANY
128 # define a_XSSL_X509_V_ANY
130 #ifndef X509_V_FLAG_NO_CHECK_TIME
131 # define X509_V_FLAG_NO_CHECK_TIME -1
133 # undef a_XSSL_X509_V_ANY
134 # define a_XSSL_X509_V_ANY
136 #ifndef X509_V_FLAG_PARTIAL_CHAIN
137 # define X509_V_FLAG_PARTIAL_CHAIN -1
139 # undef a_XSSL_X509_V_ANY
140 # define a_XSSL_X509_V_ANY
142 #ifndef X509_V_FLAG_X509_STRICT
143 # define X509_V_FLAG_X509_STRICT -1
145 # undef a_XSSL_X509_V_ANY
146 # define a_XSSL_X509_V_ANY
148 #ifndef X509_V_FLAG_TRUSTED_FIRST
149 # define X509_V_FLAG_TRUSTED_FIRST -1
151 # undef a_XSSL_X509_V_ANY
152 # define a_XSSL_X509_V_ANY
155 /* Some became meaningless with HAVE_XSSL_OPENSSL>=0x10100 */
157 a_XSSL_S_INIT
= 1<<0,
158 a_XSSL_S_RAND_INIT
= 1<<1,
159 a_XSSL_S_EXIT_HDL
= 1<<2,
160 a_XSSL_S_CONF_LOAD
= 1<<3,
161 a_XSSL_S_ALGO_LOAD
= 1<<4,
163 a_XSSL_S_VERIFY_ERROR
= 1<<7
166 /* We go for the OpenSSL v1.0.2+ SSL_CONF_CTX if available even if
167 * the library does internally what we'd otherwise do ourselfs.
168 * But eventually we can drop the direct use cases */
169 enum a_xssl_conf_type
{
170 a_XSSL_CT_CERTIFICATE
,
171 a_XSSL_CT_CIPHER_STRING
,
173 a_XSSL_CT_PRIVATE_KEY
,
178 struct ssl_method
{ /* TODO v15 obsolete */
179 char const sm_name
[8];
180 char const sm_map
[16];
183 #ifndef HAVE_XSSL_CONF_CTX
184 struct a_xssl_protocol
{
190 struct a_xssl_smime_cipher
{
191 char const sc_name
[8];
192 EVP_CIPHER
const *(*sc_fun
)(void);
195 struct a_xssl_smime_digest
{
196 char const sd_name
[8];
197 EVP_MD
const *(*sd_fun
)(void);
200 struct a_xssl_x509_v_flags
{
201 char const xvf_name
[20];
205 /* Supported SSL/TLS methods: update manual on change! */
207 static struct ssl_method
const _ssl_methods
[] = { /* TODO obsolete */
208 {"auto", "ALL,-SSLv2"},
209 {"ssl3", "-ALL,SSLv3"},
210 {"tls1", "-ALL,TLSv1"},
211 {"tls1.1", "-ALL,TLSv1.1"},
212 {"tls1.2", "-ALL,TLSv1.2"}
215 /* Update manual on change! */
216 #ifndef HAVE_XSSL_CONF_CTX
217 static struct a_xssl_protocol
const a_xssl_protocols
[] = {
218 {"ALL", SSL_OP_NO_SSL_MASK
},
219 {"TLSv1.2", SSL_OP_NO_TLSv1_2
},
220 {"TLSv1.1", SSL_OP_NO_TLSv1_1
},
221 {"TLSv1", SSL_OP_NO_TLSv1
},
222 {"SSLv3", SSL_OP_NO_SSLv3
},
227 /* Supported S/MIME cipher algorithms */
228 static struct a_xssl_smime_cipher
const a_xssl_smime_ciphers
[] = { /* Manual! */
229 #ifndef OPENSSL_NO_AES
230 # define a_XSSL_SMIME_DEFAULT_CIPHER EVP_aes_128_cbc /* According to RFC 5751 */
231 {"aes128", &EVP_aes_128_cbc
},
232 {"aes256", &EVP_aes_256_cbc
},
233 {"aes192", &EVP_aes_192_cbc
},
235 #ifndef OPENSSL_NO_DES
236 # ifndef a_XSSL_SMIME_DEFAULT_CIPHER
237 # define a_XSSL_SMIME_DEFAULT_CIPHER EVP_des_ede3_cbc
239 {"des3", &EVP_des_ede3_cbc
},
240 {"des", &EVP_des_cbc
},
243 #ifndef a_XSSL_SMIME_DEFAULT_CIPHER
244 # error Your OpenSSL library does not include the necessary
245 # error cipher algorithms that are required to support S/MIME
248 #ifndef OPENSSL_NO_AES
249 /* TODO obsolete a_xssl_smime_ciphers_obs */
250 static struct a_xssl_smime_cipher
const a_xssl_smime_ciphers_obs
[] = {
251 {"aes-128", &EVP_aes_128_cbc
},
252 {"aes-256", &EVP_aes_256_cbc
},
253 {"aes-192", &EVP_aes_192_cbc
}
257 /* Supported S/MIME message digest algorithms */
258 static struct a_xssl_smime_digest
const a_xssl_smime_digests
[] = { /* Manual! */
259 #define a_XSSL_SMIME_DEFAULT_DIGEST EVP_sha1 /* According to RFC 5751 */
260 #define a_XSSL_SMIME_DEFAULT_DIGEST_S "sha1"
262 {"sha256", &EVP_sha256
},
263 {"sha512", &EVP_sha512
},
264 {"sha384", &EVP_sha384
},
265 {"sha224", &EVP_sha224
},
266 #ifndef OPENSSL_NO_MD5
271 /* X509_STORE_set_flags() for *{smime,ssl}-ca-flags* */
272 static struct a_xssl_x509_v_flags
const a_xssl_x509_v_flags
[] = { /* Manual! */
273 {"no-alt-chains", X509_V_FLAG_NO_ALT_CHAINS
},
274 {"no-check-time", X509_V_FLAG_NO_CHECK_TIME
},
275 {"partial-chain", X509_V_FLAG_PARTIAL_CHAIN
},
276 {"strict", X509_V_FLAG_X509_STRICT
},
277 {"trusted-first", X509_V_FLAG_TRUSTED_FIRST
},
280 static enum a_xssl_state a_xssl_state
;
281 static size_t a_xssl_msgno
;
283 static bool_t
a_xssl_rand_init(void);
284 #if HAVE_XSSL_OPENSSL < 0x10100
285 # ifdef HAVE_SSL_ALL_ALGORITHMS
286 static void a_xssl__load_algos(void);
287 # define a_xssl_load_algos a_xssl__load_algos
289 # if defined HAVE_XSSL_CONFIG || defined HAVE_SSL_ALL_ALGORITHMS
290 static void a_xssl_atexit(void);
293 #ifndef a_xssl_load_algos
294 # define a_xssl_load_algos() do{;}while(0)
297 static bool_t
_ssl_parse_asn1_time(ASN1_TIME
const *atp
,
298 char *bdat
, size_t blen
);
299 static int _ssl_verify_cb(int success
, X509_STORE_CTX
*store
);
301 /* *smime-ca-flags*, *ssl-ca-flags* */
302 static void a_xssl_ca_flags(X509_STORE
*store
, char const *flags
);
304 /* SSL_CTX configuration */
305 static void * _ssl_conf_setup(SSL_CTX
*ctxp
);
306 static bool_t
_ssl_conf(void *confp
, enum a_xssl_conf_type ct
,
308 static bool_t
_ssl_conf_finish(void **confp
, bool_t error
);
310 static bool_t
_ssl_load_verifications(SSL_CTX
*ctxp
);
312 static enum okay
ssl_check_host(struct sock
*sp
, struct url
const *urlp
);
314 static int smime_verify(struct message
*m
, int n
,
315 n_XSSL_STACKOF(X509
) *chain
, X509_STORE
*store
);
316 static EVP_CIPHER
const * _smime_cipher(char const *name
);
317 static int ssl_password_cb(char *buf
, int size
, int rwflag
,
319 static FILE * smime_sign_cert(char const *xname
, char const *xname2
,
320 bool_t dowarn
, char const **match
);
321 static char const * _smime_sign_include_certs(char const *name
);
322 static bool_t
_smime_sign_include_chain_creat(n_XSSL_STACKOF(X509
) **chain
,
323 char const *cfiles
, char const *addr
);
324 static EVP_MD
const * _smime_sign_digest(char const *name
,
325 char const **digname
);
326 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
327 static enum okay
load_crl1(X509_STORE
*store
, char const *name
);
329 static enum okay
load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
);
332 a_xssl_rand_init(void){
333 #define a_XSSL_RAND_ENTROPY 32
334 char b64buf
[a_XSSL_RAND_ENTROPY
* 5 +1], *randfile
;
342 /* Shall use some external daemon? */ /* TODO obsolete *ssl_rand_egd* */
343 if((cp
= ok_vlook(ssl_rand_egd
)) != NULL
){ /* TODO no one supports it now! */
344 n_OBSOLETE(_("all *SSL libraries removed *ssl-rand-egd* support"));
345 #ifdef HAVE_XSSL_RAND_EGD
346 if((x
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) != NULL
&&
347 RAND_egd(cp
= x
) != -1){
351 n_err(_("*ssl_rand_egd* daemon at %s not available\n"),
352 n_shexp_quote_cp(cp
, FAL0
));
354 if(n_poption
& n_PO_D_VV
)
355 n_err(_("*ssl_rand_egd* (%s): unsupported by SSL library\n"),
356 n_shexp_quote_cp(cp
, FAL0
));
360 /* Prefer possible user setting */
361 if((cp
= ok_vlook(ssl_rand_file
)) != NULL
){
364 if((x
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
365 n_err(_("*ssl-rand-file*: expansion of %s failed "
366 "(using OpenSSL default)\n"),
367 n_shexp_quote_cp(cp
, FAL0
));
372 randfile
= n_lofi_alloc(PATH_MAX
);
373 if((cp
= RAND_file_name(randfile
, PATH_MAX
)) == NULL
){
374 n_err(_("*ssl-rand-file*: no SSL entropy file, can't seed PRNG\n"));
379 (void)RAND_load_file(cp
, a_XSSL_RAND_LOAD_FILE_MAXBYTES
);
381 /* And feed in some data, then write the updated file.
382 * While this rather feeds the PRNG with itself in the n_RANDOM_USE_XSSL
383 * case, let us stir the buffer a little bit.
384 * Estimate a low but likely still too high number of entropy bytes, use
385 * 20%: base64 uses 3 input = 4 output bytes relation, and the base64
386 * alphabet is a 6 bit one */
387 n_LCTAV(n_RANDOM_USE_XSSL
== 0 || n_RANDOM_USE_XSSL
== 1);
388 for(x
= (char*)-1;;){
389 RAND_add(n_random_create_buf(b64buf
, sizeof(b64buf
) -1, NULL
),
390 sizeof(b64buf
) -1, a_XSSL_RAND_ENTROPY
);
391 if((x
= (char*)((uintptr_t)x
>> (1 + (n_RANDOM_USE_XSSL
* 3)))) == NULL
){
392 err
= (RAND_status() == 0);
395 #if !n_RANDOM_USE_XSSL
396 if(!(err
= (RAND_status() == 0)))
402 err
= (RAND_write_file(cp
) == -1);
406 n_lofi_free(randfile
);
408 n_panic(_("Cannot seed the *SSL PseudoRandomNumberGenerator, "
409 "RAND_status() is 0!\n"
410 " Please set *ssl-rand-file* to a file with sufficient entropy.\n"
411 " On a machine with entropy: "
412 "\"$ dd if=/dev/urandom of=FILE bs=1024 count=1\"\n"));
420 #ifdef HAVE_XSSL_CONFIG
425 if(!(a_xssl_state
& a_XSSL_S_INIT
)){
426 #if HAVE_XSSL_OPENSSL >= 0x10100
427 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
428 OPENSSL_INIT_LOAD_CRYPTO_STRINGS
429 # ifdef HAVE_SSL_ALL_ALGORITHMS
430 | OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
433 # ifdef HAVE_SSL_ALL_ALGORITHMS
434 a_xssl_state
|= a_XSSL_S_ALGO_LOAD
;
437 SSL_load_error_strings();
440 a_xssl_state
|= a_XSSL_S_INIT
;
443 /* Load openssl.cnf or whatever was given in *ssl-config-file* */
444 #ifdef HAVE_XSSL_CONFIG
445 if(!(a_xssl_state
& a_XSSL_S_CONF_LOAD
) &&
446 (cp
= ok_vlook(ssl_config_file
)) != NULL
){
447 ul_i flags
= CONF_MFLAGS_IGNORE_MISSING_FILE
;
453 if(CONF_modules_load_file(cp
, n_uagent
, flags
) == 1){
454 a_xssl_state
|= a_XSSL_S_CONF_LOAD
;
455 # if HAVE_XSSL_OPENSSL < 0x10100
456 if(!(a_xssl_state
& a_XSSL_S_EXIT_HDL
)){
457 a_xssl_state
|= a_XSSL_S_EXIT_HDL
;
458 atexit(&a_xssl_atexit
); /* TODO generic program-wide event mech. */
462 ssl_gen_err(_("Ignoring CONF_modules_load_file() load error"));
466 if(!(a_xssl_state
& a_XSSL_S_RAND_INIT
) && a_xssl_rand_init())
467 a_xssl_state
|= a_XSSL_S_RAND_INIT
;
471 #if HAVE_XSSL_OPENSSL < 0x10100
472 # ifdef HAVE_SSL_ALL_ALGORITHMS
474 a_xssl__load_algos(void){
476 if(!(a_xssl_state
& a_XSSL_S_ALGO_LOAD
)){
477 a_xssl_state
|= a_XSSL_S_ALGO_LOAD
;
478 OpenSSL_add_all_algorithms();
480 if(!(a_xssl_state
& a_XSSL_S_EXIT_HDL
)){
481 a_xssl_state
|= a_XSSL_S_EXIT_HDL
;
482 atexit(&a_xssl_atexit
); /* TODO generic program-wide event mech. */
489 # if defined HAVE_XSSL_CONFIG || defined HAVE_SSL_ALL_ALGORITHMS
493 # ifdef HAVE_XSSL_CONFIG
494 if(a_xssl_state
& a_XSSL_S_CONF_LOAD
)
498 # ifdef HAVE_SSL_ALL_ALGORITHMS
499 if(a_xssl_state
& a_XSSL_S_ALGO_LOAD
)
505 #endif /* HAVE_XSSL_OPENSSL < 0x10100 */
508 _ssl_parse_asn1_time(ASN1_TIME
const *atp
, char *bdat
, size_t blen
)
515 mbp
= BIO_new(BIO_s_mem());
517 if (ASN1_TIME_print(mbp
, atp
) && (l
= BIO_get_mem_data(mbp
, &mcp
)) > 0)
518 snprintf(bdat
, blen
, "%.*s", (int)l
, mcp
);
520 snprintf(bdat
, blen
, _("Bogus certificate date: %.*s"),
521 /*is (int)*/atp
->length
, (char const*)atp
->data
);
527 return (mcp
!= NULL
);
531 _ssl_verify_cb(int success
, X509_STORE_CTX
*store
)
538 if (success
&& !(n_poption
& n_PO_D_V
))
541 if (a_xssl_msgno
!= 0) {
542 n_err(_("Message %lu:\n"), (ul_i
)a_xssl_msgno
);
545 n_err(_(" Certificate depth %d %s\n"),
546 X509_STORE_CTX_get_error_depth(store
), (success
? n_empty
: V_(n_error
)));
548 if ((cert
= X509_STORE_CTX_get_current_cert(store
)) != NULL
) {
549 X509_NAME_oneline(X509_get_subject_name(cert
), data
, sizeof data
);
550 n_err(_(" subject = %s\n"), data
);
552 _ssl_parse_asn1_time(a_xssl_X509_get_notBefore(cert
), data
, sizeof data
);
553 n_err(_(" notBefore = %s\n"), data
);
555 _ssl_parse_asn1_time(a_xssl_X509_get_notAfter(cert
), data
, sizeof data
);
556 n_err(_(" notAfter = %s\n"), data
);
558 X509_NAME_oneline(X509_get_issuer_name(cert
), data
, sizeof data
);
559 n_err(_(" issuer = %s\n"), data
);
563 int err
= X509_STORE_CTX_get_error(store
);
565 n_err(_(" err %i: %s\n"), err
, X509_verify_cert_error_string(err
));
566 a_xssl_state
|= a_XSSL_S_VERIFY_ERROR
;
569 if (!success
&& ssl_verify_decide() != OKAY
)
577 a_xssl_ca_flags(X509_STORE
*store
, char const *flags
){
582 iolist
= savestr(flags
);
584 while((cp
= n_strsep(&iolist
, ',', TRU1
)) != NULL
){
585 struct a_xssl_x509_v_flags
const *xvfp
;
587 for(xvfp
= &a_xssl_x509_v_flags
[0];
588 xvfp
< &a_xssl_x509_v_flags
[n_NELEM(a_xssl_x509_v_flags
)];
590 if(!asccasecmp(cp
, xvfp
->xvf_name
)){
591 if(xvfp
->xvf_flag
!= -1){
592 #ifdef a_XSSL_X509_V_ANY
593 X509_STORE_set_flags(store
, xvfp
->xvf_flag
);
595 }else if(n_poption
& n_PO_D_V
)
596 n_err(_("*{smime,ssl}-ca-flags*: "
597 "directive not supported: %s\n"), cp
);
600 n_err(_("*{smime,ssl}-ca-flags*: invalid directive: %s\n"), cp
);
606 #ifdef HAVE_XSSL_CONF_CTX
608 _ssl_conf_setup(SSL_CTX
*ctxp
)
613 if ((sccp
= SSL_CONF_CTX_new()) != NULL
) {
614 SSL_CONF_CTX_set_flags(sccp
,
615 SSL_CONF_FLAG_FILE
| SSL_CONF_FLAG_CLIENT
|
616 SSL_CONF_FLAG_CERTIFICATE
| SSL_CONF_FLAG_SHOW_ERRORS
);
618 SSL_CONF_CTX_set_ssl_ctx(sccp
, ctxp
);
620 ssl_gen_err(_("SSL_CONF_CTX_new() failed"));
627 _ssl_conf(void *confp
, enum a_xssl_conf_type ct
, char const *value
)
631 SSL_CONF_CTX
*sccp
= (SSL_CONF_CTX
*)confp
;
635 case a_XSSL_CT_CERTIFICATE
:
637 rv
= SSL_CONF_cmd(sccp
, "Certificate", value
);
639 case a_XSSL_CT_CIPHER_STRING
:
640 cmsg
= "ssl-cipher-list";
641 rv
= SSL_CONF_cmd(sccp
, "CipherString", value
);
643 case a_XSSL_CT_PRIVATE_KEY
:
645 rv
= SSL_CONF_cmd(sccp
, "PrivateKey", value
);
648 case a_XSSL_CT_OPTIONS
:
649 cmsg
= "ssl-options";
650 rv
= SSL_CONF_cmd(sccp
, "Options", "Bugs");
652 case a_XSSL_CT_PROTOCOL
:
653 cmsg
= "ssl-protocol";
654 rv
= SSL_CONF_cmd(sccp
, "Protocol", value
);
656 case a_XSSL_CT_CURVES
:
658 rv
= SSL_CONF_cmd(sccp
, "Curves", value
);
666 ssl_gen_err(_("SSL_CONF_CTX_cmd() failed for *%s*"), cmsg
);
668 n_err(_("%s: *%s* implementation error, please report this\n"),
678 _ssl_conf_finish(void **confp
, bool_t error
)
680 SSL_CONF_CTX
**sccp
= (SSL_CONF_CTX
**)confp
;
685 rv
= (SSL_CONF_CTX_finish(*sccp
) != 0);
687 SSL_CONF_CTX_free(*sccp
);
694 #else /* HAVE_XSSL_CONF_CTX */
696 _ssl_conf_setup(SSL_CTX
* ctxp
)
702 _ssl_conf(void *confp
, enum a_xssl_conf_type ct
, char const *value
){
709 case a_XSSL_CT_CERTIFICATE
:
710 if(SSL_CTX_use_certificate_chain_file(ctxp
, value
) != 1){
711 ssl_gen_err(_("Can't load certificate from file %s\n"),
712 n_shexp_quote_cp(value
, FAL0
));
716 case a_XSSL_CT_CIPHER_STRING
:
717 if(SSL_CTX_set_cipher_list(ctxp
, value
) != 1){
718 ssl_gen_err(_("Invalid cipher string: %s\n"), value
);
722 case a_XSSL_CT_CURVES
:
723 #ifdef SSL_CTRL_SET_CURVES_LIST
724 if(SSL_CTX_set1_curves_list(ctxp
, value
) != 1){
725 ssl_gen_err(_("Invalid curves string: %s\n"), value
);
729 n_err(_("*ssl-curves*: as such not supported\n"));
733 case a_XSSL_CT_PRIVATE_KEY
:
734 if(SSL_CTX_use_PrivateKey_file(ctxp
, value
, SSL_FILETYPE_PEM
) != 1){
735 ssl_gen_err(_("Can't load private key from file %s\n"),
736 n_shexp_quote_cp(value
, FAL0
));
740 case a_XSSL_CT_OPTIONS
:
741 /* "Options"="Bugs" TODO *ssl-options* */
742 SSL_CTX_set_options(ctxp
, SSL_OP_ALL
);
744 case a_XSSL_CT_PROTOCOL
:{
745 char *iolist
, *cp
, addin
;
750 for(iolist
= cp
= savestr(value
);
751 (cp
= n_strsep(&iolist
, ',', FAL0
)) != NULL
;){
753 n_err(_("*ssl-protocol*: empty arguments are not supported\n"));
759 case '-': addin
= FAL0
; /* FALLTHRU */
760 case '+': ++cp
; /* FALLTHRU */
765 if(!asccasecmp(cp
, a_xssl_protocols
[i
].sp_name
)){
766 /* We need to inverse the meaning of the _NO_s */
768 opts
|= a_xssl_protocols
[i
].sp_flag
;
770 opts
&= ~a_xssl_protocols
[i
].sp_flag
;
773 if(++i
< n_NELEM(a_xssl_protocols
))
775 n_err(_("*ssl-protocol*: unsupported value: %s\n"), cp
);
780 SSL_CTX_set_options(ctxp
, opts
);
785 return (confp
!= NULL
);
789 _ssl_conf_finish(void **confp
, bool_t error
)
795 #endif /* !HAVE_XSSL_CONF_CTX */
798 _ssl_load_verifications(SSL_CTX
*ctxp
)
800 char *ca_dir
, *ca_file
;
805 if (ssl_verify_level
== SSL_VERIFY_IGNORE
) {
810 if ((ca_dir
= ok_vlook(ssl_ca_dir
)) != NULL
)
811 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
812 if ((ca_file
= ok_vlook(ssl_ca_file
)) != NULL
)
813 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
815 if ((ca_dir
!= NULL
|| ca_file
!= NULL
) &&
816 SSL_CTX_load_verify_locations(ctxp
, ca_file
, ca_dir
) != 1) {
817 char const *m1
, *m2
, *m3
;
819 if (ca_dir
!= NULL
) {
821 m2
= (ca_file
!= NULL
) ? _(" or ") : n_empty
;
824 m3
= (ca_file
!= NULL
) ? ca_file
: n_empty
;
825 ssl_gen_err(_("Error loading %s%s%s\n"), m1
, m2
, m3
);
832 if((xv15
= ok_blook(ssl_no_default_ca
)))
833 n_OBSOLETE(_("please use *ssl-ca-no-defaults*, "
834 "not *ssl-no-default-ca*"));
835 if(!ok_blook(ssl_ca_no_defaults
) && !xv15
&&
836 SSL_CTX_set_default_verify_paths(ctxp
) != 1) {
837 ssl_gen_err(_("Error loading built-in default CA locations\n"));
842 a_xssl_state
&= ~a_XSSL_S_VERIFY_ERROR
;
844 SSL_CTX_set_verify(ctxp
, SSL_VERIFY_PEER
, &_ssl_verify_cb
);
845 store
= SSL_CTX_get_cert_store(ctxp
);
846 load_crls(store
, ok_v_ssl_crl_file
, ok_v_ssl_crl_dir
);
847 a_xssl_ca_flags(store
, ok_vlook(ssl_ca_flags
));
856 ssl_check_host(struct sock
*sp
, struct url
const *urlp
)
860 n_XSSL_STACKOF(GENERAL_NAME
) *gens
;
866 if ((cert
= SSL_get_peer_certificate(sp
->s_ssl
)) == NULL
) {
867 n_err(_("No certificate from: %s\n"), urlp
->url_h_p
.s
);
871 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
875 for (i
= 0; i
< sk_GENERAL_NAME_num(gens
); ++i
) {
876 gen
= sk_GENERAL_NAME_value(gens
, i
);
877 if (gen
->type
== GEN_DNS
) {
878 if (n_poption
& n_PO_D_V
)
879 n_err(_("Comparing subject_alt_name: need<%s> is<%s>\n"),
880 urlp
->url_host
.s
, (char*)gen
->d
.ia5
->data
);
881 rv
= rfc2595_hostname_match(urlp
->url_host
.s
,
882 (char*)gen
->d
.ia5
->data
);
889 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
890 X509_NAME_get_text_by_NID(subj
, NID_commonName
, data
, sizeof data
)
892 data
[sizeof data
- 1] = '\0';
893 if (n_poption
& n_PO_D_V
)
894 n_err(_("Comparing commonName: need<%s> is<%s>\n"),
895 urlp
->url_host
.s
, data
);
896 rv
= rfc2595_hostname_match(urlp
->url_host
.s
, data
);
907 smime_verify(struct message
*m
, int n
, n_XSSL_STACKOF(X509
) *chain
,
910 char data
[LINESIZE
], *sender
, *to
, *cc
, *cnttype
;
917 n_XSSL_STACKOF(X509
) *certs
;
918 n_XSSL_STACKOF(GENERAL_NAME
) *gens
;
929 a_xssl_state
&= ~a_XSSL_S_VERIFY_ERROR
;
930 a_xssl_msgno
= (size_t)n
;
933 sender
= getsender(m
);
934 to
= hfield1("to", m
);
935 cc
= hfield1("cc", m
);
936 cnttype
= hfield1("content-type", m
);
940 #define _X (sizeof("application/") -1)
941 #define _Y(X) X, sizeof(X) -1
942 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
943 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
944 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
947 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
949 if (x
!= (struct message
*)-1) {
955 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
961 if ((fp
= Ftmp(NULL
, "smimever", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
963 n_perr(_("tempfile"), 0);
972 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
974 "Error creating BIO verification object for message %d"), n
);
978 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
979 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
982 if (PKCS7_verify(pkcs7
, chain
, store
, pb
, NULL
, 0) != 1) {
983 ssl_gen_err(_("Error verifying message %d"), n
);
987 if (sender
== NULL
) {
988 n_err(_("Warning: Message %d has no sender\n"), n
);
993 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
995 n_err(_("No certificates found in message %d\n"), n
);
999 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
1000 cert
= sk_X509_value(certs
, i
);
1001 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
1003 for (j
= 0; j
< sk_GENERAL_NAME_num(gens
); ++j
) {
1004 gen
= sk_GENERAL_NAME_value(gens
, j
);
1005 if (gen
->type
== GEN_EMAIL
) {
1006 if (n_poption
& n_PO_D_V
)
1007 n_err(_("Comparing subject_alt_name: need<%s> is<%s>)\n"),
1008 sender
, (char*)gen
->d
.ia5
->data
);
1009 if (!asccasecmp((char*)gen
->d
.ia5
->data
, sender
))
1015 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
1016 X509_NAME_get_text_by_NID(subj
, NID_pkcs9_emailAddress
,
1017 data
, sizeof data
) > 0) {
1018 data
[sizeof data
-1] = '\0';
1019 if (n_poption
& n_PO_D_V
)
1020 n_err(_("Comparing emailAddress: need<%s> is<%s>\n"),
1022 if (!asccasecmp(data
, sender
))
1026 n_err(_("Message %d: certificate does not match <%s>\n"), n
, sender
);
1029 rv
= ((a_xssl_state
& a_XSSL_S_VERIFY_ERROR
) != 0);
1031 fprintf(n_stdout
, _("Message %d was verified successfully\n"), n
);
1034 sk_X509_free(certs
);
1047 static EVP_CIPHER
const *
1048 _smime_cipher(char const *name
)
1050 EVP_CIPHER
const *cipher
;
1056 vn
= ac_alloc(i
= strlen(name
) + sizeof("smime-cipher-") -1 +1);
1057 snprintf(vn
, (int)i
, "smime-cipher-%s", name
);
1058 cp
= n_var_vlook(vn
, FAL0
);
1061 if (cp
== NULL
&& (cp
= ok_vlook(smime_cipher
)) == NULL
) {
1062 cipher
= a_XSSL_SMIME_DEFAULT_CIPHER();
1067 for (i
= 0; i
< n_NELEM(a_xssl_smime_ciphers
); ++i
)
1068 if (!asccasecmp(a_xssl_smime_ciphers
[i
].sc_name
, cp
)) {
1069 cipher
= (*a_xssl_smime_ciphers
[i
].sc_fun
)();
1072 #ifndef OPENSSL_NO_AES
1073 for (i
= 0; i
< n_NELEM(a_xssl_smime_ciphers_obs
); ++i
) /* TODO obsolete */
1074 if (!asccasecmp(a_xssl_smime_ciphers_obs
[i
].sc_name
, cp
)) {
1075 n_OBSOLETE2(_("*smime-cipher* names with hyphens will vanish"), cp
);
1076 cipher
= (*a_xssl_smime_ciphers_obs
[i
].sc_fun
)();
1081 /* Not a built-in algorithm, but we may have dynamic support for more */
1082 #ifdef HAVE_SSL_ALL_ALGORITHMS
1083 a_xssl_load_algos();
1084 if((cipher
= EVP_get_cipherbyname(cp
)) != NULL
)
1088 n_err(_("Invalid S/MIME cipher(s): %s\n"), cp
);
1095 ssl_password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
1104 if(userdata
!= NULL
){
1108 if(url_parse(&url
, CPROTO_CCRED
, userdata
)){
1109 if(ccred_lookup(&cred
, &url
)){
1112 if((slen
= n_strscpy(buf
, cred
.cc_pass
.s
, size
)) >= 0){
1123 if ((pass
= getpassword("PEM pass phrase:")) != NULL
) {
1125 if (UICMP(z
, len
, >=, size
))
1127 memcpy(buf
, pass
, len
);
1138 smime_sign_cert(char const *xname
, char const *xname2
, bool_t dowarn
,
1144 char const *name
= xname
, *name2
= xname2
, *cp
;
1150 np
= lextract(name
, GTO
| GSKIN
);
1151 while (np
!= NULL
) {
1152 /* This needs to be more intelligent since it will currently take the
1153 * first name for which a private key is available regardless of
1154 * whether it is the right one for the message */
1155 vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1156 snprintf(vn
, vs
, "smime-sign-cert-%s", np
->n_name
);
1157 cp
= n_var_vlook(vn
, FAL0
);
1161 *match
= np
->n_name
;
1166 if (name2
!= NULL
) {
1173 if ((cp
= ok_vlook(smime_sign_cert
)) == NULL
)
1178 if ((cp
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
1180 if ((fp
= Fopen(cp
, "r")) == NULL
)
1187 n_err(_("Could not find a certificate for %s%s%s\n"),
1188 xname
, (xname2
!= NULL
? _("or ") : n_empty
),
1189 (xname2
!= NULL
? xname2
: n_empty
));
1194 _smime_sign_include_certs(char const *name
)
1199 /* See comments in smime_sign_cert() for algorithm pitfalls */
1203 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1207 vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1208 snprintf(vn
, vs
, "smime-sign-include-certs-%s", np
->n_name
);
1209 rv
= n_var_vlook(vn
, FAL0
);
1215 rv
= ok_vlook(smime_sign_include_certs
);
1222 _smime_sign_include_chain_creat(n_XSSL_STACKOF(X509
) **chain
,
1223 char const *cfiles
, char const *addr
)
1227 char *nfield
, *cfield
, *x
;
1230 *chain
= sk_X509_new_null();
1232 for (nfield
= savestr(cfiles
);
1233 (cfield
= n_strsep(&nfield
, ',', TRU1
)) != NULL
;) {
1234 if ((x
= fexpand(cfield
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1235 (fp
= Fopen(cfield
= x
, "r")) == NULL
) {
1239 if ((tmp
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, n_UNCONST(addr
))
1241 ssl_gen_err(_("Error reading certificate from %s"),
1242 n_shexp_quote_cp(cfield
, FAL0
));
1246 sk_X509_push(*chain
, tmp
);
1250 if (sk_X509_num(*chain
) == 0) {
1251 n_err(_("*smime-sign-include-certs* defined but empty\n"));
1256 return (*chain
!= NULL
);
1258 sk_X509_pop_free(*chain
, X509_free
);
1263 static EVP_MD
const *
1264 _smime_sign_digest(char const *name
, char const **digname
)
1266 EVP_MD
const *digest
;
1271 /* See comments in smime_sign_cert() for algorithm pitfalls */
1275 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1277 char *vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1278 snprintf(vn
, vs
, "smime-sign-message-digest-%s", np
->n_name
);
1279 cp
= n_var_vlook(vn
, FAL0
);
1286 if ((cp
= ok_vlook(smime_sign_message_digest
)) == NULL
) {
1287 digest
= a_XSSL_SMIME_DEFAULT_DIGEST();
1288 *digname
= a_XSSL_SMIME_DEFAULT_DIGEST_S
;
1294 { char *x
= salloc(i
+1);
1295 i_strcpy(x
, cp
, i
+1);
1300 for (i
= 0; i
< n_NELEM(a_xssl_smime_digests
); ++i
)
1301 if (!asccasecmp(a_xssl_smime_digests
[i
].sd_name
, cp
)) {
1302 digest
= (*a_xssl_smime_digests
[i
].sd_fun
)();
1306 /* Not a built-in algorithm, but we may have dynamic support for more */
1307 #ifdef HAVE_SSL_ALL_ALGORITHMS
1308 a_xssl_load_algos();
1309 if((digest
= EVP_get_digestbyname(cp
)) != NULL
)
1313 n_err(_("Invalid message digest: %s\n"), cp
);
1320 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1322 load_crl1(X509_STORE
*store
, char const *name
)
1324 X509_LOOKUP
*lookup
;
1325 enum okay rv
= STOP
;
1328 if (n_poption
& n_PO_D_V
)
1329 n_err(_("Loading CRL from %s\n"), n_shexp_quote_cp(name
, FAL0
));
1330 if ((lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file())) == NULL
) {
1331 ssl_gen_err(_("Error creating X509 lookup object"));
1334 if (X509_load_crl_file(lookup
, name
, X509_FILETYPE_PEM
) != 1) {
1335 ssl_gen_err(_("Error loading CRL from %s"), n_shexp_quote_cp(name
, FAL0
));
1343 #endif /* new OpenSSL */
1346 load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
)
1348 char *crl_file
, *crl_dir
;
1349 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1355 enum okay rv
= STOP
;
1358 if ((crl_file
= n_var_oklook(fok
)) != NULL
) {
1359 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1360 if ((crl_file
= fexpand(crl_file
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1361 load_crl1(store
, crl_file
) != OKAY
)
1364 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1369 if ((crl_dir
= n_var_oklook(dok
)) != NULL
) {
1370 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1372 if ((x
= fexpand(crl_dir
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1373 (dirp
= opendir(crl_dir
= x
)) == NULL
) {
1378 ds
= strlen(crl_dir
);
1379 fn
= smalloc(fs
= ds
+ 20);
1380 memcpy(fn
, crl_dir
, ds
);
1382 while ((dp
= readdir(dirp
)) != NULL
) {
1383 if (dp
->d_name
[0] == '.' && (dp
->d_name
[1] == '\0' ||
1384 (dp
->d_name
[1] == '.' && dp
->d_name
[2] == '\0')))
1386 if (dp
->d_name
[0] == '.')
1388 if (ds
+ (es
= strlen(dp
->d_name
)) + 2 < fs
)
1389 fn
= srealloc(fn
, fs
= ds
+ es
+ 20);
1390 memcpy(fn
+ ds
+ 1, dp
->d_name
, es
+ 1);
1391 if (load_crl1(store
, fn
) != OKAY
) {
1399 #else /* old OpenSSL */
1400 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1404 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1405 if (crl_file
|| crl_dir
)
1406 X509_STORE_set_flags(store
, X509_V_FLAG_CRL_CHECK
|
1407 X509_V_FLAG_CRL_CHECK_ALL
);
1415 #if n_RANDOM_USE_XSSL
1417 ssl_rand_bytes(void *buf
, size_t blen
){
1420 if(!(a_xssl_state
& a_XSSL_S_RAND_INIT
) && a_xssl_rand_init())
1421 a_xssl_state
|= a_XSSL_S_RAND_INIT
;
1426 i
= n_MIN(SI32_MAX
, blen
);
1429 buf
= (ui8_t
*)buf
+ i
;
1436 ssl_open(struct url
const *urlp
, struct sock
*sp
)
1440 char const *cp
, *cp_base
;
1442 enum okay rv
= STOP
;
1447 ssl_set_verify_level(urlp
);
1449 if ((ctxp
= SSL_CTX_new(n_XSSL_CLIENT_METHOD())) == NULL
) {
1450 ssl_gen_err(_("SSL_CTX_new() failed"));
1454 /* Available with OpenSSL 0.9.6 or later */
1455 #ifdef SSL_MODE_AUTO_RETRY
1456 SSL_CTX_set_mode(ctxp
, SSL_MODE_AUTO_RETRY
);
1459 if ((confp
= _ssl_conf_setup(ctxp
)) == NULL
)
1462 /* TODO obsolete Check for *ssl-method*, warp to a *ssl-protocol* value */
1463 if ((cp
= xok_vlook(ssl_method
, urlp
, OXM_ALL
)) != NULL
) {
1464 n_OBSOLETE(_("please use *ssl-protocol* instead of *ssl-method*"));
1465 if (n_poption
& n_PO_D_V
)
1466 n_err(_("*ssl-method*: %s\n"), cp
);
1468 if (!asccasecmp(_ssl_methods
[i
].sm_name
, cp
)) {
1469 cp
= _ssl_methods
[i
].sm_map
;
1472 if (++i
== n_NELEM(_ssl_methods
)) {
1473 n_err(_("Unsupported TLS/SSL method: %s\n"), cp
);
1478 /* *ssl-protocol* */
1479 if ((cp_base
= xok_vlook(ssl_protocol
, urlp
, OXM_ALL
)) != NULL
) {
1480 if (n_poption
& n_PO_D_V
)
1481 n_err(_("*ssl-protocol*: %s\n"), cp_base
);
1484 cp
= (cp
!= NULL
? savecatsep(cp
, ',', n_XSSL_DISABLED_PROTOCOLS
)
1485 : n_XSSL_DISABLED_PROTOCOLS
);
1486 if (!_ssl_conf(confp
, a_XSSL_CT_PROTOCOL
, cp
))
1490 if ((cp
= xok_vlook(ssl_cert
, urlp
, OXM_ALL
)) != NULL
) {
1491 if (n_poption
& n_PO_D_V
)
1492 n_err(_("*ssl-cert* %s\n"), n_shexp_quote_cp(cp
, FAL0
));
1493 if ((cp_base
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
) {
1494 n_err(_("*ssl-cert* value expansion failed: %s\n"),
1495 n_shexp_quote_cp(cp
, FAL0
));
1499 if (!_ssl_conf(confp
, a_XSSL_CT_CERTIFICATE
, cp
))
1503 if ((cp_base
= xok_vlook(ssl_key
, urlp
, OXM_ALL
)) != NULL
) {
1504 if (n_poption
& n_PO_D_V
)
1505 n_err(_("*ssl-key* %s\n"), n_shexp_quote_cp(cp_base
, FAL0
));
1506 if ((cp
= fexpand(cp_base
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
) {
1507 n_err(_("*ssl-key* value expansion failed: %s\n"),
1508 n_shexp_quote_cp(cp_base
, FAL0
));
1512 if (!_ssl_conf(confp
, a_XSSL_CT_PRIVATE_KEY
, cp
))
1516 if ((cp
= xok_vlook(ssl_cipher_list
, urlp
, OXM_ALL
)) != NULL
&&
1517 !_ssl_conf(confp
, a_XSSL_CT_CIPHER_STRING
, cp
))
1519 if ((cp
= xok_vlook(ssl_curves
, urlp
, OXM_ALL
)) != NULL
&&
1520 !_ssl_conf(confp
, a_XSSL_CT_CURVES
, cp
))
1523 if (!_ssl_load_verifications(ctxp
))
1526 if (!_ssl_conf(confp
, a_XSSL_CT_OPTIONS
, NULL
)) /* TODO *ssl-options* */
1529 /* Done with context setup, create our new per-connection structure */
1530 if (!_ssl_conf_finish(&confp
, FAL0
))
1533 if ((sp
->s_ssl
= SSL_new(ctxp
)) == NULL
) {
1534 ssl_gen_err(_("SSL_new() failed"));
1538 /* Try establish SNI extension; even though this is a TLS extension the
1539 * protocol isn't checked once the host name is set, and therefore i've
1540 * refrained from changing so much code just to check out whether we are
1541 * using SSLv3, which should become rarer and rarer */
1542 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1543 if((urlp
->url_flags
& n_URL_TLS_MASK
) &&
1544 (urlp
->url_flags
& n_URL_HOST_IS_NAME
)){
1545 if(!SSL_set_tlsext_host_name(sp
->s_ssl
, urlp
->url_host
.s
) &&
1546 (n_poption
& n_PO_D_V
))
1547 n_err(_("Hostname cannot be used with ServerNameIndication "
1548 "TLS extension: %s\n"),
1549 n_shexp_quote_cp(urlp
->url_host
.s
, FAL0
));
1553 SSL_set_fd(sp
->s_ssl
, sp
->s_fd
);
1555 if (SSL_connect(sp
->s_ssl
) < 0) {
1556 ssl_gen_err(_("could not initiate SSL/TLS connection"));
1560 if (ssl_verify_level
!= SSL_VERIFY_IGNORE
) {
1561 if (ssl_check_host(sp
, urlp
) != OKAY
) {
1562 n_err(_("Host certificate does not match: %s\n"), urlp
->url_h_p
.s
);
1563 if (ssl_verify_decide() != OKAY
)
1568 /* We're fully setup: since we don't reuse the SSL_CTX (pooh) keep it local
1569 * and free it right now -- it is reference counted by sp->s_ssl.. */
1577 SSL_free(sp
->s_ssl
);
1581 _ssl_conf_finish(&confp
, TRU1
);
1588 ssl_gen_err(char const *fmt
, ...)
1597 n_err(_(": %s\n"), ERR_error_string(ERR_get_error(), NULL
));
1604 int *msgvec
= vp
, *ip
, ec
= 0, rv
= 1;
1605 X509_STORE
*store
= NULL
;
1606 char *ca_dir
, *ca_file
;
1611 ssl_verify_level
= SSL_VERIFY_STRICT
;
1612 if ((store
= X509_STORE_new()) == NULL
) {
1613 ssl_gen_err(_("Error creating X509 store"));
1616 X509_STORE_set_verify_cb_func(store
, &_ssl_verify_cb
);
1618 if ((ca_dir
= ok_vlook(smime_ca_dir
)) != NULL
)
1619 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
1620 if ((ca_file
= ok_vlook(smime_ca_file
)) != NULL
)
1621 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
1623 if (ca_dir
!= NULL
|| ca_file
!= NULL
) {
1624 if (X509_STORE_load_locations(store
, ca_file
, ca_dir
) != 1) {
1625 ssl_gen_err(_("Error loading %s"),
1626 (ca_file
!= NULL
) ? ca_file
: ca_dir
);
1634 if((xv15
= ok_blook(smime_no_default_ca
)))
1635 n_OBSOLETE(_("please use *smime-ca-no-defaults*, "
1636 "not *smime-no-default-ca*"));
1637 if(!ok_blook(smime_ca_no_defaults
) && !xv15
&&
1638 X509_STORE_set_default_paths(store
) != 1) {
1639 ssl_gen_err(_("Error loading built-in default CA locations\n"));
1644 if (load_crls(store
, ok_v_smime_crl_file
, ok_v_smime_crl_dir
) != OKAY
)
1647 a_xssl_ca_flags(store
, ok_vlook(smime_ca_flags
));
1650 for (ip
= msgvec
; *ip
!= 0; ++ip
) {
1651 struct message
*mp
= message
+ *ip
- 1;
1653 ec
|= smime_verify(mp
, *ip
, NULL
, store
);
1659 n_exit_status
|= n_EXIT_ERR
;
1662 X509_STORE_free(store
);
1668 smime_sign(FILE *ip
, char const *addr
)
1670 FILE *rv
, *sp
, *fp
, *bp
, *hp
;
1672 n_XSSL_STACKOF(X509
) *chain
= NULL
;
1673 EVP_PKEY
*pkey
= NULL
;
1681 assert(addr
!= NULL
);
1682 rv
= sp
= fp
= bp
= hp
= NULL
;
1687 n_err(_("No *from* address for signing specified\n"));
1690 if ((fp
= smime_sign_cert(addr
, NULL
, 1, NULL
)) == NULL
)
1693 if ((pkey
= PEM_read_PrivateKey(fp
, NULL
, &ssl_password_cb
,
1694 savecat(addr
, ".smime-cert-key"))) == NULL
) {
1695 ssl_gen_err(_("Error reading private key from"));
1700 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
,
1701 savecat(addr
, ".smime-cert-cert"))) == NULL
) {
1702 ssl_gen_err(_("Error reading signer certificate from"));
1708 if ((name
= _smime_sign_include_certs(addr
)) != NULL
&&
1709 !_smime_sign_include_chain_creat(&chain
, name
,
1710 savecat(addr
, ".smime-include-certs")))
1714 if ((md
= _smime_sign_digest(addr
, &name
)) == NULL
)
1717 if ((sp
= Ftmp(NULL
, "smimesign", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
1719 n_perr(_("tempfile"), 0);
1724 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
1730 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
1731 (sb
= BIO_new_fp(sp
, BIO_NOCLOSE
)) == NULL
) {
1732 ssl_gen_err(_("Error creating BIO signing objects"));
1738 #define _X PKCS7_DETACHED | PKCS7_PARTIAL
1739 if ((pkcs7
= PKCS7_sign(NULL
, NULL
, chain
, bb
, _X
)) == NULL
) {
1740 ssl_gen_err(_("Error creating the PKCS#7 signing object"));
1744 if (PKCS7_sign_add_signer(pkcs7
, cert
, pkey
, md
, _X
) == NULL
) {
1745 ssl_gen_err(_("Error setting PKCS#7 signing object signer"));
1749 if (!PKCS7_final(pkcs7
, bb
, _X
)) {
1750 ssl_gen_err(_("Error finalizing the PKCS#7 signing object"));
1756 if (PEM_write_bio_PKCS7(sb
, pkcs7
) == 0) {
1757 ssl_gen_err(_("Error writing signed S/MIME data"));
1771 rv
= smime_sign_assemble(hp
, bp
, sp
, name
);
1772 hp
= bp
= sp
= NULL
;
1777 sk_X509_pop_free(chain
, X509_free
);
1781 EVP_PKEY_free(pkey
);
1795 smime_encrypt(FILE *ip
, char const *xcertfile
, char const *to
)
1797 FILE *rv
, *yp
, *fp
, *bp
, *hp
;
1801 n_XSSL_STACKOF(X509
) *certs
;
1802 EVP_CIPHER
const *cipher
;
1808 rv
= yp
= fp
= bp
= hp
= NULL
;
1810 if ((certfile
= fexpand(xcertfile
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
1815 if ((cipher
= _smime_cipher(to
)) == NULL
)
1818 if ((fp
= Fopen(certfile
, "r")) == NULL
) {
1819 n_perr(certfile
, 0);
1822 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, NULL
)) == NULL
) {
1823 ssl_gen_err(_("Error reading encryption certificate from %s"),
1824 n_shexp_quote_cp(certfile
, FAL0
));
1833 certs
= sk_X509_new_null();
1834 sk_X509_push(certs
, cert
);
1836 if ((yp
= Ftmp(NULL
, "smimeenc", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
1838 n_perr(_("tempfile"), 0);
1843 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
1847 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
1848 (yb
= BIO_new_fp(yp
, BIO_NOCLOSE
)) == NULL
) {
1849 ssl_gen_err(_("Error creating BIO encryption objects"));
1853 if ((pkcs7
= PKCS7_encrypt(certs
, bb
, cipher
, 0)) == NULL
) {
1854 ssl_gen_err(_("Error creating the PKCS#7 encryption object"));
1858 if (PEM_write_bio_PKCS7(yb
, pkcs7
) == 0) {
1859 ssl_gen_err(_("Error writing encrypted S/MIME data"));
1874 rv
= smime_encrypt_assemble(hp
, yp
);
1878 sk_X509_pop_free(certs
, X509_free
);
1893 smime_decrypt(struct message
*m
, char const *to
, char const *cc
,
1909 ob
= bb
= pb
= NULL
;
1911 bp
= hp
= op
= NULL
;
1915 if((yp
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
1920 if((op
= smime_sign_cert(to
, cc
, 0, &myaddr
)) != NULL
){
1921 pkey
= PEM_read_PrivateKey(op
, NULL
, &ssl_password_cb
,
1922 savecat(myaddr
, ".smime-cert-key"));
1924 ssl_gen_err(_("Error reading private key"));
1929 if((cert
= PEM_read_X509(op
, NULL
, &ssl_password_cb
,
1930 savecat(myaddr
, ".smime-cert-cert"))) == NULL
){
1931 ssl_gen_err(_("Error reading decryption certificate"));
1939 if((op
= Ftmp(NULL
, "smimedec", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) == NULL
){
1940 n_perr(_("tempfile"), 0);
1944 if(smime_split(yp
, &hp
, &bp
, size
, 1) == STOP
)
1947 if((ob
= BIO_new_fp(op
, BIO_NOCLOSE
)) == NULL
||
1948 (bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
){
1949 ssl_gen_err(_("Error creating BIO decryption objects"));
1953 if((pkcs7
= SMIME_read_PKCS7(bb
, &pb
)) == NULL
){
1954 ssl_gen_err(_("Error reading PKCS#7 object"));
1958 if(PKCS7_type_is_signed(pkcs7
)){
1960 setinput(&mb
, m
, NEED_BODY
);
1961 rv
= (struct message
*)-1;
1964 if(PKCS7_verify(pkcs7
, NULL
, NULL
, NULL
, ob
,
1965 PKCS7_NOVERIFY
| PKCS7_NOSIGS
) != 1)
1967 fseek(hp
, 0L, SEEK_END
);
1968 fprintf(hp
, "X-Encryption-Cipher: none\n");
1970 }else if(pkey
== NULL
){
1971 n_err(_("No appropriate private key found\n"));
1973 }else if(cert
== NULL
){
1974 n_err(_("No appropriate certificate found\n"));
1976 }else if(PKCS7_decrypt(pkcs7
, pkey
, cert
, ob
, 0) != 1){
1978 ssl_gen_err(_("Error decrypting PKCS#7 object"));
1985 rv
= smime_decrypt_assemble(m
, hp
, op
);
1986 hp
= op
= NULL
; /* xxx closed by decrypt_assemble */
2003 EVP_PKEY_free(pkey
);
2009 smime_certsave(struct message
*m
, int n
, FILE *op
)
2012 char *to
, *cc
, *cnttype
;
2018 n_XSSL_STACKOF(X509
) *certs
, *chain
= NULL
;
2020 enum okay rv
= STOP
;
2025 a_xssl_msgno
= (size_t)n
;
2027 to
= hfield1("to", m
);
2028 cc
= hfield1("cc", m
);
2029 cnttype
= hfield1("content-type", m
);
2031 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2036 #define _X (sizeof("application/") -1)
2037 #define _Y(X) X, sizeof(X) -1
2038 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
2039 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
2040 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
2043 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
2045 if (x
!= (struct message
*)-1) {
2052 if ((fp
= Ftmp(NULL
, "smimecert", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2054 n_perr(_("tempfile"), 0);
2058 while (size
-- > 0) {
2065 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
2066 ssl_gen_err("Error creating BIO object for message %d", n
);
2071 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
2072 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
2080 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
2081 if (certs
== NULL
) {
2082 n_err(_("No certificates found in message %d\n"), n
);
2086 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
2087 cert
= sk_X509_value(certs
, i
);
2088 if (X509_print_fp(op
, cert
) == 0 || PEM_write_X509(op
, cert
) == 0) {
2089 ssl_gen_err(_("Error writing certificate %d from message %d"),
2101 #endif /* HAVE_XSSL */