1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ OpenSSL client implementation according to: John Viega, Matt Messier,
3 *@ Pravir Chandra: Network Security with OpenSSL. Sebastopol, CA 2002.
4 *@ TODO This needs an overhaul -- there _are_ stack leaks!?
6 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
7 * Copyright (c) 2012 - 2018 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
11 * Gunnar Ritter. All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by Gunnar Ritter
24 * and his contributors.
25 * 4. Neither the name of Gunnar Ritter nor the names of his contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #ifndef HAVE_AMALGAMATION
50 #include <sys/socket.h>
52 #include <openssl/crypto.h>
53 #include <openssl/err.h>
54 #include <openssl/evp.h>
55 #include <openssl/opensslv.h>
56 #include <openssl/pem.h>
57 #include <openssl/rand.h>
58 #include <openssl/ssl.h>
59 #include <openssl/x509v3.h>
60 #include <openssl/x509.h>
62 #ifdef HAVE_XSSL_CONFIG
63 # include <openssl/conf.h>
66 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
70 /* Compatibility shims which assume 0/-1 cannot really happen */
71 #ifndef HAVE_XSSL_CONF_CTX
72 # ifndef SSL_OP_NO_SSLv2
73 # define SSL_OP_NO_SSLv2 0
75 # ifndef SSL_OP_NO_SSLv3
76 # define SSL_OP_NO_SSLv3 0
78 # ifndef SSL_OP_NO_TLSv1
79 # define SSL_OP_NO_TLSv1 0
81 # ifndef SSL_OP_NO_TLSv1_1
82 # define SSL_OP_NO_TLSv1_1 0
84 # ifndef SSL_OP_NO_TLSv1_2
85 # define SSL_OP_NO_TLSv1_2 0
87 /* SSL_CONF_CTX and _OP_NO_SSL_MASK were both introduced with 1.0.2!?! */
88 # ifndef SSL_OP_NO_SSL_MASK
89 # define SSL_OP_NO_SSL_MASK \
90 (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |\
91 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2)
95 # define SSL2_VERSION 0
98 # define SSL3_VERSION 0
100 # ifndef TLS1_VERSION
101 # define TLS1_VERSION 0
103 # ifndef TLS1_1_VERSION
104 # define TLS1_1_VERSION 0
106 # ifndef TLS1_2_VERSION
107 # define TLS1_2_VERSION 0
111 #ifdef HAVE_XSSL_STACK_OF
112 # define n_XSSL_STACKOF(X) STACK_OF(X)
114 # define n_XSSL_STACKOF(X) /*X*/STACK
117 #if OPENSSL_VERSION_NUMBER + 0 >= 0x0090581fL
118 # define a_XSSL_RAND_LOAD_FILE_MAXBYTES -1
120 # define a_XSSL_RAND_LOAD_FILE_MAXBYTES 1024
123 /* Compatibility sighs (that sigh is _really_ a cute one) */
124 #if HAVE_XSSL_OPENSSL >= 0x10100
125 # define a_xssl_X509_get_notBefore X509_get0_notBefore
126 # define a_xssl_X509_get_notAfter X509_get0_notAfter
128 # define a_xssl_X509_get_notBefore X509_get_notBefore
129 # define a_xssl_X509_get_notAfter X509_get_notAfter
132 /* X509_STORE_set_flags */
133 #undef a_XSSL_X509_V_ANY
134 #ifndef X509_V_FLAG_NO_ALT_CHAINS
135 # define X509_V_FLAG_NO_ALT_CHAINS -1
137 # undef a_XSSL_X509_V_ANY
138 # define a_XSSL_X509_V_ANY
140 #ifndef X509_V_FLAG_NO_CHECK_TIME
141 # define X509_V_FLAG_NO_CHECK_TIME -1
143 # undef a_XSSL_X509_V_ANY
144 # define a_XSSL_X509_V_ANY
146 #ifndef X509_V_FLAG_PARTIAL_CHAIN
147 # define X509_V_FLAG_PARTIAL_CHAIN -1
149 # undef a_XSSL_X509_V_ANY
150 # define a_XSSL_X509_V_ANY
152 #ifndef X509_V_FLAG_X509_STRICT
153 # define X509_V_FLAG_X509_STRICT -1
155 # undef a_XSSL_X509_V_ANY
156 # define a_XSSL_X509_V_ANY
158 #ifndef X509_V_FLAG_TRUSTED_FIRST
159 # define X509_V_FLAG_TRUSTED_FIRST -1
161 # undef a_XSSL_X509_V_ANY
162 # define a_XSSL_X509_V_ANY
166 a_XSSL_S_INIT
= 1u<<0,
167 a_XSSL_S_RAND_INIT
= 1u<<1,
168 a_XSSL_S_CONF_LOAD
= 1u<<2,
170 #if HAVE_XSSL_OPENSSL < 0x10100
171 a_XSSL_S_EXIT_HDL
= 1u<<8,
172 a_XSSL_S_ALGO_LOAD
= 1u<<9,
175 a_XSSL_S_VERIFY_ERROR
= 1u<<16
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
{
185 char const sp_name
[8];
186 sl_i sp_op_no
; /* SSL_OP_NO_* bit */
187 ui16_t sp_version
; /* *_VERSION number */
188 bool_t sp_ok_minmaxproto
; /* Valid for {Min,Max}Protocol= */
189 bool_t sp_ok_proto
; /* Valid for Protocol= */
194 struct a_xssl_smime_cipher
{
195 char const sc_name
[8];
196 EVP_CIPHER
const *(*sc_fun
)(void);
199 struct a_xssl_smime_digest
{
200 char const sd_name
[8];
201 EVP_MD
const *(*sd_fun
)(void);
204 struct a_xssl_x509_v_flags
{
205 char const xvf_name
[20];
209 /* Supported SSL/TLS methods: update manual on change! */
210 static struct ssl_method
const _ssl_methods
[] = { /* TODO obsolete */
211 {"auto", "ALL,-SSLv2"},
212 {"ssl3", "-ALL,SSLv3"},
213 {"tls1", "-ALL,TLSv1"},
214 {"tls1.1", "-ALL,TLSv1.1"},
215 {"tls1.2", "-ALL,TLSv1.2"}
218 /* Update manual on change!
219 * Ensure array size by adding \0 to longest entry.
220 * Strictly to be sorted new/up to old/down, [0]=ALL, [x-1]=None! */
221 #ifndef HAVE_XSSL_CONF_CTX
222 static struct a_xssl_protocol
const a_xssl_protocols
[] = {
223 {"ALL", SSL_OP_NO_SSL_MASK
, 0, FAL0
, TRU1
, {0}},
224 {"TLSv1.2\0", SSL_OP_NO_TLSv1_2
, TLS1_2_VERSION
, TRU1
, TRU1
, {0}},
225 {"TLSv1.1", SSL_OP_NO_TLSv1_1
, TLS1_1_VERSION
, TRU1
, TRU1
, {0}},
226 {"TLSv1", SSL_OP_NO_TLSv1
, TLS1_VERSION
, TRU1
, TRU1
, {0}},
227 {"SSLv3", SSL_OP_NO_SSLv3
, SSL3_VERSION
, TRU1
, TRU1
, {0}},
228 {"SSLv2", SSL_OP_NO_SSLv2
, SSL2_VERSION
, TRU1
, TRU1
, {0}},
229 {"None", SSL_OP_NO_SSL_MASK
, 0, TRU1
, FAL0
, {0}}
231 #endif /* HAVE_XSSL_CONF_CTX */
233 /* Supported S/MIME cipher algorithms */
234 static struct a_xssl_smime_cipher
const a_xssl_smime_ciphers
[] = { /* Manual! */
235 #ifndef OPENSSL_NO_AES
236 # define a_XSSL_SMIME_DEFAULT_CIPHER EVP_aes_128_cbc /* According to RFC 5751 */
237 {"aes128", &EVP_aes_128_cbc
},
238 {"aes256", &EVP_aes_256_cbc
},
239 {"aes192", &EVP_aes_192_cbc
},
241 #ifndef OPENSSL_NO_DES
242 # ifndef a_XSSL_SMIME_DEFAULT_CIPHER
243 # define a_XSSL_SMIME_DEFAULT_CIPHER EVP_des_ede3_cbc
245 {"des3", &EVP_des_ede3_cbc
},
246 {"des", &EVP_des_cbc
},
249 #ifndef a_XSSL_SMIME_DEFAULT_CIPHER
250 # error Your OpenSSL library does not include the necessary
251 # error cipher algorithms that are required to support S/MIME
254 #ifndef OPENSSL_NO_AES
255 /* TODO obsolete a_xssl_smime_ciphers_obs */
256 static struct a_xssl_smime_cipher
const a_xssl_smime_ciphers_obs
[] = {
257 {"aes-128", &EVP_aes_128_cbc
},
258 {"aes-256", &EVP_aes_256_cbc
},
259 {"aes-192", &EVP_aes_192_cbc
}
263 /* Supported S/MIME message digest algorithms */
264 static struct a_xssl_smime_digest
const a_xssl_smime_digests
[] = { /* Manual! */
265 #define a_XSSL_SMIME_DEFAULT_DIGEST EVP_sha1 /* According to RFC 5751 */
266 #define a_XSSL_SMIME_DEFAULT_DIGEST_S "sha1"
268 {"sha256", &EVP_sha256
},
269 {"sha512", &EVP_sha512
},
270 {"sha384", &EVP_sha384
},
271 {"sha224", &EVP_sha224
},
272 #ifndef OPENSSL_NO_MD5
277 /* X509_STORE_set_flags() for *{smime,ssl}-ca-flags* */
278 static struct a_xssl_x509_v_flags
const a_xssl_x509_v_flags
[] = { /* Manual! */
279 {"no-alt-chains", X509_V_FLAG_NO_ALT_CHAINS
},
280 {"no-check-time", X509_V_FLAG_NO_CHECK_TIME
},
281 {"partial-chain", X509_V_FLAG_PARTIAL_CHAIN
},
282 {"strict", X509_V_FLAG_X509_STRICT
},
283 {"trusted-first", X509_V_FLAG_TRUSTED_FIRST
},
286 static enum a_xssl_state a_xssl_state
;
287 static size_t a_xssl_msgno
;
289 static void a_xssl_rand_init(void);
290 static void a_xssl_init(void);
292 #if HAVE_XSSL_OPENSSL < 0x10100
293 # ifdef HAVE_SSL_ALL_ALGORITHMS
294 static void a_xssl__load_algos(void);
295 # define a_xssl_load_algos a_xssl__load_algos
297 # if defined HAVE_XSSL_CONFIG || defined HAVE_SSL_ALL_ALGORITHMS
298 static void a_xssl_atexit(void);
301 #ifndef a_xssl_load_algos
302 # define a_xssl_load_algos() do{;}while(0)
305 static bool_t
_ssl_parse_asn1_time(ASN1_TIME
const *atp
,
306 char *bdat
, size_t blen
);
307 static int _ssl_verify_cb(int success
, X509_STORE_CTX
*store
);
309 /* *smime-ca-flags*, *ssl-ca-flags* */
310 static void a_xssl_ca_flags(X509_STORE
*store
, char const *flags
);
312 /* SSL_CTX configuration */
313 static void * a_xssl_conf_setup(SSL_CTX
*ctxp
, struct url
const *urlp
);
314 static bool_t
a_xssl_conf(void *confp
, char const *cmd
, char const *value
);
315 static bool_t
a_xssl_conf_finish(void **confp
, bool_t error
);
317 static bool_t
a_xssl_obsolete_conf_vars(void *confp
, struct url
const *urlp
);
318 static bool_t
a_xssl_config_pairs(void *confp
, struct url
const *urlp
);
319 static bool_t
a_xssl_load_verifications(SSL_CTX
*ctxp
, struct url
const *urlp
);
321 static enum okay
ssl_check_host(struct sock
*sp
, struct url
const *urlp
);
323 static int smime_verify(struct message
*m
, int n
,
324 n_XSSL_STACKOF(X509
) *chain
, X509_STORE
*store
);
325 static EVP_CIPHER
const * _smime_cipher(char const *name
);
326 static int ssl_password_cb(char *buf
, int size
, int rwflag
,
328 static FILE * smime_sign_cert(char const *xname
, char const *xname2
,
329 bool_t dowarn
, char const **match
);
330 static char const * _smime_sign_include_certs(char const *name
);
331 static bool_t
_smime_sign_include_chain_creat(n_XSSL_STACKOF(X509
) **chain
,
332 char const *cfiles
, char const *addr
);
333 static EVP_MD
const * _smime_sign_digest(char const *name
,
334 char const **digname
);
335 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
336 static enum okay
load_crl1(X509_STORE
*store
, char const *name
);
338 static enum okay
load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
);
341 a_xssl_rand_init(void){
342 #define a_XSSL_RAND_ENTROPY 32
343 char b64buf
[a_XSSL_RAND_ENTROPY
* 5 +1], *randfile
;
348 a_xssl_state
|= a_XSSL_S_RAND_INIT
;
353 #ifdef HAVE_XSSL_CONFIG
354 if(!(a_xssl_state
& a_XSSL_S_INIT
))
358 /* Shall use some external daemon? */
359 if((cp
= ok_vlook(ssl_rand_egd
)) != NULL
){
360 #ifdef HAVE_XSSL_RAND_EGD
361 if((x
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) != NULL
&&
362 RAND_egd(cp
= x
) != -1){
366 n_err(_("*ssl_rand_egd* daemon at %s not available\n"),
367 n_shexp_quote_cp(cp
, FAL0
));
369 if(n_poption
& n_PO_D_VV
)
370 n_err(_("*ssl_rand_egd* (%s): unsupported by SSL library\n"),
371 n_shexp_quote_cp(cp
, FAL0
));
375 /* Prefer possible user setting */
376 if((cp
= ok_vlook(ssl_rand_file
)) != NULL
){
379 if((x
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
380 n_err(_("*ssl-rand-file*: expansion of %s failed "
381 "(using OpenSSL default)\n"),
382 n_shexp_quote_cp(cp
, FAL0
));
387 randfile
= n_lofi_alloc(PATH_MAX
);
388 if((cp
= RAND_file_name(randfile
, PATH_MAX
)) == NULL
){
389 n_err(_("*ssl-rand-file*: no SSL entropy file, can't seed PRNG\n"));
394 (void)RAND_load_file(cp
, a_XSSL_RAND_LOAD_FILE_MAXBYTES
);
396 /* And feed in some data, then write the updated file.
397 * While this rather feeds the PRNG with itself in the n_RANDOM_USE_XSSL
398 * case, let us stir the buffer a little bit.
399 * Estimate a low but likely still too high number of entropy bytes, use
400 * 20%: base64 uses 3 input = 4 output bytes relation, and the base64
401 * alphabet is a 6 bit one */
402 n_LCTAV(n_RANDOM_USE_XSSL
== 0 || n_RANDOM_USE_XSSL
== 1);
403 for(x
= (char*)-1;;){
404 RAND_add(n_random_create_buf(b64buf
, sizeof(b64buf
) -1, NULL
),
405 sizeof(b64buf
) -1, a_XSSL_RAND_ENTROPY
);
406 if((x
= (char*)((uintptr_t)x
>> (1 + (n_RANDOM_USE_XSSL
* 3)))) == NULL
){
407 err
= (RAND_status() == 0);
410 #if !n_RANDOM_USE_XSSL
411 if(!(err
= (RAND_status() == 0)))
417 err
= (RAND_write_file(cp
) == -1);
421 n_lofi_free(randfile
);
423 n_panic(_("Cannot seed the *SSL PseudoRandomNumberGenerator, "
424 "RAND_status() is 0!\n"
425 " Please set *ssl-rand-file* to a file with sufficient entropy.\n"
426 " On a machine with entropy: "
427 "\"$ dd if=/dev/urandom of=FILE bs=1024 count=1\"\n"));
433 #ifdef HAVE_XSSL_CONFIG
438 if(a_xssl_state
& a_XSSL_S_INIT
)
441 #if HAVE_XSSL_OPENSSL >= 0x10100
442 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
443 OPENSSL_INIT_LOAD_CRYPTO_STRINGS
444 # ifdef HAVE_SSL_ALL_ALGORITHMS
445 | OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
449 SSL_load_error_strings();
453 a_xssl_state
|= a_XSSL_S_INIT
;
456 /* Load openssl.cnf or whatever was given in *ssl-config-file* */
457 #ifdef HAVE_XSSL_CONFIG
458 if((cp
= ok_vlook(ssl_config_file
)) != NULL
){
465 flags
= CONF_MFLAGS_IGNORE_MISSING_FILE
;
466 }else if((msg
= cp
, cp
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) != NULL
)
469 n_err(_("*ssl-config-file*: file expansion failed: %s\n"),
470 n_shexp_quote_cp(msg
, FAL0
));
474 if(CONF_modules_load_file(cp
, n_uagent
, flags
) == 1){
475 a_xssl_state
|= a_XSSL_S_CONF_LOAD
;
476 # if HAVE_XSSL_OPENSSL < 0x10100
477 if(!(a_xssl_state
& a_XSSL_S_EXIT_HDL
)){
478 a_xssl_state
|= a_XSSL_S_EXIT_HDL
;
479 atexit(&a_xssl_atexit
); /* TODO generic program-wide event mech. */
482 if(n_poption
& n_PO_D_V
)
483 n_err(_("Loaded SSL/TLS configuration for %s from %s\n"), n_uagent
,
484 n_shexp_quote_cp(msg
, FAL0
));
487 ssl_gen_err(_("SSL/TLS CONF_modules_load_file() load error"));
489 #endif /* HAVE_XSSL_CONFIG */
491 if(!(a_xssl_state
& a_XSSL_S_RAND_INIT
))
497 #if HAVE_XSSL_OPENSSL < 0x10100
498 # ifdef HAVE_SSL_ALL_ALGORITHMS
500 a_xssl__load_algos(void){
502 if(!(a_xssl_state
& a_XSSL_S_ALGO_LOAD
)){
503 a_xssl_state
|= a_XSSL_S_ALGO_LOAD
;
504 OpenSSL_add_all_algorithms();
506 if(!(a_xssl_state
& a_XSSL_S_EXIT_HDL
)){
507 a_xssl_state
|= a_XSSL_S_EXIT_HDL
;
508 atexit(&a_xssl_atexit
); /* TODO generic program-wide event mech. */
515 # if defined HAVE_XSSL_CONFIG || defined HAVE_SSL_ALL_ALGORITHMS
519 # ifdef HAVE_XSSL_CONFIG
520 if(a_xssl_state
& a_XSSL_S_CONF_LOAD
)
524 # ifdef HAVE_SSL_ALL_ALGORITHMS
525 if(a_xssl_state
& a_XSSL_S_ALGO_LOAD
)
531 #endif /* HAVE_XSSL_OPENSSL < 0x10100 */
534 _ssl_parse_asn1_time(ASN1_TIME
const *atp
, char *bdat
, size_t blen
)
541 mbp
= BIO_new(BIO_s_mem());
543 if (ASN1_TIME_print(mbp
, atp
) && (l
= BIO_get_mem_data(mbp
, &mcp
)) > 0)
544 snprintf(bdat
, blen
, "%.*s", (int)l
, mcp
);
546 snprintf(bdat
, blen
, _("Bogus certificate date: %.*s"),
547 /*is (int)*/atp
->length
, (char const*)atp
->data
);
553 return (mcp
!= NULL
);
557 _ssl_verify_cb(int success
, X509_STORE_CTX
*store
)
564 if (success
&& !(n_poption
& n_PO_D_V
))
567 if (a_xssl_msgno
!= 0) {
568 n_err(_("Message %lu:\n"), (ul_i
)a_xssl_msgno
);
571 n_err(_(" Certificate depth %d %s\n"),
572 X509_STORE_CTX_get_error_depth(store
), (success
? n_empty
: V_(n_error
)));
574 if ((cert
= X509_STORE_CTX_get_current_cert(store
)) != NULL
) {
575 X509_NAME_oneline(X509_get_subject_name(cert
), data
, sizeof data
);
576 n_err(_(" subject = %s\n"), data
);
578 _ssl_parse_asn1_time(a_xssl_X509_get_notBefore(cert
), data
, sizeof data
);
579 n_err(_(" notBefore = %s\n"), data
);
581 _ssl_parse_asn1_time(a_xssl_X509_get_notAfter(cert
), data
, sizeof data
);
582 n_err(_(" notAfter = %s\n"), data
);
584 X509_NAME_oneline(X509_get_issuer_name(cert
), data
, sizeof data
);
585 n_err(_(" issuer = %s\n"), data
);
589 int err
= X509_STORE_CTX_get_error(store
);
591 n_err(_(" err %i: %s\n"), err
, X509_verify_cert_error_string(err
));
592 a_xssl_state
|= a_XSSL_S_VERIFY_ERROR
;
595 if (!success
&& ssl_verify_decide() != OKAY
)
603 a_xssl_ca_flags(X509_STORE
*store
, char const *flags
){
608 iolist
= savestr(flags
);
610 while((cp
= n_strsep(&iolist
, ',', TRU1
)) != NULL
){
611 struct a_xssl_x509_v_flags
const *xvfp
;
613 for(xvfp
= &a_xssl_x509_v_flags
[0];
614 xvfp
< &a_xssl_x509_v_flags
[n_NELEM(a_xssl_x509_v_flags
)];
616 if(!asccasecmp(cp
, xvfp
->xvf_name
)){
617 if(xvfp
->xvf_flag
!= -1){
618 #ifdef a_XSSL_X509_V_ANY
619 X509_STORE_set_flags(store
, xvfp
->xvf_flag
);
621 }else if(n_poption
& n_PO_D_V
)
622 n_err(_("*{smime,ssl}-ca-flags*: "
623 "directive not supported: %s\n"), cp
);
626 n_err(_("*{smime,ssl}-ca-flags*: invalid directive: %s\n"), cp
);
632 #ifdef HAVE_XSSL_CONF_CTX
634 a_xssl_conf_setup(SSL_CTX
*ctxp
, struct url
const *urlp
){
641 if((cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
642 # ifdef HAVE_XSSL_CTX_CONFIG
643 if(!(a_xssl_state
& a_XSSL_S_CONF_LOAD
)){
644 n_err(_("*ssl-config-module*: no *ssl-config-file* loaded: %s\n"),
645 n_shexp_quote_cp(cp
, FAL0
));
647 }else if(!SSL_CTX_config(ctxp
, cp
)){
648 ssl_gen_err(_("*ssl-config-module*: load error for %s, section [%s]"),
649 n_uagent
, n_shexp_quote_cp(cp
, FAL0
));
653 n_err(_("*ssl-config-module*: set but not supported: %s\n"),
654 n_shexp_quote_cp(cp
, FAL0
));
659 if((sccp
= SSL_CONF_CTX_new()) != NULL
){
660 SSL_CONF_CTX_set_flags(sccp
,
661 SSL_CONF_FLAG_FILE
| SSL_CONF_FLAG_CLIENT
|
662 SSL_CONF_FLAG_CERTIFICATE
| SSL_CONF_FLAG_SHOW_ERRORS
);
664 SSL_CONF_CTX_set_ssl_ctx(sccp
, ctxp
);
666 ssl_gen_err(_("SSL_CONF_CTX_new() failed"));
673 a_xssl_conf(void *confp
, char const *cmd
, char const *value
){
678 if(n_poption
& n_PO_D_V
)
679 n_err(_("SSL/TLS: applying config: %s = %s\n"),
680 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
682 rv
= SSL_CONF_cmd(sccp
= confp
, cmd
, value
);
686 cmd
= n_shexp_quote_cp(cmd
, FAL0
);
687 value
= n_shexp_quote_cp(value
, FAL0
);
689 ssl_gen_err(_("SSL/TLS: config failure: %s = %s"), cmd
, value
);
691 n_err(_("SSL/TLS: please report this config error: %s = %s\n"),
700 a_xssl_conf_finish(void **confp
, bool_t error
){
705 sccp
= (SSL_CONF_CTX
**)confp
;
708 rv
= (SSL_CONF_CTX_finish(*sccp
) != 0);
710 SSL_CONF_CTX_free(*sccp
);
717 #else /* HAVE_XSSL_CONF_CTX */
718 # ifdef HAVE_XSSL_CTX_CONFIG
719 # error SSL_CTX_config(3) support unexpected without SSL_CONF_CTX support
723 a_xssl_conf_setup(SSL_CTX
* ctxp
, struct url
const *urlp
){
727 if((cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
728 n_err(_("*ssl-config-module*: set but not supported: %s\n"),
729 n_shexp_quote_cp(cp
, FAL0
));
737 a_xssl_conf(void *confp
, char const *cmd
, char const *value
){
738 char const *xcmd
, *emsg
;
742 if(n_poption
& n_PO_D_V
)
743 n_err(_("SSL/TLS: applying config: %s = %s\n"),
744 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
748 if(!asccasecmp(cmd
, xcmd
= "Certificate")){
749 if(SSL_CTX_use_certificate_chain_file(ctxp
, value
) != 1){
750 emsg
= N_("SSL/TLS: %s: cannot load from file %s\n");
753 }else if(!asccasecmp(cmd
, xcmd
= "CipherList")){
754 if(SSL_CTX_set_cipher_list(ctxp
, value
) != 1){
755 emsg
= N_("SSL/TLS: %s: invalid: %s\n");
758 }else if(!asccasecmp(cmd
, xcmd
= "Curves")){
759 #ifdef SSL_CTRL_SET_CURVES_LIST
760 if(SSL_CTX_set1_curves_list(ctxp
, value
) != 1){
761 emsg
= N_("SSL/TLS: %s: invalid: %s\n");
766 emsg
= N_("SSL/TLS: %s: directive not supported\n");
769 }else if((emsg
= NULL
, !asccasecmp(cmd
, xcmd
= "MaxProtocol")) ||
770 (emsg
= (char*)-1, !asccasecmp(cmd
, xcmd
= "MinProtocol"))){
771 #ifndef HAVE_XSSL_SET_MIN_PROTO_VERSION
773 emsg
= N_("SSL/TLS: %s: directive not supported\n");
776 struct a_xssl_protocol
const *xpp
;
779 for(i
= 1 /* [0] == ALL */;;){
780 xpp
= &a_xssl_protocols
[i
];
782 if(xpp
->sp_ok_minmaxproto
&& !asccasecmp(value
, xpp
->sp_name
))
785 if(++i
>= n_NELEM(a_xssl_protocols
)){
786 emsg
= N_("SSL/TLS: %s: unsupported element: %s\n");
791 if((emsg
== NULL
? SSL_CTX_set_max_proto_version(ctxp
, xpp
->sp_version
)
792 : SSL_CTX_set_min_proto_version(ctxp
, xpp
->sp_version
)) != 1){
793 emsg
= N_("SSL/TLS: %s: invalid protocol: %s\n");
796 #endif /* !HAVE_XSSL_SET_MIN_PROTO_VERSION */
797 }else if(!asccasecmp(cmd
, xcmd
= "Options")){
798 if(asccasecmp(value
, "Bugs")){
799 emsg
= N_("SSL/TLS: %s: fallback only supports value \"Bugs\": %s\n");
802 SSL_CTX_set_options(ctxp
, SSL_OP_ALL
);
803 }else if(!asccasecmp(cmd
, xcmd
= "PrivateKey")){
804 if(SSL_CTX_use_PrivateKey_file(ctxp
, value
, SSL_FILETYPE_PEM
) != 1){
805 emsg
= N_("%s: cannot load from file %s\n");
808 }else if(!asccasecmp(cmd
, xcmd
= "Protocol")){
809 char *iolist
, *cp
, addin
;
815 for(iolist
= cp
= savestr(value
);
816 (cp
= n_strsep(&iolist
, ',', FAL0
)) != NULL
;){
819 emsg
= N_("SSL/TLS: %s: empty elements are not supported\n");
825 case '-': addin
= FAL0
; /* FALLTHRU */
826 case '+': ++cp
; /* FALLTHRU */
831 struct a_xssl_protocol
const *xpp
;
833 xpp
= &a_xssl_protocols
[i
];
835 if(xpp
->sp_ok_proto
&& !asccasecmp(cp
, xpp
->sp_name
)){
836 /* We need to inverse the meaning of the _NO_s */
838 opts
|= xpp
->sp_op_no
;
840 opts
&= ~xpp
->sp_op_no
;
844 if(++i
>= n_NELEM(a_xssl_protocols
)){
845 emsg
= N_("SSL/TLS: %s: unsupported element: %s\n");
851 SSL_CTX_clear_options(ctxp
, SSL_OP_NO_SSL_MASK
);
852 SSL_CTX_set_options(ctxp
, opts
);
854 xcmd
= n_shexp_quote_cp(cmd
, FAL0
);
855 emsg
= N_("SSL/TLS: unsupported directive: %s: value: %s\n");
861 return (confp
!= NULL
);
863 ssl_gen_err(V_(emsg
), xcmd
, n_shexp_quote_cp(value
, FAL0
));
868 value
= n_shexp_quote_cp(value
, FAL0
);
869 n_err(V_(emsg
), xcmd
, value
);
875 a_xssl_conf_finish(void **confp
, bool_t error
){
880 #endif /* !HAVE_XSSL_CONF_CTX */
883 a_xssl_obsolete_conf_vars(void *confp
, struct url
const *urlp
){
884 char const *cp
, *cp_base
, *certchain
;
890 /* Certificate via ssl-cert */
891 if((certchain
= cp
= xok_vlook(ssl_cert
, urlp
, OXM_ALL
)) != NULL
){
892 n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-cert*"));
893 if((cp_base
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
894 n_err(_("*ssl-cert* value expansion failed: %s\n"),
895 n_shexp_quote_cp(cp
, FAL0
));
898 if(!a_xssl_conf(confp
, "Certificate", certchain
= cp_base
))
902 /* CipherList via ssl-ciper-list */
903 if((cp
= xok_vlook(ssl_cipher_list
, urlp
, OXM_ALL
)) != NULL
){
904 n_OBSOLETE(_("please use *ssl-config-pairs* instead of "
905 "*ssl-cipher-list*"));
906 if(!a_xssl_conf(confp
, "CipherList", cp
))
910 /* Curves via ssl-curves */
911 if((cp
= xok_vlook(ssl_curves
, urlp
, OXM_ALL
)) != NULL
){
912 n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-curves*"));
913 if(!a_xssl_conf(confp
, "Curves", cp
))
917 /* PrivateKey via ssl-key */
918 if((cp
= xok_vlook(ssl_key
, urlp
, OXM_ALL
)) != NULL
){
919 n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-curves*"));
920 if((cp_base
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
921 n_err(_("*ssl-key* value expansion failed: %s\n"),
922 n_shexp_quote_cp(cp
, FAL0
));
926 if(certchain
== NULL
){
927 n_err(_("*ssl-key* can only be used together with *ssl-cert*! "
928 "And use *ssl-config-pairs*!\n"));
932 if((cp
!= NULL
|| (cp
= certchain
) != NULL
) &&
933 !a_xssl_conf(confp
, "PrivateKey", cp
))
936 /* Protocol via ssl-method or ssl-protocol */
937 if((cp
= xok_vlook(ssl_method
, urlp
, OXM_ALL
)) != NULL
){
940 n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-method*"));
942 if(!asccasecmp(_ssl_methods
[i
].sm_name
, cp
)){
943 cp
= _ssl_methods
[i
].sm_map
;
946 if(++i
== n_NELEM(_ssl_methods
)){
947 n_err(_("Unsupported TLS/SSL method: %s\n"), cp
);
952 if((cp_base
= xok_vlook(ssl_protocol
, urlp
, OXM_ALL
)) != NULL
){
953 n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-protocol*"));
954 if(cp
!= NULL
&& (n_poption
& n_PO_D_V
))
955 n_err(_("*ssl-protocol* overrides *ssl-method*! "
956 "And please use *ssl-config-pairs* instead!\n"));
959 if(cp
!= NULL
&& !a_xssl_conf(confp
, "Protocol", cp
))
969 a_xssl_config_pairs(void *confp
, struct url
const *urlp
){
970 /* Due to interdependencies some commands have to be delayed a bit */
971 static char const cmdcert
[] = "Certificate", cmdprivkey
[] = "PrivateKey";
972 char const *valcert
, *valprivkey
;
973 char *pairs
, *cp
, *cmd
, *val
;
976 if((pairs
= n_UNCONST(xok_vlook(ssl_config_pairs
, urlp
, OXM_ALL
))) == NULL
)
978 pairs
= savestr(pairs
);
980 valcert
= valprivkey
= NULL
;
982 while((cp
= n_strsep_esc(&pairs
, ',', FAL0
)) != NULL
){
989 a_EXPAND_MASK
= a_EXPAND
| a_CERT
| a_PRIVKEY
992 /* Directive, space trimmed */
993 if((cmd
= strchr(cp
, '=')) == NULL
){
996 pairs
= n_UNCONST(n_empty
);
997 n_err(_("*ssl-config-pairs*: missing directive: %s; rest: %s\n"),
998 n_shexp_quote_cp(cp
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1003 if((cmd
> cp
&& cmd
[-1] == '*')){
1008 while(cmd
> cp
&& (c
= cmd
[-1], blankspacechar(c
)))
1015 /* Command with special treatment? */
1016 if(!asccasecmp(cmd
, cmdcert
))
1018 else if(!asccasecmp(cmd
, cmdprivkey
))
1021 /* Value, space trimmed */
1022 while((c
= *val
) != '\0' && blankspacechar(c
))
1024 cp
= &val
[strlen(val
)];
1025 while(cp
> val
&& (c
= cp
[-1], blankspacechar(c
)))
1030 pairs
= n_UNCONST(n_empty
);
1031 n_err(_("*ssl-config-pairs*: missing value: %s; rest: %s\n"),
1032 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1036 /* Filename transformations to be applied? */
1037 if(f
& a_EXPAND_MASK
){
1038 if((cp
= fexpand(val
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
1040 pairs
= n_UNCONST(n_empty
);
1041 n_err(_("*ssl-config-pairs*: value expansion failed: %s: %s; "
1043 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(val
, FAL0
),
1044 n_shexp_quote_cp(pairs
, FAL0
));
1050 /* Some things have to be delayed */
1053 else if(f
& a_PRIVKEY
)
1055 else if(!a_xssl_conf(confp
, cmd
, val
)){
1056 pairs
= n_UNCONST(n_empty
);
1061 /* Work the delayed ones */
1062 if((valcert
!= NULL
&& !a_xssl_conf(confp
, cmdcert
, valcert
)) ||
1063 ((valprivkey
!= NULL
|| (valprivkey
= valcert
) != NULL
) &&
1064 !a_xssl_conf(confp
, cmdprivkey
, valprivkey
)))
1065 pairs
= n_UNCONST(n_empty
);
1069 return (pairs
== NULL
);
1073 a_xssl_load_verifications(SSL_CTX
*ctxp
, struct url
const *urlp
){
1074 char *ca_dir
, *ca_file
;
1079 if(ssl_verify_level
== SSL_VERIFY_IGNORE
){
1085 if((ca_dir
= xok_vlook(ssl_ca_dir
, urlp
, OXM_ALL
)) != NULL
)
1086 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
1087 if((ca_file
= xok_vlook(ssl_ca_file
, urlp
, OXM_ALL
)) != NULL
)
1088 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
1090 if((ca_dir
!= NULL
|| ca_file
!= NULL
) &&
1091 SSL_CTX_load_verify_locations(ctxp
, ca_file
, ca_dir
) != 1){
1092 char const *m1
, *m2
, *m3
;
1096 m2
= (ca_file
!= NULL
) ? _(" or ") : n_empty
;
1099 m3
= (ca_file
!= NULL
) ? ca_file
: n_empty
;
1100 ssl_gen_err(_("Error loading %s%s%s\n"), m1
, m2
, m3
);
1107 if((xv15
= ok_blook(ssl_no_default_ca
)))
1108 n_OBSOLETE(_("please use *ssl-ca-no-defaults*, "
1109 "not *ssl-no-default-ca*"));
1110 if(!xok_blook(ssl_ca_no_defaults
, urlp
, OXM_ALL
) && !xv15
&&
1111 SSL_CTX_set_default_verify_paths(ctxp
) != 1) {
1112 ssl_gen_err(_("Error loading built-in default CA locations\n"));
1117 a_xssl_state
&= ~a_XSSL_S_VERIFY_ERROR
;
1119 SSL_CTX_set_verify(ctxp
, SSL_VERIFY_PEER
, &_ssl_verify_cb
);
1120 store
= SSL_CTX_get_cert_store(ctxp
);
1121 load_crls(store
, ok_v_ssl_crl_file
, ok_v_ssl_crl_dir
);
1122 a_xssl_ca_flags(store
, xok_vlook(ssl_ca_flags
, urlp
, OXM_ALL
));
1131 ssl_check_host(struct sock
*sp
, struct url
const *urlp
)
1135 n_XSSL_STACKOF(GENERAL_NAME
) *gens
;
1138 enum okay rv
= STOP
;
1141 if ((cert
= SSL_get_peer_certificate(sp
->s_ssl
)) == NULL
) {
1142 n_err(_("No certificate from: %s\n"), urlp
->url_h_p
.s
);
1146 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
1150 for (i
= 0; i
< sk_GENERAL_NAME_num(gens
); ++i
) {
1151 gen
= sk_GENERAL_NAME_value(gens
, i
);
1152 if (gen
->type
== GEN_DNS
) {
1153 if (n_poption
& n_PO_D_V
)
1154 n_err(_("Comparing subject_alt_name: need<%s> is<%s>\n"),
1155 urlp
->url_host
.s
, (char*)gen
->d
.ia5
->data
);
1156 rv
= rfc2595_hostname_match(urlp
->url_host
.s
,
1157 (char*)gen
->d
.ia5
->data
);
1164 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
1165 X509_NAME_get_text_by_NID(subj
, NID_commonName
, data
, sizeof data
)
1167 data
[sizeof data
- 1] = '\0';
1168 if (n_poption
& n_PO_D_V
)
1169 n_err(_("Comparing commonName: need<%s> is<%s>\n"),
1170 urlp
->url_host
.s
, data
);
1171 rv
= rfc2595_hostname_match(urlp
->url_host
.s
, data
);
1182 smime_verify(struct message
*m
, int n
, n_XSSL_STACKOF(X509
) *chain
,
1185 char data
[LINESIZE
], *sender
, *to
, *cc
, *cnttype
;
1192 n_XSSL_STACKOF(X509
) *certs
;
1193 n_XSSL_STACKOF(GENERAL_NAME
) *gens
;
1204 a_xssl_state
&= ~a_XSSL_S_VERIFY_ERROR
;
1205 a_xssl_msgno
= (size_t)n
;
1208 sender
= getsender(m
);
1209 to
= hfield1("to", m
);
1210 cc
= hfield1("cc", m
);
1211 cnttype
= hfield1("content-type", m
);
1215 #define _X (sizeof("application/") -1)
1216 #define _Y(X) X, sizeof(X) -1
1217 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
1218 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
1219 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
1222 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
1224 if (x
!= (struct message
*)-1) {
1230 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
1236 if ((fp
= Ftmp(NULL
, "smimever", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
1238 n_perr(_("tempfile"), 0);
1241 while (size
-- > 0) {
1247 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
1249 "Error creating BIO verification object for message %d"), n
);
1253 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
1254 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
1257 if (PKCS7_verify(pkcs7
, chain
, store
, pb
, NULL
, 0) != 1) {
1258 ssl_gen_err(_("Error verifying message %d"), n
);
1262 if (sender
== NULL
) {
1263 n_err(_("Warning: Message %d has no sender\n"), n
);
1268 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
1269 if (certs
== NULL
) {
1270 n_err(_("No certificates found in message %d\n"), n
);
1274 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
1275 cert
= sk_X509_value(certs
, i
);
1276 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
1278 for (j
= 0; j
< sk_GENERAL_NAME_num(gens
); ++j
) {
1279 gen
= sk_GENERAL_NAME_value(gens
, j
);
1280 if (gen
->type
== GEN_EMAIL
) {
1281 if (n_poption
& n_PO_D_V
)
1282 n_err(_("Comparing subject_alt_name: need<%s> is<%s>)\n"),
1283 sender
, (char*)gen
->d
.ia5
->data
);
1284 if (!asccasecmp((char*)gen
->d
.ia5
->data
, sender
))
1290 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
1291 X509_NAME_get_text_by_NID(subj
, NID_pkcs9_emailAddress
,
1292 data
, sizeof data
) > 0) {
1293 data
[sizeof data
-1] = '\0';
1294 if (n_poption
& n_PO_D_V
)
1295 n_err(_("Comparing emailAddress: need<%s> is<%s>\n"),
1297 if (!asccasecmp(data
, sender
))
1301 n_err(_("Message %d: certificate does not match <%s>\n"), n
, sender
);
1304 rv
= ((a_xssl_state
& a_XSSL_S_VERIFY_ERROR
) != 0);
1306 fprintf(n_stdout
, _("Message %d was verified successfully\n"), n
);
1309 sk_X509_free(certs
);
1322 static EVP_CIPHER
const *
1323 _smime_cipher(char const *name
)
1325 EVP_CIPHER
const *cipher
;
1331 vn
= ac_alloc(i
= strlen(name
) + sizeof("smime-cipher-") -1 +1);
1332 snprintf(vn
, (int)i
, "smime-cipher-%s", name
);
1333 cp
= n_var_vlook(vn
, FAL0
);
1336 if (cp
== NULL
&& (cp
= ok_vlook(smime_cipher
)) == NULL
) {
1337 cipher
= a_XSSL_SMIME_DEFAULT_CIPHER();
1342 for (i
= 0; i
< n_NELEM(a_xssl_smime_ciphers
); ++i
)
1343 if (!asccasecmp(a_xssl_smime_ciphers
[i
].sc_name
, cp
)) {
1344 cipher
= (*a_xssl_smime_ciphers
[i
].sc_fun
)();
1347 #ifndef OPENSSL_NO_AES
1348 for (i
= 0; i
< n_NELEM(a_xssl_smime_ciphers_obs
); ++i
) /* TODO obsolete */
1349 if (!asccasecmp(a_xssl_smime_ciphers_obs
[i
].sc_name
, cp
)) {
1350 n_OBSOLETE2(_("*smime-cipher* names with hyphens will vanish"), cp
);
1351 cipher
= (*a_xssl_smime_ciphers_obs
[i
].sc_fun
)();
1356 /* Not a built-in algorithm, but we may have dynamic support for more */
1357 #ifdef HAVE_SSL_ALL_ALGORITHMS
1358 if((cipher
= EVP_get_cipherbyname(cp
)) != NULL
)
1362 n_err(_("Invalid S/MIME cipher(s): %s\n"), cp
);
1369 ssl_password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
1378 if(userdata
!= NULL
){
1382 if(url_parse(&url
, CPROTO_CCRED
, userdata
)){
1383 if(ccred_lookup(&cred
, &url
)){
1386 if((slen
= n_strscpy(buf
, cred
.cc_pass
.s
, size
)) >= 0){
1397 if ((pass
= getpassword("PEM pass phrase:")) != NULL
) {
1399 if (UICMP(z
, len
, >=, size
))
1401 memcpy(buf
, pass
, len
);
1412 smime_sign_cert(char const *xname
, char const *xname2
, bool_t dowarn
,
1418 char const *name
= xname
, *name2
= xname2
, *cp
;
1424 np
= lextract(name
, GTO
| GSKIN
);
1425 while (np
!= NULL
) {
1426 /* This needs to be more intelligent since it will currently take the
1427 * first name for which a private key is available regardless of
1428 * whether it is the right one for the message */
1429 vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1430 snprintf(vn
, vs
, "smime-sign-cert-%s", np
->n_name
);
1431 cp
= n_var_vlook(vn
, FAL0
);
1435 *match
= np
->n_name
;
1440 if (name2
!= NULL
) {
1447 if ((cp
= ok_vlook(smime_sign_cert
)) == NULL
)
1452 if ((cp
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
1454 if ((fp
= Fopen(cp
, "r")) == NULL
)
1461 n_err(_("Could not find a certificate for %s%s%s\n"),
1462 xname
, (xname2
!= NULL
? _("or ") : n_empty
),
1463 (xname2
!= NULL
? xname2
: n_empty
));
1468 _smime_sign_include_certs(char const *name
)
1473 /* See comments in smime_sign_cert() for algorithm pitfalls */
1477 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1481 vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1482 snprintf(vn
, vs
, "smime-sign-include-certs-%s", np
->n_name
);
1483 rv
= n_var_vlook(vn
, FAL0
);
1489 rv
= ok_vlook(smime_sign_include_certs
);
1496 _smime_sign_include_chain_creat(n_XSSL_STACKOF(X509
) **chain
,
1497 char const *cfiles
, char const *addr
)
1501 char *nfield
, *cfield
, *x
;
1504 *chain
= sk_X509_new_null();
1506 for (nfield
= savestr(cfiles
);
1507 (cfield
= n_strsep(&nfield
, ',', TRU1
)) != NULL
;) {
1508 if ((x
= fexpand(cfield
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1509 (fp
= Fopen(cfield
= x
, "r")) == NULL
) {
1513 if ((tmp
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, n_UNCONST(addr
))
1515 ssl_gen_err(_("Error reading certificate from %s"),
1516 n_shexp_quote_cp(cfield
, FAL0
));
1520 sk_X509_push(*chain
, tmp
);
1524 if (sk_X509_num(*chain
) == 0) {
1525 n_err(_("*smime-sign-include-certs* defined but empty\n"));
1530 return (*chain
!= NULL
);
1532 sk_X509_pop_free(*chain
, X509_free
);
1537 static EVP_MD
const *
1538 _smime_sign_digest(char const *name
, char const **digname
)
1540 EVP_MD
const *digest
;
1545 /* See comments in smime_sign_cert() for algorithm pitfalls */
1549 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1551 char *vn
= ac_alloc(vs
= strlen(np
->n_name
) + 30);
1552 snprintf(vn
, vs
, "smime-sign-message-digest-%s", np
->n_name
);
1553 cp
= n_var_vlook(vn
, FAL0
);
1560 if ((cp
= ok_vlook(smime_sign_message_digest
)) == NULL
) {
1561 digest
= a_XSSL_SMIME_DEFAULT_DIGEST();
1562 *digname
= a_XSSL_SMIME_DEFAULT_DIGEST_S
;
1568 { char *x
= salloc(i
+1);
1569 i_strcpy(x
, cp
, i
+1);
1574 for (i
= 0; i
< n_NELEM(a_xssl_smime_digests
); ++i
)
1575 if (!asccasecmp(a_xssl_smime_digests
[i
].sd_name
, cp
)) {
1576 digest
= (*a_xssl_smime_digests
[i
].sd_fun
)();
1580 /* Not a built-in algorithm, but we may have dynamic support for more */
1581 #ifdef HAVE_SSL_ALL_ALGORITHMS
1582 if((digest
= EVP_get_digestbyname(cp
)) != NULL
)
1586 n_err(_("Invalid message digest: %s\n"), cp
);
1593 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1595 load_crl1(X509_STORE
*store
, char const *name
)
1597 X509_LOOKUP
*lookup
;
1598 enum okay rv
= STOP
;
1601 if (n_poption
& n_PO_D_V
)
1602 n_err(_("Loading CRL from %s\n"), n_shexp_quote_cp(name
, FAL0
));
1603 if ((lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file())) == NULL
) {
1604 ssl_gen_err(_("Error creating X509 lookup object"));
1607 if (X509_load_crl_file(lookup
, name
, X509_FILETYPE_PEM
) != 1) {
1608 ssl_gen_err(_("Error loading CRL from %s"), n_shexp_quote_cp(name
, FAL0
));
1616 #endif /* new OpenSSL */
1619 load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
)
1621 char *crl_file
, *crl_dir
;
1622 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1628 enum okay rv
= STOP
;
1631 if ((crl_file
= n_var_oklook(fok
)) != NULL
) {
1632 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1633 if ((crl_file
= fexpand(crl_file
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1634 load_crl1(store
, crl_file
) != OKAY
)
1637 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1642 if ((crl_dir
= n_var_oklook(dok
)) != NULL
) {
1643 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1645 if ((x
= fexpand(crl_dir
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1646 (dirp
= opendir(crl_dir
= x
)) == NULL
) {
1651 ds
= strlen(crl_dir
);
1652 fn
= smalloc(fs
= ds
+ 20);
1653 memcpy(fn
, crl_dir
, ds
);
1655 while ((dp
= readdir(dirp
)) != NULL
) {
1656 if (dp
->d_name
[0] == '.' && (dp
->d_name
[1] == '\0' ||
1657 (dp
->d_name
[1] == '.' && dp
->d_name
[2] == '\0')))
1659 if (dp
->d_name
[0] == '.')
1661 if (ds
+ (es
= strlen(dp
->d_name
)) + 2 < fs
)
1662 fn
= srealloc(fn
, fs
= ds
+ es
+ 20);
1663 memcpy(fn
+ ds
+ 1, dp
->d_name
, es
+ 1);
1664 if (load_crl1(store
, fn
) != OKAY
) {
1672 #else /* old OpenSSL */
1673 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1677 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1678 if (crl_file
|| crl_dir
)
1679 X509_STORE_set_flags(store
, X509_V_FLAG_CRL_CHECK
|
1680 X509_V_FLAG_CRL_CHECK_ALL
);
1688 #if n_RANDOM_USE_XSSL
1690 ssl_rand_bytes(void *buf
, size_t blen
){
1693 if(!(a_xssl_state
& a_XSSL_S_RAND_INIT
))
1699 i
= n_MIN(SI32_MAX
, blen
);
1702 buf
= (ui8_t
*)buf
+ i
;
1709 ssl_open(struct url
const *urlp
, struct sock
*sp
){
1718 ssl_set_verify_level(urlp
);
1720 if((ctxp
= SSL_CTX_new(n_XSSL_CLIENT_METHOD())) == NULL
){
1721 ssl_gen_err(_("SSL_CTX_new() failed"));
1725 /* Available with OpenSSL 0.9.6 or later */
1726 #ifdef SSL_MODE_AUTO_RETRY
1727 SSL_CTX_set_mode(ctxp
, SSL_MODE_AUTO_RETRY
);
1730 if((confp
= a_xssl_conf_setup(ctxp
, urlp
)) == NULL
)
1733 if(!a_xssl_obsolete_conf_vars(confp
, urlp
))
1735 if(!a_xssl_config_pairs(confp
, urlp
))
1737 if(!a_xssl_load_verifications(ctxp
, urlp
))
1740 /* Done with context setup, create our new per-connection structure */
1741 if(!a_xssl_conf_finish(&confp
, FAL0
))
1744 if ((sp
->s_ssl
= SSL_new(ctxp
)) == NULL
) {
1745 ssl_gen_err(_("SSL_new() failed"));
1749 /* Try establish SNI extension; even though this is a TLS extension the
1750 * protocol isn't checked once the host name is set, and therefore i've
1751 * refrained from changing so much code just to check out whether we are
1752 * using SSLv3, which should become more and more rare */
1753 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1754 if((urlp
->url_flags
& n_URL_TLS_MASK
) &&
1755 (urlp
->url_flags
& n_URL_HOST_IS_NAME
)){
1756 if(!SSL_set_tlsext_host_name(sp
->s_ssl
, urlp
->url_host
.s
) &&
1757 (n_poption
& n_PO_D_V
))
1758 n_err(_("Hostname cannot be used with ServerNameIndication "
1759 "TLS extension: %s\n"),
1760 n_shexp_quote_cp(urlp
->url_host
.s
, FAL0
));
1764 SSL_set_fd(sp
->s_ssl
, sp
->s_fd
);
1766 if (SSL_connect(sp
->s_ssl
) < 0) {
1767 ssl_gen_err(_("could not initiate SSL/TLS connection"));
1771 if (ssl_verify_level
!= SSL_VERIFY_IGNORE
) {
1772 if (ssl_check_host(sp
, urlp
) != OKAY
) {
1773 n_err(_("Host certificate does not match: %s\n"), urlp
->url_h_p
.s
);
1774 if (ssl_verify_decide() != OKAY
)
1779 /* We're fully setup: since we don't reuse the SSL_CTX (pooh) keep it local
1780 * and free it right now -- it is reference counted by sp->s_ssl.. */
1788 SSL_free(sp
->s_ssl
);
1792 a_xssl_conf_finish(&confp
, TRU1
);
1799 ssl_gen_err(char const *fmt
, ...)
1808 n_err(_(": %s\n"), ERR_error_string(ERR_get_error(), NULL
));
1815 int *msgvec
= vp
, *ip
, ec
= 0, rv
= 1;
1816 X509_STORE
*store
= NULL
;
1817 char *ca_dir
, *ca_file
;
1822 ssl_verify_level
= SSL_VERIFY_STRICT
;
1823 if ((store
= X509_STORE_new()) == NULL
) {
1824 ssl_gen_err(_("Error creating X509 store"));
1827 X509_STORE_set_verify_cb_func(store
, &_ssl_verify_cb
);
1829 if ((ca_dir
= ok_vlook(smime_ca_dir
)) != NULL
)
1830 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
1831 if ((ca_file
= ok_vlook(smime_ca_file
)) != NULL
)
1832 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
1834 if (ca_dir
!= NULL
|| ca_file
!= NULL
) {
1835 if (X509_STORE_load_locations(store
, ca_file
, ca_dir
) != 1) {
1836 ssl_gen_err(_("Error loading %s"),
1837 (ca_file
!= NULL
) ? ca_file
: ca_dir
);
1845 if((xv15
= ok_blook(smime_no_default_ca
)))
1846 n_OBSOLETE(_("please use *smime-ca-no-defaults*, "
1847 "not *smime-no-default-ca*"));
1848 if(!ok_blook(smime_ca_no_defaults
) && !xv15
&&
1849 X509_STORE_set_default_paths(store
) != 1) {
1850 ssl_gen_err(_("Error loading built-in default CA locations\n"));
1855 if (load_crls(store
, ok_v_smime_crl_file
, ok_v_smime_crl_dir
) != OKAY
)
1858 a_xssl_ca_flags(store
, ok_vlook(smime_ca_flags
));
1861 for (ip
= msgvec
; *ip
!= 0; ++ip
) {
1862 struct message
*mp
= message
+ *ip
- 1;
1864 ec
|= smime_verify(mp
, *ip
, NULL
, store
);
1870 n_exit_status
|= n_EXIT_ERR
;
1873 X509_STORE_free(store
);
1879 smime_sign(FILE *ip
, char const *addr
)
1881 FILE *rv
, *sp
, *fp
, *bp
, *hp
;
1883 n_XSSL_STACKOF(X509
) *chain
= NULL
;
1884 EVP_PKEY
*pkey
= NULL
;
1892 assert(addr
!= NULL
);
1893 rv
= sp
= fp
= bp
= hp
= NULL
;
1898 n_err(_("No *from* address for signing specified\n"));
1901 if ((fp
= smime_sign_cert(addr
, NULL
, 1, NULL
)) == NULL
)
1904 if ((pkey
= PEM_read_PrivateKey(fp
, NULL
, &ssl_password_cb
,
1905 savecat(addr
, ".smime-cert-key"))) == NULL
) {
1906 ssl_gen_err(_("Error reading private key from"));
1911 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
,
1912 savecat(addr
, ".smime-cert-cert"))) == NULL
) {
1913 ssl_gen_err(_("Error reading signer certificate from"));
1919 if ((name
= _smime_sign_include_certs(addr
)) != NULL
&&
1920 !_smime_sign_include_chain_creat(&chain
, name
,
1921 savecat(addr
, ".smime-include-certs")))
1925 if ((md
= _smime_sign_digest(addr
, &name
)) == NULL
)
1928 if ((sp
= Ftmp(NULL
, "smimesign", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
1930 n_perr(_("tempfile"), 0);
1935 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
1941 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
1942 (sb
= BIO_new_fp(sp
, BIO_NOCLOSE
)) == NULL
) {
1943 ssl_gen_err(_("Error creating BIO signing objects"));
1949 #define _X PKCS7_DETACHED | PKCS7_PARTIAL
1950 if ((pkcs7
= PKCS7_sign(NULL
, NULL
, chain
, bb
, _X
)) == NULL
) {
1951 ssl_gen_err(_("Error creating the PKCS#7 signing object"));
1955 if (PKCS7_sign_add_signer(pkcs7
, cert
, pkey
, md
, _X
) == NULL
) {
1956 ssl_gen_err(_("Error setting PKCS#7 signing object signer"));
1960 if (!PKCS7_final(pkcs7
, bb
, _X
)) {
1961 ssl_gen_err(_("Error finalizing the PKCS#7 signing object"));
1967 if (PEM_write_bio_PKCS7(sb
, pkcs7
) == 0) {
1968 ssl_gen_err(_("Error writing signed S/MIME data"));
1982 rv
= smime_sign_assemble(hp
, bp
, sp
, name
);
1983 hp
= bp
= sp
= NULL
;
1988 sk_X509_pop_free(chain
, X509_free
);
1992 EVP_PKEY_free(pkey
);
2006 smime_encrypt(FILE *ip
, char const *xcertfile
, char const *to
)
2008 FILE *rv
, *yp
, *fp
, *bp
, *hp
;
2012 n_XSSL_STACKOF(X509
) *certs
;
2013 EVP_CIPHER
const *cipher
;
2019 rv
= yp
= fp
= bp
= hp
= NULL
;
2021 if ((certfile
= fexpand(xcertfile
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
2026 if ((cipher
= _smime_cipher(to
)) == NULL
)
2029 if ((fp
= Fopen(certfile
, "r")) == NULL
) {
2030 n_perr(certfile
, 0);
2033 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, NULL
)) == NULL
) {
2034 ssl_gen_err(_("Error reading encryption certificate from %s"),
2035 n_shexp_quote_cp(certfile
, FAL0
));
2044 certs
= sk_X509_new_null();
2045 sk_X509_push(certs
, cert
);
2047 if ((yp
= Ftmp(NULL
, "smimeenc", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2049 n_perr(_("tempfile"), 0);
2054 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
2058 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
2059 (yb
= BIO_new_fp(yp
, BIO_NOCLOSE
)) == NULL
) {
2060 ssl_gen_err(_("Error creating BIO encryption objects"));
2064 if ((pkcs7
= PKCS7_encrypt(certs
, bb
, cipher
, 0)) == NULL
) {
2065 ssl_gen_err(_("Error creating the PKCS#7 encryption object"));
2069 if (PEM_write_bio_PKCS7(yb
, pkcs7
) == 0) {
2070 ssl_gen_err(_("Error writing encrypted S/MIME data"));
2085 rv
= smime_encrypt_assemble(hp
, yp
);
2089 sk_X509_pop_free(certs
, X509_free
);
2104 smime_decrypt(struct message
*m
, char const *to
, char const *cc
,
2120 ob
= bb
= pb
= NULL
;
2122 bp
= hp
= op
= NULL
;
2126 if((yp
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2131 if((op
= smime_sign_cert(to
, cc
, 0, &myaddr
)) != NULL
){
2132 pkey
= PEM_read_PrivateKey(op
, NULL
, &ssl_password_cb
,
2133 savecat(myaddr
, ".smime-cert-key"));
2135 ssl_gen_err(_("Error reading private key"));
2140 if((cert
= PEM_read_X509(op
, NULL
, &ssl_password_cb
,
2141 savecat(myaddr
, ".smime-cert-cert"))) == NULL
){
2142 ssl_gen_err(_("Error reading decryption certificate"));
2150 if((op
= Ftmp(NULL
, "smimedec", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) == NULL
){
2151 n_perr(_("tempfile"), 0);
2155 if(smime_split(yp
, &hp
, &bp
, size
, 1) == STOP
)
2158 if((ob
= BIO_new_fp(op
, BIO_NOCLOSE
)) == NULL
||
2159 (bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
){
2160 ssl_gen_err(_("Error creating BIO decryption objects"));
2164 if((pkcs7
= SMIME_read_PKCS7(bb
, &pb
)) == NULL
){
2165 ssl_gen_err(_("Error reading PKCS#7 object"));
2169 if(PKCS7_type_is_signed(pkcs7
)){
2171 setinput(&mb
, m
, NEED_BODY
);
2172 rv
= (struct message
*)-1;
2175 if(PKCS7_verify(pkcs7
, NULL
, NULL
, NULL
, ob
,
2176 PKCS7_NOVERIFY
| PKCS7_NOSIGS
) != 1)
2178 fseek(hp
, 0L, SEEK_END
);
2179 fprintf(hp
, "X-Encryption-Cipher: none\n");
2181 }else if(pkey
== NULL
){
2182 n_err(_("No appropriate private key found\n"));
2184 }else if(cert
== NULL
){
2185 n_err(_("No appropriate certificate found\n"));
2187 }else if(PKCS7_decrypt(pkcs7
, pkey
, cert
, ob
, 0) != 1){
2189 ssl_gen_err(_("Error decrypting PKCS#7 object"));
2196 rv
= smime_decrypt_assemble(m
, hp
, op
);
2197 hp
= op
= NULL
; /* xxx closed by decrypt_assemble */
2214 EVP_PKEY_free(pkey
);
2220 smime_certsave(struct message
*m
, int n
, FILE *op
)
2223 char *to
, *cc
, *cnttype
;
2229 n_XSSL_STACKOF(X509
) *certs
, *chain
= NULL
;
2231 enum okay rv
= STOP
;
2236 a_xssl_msgno
= (size_t)n
;
2238 to
= hfield1("to", m
);
2239 cc
= hfield1("cc", m
);
2240 cnttype
= hfield1("content-type", m
);
2242 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2247 #define _X (sizeof("application/") -1)
2248 #define _Y(X) X, sizeof(X) -1
2249 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
2250 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
2251 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
2254 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
2256 if (x
!= (struct message
*)-1) {
2263 if ((fp
= Ftmp(NULL
, "smimecert", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2265 n_perr(_("tempfile"), 0);
2269 while (size
-- > 0) {
2276 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
2277 ssl_gen_err("Error creating BIO object for message %d", n
);
2282 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
2283 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
2291 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
2292 if (certs
== NULL
) {
2293 n_err(_("No certificates found in message %d\n"), n
);
2297 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
2298 cert
= sk_X509_value(certs
, i
);
2299 if (X509_print_fp(op
, cert
) == 0 || PEM_write_X509(op
, cert
) == 0) {
2300 ssl_gen_err(_("Error writing certificate %d from message %d"),
2312 #endif /* HAVE_XSSL */