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.
5 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
6 * Copyright (c) 2012 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
7 * SPDX-License-Identifier: BSD-4-Clause TODO ISC
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
45 #ifndef mx_HAVE_AMALGAMATION
50 #ifdef mx_HAVE_XTLS /* Shorthand for mx_HAVE_TLS==mx_TLS_IMPL{...} */
51 #include <sys/socket.h>
53 #include <openssl/crypto.h>
54 #include <openssl/err.h>
55 #include <openssl/evp.h>
56 #include <openssl/opensslv.h>
57 #include <openssl/pem.h>
58 #include <openssl/rand.h>
59 #include <openssl/ssl.h>
60 #include <openssl/x509v3.h>
61 #include <openssl/x509.h>
63 #ifdef mx_XTLS_HAVE_CONFIG
64 # include <openssl/conf.h>
66 #ifdef mx_XTLS_HAVE_SET_RESEED_DEFAULTS
67 # include <openssl/rand_drbg.h>
70 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
77 #include "mx/cred-auth.h"
78 #include "mx/file-streams.h"
80 #include "mx/net-socket.h"
81 #include "mx/random.h"
86 #include "su/code-in.h"
88 /* Compatibility shims which assume 0/-1 cannot really happen */
89 /* Always for _protocols #ifndef mx_XTLS_HAVE_CONF_CTX */
90 # ifndef SSL_OP_NO_SSLv2
91 # define SSL_OP_NO_SSLv2 0
93 # ifndef SSL_OP_NO_SSLv3
94 # define SSL_OP_NO_SSLv3 0
96 # ifndef SSL_OP_NO_TLSv1
97 # define SSL_OP_NO_TLSv1 0
99 # ifndef SSL_OP_NO_TLSv1_1
100 # define SSL_OP_NO_TLSv1_1 0
102 # ifndef SSL_OP_NO_TLSv1_2
103 # define SSL_OP_NO_TLSv1_2 0
105 # ifndef SSL_OP_NO_TLSv1_3
106 # define SSL_OP_NO_TLSv1_3 0
108 /* SSL_CONF_CTX and _OP_NO_SSL_MASK were both introduced with 1.0.2!?! */
109 # ifndef SSL_OP_NO_SSL_MASK
110 # define SSL_OP_NO_SSL_MASK \
111 ( SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | \
112 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | \
116 CTA(SSL_OP_NO_SSL_MASK
!= 0,
117 "One of _SSLv[23], _TLSv1, _TLSv1_[123] is needed");
119 # ifndef SSL2_VERSION
120 # define SSL2_VERSION 0
122 # ifndef SSL3_VERSION
123 # define SSL3_VERSION 0
125 # ifndef TLS1_VERSION
126 # define TLS1_VERSION 0
128 # ifndef TLS1_1_VERSION
129 # define TLS1_1_VERSION 0
131 # ifndef TLS1_2_VERSION
132 # define TLS1_2_VERSION 0
134 # ifndef TLS1_3_VERSION
135 # define TLS1_3_VERSION 0
139 #ifdef mx_XTLS_HAVE_STACK_OF
140 # define a_XTLS_STACKOF(X) STACK_OF(X)
142 # define a_XTLS_STACKOF(X) /*X*/STACK
145 #ifdef mx_XTLS_HAVE_RAND_FILE
146 # if OPENSSL_VERSION_NUMBER + 0 >= 0x0090581fL
147 # define a_XTLS_RAND_LOAD_FILE_MAXBYTES -1
149 # define a_XTLS_RAND_LOAD_FILE_MAXBYTES 1024
153 /* More cute compatibility sighs */
154 #if mx_HAVE_XTLS >= 0x10100
155 # define a_xtls_X509_get_notBefore X509_get0_notBefore
156 # define a_xtls_X509_get_notAfter X509_get0_notAfter
157 # define a_xtls_SSL_get_verified_chain SSL_get0_verified_chain
159 # define a_xtls_X509_get_notBefore X509_get_notBefore
160 # define a_xtls_X509_get_notAfter X509_get_notAfter
161 # define a_xtls_SSL_get_verified_chain SSL_get_peer_cert_chain
164 #if mx_HAVE_XTLS >= 0x30000
165 /* OpenSSL 3.0: algorithm providers are dynamic and lazily resolved,
166 * so anything "implicitly fetched" (crypto(7)) may fail later on.
167 * As pre 3.0.0 was only "implicit" it is a complicated backward-incompat-
168 * ible mess (internal lazy fetching is then a single line of code) */
169 # define a_XTLS_CRYPTO_FETCH
170 # define a_XTLS__NFETCH_INJ(X)
171 # define a_XTLS__JFETCH jfetch
173 # define a_xtls_SSL_CTX_load_verify_file(CTXP,FILE) \
174 SSL_CTX_load_verify_file(CTXP, FILE)
175 # define a_xtls_SSL_CTX_load_verify_dir(CTXP,DIR) \
176 SSL_CTX_load_verify_dir(ctxp, ca_dir)
178 # define a_xtls_X509_STORE_load_file(STORE,FILE) \
179 X509_STORE_load_file(STORE, FILE)
180 # define a_xtls_X509_STORE_load_path(STORE,PATH) \
181 X509_STORE_load_path(STORE, PATH)
183 # define a_xtls_SSL_get_peer_certificate(TLSP) \
184 SSL_get0_peer_certificate(TLSP)
185 # define a_xtls_SSL_get_peer_certificate__FREE(CERT)
188 # undef a_XTLS_CRYPTO_FETCH
189 # define a_XTLS__NFETCH_INJ(X) X
190 # define a_XTLS__JFETCH jleave
192 # define a_xtls_SSL_CTX_load_verify_file(CTXP,FILE) \
193 SSL_CTX_load_verify_locations(CTXP, FILE, NIL)
194 # define a_xtls_SSL_CTX_load_verify_dir(CTXP,DIR) \
195 SSL_CTX_load_verify_locations(CTXP, NIL, DIR)
197 # define a_xtls_X509_STORE_load_file(STORE,FILE) \
198 X509_STORE_load_locations(STORE, FILE, NIL)
199 # define a_xtls_X509_STORE_load_path(STORE,PATH) \
200 X509_STORE_load_locations(STORE, NIL, PATH)
202 # define a_xtls_SSL_get_peer_certificate(TLSP) \
203 SSL_get_peer_certificate(TLSP)
204 # define a_xtls_SSL_get_peer_certificate__FREE(CERT) \
206 #endif /* mx_HAVE_XTLS >= 0x30000 */
208 /* X509_STORE_set_flags */
209 #undef a_XTLS_X509_V_ANY
210 #ifndef X509_V_FLAG_NO_ALT_CHAINS
211 # define X509_V_FLAG_NO_ALT_CHAINS -1
213 # undef a_XTLS_X509_V_ANY
214 # define a_XTLS_X509_V_ANY
216 #ifndef X509_V_FLAG_NO_CHECK_TIME
217 # define X509_V_FLAG_NO_CHECK_TIME -1
219 # undef a_XTLS_X509_V_ANY
220 # define a_XTLS_X509_V_ANY
222 #ifndef X509_V_FLAG_PARTIAL_CHAIN
223 # define X509_V_FLAG_PARTIAL_CHAIN -1
225 # undef a_XTLS_X509_V_ANY
226 # define a_XTLS_X509_V_ANY
228 #ifndef X509_V_FLAG_X509_STRICT
229 # define X509_V_FLAG_X509_STRICT -1
231 # undef a_XTLS_X509_V_ANY
232 # define a_XTLS_X509_V_ANY
234 #ifndef X509_V_FLAG_TRUSTED_FIRST
235 # define X509_V_FLAG_TRUSTED_FIRST -1
237 # undef a_XTLS_X509_V_ANY
238 # define a_XTLS_X509_V_ANY
242 a_XTLS_S_INIT
= 1u<<0,
243 a_XTLS_S_RAND_DRBG_INIT
= 1u<<1,
244 a_XTLS_S_RAND_INIT
= 1u<<2,
245 a_XTLS_S_CONF_LOAD
= 1u<<3,
247 #if mx_HAVE_XTLS < 0x10100
248 a_XTLS_S_EXIT_HDL
= 1u<<8,
249 a_XTLS_S_ALGO_LOAD
= 1u<<9,
252 a_XTLS_S_VERIFY_ERROR
= 1u<<16
255 struct ssl_method
{ /* TODO v15 obsolete */
256 char const sm_name
[8];
257 char const sm_map
[16];
260 struct a_xtls_protocol
{
261 char const xp_name
[8];
262 sl xp_op_no
; /* SSL_OP_NO_* bit */
263 u16 xp_version
; /* *_VERSION number */
264 boole xp_ok_minmaxproto
; /* Valid for {Min,Max}Protocol= */
265 boole xp_ok_proto
; /* Valid for Protocol= */
267 boole xp_is_all
; /* The special "ALL" */
271 struct a_xtls_cipher
{
272 char const xc_name
[8];
273 EVP_CIPHER
const *(*xc_fun
)(void);
276 struct a_xtls_digest
{
277 char const xd_name
[16];
278 EVP_MD
const *(*xd_fun
)(void);
281 struct a_xtls_x509_v_flags
{
282 char const xxvf_name
[20];
286 /* Supported SSL/TLS methods: update manual on change! */
287 static struct ssl_method
const _ssl_methods
[] = { /* TODO obsolete */
288 {"auto", "ALL,-SSLv2"},
289 {"ssl3", "-ALL,SSLv3"},
290 {"tls1", "-ALL,TLSv1"},
291 {"tls1.1", "-ALL,TLSv1.1"},
292 {"tls1.2", "-ALL,TLSv1.2"}
295 /* Update manual on change!
296 * Ensure array size by adding \0 to longest entry.
297 * Strictly to be sorted new/up to old/down, [0]=ALL, [x-1]=None! */
298 static struct a_xtls_protocol
const a_xtls_protocols
[] = {
299 {"ALL", SSL_OP_NO_SSL_MASK
, 0, FAL0
, TRU1
, FAL0
, TRU1
, {0}},
300 {"TLSv1.3\0", SSL_OP_NO_TLSv1_3
, TLS1_3_VERSION
, TRU1
,TRU1
,FAL0
,FAL0
,{0}},
301 {"TLSv1.2", SSL_OP_NO_TLSv1_2
, TLS1_2_VERSION
, TRU1
, TRU1
, FAL0
, FAL0
, {0}},
302 {"TLSv1.1", SSL_OP_NO_TLSv1_1
, TLS1_1_VERSION
, TRU1
, TRU1
, FAL0
, FAL0
, {0}},
303 {"TLSv1", SSL_OP_NO_TLSv1
, TLS1_VERSION
, TRU1
, TRU1
, FAL0
, FAL0
, {0}},
304 {"SSLv3", SSL_OP_NO_SSLv3
, SSL3_VERSION
, TRU1
, TRU1
, FAL0
, FAL0
, {0}},
305 {"SSLv2", SSL_OP_NO_SSLv2
, SSL2_VERSION
, TRU1
, TRU1
, FAL0
, FAL0
, {0}},
306 {"None", SSL_OP_NO_SSL_MASK
, 0, TRU1
, FAL0
, TRU1
, FAL0
, {0}}
309 /* Supported S/MIME cipher algorithms */
310 static struct a_xtls_cipher
const a_xtls_ciphers
[] = { /*Manual!*/
311 #ifndef OPENSSL_NO_AES
312 # define a_XTLS_SMIME_DEFAULT_CIPHER EVP_aes_128_cbc /* According RFC 5751 */
313 # define a_XTLS_SMIME_DEFAULT_CIPHER_S "AES128"
314 {"AES128", &EVP_aes_128_cbc
},
315 {"AES256", &EVP_aes_256_cbc
},
316 {"AES192", &EVP_aes_192_cbc
},
318 #ifndef OPENSSL_NO_DES
319 # ifndef a_XTLS_SMIME_DEFAULT_CIPHER
320 # define a_XTLS_SMIME_DEFAULT_CIPHER EVP_des_ede3_cbc
321 # define a_XTLS_SMIME_DEFAULT_CIPHER_S "DES3"
323 {"DES3", &EVP_des_ede3_cbc
},
324 {"DES", &EVP_des_cbc
},
327 #ifndef a_XTLS_SMIME_DEFAULT_CIPHER
328 # error Your OpenSSL library does not include the necessary
329 # error cipher algorithms that are required to support S/MIME
332 #ifndef OPENSSL_NO_AES
333 /* TODO obsolete a_xtls_smime_ciphers_obs */
334 static struct a_xtls_cipher
const a_xtls_smime_ciphers_obs
[] = {
335 {"AES-128", &EVP_aes_128_cbc
},
336 {"AES-256", &EVP_aes_256_cbc
},
337 {"AES-192", &EVP_aes_192_cbc
}
341 /* Supported S/MIME message digest algorithms.
342 * Update manual on default changes! */
343 static struct a_xtls_digest
const a_xtls_digests
[] = { /*Manual!*/
344 #ifdef mx_XTLS_HAVE_BLAKE2
345 {"BLAKE2b512\0", &EVP_blake2b512
},
346 {"BLAKE2s256", &EVP_blake2s256
},
347 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
348 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_blake2s256
349 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "BLAKE2s256"
353 #ifdef mx_XTLS_HAVE_SHA3
354 {"SHA3-512\0", &EVP_sha3_512
},
355 {"SHA3-384", &EVP_sha3_384
},
356 {"SHA3-256", &EVP_sha3_256
},
357 {"SHA3-224", &EVP_sha3_224
},
360 #ifndef OPENSSL_NO_SHA512
361 {"SHA512\0", &EVP_sha512
},
362 {"SHA384", &EVP_sha384
},
363 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
364 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha512
365 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA512"
369 #ifndef OPENSSL_NO_SHA256
370 {"SHA256\0", &EVP_sha256
},
371 {"SHA224", &EVP_sha224
},
372 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
373 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha256
374 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA256"
376 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
377 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_sha256
378 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "SHA256"
382 #ifndef OPENSSL_NO_SHA
383 {"SHA1\0", &EVP_sha1
},
384 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
385 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha1
386 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA1"
388 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
389 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_sha1
390 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "SHA1"
394 #ifndef OPENSSL_NO_MD5
399 #if !defined a_XTLS_SMIME_DEFAULT_DIGEST || \
400 !defined a_XTLS_FINGERPRINT_DEFAULT_DIGEST
401 # error Not enough supported message digest algorithms available
404 /* X509_STORE_set_flags() for *{smime,ssl}-ca-flags* */
405 static struct a_xtls_x509_v_flags
const a_xtls_x509_v_flags
[] = { /* Manual! */
406 {"no-alt-chains", X509_V_FLAG_NO_ALT_CHAINS
},
407 {"no-check-time", X509_V_FLAG_NO_CHECK_TIME
},
408 {"partial-chain", X509_V_FLAG_PARTIAL_CHAIN
},
409 {"strict", X509_V_FLAG_X509_STRICT
},
410 {"trusted-first", X509_V_FLAG_TRUSTED_FIRST
},
413 static uz a_xtls_state
;
414 static uz a_xtls_msgno
;
416 /* Special pre-PRNG PRNG init */
417 #ifdef mx_XTLS_HAVE_SET_RESEED_DEFAULTS
418 SINLINE
void a_xtls_rand_drbg_init(void);
420 # define a_xtls_rand_drbg_init() \
421 do {a_xtls_state |= a_XTLS_S_RAND_DRBG_INIT;} while(0)
425 #ifdef mx_XTLS_HAVE_RAND_FILE
426 static void a_xtls_rand_init(void);
428 # define a_xtls_rand_init() \
429 do {a_xtls_state |= a_XTLS_S_RAND_INIT;} while(0)
433 static void a_xtls_init(void);
435 #if mx_HAVE_XTLS < 0x10100
436 # ifdef mx_HAVE_TLS_ALL_ALGORITHMS
437 static void a_xtls__load_algos(void);
438 # define a_xtls_load_algos a_xtls__load_algos
440 # if defined mx_XTLS_HAVE_CONFIG || defined mx_HAVE_TLS_ALL_ALGORITHMS
441 static void a_xtls_atexit(void);
444 #ifndef a_xtls_load_algos
445 # define a_xtls_load_algos() do{;}while(0)
448 static boole
a_xtls_parse_asn1_time(ASN1_TIME
const *atp
,
449 char *bdat
, uz blen
);
450 static int a_xtls_verify_cb(int success
, X509_STORE_CTX
*store
);
452 static boole
a_xtls_digest_find(boole fingerprint
, char const *name
,
453 EVP_MD
const **mdp
, char const **normalized_name_or_nil
, boole
*freeit
);
455 /* *smime-ca-flags*, *tls-ca-flags* */
456 static void a_xtls_ca_flags(X509_STORE
*store
, char const *flags
);
458 /* SSL_CTX configuration; the latter always NULLs *confp */
459 static void *a_xtls_conf_setup(SSL_CTX
*ctxp
, struct mx_url
const *urlp
);
460 static boole
a_xtls_conf(void *confp
, char const *cmd
, char const *value
);
461 static boole
a_xtls_conf_finish(void **confp
, boole error
);
463 static boole
a_xtls_obsolete_conf_vars(void *confp
, struct mx_url
const *urlp
);
464 static boole
a_xtls_config_pairs(void *confp
, struct mx_url
const *urlp
);
465 static boole
a_xtls_load_verifications(SSL_CTX
*ctxp
,
466 struct mx_url
const *urlp
);
468 static boole
a_xtls_check_host(struct mx_socket
*sop
, X509
*peercert
,
469 struct mx_url
const *urlp
);
471 static int smime_verify(struct message
*m
, int n
,
472 a_XTLS_STACKOF(X509
) *chain
, X509_STORE
*store
);
473 static EVP_CIPHER
const *a_xtls_smime_cipher(char const *name
, boole
*freeit
);
475 static int ssl_password_cb(char *buf
, int size
, int rwflag
,
477 static FILE * smime_sign_cert(char const *xname
, char const *xname2
,
478 boole dowarn
, char const **match
, boole fallback_from
);
479 static char const *a_xtls_smime_sign_include_certs(char const *name
);
480 static boole
a_xtls_smime_sign_include_chain_creat(a_XTLS_STACKOF(X509
) **chain
,
481 char const *cfiles
, char const *addr
);
482 static EVP_MD
const *a_xtls_smime_sign_digest(char const *name
,
483 char const **digname
, boole
*freeit
);
484 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
485 static enum okay
load_crl1(X509_STORE
*store
, char const *name
);
487 static enum okay
load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
);
489 #ifdef mx_XTLS_HAVE_SET_RESEED_DEFAULTS
491 a_xtls_rand_drbg_init(void){
492 (void)RAND_DRBG_set_reseed_defaults(0, 0, 0, 0); /* (does not fail here) */
493 a_xtls_state
|= a_XTLS_S_RAND_DRBG_INIT
;
497 #ifdef mx_XTLS_HAVE_RAND_FILE
499 a_xtls_rand_init(void){
500 # define a_XTLS_RAND_ENTROPY 32
501 char b64buf
[a_XTLS_RAND_ENTROPY
* 5 +1], *randfile
;
506 a_xtls_rand_drbg_init();
507 a_xtls_state
|= a_XTLS_S_RAND_INIT
;
509 # ifdef mx_XTLS_HAVE_CONFIG
510 if(!(a_xtls_state
& a_XTLS_S_INIT
))
517 /* Prefer possible user setting */
518 if((cp
= ok_vlook(tls_rand_file
)) != NULL
||
519 (cp
= ok_vlook(ssl_rand_file
)) != NULL
){
522 if((x
= fexpand(cp
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
524 n_err(_("*tls-rand-file*: expansion of %s failed "
525 "(using default)\n"),
526 n_shexp_quote_cp(cp
, FAL0
));
531 randfile
= n_lofi_alloc(PATH_MAX
);
532 if((cp
= RAND_file_name(randfile
, PATH_MAX
)) == NULL
){
533 n_err(_("*tls-rand-file*: no TLS entropy file, can't seed PRNG\n"));
538 (void)RAND_load_file(cp
, a_XTLS_RAND_LOAD_FILE_MAXBYTES
);
540 /* And feed in some data, then write the updated file.
541 * While this rather feeds the PRNG with itself in the RANDOM_IMPL_TLS
542 * case, let us stir the buffer a little bit.
543 * Estimate a low but likely still too high number of entropy bytes, use
544 * 20%: base64 uses 3 input = 4 output bytes relation, and the base64
545 * alphabet is a 6 bit one */
546 for(x
= (char*)-1;;){
547 RAND_add(mx_random_create_buf(b64buf
, sizeof(b64buf
) -1, NIL
),
548 sizeof(b64buf
) -1, a_XTLS_RAND_ENTROPY
);
549 if((x
= (char*)((up
)x
>> (1
550 # if mx_HAVE_RANDOM == mx_RANDOM_IMPL_TLS
554 err
= (RAND_status() == 0);
557 # if mx_HAVE_RANDOM != mx_RANDOM_IMPL_TLS
558 if(!(err
= (RAND_status() == 0)))
564 err
= (RAND_write_file(cp
) == -1);
568 n_lofi_free(randfile
);
570 n_panic(_("Cannot seed the *TLS PseudoRandomNumberGenerator, "
571 "RAND_status() is 0!\n"
572 " Please set *tls-rand-file* to a file with sufficient entropy.\n"
573 " On a machine with entropy: "
574 "\"$ dd if=/dev/urandom of=FILE bs=1024 count=1\"\n"));
577 #endif /* mx_XTLS_HAVE_RAND_FILE */
581 #ifdef mx_XTLS_HAVE_CONFIG
586 if(a_xtls_state
& a_XTLS_S_INIT
)
589 #if mx_HAVE_XTLS >= 0x10100
590 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
591 OPENSSL_INIT_LOAD_CRYPTO_STRINGS
592 # ifdef mx_HAVE_TLS_ALL_ALGORITHMS
593 # ifdef OPENSSL_INIT_ADD_ALL_CIPHERS
594 | OPENSSL_INIT_ADD_ALL_CIPHERS
596 # ifdef OPENSSL_INIT_ADD_ALL_DIGESTS
597 | OPENSSL_INIT_ADD_ALL_DIGESTS
600 # ifdef OPENSSL_INIT_NO_LOAD_CONFIG
601 | OPENSSL_INIT_NO_LOAD_CONFIG
605 SSL_load_error_strings();
609 a_xtls_state
|= a_XTLS_S_INIT
;
611 a_xtls_rand_drbg_init();
613 /* Load openssl.cnf or whatever was given in *tls-config-file* */
614 #ifdef mx_XTLS_HAVE_CONFIG
615 if((cp
= ok_vlook(tls_config_file
)) != NULL
||
616 (cp
= ok_vlook(ssl_config_file
)) != NULL
){
623 flags
= CONF_MFLAGS_IGNORE_MISSING_FILE
;
624 }else if((msg
= cp
, cp
= fexpand(cp
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
|
625 FEXP_NSHELL
))) != NIL
)
628 n_err(_("*tls-config-file*: file expansion failed: %s\n"),
629 n_shexp_quote_cp(msg
, FAL0
));
633 if(CONF_modules_load_file(cp
, n_uagent
, flags
) == 1){
634 a_xtls_state
|= a_XTLS_S_CONF_LOAD
;
635 # if mx_HAVE_XTLS < 0x10100
636 if(!(a_xtls_state
& a_XTLS_S_EXIT_HDL
)){
637 a_xtls_state
|= a_XTLS_S_EXIT_HDL
;
638 atexit(&a_xtls_atexit
); /* TODO generic program-wide event mech. */
641 if(n_poption
& n_PO_D_V
)
642 n_err(_("Loaded TLS configuration for %s from %s\n"), n_uagent
,
643 n_shexp_quote_cp(msg
, FAL0
));
646 ssl_gen_err(_("TLS CONF_modules_load_file() load error"));
648 #endif /* mx_XTLS_HAVE_CONFIG */
650 if(!(a_xtls_state
& a_XTLS_S_RAND_INIT
))
657 #if mx_HAVE_XTLS < 0x10100
658 # ifdef mx_HAVE_TLS_ALL_ALGORITHMS
660 a_xtls__load_algos(void){
662 if(!(a_xtls_state
& a_XTLS_S_ALGO_LOAD
)){
663 a_xtls_state
|= a_XTLS_S_ALGO_LOAD
;
664 OpenSSL_add_all_algorithms();
666 if(!(a_xtls_state
& a_XTLS_S_EXIT_HDL
)){
667 a_xtls_state
|= a_XTLS_S_EXIT_HDL
;
668 atexit(&a_xtls_atexit
); /* TODO generic program-wide event mech. */
675 # if defined mx_XTLS_HAVE_CONFIG || defined mx_HAVE_TLS_ALL_ALGORITHMS
680 # ifdef mx_XTLS_HAVE_CONFIG
681 if(a_xtls_state
& a_XTLS_S_CONF_LOAD
)
685 # ifdef mx_HAVE_TLS_ALL_ALGORITHMS
686 if(a_xtls_state
& a_XTLS_S_ALGO_LOAD
)
693 #endif /* mx_HAVE_XTLS < 0x10100 */
696 a_xtls_parse_asn1_time(ASN1_TIME
const *atp
, char *bdat
, uz blen
)
703 mbp
= BIO_new(BIO_s_mem());
705 if (ASN1_TIME_print(mbp
, C(ASN1_TIME
*,atp
)) &&
706 (l
= BIO_get_mem_data(mbp
, &mcp
)) > 0)
707 snprintf(bdat
, blen
, "%.*s", (int)l
, mcp
);
709 snprintf(bdat
, blen
, _("Bogus certificate date: %.*s"),
710 /*is (int)*/atp
->length
, (char const*)atp
->data
);
716 return (mcp
!= NULL
);
720 a_xtls_verify_cb(int success
, X509_STORE_CTX
*store
)
727 if (success
&& !(n_poption
& n_PO_D_V
))
730 if (a_xtls_msgno
!= 0) {
731 n_err(_("Message %lu:\n"), (ul
)a_xtls_msgno
);
734 n_err(_(" Certificate depth %d %s\n"),
735 X509_STORE_CTX_get_error_depth(store
),
736 (success
? su_empty
: V_(n_error
)));
738 if ((cert
= X509_STORE_CTX_get_current_cert(store
)) != NULL
) {
739 X509_NAME_oneline(X509_get_subject_name(cert
), data
, sizeof data
);
740 n_err(_(" subject = %s\n"), data
);
742 a_xtls_parse_asn1_time(a_xtls_X509_get_notBefore(cert
),
744 n_err(_(" notBefore = %s\n"), data
);
746 a_xtls_parse_asn1_time(a_xtls_X509_get_notAfter(cert
),
748 n_err(_(" notAfter = %s\n"), data
);
750 X509_NAME_oneline(X509_get_issuer_name(cert
), data
, sizeof data
);
751 n_err(_(" issuer = %s\n"), data
);
755 int err
= X509_STORE_CTX_get_error(store
);
757 n_err(_(" err %i: %s\n"), err
, X509_verify_cert_error_string(err
));
758 a_xtls_state
|= a_XTLS_S_VERIFY_ERROR
;
762 rv
= n_tls_verify_decide();
769 a_xtls_digest_find(boole fingerprint
, char const *name
, EVP_MD
const **mdp
,
770 char const **normalized_name_or_nil
, boole
*freeit
){
777 name
= fingerprint
? a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S
778 : a_XTLS_SMIME_DEFAULT_DIGEST_S
;
779 a_XTLS__NFETCH_INJ(*mdp
= fingerprint
780 ? a_XTLS_FINGERPRINT_DEFAULT_DIGEST()
781 : a_XTLS_SMIME_DEFAULT_DIGEST();)
789 nn
= cp
= su_LOFI_ALLOC(i
+1);
790 while((c
= *name
++) != '\0')
791 *cp
++ = su_cs_to_upper(c
);
793 name
= savestrbuf(nn
, P2UZ(cp
- nn
));
797 for(i
= 0; i
< NELEM(a_xtls_digests
); ++i
)
798 if(!su_cs_cmp(a_xtls_digests
[i
].xd_name
, name
)){
799 a_XTLS__NFETCH_INJ(*mdp
= (*a_xtls_digests
[i
].xd_fun
)();)
800 name
= a_xtls_digests
[i
].xd_name
;
804 /* Not a built-in algorithm, but we may have dynamic support for more */
805 #if defined mx_HAVE_TLS_ALL_ALGORITHMS && !defined a_XTLS_CRYPTO_FETCH
806 if((*mdp
= EVP_get_digestbyname(name
)) != NIL
)
810 #ifdef a_XTLS_CRYPTO_FETCH
812 if((*mdp
= EVP_MD_fetch(NIL
, name
, NIL
)) != NIL
){
818 n_err(_("Invalid message digest: %s\n"), n_shexp_quote_cp(name
, FAL0
));
822 if(normalized_name_or_nil
!= NIL
)
823 *normalized_name_or_nil
= name
;
826 return (*mdp
!= NIL
);
830 a_xtls_ca_flags(X509_STORE
*store
, char const *flags
){
835 iolist
= savestr(flags
);
837 while((cp
= su_cs_sep_c(&iolist
, ',', TRU1
)) != NULL
){
838 struct a_xtls_x509_v_flags
const *xvfp
;
840 for(xvfp
= &a_xtls_x509_v_flags
[0];
841 xvfp
< &a_xtls_x509_v_flags
[NELEM(a_xtls_x509_v_flags
)];
843 if(!su_cs_cmp_case(cp
, xvfp
->xxvf_name
)){
844 if(xvfp
->xxvf_flag
!= -1){
845 #ifdef a_XTLS_X509_V_ANY
846 X509_STORE_set_flags(store
, xvfp
->xxvf_flag
);
848 }else if(n_poption
& n_PO_D_V
)
849 n_err(_("*{smime,tls}-ca-flags*: "
850 "directive not supported: %s\n"), cp
);
853 n_err(_("*{smime,tls}-ca-flags*: invalid directive: %s\n"), cp
);
859 #ifdef mx_XTLS_HAVE_CONF_CTX
861 a_xtls_conf_setup(SSL_CTX
*ctxp
, struct mx_url
const *urlp
){
868 if((cp
= xok_vlook(tls_config_module
, urlp
, OXM_ALL
)) != NULL
||
869 (cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
870 # ifdef mx_XTLS_HAVE_CTX_CONFIG
871 if(!(a_xtls_state
& a_XTLS_S_CONF_LOAD
)){
872 n_err(_("*tls-config-module*: no *tls-config-file* loaded: %s\n"),
873 n_shexp_quote_cp(cp
, FAL0
));
875 }else if(!SSL_CTX_config(ctxp
, cp
)){
876 ssl_gen_err(_("*tls-config-module*: load error for %s, section [%s]"),
877 n_uagent
, n_shexp_quote_cp(cp
, FAL0
));
881 n_err(_("*tls-config-module*: set but not supported: %s\n"),
882 n_shexp_quote_cp(cp
, FAL0
));
887 if((sccp
= SSL_CONF_CTX_new()) != NULL
){
888 SSL_CONF_CTX_set_flags(sccp
,
889 SSL_CONF_FLAG_FILE
| SSL_CONF_FLAG_CLIENT
|
890 SSL_CONF_FLAG_CERTIFICATE
| SSL_CONF_FLAG_SHOW_ERRORS
);
892 SSL_CONF_CTX_set_ssl_ctx(sccp
, ctxp
);
894 ssl_gen_err(_("SSL_CONF_CTX_new() failed"));
901 a_xtls_conf(void *confp
, char const *cmd
, char const *value
){
906 if(n_poption
& n_PO_D_V
)
907 n_err(_("TLS: applying config: %s = %s\n"),
908 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
910 rv
= SSL_CONF_cmd(sccp
= confp
, cmd
, value
);
914 cmd
= n_shexp_quote_cp(cmd
, FAL0
);
915 value
= n_shexp_quote_cp(value
, FAL0
);
917 ssl_gen_err(_("TLS: config failure: %s = %s"), cmd
, value
);
922 case -2: err
= N_("TLS: config command not recognized"); break;
923 case -3: err
= N_("TLS: missing required config argument"); break;
924 default: err
= N_("TLS: unspecified config error"); break;
927 n_err(_("%s (%d): %s = %s\n"), err
, rv
, cmd
, value
);
936 a_xtls_conf_finish(void **confp
, boole error
){
941 sccp
= (SSL_CONF_CTX
*)*confp
;
945 rv
= (SSL_CONF_CTX_finish(sccp
) != 0);
947 SSL_CONF_CTX_free(sccp
);
952 #else /* mx_XTLS_HAVE_CONF_CTX */
953 # ifdef mx_XTLS_HAVE_CTX_CONFIG
954 # error SSL_CTX_config(3) support unexpected without SSL_CONF_CTX support
958 a_xtls_conf_setup(SSL_CTX
* ctxp
, struct mx_url
const *urlp
){
962 if((cp
= xok_vlook(tls_config_module
, urlp
, OXM_ALL
)) != NULL
||
963 (cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
964 n_err(_("*tls-config-module*: set but not supported: %s\n"),
965 n_shexp_quote_cp(cp
, FAL0
));
973 a_xtls_conf(void *confp
, char const *cmd
, char const *value
){
974 char const *xcmd
, *emsg
;
978 if(n_poption
& n_PO_D_V
)
979 n_err(_("TLS: applying config: %s = %s\n"),
980 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
984 if(!su_cs_cmp_case(cmd
, xcmd
= "Certificate")){
985 if(SSL_CTX_use_certificate_chain_file(ctxp
, value
) != 1){
986 emsg
= N_("TLS: %s: cannot load from file %s\n");
989 }else if(!su_cs_cmp_case(cmd
, xcmd
= "CipherString") ||
990 !su_cs_cmp_case(cmd
, xcmd
= "CipherList")/* XXX bad bug in past! */){
991 if(SSL_CTX_set_cipher_list(ctxp
, value
) != 1){
992 emsg
= N_("TLS: %s: invalid: %s\n");
995 }else if(!su_cs_cmp_case(cmd
, xcmd
= "Ciphersuites")){
996 # ifdef mx_XTLS_HAVE_SET_CIPHERSUITES
997 if(SSL_CTX_set_ciphersuites(ctxp
, value
) != 1){
998 emsg
= N_("TLS: %s: invalid: %s\n");
1003 emsg
= N_("TLS: %s: directive not supported\n");
1006 }else if(!su_cs_cmp_case(cmd
, xcmd
= "Curves")){
1007 # ifdef SSL_CTRL_SET_CURVES_LIST
1008 if(SSL_CTX_set1_curves_list(ctxp
, n_UNCONST(value
)) != 1){
1009 emsg
= N_("TLS: %s: invalid: %s\n");
1014 emsg
= N_("TLS: %s: directive not supported\n");
1017 }else if((emsg
= NULL
, !su_cs_cmp_case(cmd
, xcmd
= "MaxProtocol")) ||
1018 (emsg
= (char*)-1, !su_cs_cmp_case(cmd
, xcmd
= "MinProtocol"))){
1019 # ifndef mx_XTLS_HAVE_SET_MIN_PROTO_VERSION
1021 emsg
= N_("TLS: %s: directive not supported\n");
1024 struct a_xtls_protocol
const *xpp
;
1026 for(xpp
= &a_xtls_protocols
[1] /* [0] == ALL */;;)
1027 if(xpp
->xp_ok_minmaxproto
&& !su_cs_cmp_case(value
, xpp
->xp_name
)){
1028 if(xpp
->xp_op_no
== 0 || xpp
->xp_version
== 0)
1031 }else if((++xpp
)->xp_last
)
1034 if((emsg
== NULL
? SSL_CTX_set_max_proto_version(ctxp
, xpp
->xp_version
)
1035 : SSL_CTX_set_min_proto_version(ctxp
, xpp
->xp_version
)) != 1){
1036 emsg
= N_("TLS: %s: cannot set protocol version: %s\n");
1039 # endif /* !mx_XTLS_HAVE_SET_MIN_PROTO_VERSION */
1040 }else if(!su_cs_cmp_case(cmd
, xcmd
= "Options")){
1041 if(su_cs_cmp_case(value
, "Bugs")){
1042 emsg
= N_("TLS: %s: fallback only supports value \"Bugs\": %s\n");
1045 SSL_CTX_set_options(ctxp
, SSL_OP_ALL
);
1046 }else if(!su_cs_cmp_case(cmd
, xcmd
= "PrivateKey")){
1047 if(SSL_CTX_use_PrivateKey_file(ctxp
, value
, SSL_FILETYPE_PEM
) != 1){
1048 emsg
= N_("%s: cannot load from file %s\n");
1051 }else if(!su_cs_cmp_case(cmd
, xcmd
= "Protocol")){
1052 struct a_xtls_protocol
const *xpp
;
1053 char *iolist
, *cp
, addin
;
1058 for(iolist
= cp
= savestr(value
);
1059 (cp
= su_cs_sep_c(&iolist
, ',', FAL0
)) != NULL
;){
1062 emsg
= N_("TLS: %s: empty elements are not supported\n");
1068 case '-': addin
= FAL0
; /* FALLTHRU */
1069 case '+': ++cp
; /* FALLTHRU */
1073 for(xpp
= &a_xtls_protocols
[0];;){
1074 if(xpp
->xp_ok_proto
&& !su_cs_cmp_case(cp
, xpp
->xp_name
)){
1075 if((xpp
->xp_op_no
== 0 || xpp
->xp_version
== 0) &&
1078 /* We need to inverse the meaning of the _NO_s */
1080 opts
|= xpp
->xp_op_no
;
1082 opts
&= ~xpp
->xp_op_no
;
1084 }else if((++xpp
)->xp_last
){
1086 emsg
= N_("TLS: %s: unknown or unsupported protocol: %s\n");
1092 SSL_CTX_clear_options(ctxp
, SSL_OP_NO_SSL_MASK
);
1093 SSL_CTX_set_options(ctxp
, opts
);
1095 xcmd
= n_shexp_quote_cp(cmd
, FAL0
);
1096 emsg
= N_("TLS: unsupported directive: %s: value: %s\n");
1102 return (confp
!= NULL
);
1104 ssl_gen_err(V_(emsg
), xcmd
, n_shexp_quote_cp(value
, FAL0
));
1109 value
= n_shexp_quote_cp(value
, FAL0
);
1110 n_err(V_(emsg
), xcmd
, value
);
1116 a_xtls_conf_finish(void **confp
, boole error
){
1122 #endif /* !mx_XTLS_HAVE_CONF_CTX */
1125 a_xtls_obsolete_conf_vars(void *confp
, struct mx_url
const *urlp
){
1126 char const *cp
, *cp_base
, *certchain
;
1132 /* Certificate via ssl-cert */
1133 if((certchain
= cp
= xok_vlook(ssl_cert
, urlp
, OXM_ALL
)) != NULL
){
1134 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-cert*"));
1135 if((cp_base
= fexpand(cp
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1137 n_err(_("*ssl-cert* value expansion failed: %s\n"),
1138 n_shexp_quote_cp(cp
, FAL0
));
1141 if(!a_xtls_conf(confp
, "Certificate", certchain
= cp_base
))
1145 /* CipherString via ssl-ciper-list */
1146 if((cp
= xok_vlook(ssl_cipher_list
, urlp
, OXM_ALL
)) != NULL
){
1147 n_OBSOLETE(_("please use *tls-config-pairs* instead of "
1148 "*ssl-cipher-list*"));
1149 if(!a_xtls_conf(confp
, "CipherString", cp
))
1153 /* Curves via ssl-curves */
1154 if((cp
= xok_vlook(ssl_curves
, urlp
, OXM_ALL
)) != NULL
){
1155 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-curves*"));
1156 if(!a_xtls_conf(confp
, "Curves", cp
))
1160 /* PrivateKey via ssl-key */
1161 if((cp
= xok_vlook(ssl_key
, urlp
, OXM_ALL
)) != NULL
){
1162 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-key*"));
1163 if((cp_base
= fexpand(cp
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1165 n_err(_("*ssl-key* value expansion failed: %s\n"),
1166 n_shexp_quote_cp(cp
, FAL0
));
1170 if(certchain
== NULL
){
1171 n_err(_("*ssl-key* can only be used together with *ssl-cert*! "
1172 "And use *ssl-config-pairs*!\n"));
1176 if((cp
!= NULL
|| (cp
= certchain
) != NULL
) &&
1177 !a_xtls_conf(confp
, "PrivateKey", cp
))
1180 /* Protocol via ssl-method or ssl-protocol */
1181 if((cp
= xok_vlook(ssl_method
, urlp
, OXM_ALL
)) != NULL
){
1184 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-method*"));
1186 if(!su_cs_cmp_case(_ssl_methods
[i
].sm_name
, cp
)){
1187 cp
= _ssl_methods
[i
].sm_map
;
1190 if(++i
== NELEM(_ssl_methods
)){
1191 n_err(_("Unsupported SSL method: %s\n"), cp
);
1196 if((cp_base
= xok_vlook(ssl_protocol
, urlp
, OXM_ALL
)) != NULL
){
1197 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-protocol*"));
1198 if(cp
!= NULL
&& (n_poption
& n_PO_D_V
))
1199 n_err(_("*ssl-protocol* overrides *ssl-method*! "
1200 "And please use *tls-config-pairs* instead!\n"));
1203 if(cp
!= NULL
&& !a_xtls_conf(confp
, "Protocol", cp
))
1213 a_xtls_config_pairs(void *confp
, struct mx_url
const *urlp
){
1214 /* Due to interdependencies some commands have to be delayed a bit */
1215 static char const cmdcert
[] = "Certificate", cmdprivkey
[] = "PrivateKey";
1216 char const *valcert
, *valprivkey
;
1217 char *pairs
, *cp
, *cmd
, *val
;
1220 if((pairs
= n_UNCONST(xok_vlook(tls_config_pairs
, urlp
, OXM_ALL
))
1222 (pairs
= n_UNCONST(xok_vlook(ssl_config_pairs
, urlp
, OXM_ALL
))
1225 pairs
= savestr(pairs
);
1227 valcert
= valprivkey
= NULL
;
1229 while((cp
= su_cs_sep_escable_c(&pairs
, ',', FAL0
)) != NULL
){
1236 a_EXPAND_MASK
= a_EXPAND
| a_CERT
| a_PRIVKEY
1239 /* Directive, space trimmed */
1240 if((cmd
= su_cs_find_c(cp
, '=')) == NULL
){
1243 pairs
= n_UNCONST(n_empty
);
1244 n_err(_("*tls-config-pairs*: missing directive: %s; rest: %s\n"),
1245 n_shexp_quote_cp(cp
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1250 if((cmd
> cp
&& cmd
[-1] == '*')){
1255 while(cmd
> cp
&& (c
= cmd
[-1], su_cs_is_space(c
)))
1262 /* Command with special treatment? */
1263 if(!su_cs_cmp_case(cmd
, cmdcert
))
1265 else if(!su_cs_cmp_case(cmd
, cmdprivkey
))
1268 /* Value, space trimmed */
1269 while((c
= *val
) != '\0' && su_cs_is_space(c
))
1271 cp
= &val
[su_cs_len(val
)];
1272 while(cp
> val
&& (c
= cp
[-1], su_cs_is_space(c
)))
1277 pairs
= n_UNCONST(n_empty
);
1278 n_err(_("*tls-config-pairs*: missing value: %s; rest: %s\n"),
1279 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1283 /* Filename transformations to be applied? */
1284 if(f
& a_EXPAND_MASK
){
1285 if((cp
= fexpand(val
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1288 pairs
= n_UNCONST(n_empty
);
1289 n_err(_("*tls-config-pairs*: value expansion failed: %s: %s; "
1291 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(val
, FAL0
),
1292 n_shexp_quote_cp(pairs
, FAL0
));
1298 /* Some things have to be delayed */
1301 else if(f
& a_PRIVKEY
)
1303 else if(!a_xtls_conf(confp
, cmd
, val
)){
1304 pairs
= n_UNCONST(n_empty
);
1309 /* Work the delayed ones */
1310 if((valcert
!= NULL
&& !a_xtls_conf(confp
, cmdcert
, valcert
)) ||
1311 ((valprivkey
!= NULL
|| (valprivkey
= valcert
) != NULL
) &&
1312 !a_xtls_conf(confp
, cmdprivkey
, valprivkey
)))
1313 pairs
= n_UNCONST(n_empty
);
1317 return (pairs
== NULL
);
1321 a_xtls_load_verifications(SSL_CTX
*ctxp
, struct mx_url
const *urlp
){
1322 char *ca_dir
, *ca_file
;
1327 if(n_tls_verify_level
== n_TLS_VERIFY_IGNORE
){
1333 if((ca_dir
= xok_vlook(tls_ca_dir
, urlp
, OXM_ALL
)) != NULL
||
1334 (ca_dir
= xok_vlook(ssl_ca_dir
, urlp
, OXM_ALL
)) != NULL
)
1335 ca_dir
= fexpand(ca_dir
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
));
1336 if((ca_file
= xok_vlook(tls_ca_file
, urlp
, OXM_ALL
)) != NULL
||
1337 (ca_file
= xok_vlook(ssl_ca_file
, urlp
, OXM_ALL
)) != NULL
)
1338 ca_file
= fexpand(ca_file
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
|
1341 if(ca_file
!= NIL
&& a_xtls_SSL_CTX_load_verify_file(ctxp
, ca_file
) != 1){
1342 ssl_gen_err(_("Error loading %s\n"), n_shexp_quote_cp(ca_file
, FAL0
));
1346 if(ca_dir
!= NIL
&& a_xtls_SSL_CTX_load_verify_dir(ctxp
, ca_dir
) != 1){
1347 ssl_gen_err(_("Error loading %s\n"), n_shexp_quote_cp(ca_dir
, FAL0
));
1354 if((xv15
= ok_blook(ssl_no_default_ca
)))
1355 n_OBSOLETE(_("please use *tls-ca-no-defaults*, "
1356 "not *ssl-no-default-ca*"));
1357 if(!xok_blook(tls_ca_no_defaults
, urlp
, OXM_ALL
) &&
1358 !xok_blook(ssl_ca_no_defaults
, urlp
, OXM_ALL
) && !xv15
&&
1359 SSL_CTX_set_default_verify_paths(ctxp
) != 1) {
1360 ssl_gen_err(_("Error loading built-in default CA locations\n"));
1365 a_xtls_state
&= ~a_XTLS_S_VERIFY_ERROR
;
1367 SSL_CTX_set_verify(ctxp
, SSL_VERIFY_PEER
, &a_xtls_verify_cb
);
1368 store
= SSL_CTX_get_cert_store(ctxp
);
1369 load_crls(store
, ok_v_tls_crl_file
, ok_v_tls_crl_dir
);
1370 a_xtls_ca_flags(store
, xok_vlook(tls_ca_flags
, urlp
, OXM_ALL
));
1371 a_xtls_ca_flags(store
, xok_vlook(ssl_ca_flags
, urlp
, OXM_ALL
));
1380 a_xtls_check_host(struct mx_socket
*sop
, X509
*peercert
,
1381 struct mx_url
const *urlp
){
1383 a_XTLS_STACKOF(GENERAL_NAME
) *gens
;
1392 if((gens
= X509_get_ext_d2i(peercert
, NID_subject_alt_name
, NULL
, NULL
)
1396 for(i
= 0; i
< sk_GENERAL_NAME_num(gens
); ++i
){
1397 gen
= sk_GENERAL_NAME_value(gens
, i
);
1398 if(gen
->type
== GEN_DNS
){
1399 if(n_poption
& n_PO_D_V
)
1400 n_err(_("Comparing subject_alt_name: need<%s> is<%s>\n"),
1401 urlp
->url_host
.s
, (char*)gen
->d
.ia5
->data
);
1402 if((rv
= n_tls_rfc2595_hostname_match(urlp
->url_host
.s
,
1403 (char*)gen
->d
.ia5
->data
)))
1409 if((subj
= X509_get_subject_name(peercert
)) != NULL
&&
1410 X509_NAME_get_text_by_NID(subj
, NID_commonName
, data
, sizeof data
1412 data
[sizeof data
- 1] = '\0';
1413 if(n_poption
& n_PO_D_V
)
1414 n_err(_("Comparing commonName: need<%s> is<%s>\n"),
1415 urlp
->url_host
.s
, data
);
1416 rv
= n_tls_rfc2595_hostname_match(urlp
->url_host
.s
, data
);
1424 smime_verify(struct message
*m
, int n
, a_XTLS_STACKOF(X509
) *chain
,
1427 char data
[LINESIZE
], *sender
, *to
, *cc
, *cnttype
;
1434 a_XTLS_STACKOF(X509
) *certs
;
1435 a_XTLS_STACKOF(GENERAL_NAME
) *gens
;
1446 a_xtls_state
&= ~a_XTLS_S_VERIFY_ERROR
;
1447 a_xtls_msgno
= (uz
)n
;
1450 sender
= getsender(m
);
1451 to
= hfield1("to", m
);
1452 cc
= hfield1("cc", m
);
1453 cnttype
= hfield1("content-type", m
);
1457 #define _X (sizeof("application/") -1)
1458 #define _Y(X) X, sizeof(X) -1
1459 if (cnttype
&& su_cs_starts_with_case(cnttype
, "application/") &&
1460 (!su_cs_cmp_case_n(cnttype
+ _X
, _Y("pkcs7-mime")) ||
1461 !su_cs_cmp_case_n(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
1464 if ((x
= smime_decrypt(m
, to
, cc
, TRU1
)) == NULL
)
1466 if (x
!= (struct message
*)-1) {
1472 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
1478 if((fp
= mx_fs_tmp_open("smimever", (mx_FS_O_RDWR
| mx_FS_O_UNLINK
|
1479 mx_FS_O_REGISTER
), NIL
)) == NIL
){
1480 n_perr(_("tempfile"), 0);
1483 while (size
-- > 0) {
1489 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
1491 "Error creating BIO verification object for message %d"), n
);
1495 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
1496 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
1499 if (PKCS7_verify(pkcs7
, chain
, store
, pb
, NULL
, 0) != 1) {
1500 ssl_gen_err(_("Error verifying message %d"), n
);
1504 if (sender
== NULL
) {
1505 n_err(_("Warning: Message %d has no sender\n"), n
);
1510 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
1511 if (certs
== NULL
) {
1512 n_err(_("No certificates found in message %d\n"), n
);
1516 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
1517 cert
= sk_X509_value(certs
, i
);
1518 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
1520 for (j
= 0; j
< sk_GENERAL_NAME_num(gens
); ++j
) {
1521 gen
= sk_GENERAL_NAME_value(gens
, j
);
1522 if (gen
->type
== GEN_EMAIL
) {
1523 if (n_poption
& n_PO_D_V
)
1524 n_err(_("Comparing subject_alt_name: need<%s> is<%s>)\n"),
1525 sender
, (char*)gen
->d
.ia5
->data
);
1526 if (!su_cs_cmp_case((char*)gen
->d
.ia5
->data
, sender
))
1532 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
1533 X509_NAME_get_text_by_NID(subj
, NID_pkcs9_emailAddress
,
1534 data
, sizeof data
) > 0) {
1535 data
[sizeof data
-1] = '\0';
1536 if (n_poption
& n_PO_D_V
)
1537 n_err(_("Comparing emailAddress: need<%s> is<%s>\n"),
1539 if (!su_cs_cmp_case(data
, sender
))
1543 n_err(_("Message %d: certificate does not match <%s>\n"), n
, sender
);
1546 rv
= ((a_xtls_state
& a_XTLS_S_VERIFY_ERROR
) != 0);
1548 fprintf(n_stdout
, _("Message %d was verified successfully\n"), n
);
1551 sk_X509_free(certs
);
1564 static EVP_CIPHER
const *
1565 a_xtls_smime_cipher(char const *name
, boole
*freeit
){
1566 EVP_CIPHER
const *cipher
;
1574 vn
= su_LOFI_ALLOC(i
= su_cs_len(name
) + sizeof("smime-cipher-") -1 +1);
1575 snprintf(vn
, S(int,i
), "smime-cipher-%s", name
);
1576 cp
= n_var_vlook(vn
, FAL0
);
1579 if(cp
== NIL
&& (cp
= ok_vlook(smime_cipher
)) == NIL
){
1580 a_XTLS__NFETCH_INJ(cipher
= a_XTLS_SMIME_DEFAULT_CIPHER();)
1581 cp
= a_XTLS_SMIME_DEFAULT_CIPHER_S
;
1582 goto a_XTLS__JFETCH
;
1586 for(i
= 0; i
< NELEM(a_xtls_ciphers
); ++i
)
1587 if(!su_cs_cmp_case(a_xtls_ciphers
[i
].xc_name
, cp
)){
1588 a_XTLS__NFETCH_INJ(cipher
= (*a_xtls_ciphers
[i
].xc_fun
)();)
1589 cp
= a_xtls_ciphers
[i
].xc_name
;
1590 goto a_XTLS__JFETCH
;
1592 #ifndef OPENSSL_NO_AES
1593 for(i
= 0; i
< NELEM(a_xtls_smime_ciphers_obs
); ++i
)/* TODO v15-compat */
1594 if(!su_cs_cmp_case(a_xtls_smime_ciphers_obs
[i
].xc_name
, cp
)){
1595 n_OBSOLETE2(_("*smime-cipher* names with hyphens will vanish"), cp
);
1596 a_XTLS__NFETCH_INJ(cipher
= (*a_xtls_smime_ciphers_obs
[i
].xc_fun
)();)
1597 cp
= a_xtls_smime_ciphers_obs
[i
].xc_name
;
1598 goto a_XTLS__JFETCH
;
1602 /* Not a built-in algorithm, but we may have dynamic support for more */
1603 #if defined mx_HAVE_TLS_ALL_ALGORITHMS && !defined a_XTLS_CRYPTO_FETCH
1604 if((cipher
= EVP_get_cipherbyname(cp
)) != NIL
)
1608 #ifdef a_XTLS_CRYPTO_FETCH
1610 if((cipher
= EVP_CIPHER_fetch(NIL
, cp
, NIL
)) != NIL
){
1616 n_err(_("Invalid S/MIME cipher(s): %s\n"), cp
);
1623 ssl_password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
1632 if(userdata
!= NULL
){
1634 struct mx_cred_ctx cred
;
1636 if(mx_url_parse(&url
, CPROTO_CCRED
, userdata
)){
1637 if(mx_cred_auth_lookup(&cred
, &url
)){
1640 if((end
= su_cs_pcopy_n(buf
, cred
.cc_pass
.s
, size
)) != NULL
){
1641 size
= (int)P2UZ(end
- buf
);
1651 if((pass
= mx_tty_getpass("PEM pass phrase:")) != NIL
){
1652 len
= su_cs_len(pass
);
1653 if (UCMP(z
, len
, >=, size
))
1655 su_mem_copy(buf
, pass
, len
);
1666 smime_sign_cert(char const *xname
, char const *xname2
, boole dowarn
,
1667 char const **match
, boole fallback_from
)
1672 char const *name
= xname
, *name2
= xname2
, *cp
;
1678 np
= lextract(name
, GTO
| GSKIN
);
1679 while (np
!= NULL
) {
1680 /* This needs to be more intelligent since it will currently take the
1681 * first name for which a private key is available regardless of
1682 * whether it is the right one for the message */
1683 vn
= n_lofi_alloc(vs
= su_cs_len(np
->n_name
) + 30);
1684 snprintf(vn
, vs
, "smime-sign-cert-%s", np
->n_name
);
1685 cp
= n_var_vlook(vn
, FAL0
);
1689 *match
= np
->n_name
;
1694 if (name2
!= NULL
) {
1701 /* It is the default *smime-sign-cert* / *from* pair */
1702 if((cp
= ok_vlook(smime_sign_cert
)) == NIL
)
1706 name
= fallback_from
? myorigin(NIL
) : NIL
;
1707 *match
= (name
== NIL
) ? NIL
: savestr(name
);
1711 if((cp
= fexpand(cp
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1714 if((fp
= mx_fs_open(cp
, "r")) == NIL
)
1723 n_err(_("Could not find a certificate for %s%s%s\n"),
1724 xname
, (xname2
!= NULL
? _("or ") : n_empty
),
1725 (xname2
!= NULL
? xname2
: n_empty
));
1730 a_xtls_smime_sign_include_certs(char const *name
)
1735 /* See comments in smime_sign_cert() for algorithm pitfalls */
1739 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1743 vn
= n_lofi_alloc(vs
= su_cs_len(np
->n_name
) + 30);
1744 snprintf(vn
, vs
, "smime-sign-include-certs-%s", np
->n_name
);
1745 rv
= n_var_vlook(vn
, FAL0
);
1751 rv
= ok_vlook(smime_sign_include_certs
);
1758 a_xtls_smime_sign_include_chain_creat(a_XTLS_STACKOF(X509
) **chain
,
1759 char const *cfiles
, char const *addr
)
1763 char *nfield
, *cfield
, *x
;
1766 *chain
= sk_X509_new_null();
1768 for (nfield
= savestr(cfiles
);
1769 (cfield
= su_cs_sep_c(&nfield
, ',', TRU1
)) != NULL
;) {
1770 if((x
= fexpand(cfield
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1771 ) == NIL
|| (fp
= mx_fs_open(cfield
= x
, "r")) == NIL
){
1775 if ((tmp
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, n_UNCONST(addr
))
1777 ssl_gen_err(_("Error reading certificate from %s"),
1778 n_shexp_quote_cp(cfield
, FAL0
));
1782 sk_X509_push(*chain
, tmp
);
1786 if (sk_X509_num(*chain
) == 0) {
1787 n_err(_("*smime-sign-include-certs* defined but empty\n"));
1792 return (*chain
!= NULL
);
1794 sk_X509_pop_free(*chain
, X509_free
);
1799 static EVP_MD
const *
1800 a_xtls_smime_sign_digest(char const *name
, char const **digname
,
1806 /* See comments in smime_sign_cert() for algorithm pitfalls */
1810 for(np
= lextract(name
, GTO
| GSKIN
); np
!= NIL
; np
= np
->n_flink
){
1814 vn
= su_LOFI_ALLOC(vs
= su_cs_len(np
->n_name
) + 30);
1815 snprintf(vn
, vs
, "smime-sign-digest-%s", np
->n_name
);
1816 if((cp
= n_var_vlook(vn
, FAL0
)) == NIL
){
1817 snprintf(vn
, vs
, "smime-sign-message-digest-%s",np
->n_name
);/*v15*/
1818 cp
= n_var_vlook(vn
, FAL0
);
1827 if((cp
= ok_vlook(smime_sign_digest
)) != NIL
)
1829 cp
= ok_vlook(smime_sign_message_digest
)/* v15 */;
1832 if(a_xtls_digest_find(FAL0
, cp
, &md
, digname
, freeit
)){
1833 #ifndef PKCS7_PARTIAL
1834 n_err(_("ALERT: old OpenSSL version, *smime-sign-digest*=%s ignored\n"),
1843 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1845 load_crl1(X509_STORE
*store
, char const *name
)
1847 X509_LOOKUP
*lookup
;
1848 enum okay rv
= STOP
;
1851 if (n_poption
& n_PO_D_V
)
1852 n_err(_("Loading CRL from %s\n"), n_shexp_quote_cp(name
, FAL0
));
1853 if ((lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file())) == NULL
) {
1854 ssl_gen_err(_("Error creating X509 lookup object"));
1857 if (X509_load_crl_file(lookup
, name
, X509_FILETYPE_PEM
) != 1) {
1858 ssl_gen_err(_("Error loading CRL from %s"),
1859 n_shexp_quote_cp(name
, FAL0
));
1867 #endif /* new OpenSSL */
1870 load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
)/*TODO nevertried*/
1872 char *crl_file
, *crl_dir
;
1873 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1887 if ((crl_file
= n_var_oklook(fok
)) != NULL
) {
1888 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1889 if((crl_file
= fexpand(crl_file
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
|
1890 FEXP_NSHELL
))) == NIL
|| load_crl1(store
, crl_file
) != OKAY
)
1894 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1899 if ((crl_dir
= n_var_oklook(dok
)) != NULL
) {
1900 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1903 if((x
= fexpand(crl_dir
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
))
1904 ) == NIL
|| (dirp
= opendir(crl_dir
= x
)) == NIL
){
1909 ds
= su_cs_len(crl_dir
);
1910 fn
= n_alloc(fs
= ds
+ 20);
1911 su_mem_copy(fn
, crl_dir
, ds
);
1913 while ((dp
= readdir(dirp
)) != NULL
) {
1914 if (dp
->d_name
[0] == '.' && (dp
->d_name
[1] == '\0' ||
1915 (dp
->d_name
[1] == '.' && dp
->d_name
[2] == '\0')))
1917 if (dp
->d_name
[0] == '.')
1919 if (ds
+ (es
= su_cs_len(dp
->d_name
)) + 2 < fs
)
1920 fn
= n_realloc(fn
, fs
= ds
+ es
+ 20);
1921 su_mem_copy(fn
+ ds
+ 1, dp
->d_name
, es
+ 1);
1922 if (load_crl1(store
, fn
) != OKAY
) {
1931 #else /* old OpenSSL */
1932 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1937 if(fok
== ok_v_tls_crl_file
){
1938 fok
= ok_v_ssl_crl_file
;
1939 dok
= ok_v_ssl_crl_dir
;
1942 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1944 X509_STORE_set_flags(store
, X509_V_FLAG_CRL_CHECK
|
1945 X509_V_FLAG_CRL_CHECK_ALL
);
1953 #if mx_HAVE_RANDOM == mx_RANDOM_IMPL_TLS
1955 mx_tls_rand_bytes(void *buf
, uz blen
){
1957 if(!(a_xtls_state
& a_XTLS_S_RAND_INIT
))
1963 switch(RAND_bytes(buf
, i
= MIN(S32_MAX
, blen
))){
1965 /* LibreSSL always succeeds, i think it aborts otherwise.
1966 * With elder OpenSSL we ensure via RAND_status() in
1967 * a_xtls_rand_init() that the PRNG is seeded, so it does not fail.
1969 * With newer OpenSSL we disable automatic reseeding, but do not
1970 * ASSERT RAND_status() ("Since you always have to check RAND_bytes's
1971 * return value now, RAND_status is mostly useless.",
1972 * 20190104180735.GA25041@roeckx.be), so we have not that many options
1973 * on what to do. Since OSs will try hard to serve, a simple sleep
1974 * may be it, so do that */
1975 #if mx_HAVE_TLS != mx_TLS_IMPL_RESSL && !defined mx_XTLS_HAVE_RAND_FILE
1976 n_err(_("TLS RAND_bytes(3ssl) failed (missing entropy?), "
1977 "waiting a bit\n"));
1978 /* Around ~Y2K+1 anything <= was a busy loop iirc, so give pad */
1979 n_msleep(250, FAL0
);
1991 #endif /* HAVE_RANDOM == RANDOM_IMPL_TLS */
1994 n_tls_open(struct mx_url
*urlp
, struct mx_socket
*sop
){ /* TODO split */
1997 const EVP_MD
*fprnt_mdp
;
1998 char const *fprnt
, *fprnt_namep
;
2005 n_tls_set_verify_level(urlp
); /* TODO should come in via URL! */
2008 if(urlp
->url_cproto
!= CPROTO_CERTINFO
)
2009 fprnt
= xok_vlook(tls_fingerprint
, urlp
, OXM_ALL
);
2015 if(fprnt
!= NIL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
2016 (n_poption
& n_PO_D_V
)){
2017 fprnt_namep
= xok_vlook(tls_fingerprint_digest
, urlp
, OXM_ALL
);
2018 if(!a_xtls_digest_find(TRU1
, fprnt_namep
, &fprnt_mdp
, &fprnt_namep
,
2023 if((ctxp
= SSL_CTX_new(mx_XTLS_CLIENT_METHOD())) == NULL
){
2024 ssl_gen_err(_("SSL_CTX_new() failed"));
2028 /* Available with OpenSSL 0.9.6 or later */
2029 #ifdef SSL_MODE_AUTO_RETRY
2030 SSL_CTX_set_mode(ctxp
, SSL_MODE_AUTO_RETRY
);
2033 if((confp
= a_xtls_conf_setup(ctxp
, urlp
)) == NULL
)
2036 if(!a_xtls_obsolete_conf_vars(confp
, urlp
))
2038 if(!a_xtls_config_pairs(confp
, urlp
))
2040 if((fprnt
== NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
) &&
2041 !a_xtls_load_verifications(ctxp
, urlp
))
2044 /* Done with context setup, create our new per-connection structure */
2045 if(!a_xtls_conf_finish(&confp
, FAL0
))
2047 ASSERT(confp
== NULL
);
2049 if((sop
->s_tls
= SSL_new(ctxp
)) == NULL
){
2050 ssl_gen_err(_("SSL_new() failed"));
2054 /* Try establish SNI extension; even though this is a TLS extension the
2055 * protocol isn't checked by OpenSSL once the host name is set, and
2056 * therefore i refrained from changing so much code just to check out
2057 * whether we are using SSLv3, which should become more and more rare */
2058 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2059 if((urlp
->url_flags
& mx_URL_TLS_MASK
) &&
2060 (urlp
->url_flags
& mx_URL_HOST_IS_NAME
)){
2061 if(!SSL_set_tlsext_host_name(sop
->s_tls
, urlp
->url_host
.s
) &&
2062 (n_poption
& n_PO_D_V
))
2063 n_err(_("Hostname cannot be used with ServerNameIndication "
2064 "TLS extension: %s\n"),
2065 n_shexp_quote_cp(urlp
->url_host
.s
, FAL0
));
2069 SSL_set_fd(sop
->s_tls
, sop
->s_fd
);
2070 mx_socket_reset_io_buf(sop
);
2072 if(SSL_connect(sop
->s_tls
) < 0){
2073 ssl_gen_err(_("could not initiate TLS connection"));
2077 if(fprnt
!= NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
2078 n_tls_verify_level
!= n_TLS_VERIFY_IGNORE
){
2082 if((peercert
= a_xtls_SSL_get_peer_certificate(sop
->s_tls
)) == NIL
){
2083 n_err(_("TLS: no certificate from peer: %s\n"), urlp
->url_h_p
.s
);
2090 if(!a_xtls_check_host(sop
, peercert
, urlp
)){
2091 n_err(_("TLS certificate does not match: %s\n"), urlp
->url_h_p
.s
);
2092 stay
= n_tls_verify_decide();
2094 if(n_poption
& n_PO_D_V
)
2095 n_err(_("TLS certificate ok\n"));
2100 if(fprnt
!= NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
2101 (n_poption
& n_PO_D_V
)){
2102 char fpmdhexbuf
[EVP_MAX_MD_SIZE
* 3], *cp
;
2103 unsigned char fpmdbuf
[EVP_MAX_MD_SIZE
], *ucp
;
2104 unsigned int fpmdlen
;
2106 if(!X509_digest(peercert
, fprnt_mdp
, fpmdbuf
, &fpmdlen
)){
2107 ssl_gen_err(_("TLS %s fingerprint creation failed"), fprnt_namep
);
2110 ASSERT(fpmdlen
<= EVP_MAX_MD_SIZE
);
2112 for(cp
= fpmdhexbuf
, ucp
= fpmdbuf
; fpmdlen
> 0; --fpmdlen
){
2113 n_c_to_hex_base16(cp
, (char)*ucp
++);
2119 if(n_poption
& n_PO_D_V
)
2120 n_err(_("TLS %s fingerprint: %s\n"), fprnt_namep
, fpmdhexbuf
);
2122 if(!(stay
= !su_cs_cmp_case(fprnt
, fpmdhexbuf
))){
2123 n_err(_("TLS fingerprint mismatch: %s\n"
2124 " Expected: %s\n Detected: %s\n"),
2125 urlp
->url_h_p
.s
, fprnt
, fpmdhexbuf
);
2126 stay
= n_tls_verify_decide();
2127 }else if(n_poption
& n_PO_D_V
)
2128 n_err(_("TLS fingerprint ok\n"));
2130 }else if(urlp
->url_cproto
== CPROTO_CERTINFO
){
2134 a_XTLS_STACKOF(X509
) *certs
;
2136 sop
->s_tls_finger
= savestrbuf(fpmdhexbuf
,
2137 P2UZ(cp
- fpmdhexbuf
));
2139 /* For the sake of `tls cert(chain|ificate)', this too */
2141 /*if((certs = SSL_get_peer_cert_chain(sop->s_tls)) != NIL)*/
2142 if((certs
= a_xtls_SSL_get_verified_chain(sop
->s_tls
)) != NIL
){
2143 if((biop
= BIO_new(BIO_s_mem())) != NIL
){
2147 for(i
= 0; i
< sk_X509_num(certs
); ++i
){
2148 peercert
= sk_X509_value(certs
, i
);
2149 if(((n_poption
& n_PO_D_V
) &&
2150 X509_print(biop
, peercert
) == 0) ||
2151 PEM_write_bio_X509(biop
, peercert
) == 0){
2152 ssl_gen_err(_("Error storing certificate %d from %s"),
2153 i
, urlp
->url_h_p
.s
);
2159 i
= BIO_get_mem_data(biop
, &xcp
);
2161 sop
->s_tls_certificate
= savestrbuf(xcp
, i
);
2166 if(peercert
!= NIL
){
2167 i
= BIO_get_mem_data(biop
, &xcp
);
2169 sop
->s_tls_certchain
= savestrbuf(xcp
, i
);
2179 a_xtls_SSL_get_peer_certificate__FREE(peercert
);
2184 if(n_poption
& n_PO_D_V
){
2185 struct a_xtls_protocol
const *xpp
;
2188 ver
= SSL_version(sop
->s_tls
);
2189 for(xpp
= &a_xtls_protocols
[1] /* [0] == ALL */;; ++xpp
)
2190 if(xpp
->xp_version
== ver
|| xpp
->xp_last
){
2191 n_err(_("TLS connection using %s / %s\n"),
2192 (xpp
->xp_last
? n_qm
: xpp
->xp_name
),
2193 SSL_get_cipher(sop
->s_tls
));
2200 /* We're fully setup: since we don't reuse the SSL_CTX (pooh) keep it local
2201 * and free it right now -- it is reference counted by sp->s_tls.. */
2205 #ifdef a_XTLS_CRYPTO_FETCH
2207 EVP_MD_free(UNCONST(EVP_MD
*,fprnt_mdp
));
2211 return (sop
->s_tls
!= NIL
);
2214 SSL_free(sop
->s_tls
);
2218 a_xtls_conf_finish(&confp
, TRU1
);
2223 ssl_gen_err(char const *fmt
, ...)
2232 n_err(_(": %s\n"), ERR_error_string(ERR_get_error(), NULL
));
2239 int *msgvec
= vp
, *ip
, ec
= 0, rv
= 1;
2240 X509_STORE
*store
= NULL
;
2241 char *ca_dir
, *ca_file
;
2246 n_tls_verify_level
= n_TLS_VERIFY_STRICT
;
2247 if ((store
= X509_STORE_new()) == NULL
) {
2248 ssl_gen_err(_("Error creating X509 store"));
2251 X509_STORE_set_verify_cb_func(store
, &a_xtls_verify_cb
);
2253 if((ca_dir
= ok_vlook(smime_ca_dir
)) != NIL
)
2254 ca_dir
= fexpand(ca_dir
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
| FEXP_NSHELL
));
2255 if((ca_file
= ok_vlook(smime_ca_file
)) != NIL
)
2256 ca_file
= fexpand(ca_file
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
|
2259 if(ca_file
!= NIL
&& a_xtls_X509_STORE_load_file(store
, ca_file
) != 1){
2260 ssl_gen_err(_("Error loading %s\n"), n_shexp_quote_cp(ca_file
, FAL0
));
2264 if(ca_dir
!= NIL
&& a_xtls_X509_STORE_load_path(store
, ca_dir
) != 1){
2265 ssl_gen_err(_("Error loading %s\n"), n_shexp_quote_cp(ca_dir
, FAL0
));
2272 if((xv15
= ok_blook(smime_no_default_ca
)))
2273 n_OBSOLETE(_("please use *smime-ca-no-defaults*, "
2274 "not *smime-no-default-ca*"));
2275 if(!ok_blook(smime_ca_no_defaults
) && !xv15
&&
2276 X509_STORE_set_default_paths(store
) != 1) {
2277 ssl_gen_err(_("Error loading built-in default CA locations\n"));
2282 if (load_crls(store
, ok_v_smime_crl_file
, ok_v_smime_crl_dir
) != OKAY
)
2285 a_xtls_ca_flags(store
, ok_vlook(smime_ca_flags
));
2288 for (ip
= msgvec
; *ip
!= 0; ++ip
) {
2289 struct message
*mp
= message
+ *ip
- 1;
2291 ec
|= smime_verify(mp
, *ip
, NULL
, store
);
2297 n_exit_status
|= n_EXIT_ERR
;
2300 X509_STORE_free(store
);
2306 smime_sign(FILE *ip
, char const *addr
){
2310 a_XTLS_STACKOF(X509
) *chain
;
2313 FILE *rv
, *sfp
, *fp
, *bp
, *hp
;
2315 boole bail
, free_md
;
2318 /* TODO smime_sign(): addr should vanish, it is either *from* aka *sender*
2319 * TODO or what we parsed as From:/Sender: from a template. This latter
2320 * TODO should set *from* / *sender* in a scope, we should use *sender*:
2321 * TODO *sender* should be set to the real *from*! */
2322 ASSERT(addr
!= NIL
);
2323 bail
= free_md
= FAL0
;
2325 rv
= sfp
= fp
= bp
= hp
= NIL
;
2332 if((fp
= smime_sign_cert(addr
, NIL
, 1, NIL
, FAL0
)) == NIL
)
2335 if((pkey
= PEM_read_PrivateKey(fp
, NIL
, &ssl_password_cb
,
2336 savecat(addr
, ".smime-cert-key"))) == NIL
){
2337 ssl_gen_err(_("Error reading private key from"));
2343 if((cert
= PEM_read_X509(fp
, NIL
, &ssl_password_cb
,
2344 savecat(addr
, ".smime-cert-cert"))) == NIL
){
2345 ssl_gen_err(_("Error reading signer certificate from"));
2352 if((name
= a_xtls_smime_sign_include_certs(addr
)) != NIL
&&
2353 !a_xtls_smime_sign_include_chain_creat(&chain
, name
,
2354 savecat(addr
, ".smime-include-certs")))
2358 if((md
= a_xtls_smime_sign_digest(addr
, &name
, &free_md
)) == NIL
)
2361 if((sfp
= mx_fs_tmp_open("smimesign", (mx_FS_O_RDWR
| mx_FS_O_UNLINK
|
2362 mx_FS_O_REGISTER
), NIL
)) == NIL
){
2363 n_perr(_("tempfile"), 0);
2368 if(!mx_smime_split(ip
, &hp
, &bp
, -1, FAL0
))
2374 if((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NIL
||
2375 (sb
= BIO_new_fp(sfp
, BIO_NOCLOSE
)) == NIL
){
2376 ssl_gen_err(_("Error creating BIO signing objects"));
2381 #ifdef PKCS7_PARTIAL
2382 if((pkcs7
= PKCS7_sign(NULL
, NIL
, chain
, bb
,
2383 (PKCS7_DETACHED
| PKCS7_PARTIAL
))) == NIL
){
2384 ssl_gen_err(_("Error creating the PKCS#7 signing object"));
2388 if(PKCS7_sign_add_signer(pkcs7
, cert
, pkey
, md
,
2389 (PKCS7_DETACHED
| PKCS7_PARTIAL
)) == NIL
){
2390 ssl_gen_err(_("Error setting PKCS#7 signing object signer"));
2394 if(!PKCS7_final(pkcs7
, bb
, (PKCS7_DETACHED
| PKCS7_PARTIAL
))){
2395 ssl_gen_err(_("Error finalizing the PKCS#7 signing object"));
2400 if((pkcs7
= PKCS7_sign(cert
, pkey
, chain
, bb
, PKCS7_DETACHED
)) == NIL
){
2401 ssl_gen_err(_("Error creating the PKCS#7 signing object"));
2405 #endif /* !PKCS7_PARTIAL */
2407 if(PEM_write_bio_PKCS7(sb
, pkcs7
) == 0){
2408 ssl_gen_err(_("Error writing signed S/MIME data"));
2423 rv
= smime_sign_assemble(hp
, bp
, sfp
, name
);
2424 hp
= bp
= sfp
= NIL
;
2429 sk_X509_pop_free(chain
, X509_free
);
2433 EVP_PKEY_free(pkey
);
2442 #ifdef a_XTLS_CRYPTO_FETCH
2444 EVP_MD_free(UNCONST(EVP_MD
*,md
));
2452 smime_encrypt(FILE *ip
, char const *xcertfile
, char const *to
)
2454 FILE *rv
, *yp
, *fp
, *bp
, *hp
;
2458 a_XTLS_STACKOF(X509
) *certs
;
2459 EVP_CIPHER
const *cipher
;
2461 boole bail
, free_cipher
;
2464 bail
= free_cipher
= FAL0
;
2465 rv
= yp
= fp
= bp
= hp
= NULL
;
2467 if((certfile
= fexpand(xcertfile
, (FEXP_NOPROTO
| FEXP_LOCAL_FILE
|
2468 FEXP_NSHELL
))) == NIL
)
2473 if((cipher
= a_xtls_smime_cipher(to
, &free_cipher
)) == NIL
)
2476 if((fp
= mx_fs_open(certfile
, "r")) == NIL
){
2477 n_perr(certfile
, 0);
2480 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, NULL
)) == NULL
) {
2481 ssl_gen_err(_("Error reading encryption certificate from %s"),
2482 n_shexp_quote_cp(certfile
, FAL0
));
2491 certs
= sk_X509_new_null();
2492 sk_X509_push(certs
, cert
);
2494 if((yp
= mx_fs_tmp_open("smimeenc", (mx_FS_O_RDWR
| mx_FS_O_UNLINK
|
2495 mx_FS_O_REGISTER
), NIL
)) == NIL
){
2496 n_perr(_("tempfile"), 0);
2501 if(!mx_smime_split(ip
, &hp
, &bp
, -1, FAL0
))
2505 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
2506 (yb
= BIO_new_fp(yp
, BIO_NOCLOSE
)) == NULL
) {
2507 ssl_gen_err(_("Error creating BIO encryption objects"));
2511 if ((pkcs7
= PKCS7_encrypt(certs
, bb
, cipher
, 0)) == NULL
) {
2512 ssl_gen_err(_("Error creating the PKCS#7 encryption object"));
2516 if (PEM_write_bio_PKCS7(yb
, pkcs7
) == 0) {
2517 ssl_gen_err(_("Error writing encrypted S/MIME data"));
2532 rv
= smime_encrypt_assemble(hp
, yp
);
2536 sk_X509_pop_free(certs
, X509_free
);
2547 #ifdef a_XTLS_CRYPTO_FETCH
2549 EVP_CIPHER_free(UNCONST(EVP_CIPHER
*,cipher
));
2557 smime_decrypt(struct message
*m
, char const *to
, char const *cc
,
2558 boole is_a_verify_call
)
2573 ob
= bb
= pb
= NULL
;
2575 bp
= hp
= op
= NULL
;
2579 if((yp
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2584 if((op
= smime_sign_cert(to
, cc
, 0, &myaddr
, TRU1
)) != NULL
){
2585 pkey
= PEM_read_PrivateKey(op
, NULL
, &ssl_password_cb
,
2586 savecat(myaddr
, ".smime-cert-key"));
2588 ssl_gen_err(_("Error reading private key"));
2593 if((cert
= PEM_read_X509(op
, NULL
, &ssl_password_cb
,
2594 savecat(myaddr
, ".smime-cert-cert"))) == NULL
){
2595 ssl_gen_err(_("Error reading decryption certificate"));
2603 if((op
= mx_fs_tmp_open("smimed", (mx_FS_O_RDWR
| mx_FS_O_UNLINK
|
2604 mx_FS_O_REGISTER
), NIL
)) == NIL
){
2605 n_perr(_("tempfile"), 0);
2609 if(!mx_smime_split(yp
, &hp
, &bp
, size
, TRU1
))
2612 if((ob
= BIO_new_fp(op
, BIO_NOCLOSE
)) == NULL
||
2613 (bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
){
2614 ssl_gen_err(_("Error creating BIO decryption objects"));
2618 if((pkcs7
= SMIME_read_PKCS7(bb
, &pb
)) == NULL
){
2619 ssl_gen_err(_("Error reading PKCS#7 object"));
2623 if(PKCS7_type_is_signed(pkcs7
)){
2624 if(!is_a_verify_call
){
2625 setinput(&mb
, m
, NEED_BODY
);
2626 rv
= (struct message
*)-1;
2629 if(PKCS7_verify(pkcs7
, NULL
, NULL
, NULL
, ob
,
2630 PKCS7_NOVERIFY
| PKCS7_NOSIGS
) != 1)
2632 fseek(hp
, 0L, SEEK_END
);
2633 fprintf(hp
, "X-Encryption-Cipher: none\n");
2635 }else if(pkey
== NULL
){
2636 n_err(_("No appropriate private key found\n"));
2638 }else if(cert
== NULL
){
2639 n_err(_("No appropriate certificate found\n"));
2641 }else if(PKCS7_decrypt(pkcs7
, pkey
, cert
, ob
, 0) != 1){
2643 ssl_gen_err(_("Error decrypting PKCS#7 object"));
2651 if((rv
= mx_smime_decrypt_assemble(m
, hp
, op
)) == NIL
)
2652 n_err(_("I/O error while creating decrypted message\n"));
2669 EVP_PKEY_free(pkey
);
2676 smime_certsave(struct message
*m
, int n
, FILE *op
)
2679 char *to
, *cc
, *cnttype
;
2685 a_XTLS_STACKOF(X509
) *certs
, *chain
= NIL
;
2687 enum okay rv
= STOP
;
2692 a_xtls_msgno
= (uz
)n
;
2694 to
= hfield1("to", m
);
2695 cc
= hfield1("cc", m
);
2696 cnttype
= hfield1("content-type", m
);
2698 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2703 #define _X (sizeof("application/") -1)
2704 #define _Y(X) X, sizeof(X) -1
2705 if (cnttype
&& su_cs_starts_with_case(cnttype
, "application/") &&
2706 (!su_cs_cmp_case_n(cnttype
+ _X
, _Y("pkcs7-mime")) ||
2707 !su_cs_cmp_case_n(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
2710 if ((x
= smime_decrypt(m
, to
, cc
, TRU1
)) == NULL
)
2712 if (x
!= (struct message
*)-1) {
2719 if((fp
= mx_fs_tmp_open("smimecert", (mx_FS_O_RDWR
| mx_FS_O_UNLINK
|
2720 mx_FS_O_REGISTER
), NIL
)) == NIL
){
2721 n_perr(_("tempfile"), 0);
2725 while (size
-- > 0) {
2732 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
2733 ssl_gen_err("Error creating BIO object for message %d", n
);
2738 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
2739 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
2747 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
2748 if (certs
== NULL
) {
2749 n_err(_("No certificates found in message %d\n"), n
);
2753 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
2754 cert
= sk_X509_value(certs
, i
);
2755 if (X509_print_fp(op
, cert
) == 0 || PEM_write_X509(op
, cert
) == 0) {
2756 ssl_gen_err(_("Error writing certificate %d from message %d"),
2769 #include "su/code-ou.h"
2770 #endif /* mx_HAVE_XTLS */