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>.
8 * SPDX-License-Identifier: BSD-4-Clause TODO ISC
12 * Gunnar Ritter. All rights reserved.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by Gunnar Ritter
25 * and his contributors.
26 * 4. Neither the name of Gunnar Ritter nor the names of his contributors
27 * may be used to endorse or promote products derived from this software
28 * without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 #ifndef HAVE_AMALGAMATION
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 HAVE_XTLS_CONFIG
64 # include <openssl/conf.h>
67 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
71 /* Compatibility shims which assume 0/-1 cannot really happen */
72 #ifndef HAVE_XTLS_CONF_CTX
73 # ifndef SSL_OP_NO_SSLv2
74 # define SSL_OP_NO_SSLv2 0
76 # ifndef SSL_OP_NO_SSLv3
77 # define SSL_OP_NO_SSLv3 0
79 # ifndef SSL_OP_NO_TLSv1
80 # define SSL_OP_NO_TLSv1 0
82 # ifndef SSL_OP_NO_TLSv1_1
83 # define SSL_OP_NO_TLSv1_1 0
85 # ifndef SSL_OP_NO_TLSv1_2
86 # define SSL_OP_NO_TLSv1_2 0
88 # ifndef SSL_OP_NO_TLSv1_3
89 # define SSL_OP_NO_TLSv1_3 0
91 /* SSL_CONF_CTX and _OP_NO_SSL_MASK were both introduced with 1.0.2!?! */
92 # ifndef SSL_OP_NO_SSL_MASK
93 # define SSL_OP_NO_SSL_MASK \
94 (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |\
95 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 |\
100 # define SSL2_VERSION 0
102 # ifndef SSL3_VERSION
103 # define SSL3_VERSION 0
105 # ifndef TLS1_VERSION
106 # define TLS1_VERSION 0
108 # ifndef TLS1_1_VERSION
109 # define TLS1_1_VERSION 0
111 # ifndef TLS1_2_VERSION
112 # define TLS1_2_VERSION 0
114 # ifndef TLS1_3_VERSION
115 # define TLS1_3_VERSION 0
119 #ifdef HAVE_XTLS_STACK_OF
120 # define n_XTLS_STACKOF(X) STACK_OF(X)
122 # define n_XTLS_STACKOF(X) /*X*/STACK
125 #if OPENSSL_VERSION_NUMBER + 0 >= 0x0090581fL
126 # define a_XTLS_RAND_LOAD_FILE_MAXBYTES -1
128 # define a_XTLS_RAND_LOAD_FILE_MAXBYTES 1024
131 /* Compatibility sighs (that sigh is _really_ a cute one) */
132 #if HAVE_XTLS_OPENSSL >= 0x10100
133 # define a_xtls_X509_get_notBefore X509_get0_notBefore
134 # define a_xtls_X509_get_notAfter X509_get0_notAfter
136 # define a_xtls_X509_get_notBefore X509_get_notBefore
137 # define a_xtls_X509_get_notAfter X509_get_notAfter
140 /* X509_STORE_set_flags */
141 #undef a_XTLS_X509_V_ANY
142 #ifndef X509_V_FLAG_NO_ALT_CHAINS
143 # define X509_V_FLAG_NO_ALT_CHAINS -1
145 # undef a_XTLS_X509_V_ANY
146 # define a_XTLS_X509_V_ANY
148 #ifndef X509_V_FLAG_NO_CHECK_TIME
149 # define X509_V_FLAG_NO_CHECK_TIME -1
151 # undef a_XTLS_X509_V_ANY
152 # define a_XTLS_X509_V_ANY
154 #ifndef X509_V_FLAG_PARTIAL_CHAIN
155 # define X509_V_FLAG_PARTIAL_CHAIN -1
157 # undef a_XTLS_X509_V_ANY
158 # define a_XTLS_X509_V_ANY
160 #ifndef X509_V_FLAG_X509_STRICT
161 # define X509_V_FLAG_X509_STRICT -1
163 # undef a_XTLS_X509_V_ANY
164 # define a_XTLS_X509_V_ANY
166 #ifndef X509_V_FLAG_TRUSTED_FIRST
167 # define X509_V_FLAG_TRUSTED_FIRST -1
169 # undef a_XTLS_X509_V_ANY
170 # define a_XTLS_X509_V_ANY
174 a_XTLS_S_INIT
= 1u<<0,
175 a_XTLS_S_RAND_INIT
= 1u<<1,
176 a_XTLS_S_CONF_LOAD
= 1u<<2,
178 #if HAVE_XTLS_OPENSSL < 0x10100
179 a_XTLS_S_EXIT_HDL
= 1u<<8,
180 a_XTLS_S_ALGO_LOAD
= 1u<<9,
183 a_XTLS_S_VERIFY_ERROR
= 1u<<16
186 struct ssl_method
{ /* TODO v15 obsolete */
187 char const sm_name
[8];
188 char const sm_map
[16];
191 #ifndef HAVE_XTLS_CONF_CTX
192 struct a_xtls_protocol
{
193 char const xp_name
[8];
194 sl_i xp_op_no
; /* SSL_OP_NO_* bit */
195 ui16_t xp_version
; /* *_VERSION number */
196 bool_t xp_ok_minmaxproto
; /* Valid for {Min,Max}Protocol= */
197 bool_t xp_ok_proto
; /* Valid for Protocol= */
202 struct a_xtls_cipher
{
203 char const xc_name
[8];
204 EVP_CIPHER
const *(*xc_fun
)(void);
207 struct a_xtls_digest
{
208 char const xd_name
[16];
209 EVP_MD
const *(*xd_fun
)(void);
212 struct a_xtls_x509_v_flags
{
213 char const xxvf_name
[20];
217 /* Supported SSL/TLS methods: update manual on change! */
218 static struct ssl_method
const _ssl_methods
[] = { /* TODO obsolete */
219 {"auto", "ALL,-SSLv2"},
220 {"ssl3", "-ALL,SSLv3"},
221 {"tls1", "-ALL,TLSv1"},
222 {"tls1.1", "-ALL,TLSv1.1"},
223 {"tls1.2", "-ALL,TLSv1.2"}
226 /* Update manual on change!
227 * Ensure array size by adding \0 to longest entry.
228 * Strictly to be sorted new/up to old/down, [0]=ALL, [x-1]=None! */
229 #ifndef HAVE_XTLS_CONF_CTX
230 static struct a_xtls_protocol
const a_xtls_protocols
[] = {
231 {"ALL", SSL_OP_NO_SSL_MASK
, 0, FAL0
, TRU1
, {0}},
232 {"TLSv1.3\0", SSL_OP_NO_TLSv1_3
, TLS1_3_VERSION
, TRU1
, TRU1
, {0}},
233 {"TLSv1.2", SSL_OP_NO_TLSv1_2
, TLS1_2_VERSION
, TRU1
, TRU1
, {0}},
234 {"TLSv1.1", SSL_OP_NO_TLSv1_1
, TLS1_1_VERSION
, TRU1
, TRU1
, {0}},
235 {"TLSv1", SSL_OP_NO_TLSv1
, TLS1_VERSION
, TRU1
, TRU1
, {0}},
236 {"SSLv3", SSL_OP_NO_SSLv3
, SSL3_VERSION
, TRU1
, TRU1
, {0}},
237 {"SSLv2", SSL_OP_NO_SSLv2
, SSL2_VERSION
, TRU1
, TRU1
, {0}},
238 {"None", SSL_OP_NO_SSL_MASK
, 0, TRU1
, FAL0
, {0}}
240 #endif /* HAVE_XTLS_CONF_CTX */
242 /* Supported S/MIME cipher algorithms */
243 static struct a_xtls_cipher
const a_xtls_ciphers
[] = { /*Manual!*/
244 #ifndef OPENSSL_NO_AES
245 # define a_XTLS_SMIME_DEFAULT_CIPHER EVP_aes_128_cbc /* According RFC 5751 */
246 {"AES128", &EVP_aes_128_cbc
},
247 {"AES256", &EVP_aes_256_cbc
},
248 {"AES192", &EVP_aes_192_cbc
},
250 #ifndef OPENSSL_NO_DES
251 # ifndef a_XTLS_SMIME_DEFAULT_CIPHER
252 # define a_XTLS_SMIME_DEFAULT_CIPHER EVP_des_ede3_cbc
254 {"DES3", &EVP_des_ede3_cbc
},
255 {"DES", &EVP_des_cbc
},
258 #ifndef a_XTLS_SMIME_DEFAULT_CIPHER
259 # error Your OpenSSL library does not include the necessary
260 # error cipher algorithms that are required to support S/MIME
263 #ifndef OPENSSL_NO_AES
264 /* TODO obsolete a_xtls_smime_ciphers_obs */
265 static struct a_xtls_cipher
const a_xtls_smime_ciphers_obs
[] = {
266 {"AES-128", &EVP_aes_128_cbc
},
267 {"AES-256", &EVP_aes_256_cbc
},
268 {"AES-192", &EVP_aes_192_cbc
}
272 /* Supported S/MIME message digest algorithms.
273 * Update manual on default changes! */
274 static struct a_xtls_digest
const a_xtls_digests
[] = { /*Manual!*/
275 #ifdef HAVE_XTLS_BLAKE2
276 {"BLAKE2b512\0", &EVP_blake2b512
},
277 {"BLAKE2s256", &EVP_blake2s256
},
278 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
279 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_blake2s256
280 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "BLAKE2s256"
284 #ifdef HAVE_XTLS_SHA3
285 {"SHA3-512\0", &EVP_sha3_512
},
286 {"SHA3-384", &EVP_sha3_384
},
287 {"SHA3-256", &EVP_sha3_256
},
288 {"SHA3-224", &EVP_sha3_224
},
291 #ifndef OPENSSL_NO_SHA512
292 {"SHA512\0", &EVP_sha512
},
293 {"SHA384", &EVP_sha384
},
294 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
295 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha512
296 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA512"
300 #ifndef OPENSSL_NO_SHA256
301 {"SHA256\0", &EVP_sha256
},
302 {"SHA224", &EVP_sha224
},
303 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
304 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha256
305 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA256"
307 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
308 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_sha256
309 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "SHA256"
313 #ifndef OPENSSL_NO_SHA
314 {"SHA1\0", &EVP_sha1
},
315 # ifndef a_XTLS_SMIME_DEFAULT_DIGEST
316 # define a_XTLS_SMIME_DEFAULT_DIGEST EVP_sha1
317 # define a_XTLS_SMIME_DEFAULT_DIGEST_S "SHA1"
319 # ifndef a_XTLS_FINGERPRINT_DEFAULT_DIGEST
320 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST EVP_sha1
321 # define a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S "SHA1"
325 #ifndef OPENSSL_NO_MD5
330 #if !defined a_XTLS_SMIME_DEFAULT_DIGEST || \
331 !defined a_XTLS_FINGERPRINT_DEFAULT_DIGEST
332 # error Not enough supported message digest algorithms available
335 /* X509_STORE_set_flags() for *{smime,ssl}-ca-flags* */
336 static struct a_xtls_x509_v_flags
const a_xtls_x509_v_flags
[] = { /* Manual! */
337 {"no-alt-chains", X509_V_FLAG_NO_ALT_CHAINS
},
338 {"no-check-time", X509_V_FLAG_NO_CHECK_TIME
},
339 {"partial-chain", X509_V_FLAG_PARTIAL_CHAIN
},
340 {"strict", X509_V_FLAG_X509_STRICT
},
341 {"trusted-first", X509_V_FLAG_TRUSTED_FIRST
},
344 static enum a_xtls_state a_xtls_state
;
345 static size_t a_xtls_msgno
;
347 static void a_xtls_rand_init(void);
348 static void a_xtls_init(void);
350 #if HAVE_XTLS_OPENSSL < 0x10100
351 # ifdef HAVE_TLS_ALL_ALGORITHMS
352 static void a_xtls__load_algos(void);
353 # define a_xtls_load_algos a_xtls__load_algos
355 # if defined HAVE_XTLS_CONFIG || defined HAVE_TLS_ALL_ALGORITHMS
356 static void a_xtls_atexit(void);
359 #ifndef a_xtls_load_algos
360 # define a_xtls_load_algos() do{;}while(0)
363 static bool_t
a_xtls_parse_asn1_time(ASN1_TIME
const *atp
,
364 char *bdat
, size_t blen
);
365 static int a_xtls_verify_cb(int success
, X509_STORE_CTX
*store
);
367 static bool_t
a_xtls_digest_find(char const *name
, EVP_MD
const **mdp
,
368 char const **normalized_name_or_null
);
370 /* *smime-ca-flags*, *tls-ca-flags* */
371 static void a_xtls_ca_flags(X509_STORE
*store
, char const *flags
);
373 /* SSL_CTX configuration; the latter always NULLs *confp */
374 static void *a_xtls_conf_setup(SSL_CTX
*ctxp
, struct url
const *urlp
);
375 static bool_t
a_xtls_conf(void *confp
, char const *cmd
, char const *value
);
376 static bool_t
a_xtls_conf_finish(void **confp
, bool_t error
);
378 static bool_t
a_xtls_obsolete_conf_vars(void *confp
, struct url
const *urlp
);
379 static bool_t
a_xtls_config_pairs(void *confp
, struct url
const *urlp
);
380 static bool_t
a_xtls_load_verifications(SSL_CTX
*ctxp
, struct url
const *urlp
);
382 static bool_t
a_xtls_check_host(struct sock
*sp
, X509
*peercert
,
383 struct url
const *urlp
);
385 static int smime_verify(struct message
*m
, int n
,
386 n_XTLS_STACKOF(X509
) *chain
, X509_STORE
*store
);
387 static EVP_CIPHER
const * _smime_cipher(char const *name
);
388 static int ssl_password_cb(char *buf
, int size
, int rwflag
,
390 static FILE * smime_sign_cert(char const *xname
, char const *xname2
,
391 bool_t dowarn
, char const **match
);
392 static char const * _smime_sign_include_certs(char const *name
);
393 static bool_t
_smime_sign_include_chain_creat(n_XTLS_STACKOF(X509
) **chain
,
394 char const *cfiles
, char const *addr
);
395 static EVP_MD
const *a_xtls_smime_sign_digest(char const *name
,
396 char const **digname
);
397 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
398 static enum okay
load_crl1(X509_STORE
*store
, char const *name
);
400 static enum okay
load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
);
403 a_xtls_rand_init(void){
404 #define a_XTLS_RAND_ENTROPY 32
405 char b64buf
[a_XTLS_RAND_ENTROPY
* 5 +1], *randfile
;
410 a_xtls_state
|= a_XTLS_S_RAND_INIT
;
415 #ifdef HAVE_XTLS_CONFIG
416 if(!(a_xtls_state
& a_XTLS_S_INIT
))
420 /* Prefer possible user setting */
421 if((cp
= ok_vlook(tls_rand_file
)) != NULL
||
422 (cp
= ok_vlook(ssl_rand_file
)) != NULL
){
425 if((x
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
426 n_err(_("*tls-rand-file*: expansion of %s failed "
427 "(using default)\n"),
428 n_shexp_quote_cp(cp
, FAL0
));
433 randfile
= n_lofi_alloc(PATH_MAX
);
434 if((cp
= RAND_file_name(randfile
, PATH_MAX
)) == NULL
){
435 n_err(_("*tls-rand-file*: no TLS entropy file, can't seed PRNG\n"));
440 (void)RAND_load_file(cp
, a_XTLS_RAND_LOAD_FILE_MAXBYTES
);
442 /* And feed in some data, then write the updated file.
443 * While this rather feeds the PRNG with itself in the n_RANDOM_IMPL_TLS
444 * case, let us stir the buffer a little bit.
445 * Estimate a low but likely still too high number of entropy bytes, use
446 * 20%: base64 uses 3 input = 4 output bytes relation, and the base64
447 * alphabet is a 6 bit one */
448 for(x
= (char*)-1;;){
449 RAND_add(n_random_create_buf(b64buf
, sizeof(b64buf
) -1, NULL
),
450 sizeof(b64buf
) -1, a_XTLS_RAND_ENTROPY
);
451 if((x
= (char*)((uintptr_t)x
>> (1
452 #if HAVE_RANDOM == n_RANDOM_IMPL_TLS
456 err
= (RAND_status() == 0);
459 #if HAVE_RANDOM != n_RANDOM_IMPL_TLS
460 if(!(err
= (RAND_status() == 0)))
466 err
= (RAND_write_file(cp
) == -1);
470 n_lofi_free(randfile
);
472 n_panic(_("Cannot seed the *TLS PseudoRandomNumberGenerator, "
473 "RAND_status() is 0!\n"
474 " Please set *tls-rand-file* to a file with sufficient entropy.\n"
475 " On a machine with entropy: "
476 "\"$ dd if=/dev/urandom of=FILE bs=1024 count=1\"\n"));
482 #ifdef HAVE_XTLS_CONFIG
487 if(a_xtls_state
& a_XTLS_S_INIT
)
490 #if HAVE_XTLS_OPENSSL >= 0x10100
491 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
492 OPENSSL_INIT_LOAD_CRYPTO_STRINGS
493 # ifdef HAVE_TLS_ALL_ALGORITHMS
494 | OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
498 SSL_load_error_strings();
502 a_xtls_state
|= a_XTLS_S_INIT
;
505 /* Load openssl.cnf or whatever was given in *tls-config-file* */
506 #ifdef HAVE_XTLS_CONFIG
507 if((cp
= ok_vlook(tls_config_file
)) != NULL
||
508 (cp
= ok_vlook(ssl_config_file
)) != NULL
){
515 flags
= CONF_MFLAGS_IGNORE_MISSING_FILE
;
516 }else if((msg
= cp
, cp
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) != NULL
)
519 n_err(_("*tls-config-file*: file expansion failed: %s\n"),
520 n_shexp_quote_cp(msg
, FAL0
));
524 if(CONF_modules_load_file(cp
, n_uagent
, flags
) == 1){
525 a_xtls_state
|= a_XTLS_S_CONF_LOAD
;
526 # if HAVE_XTLS_OPENSSL < 0x10100
527 if(!(a_xtls_state
& a_XTLS_S_EXIT_HDL
)){
528 a_xtls_state
|= a_XTLS_S_EXIT_HDL
;
529 atexit(&a_xtls_atexit
); /* TODO generic program-wide event mech. */
532 if(n_poption
& n_PO_D_V
)
533 n_err(_("Loaded TLS configuration for %s from %s\n"), n_uagent
,
534 n_shexp_quote_cp(msg
, FAL0
));
537 ssl_gen_err(_("TLS CONF_modules_load_file() load error"));
539 #endif /* HAVE_XTLS_CONFIG */
541 if(!(a_xtls_state
& a_XTLS_S_RAND_INIT
))
547 #if HAVE_XTLS_OPENSSL < 0x10100
548 # ifdef HAVE_TLS_ALL_ALGORITHMS
550 a_xtls__load_algos(void){
552 if(!(a_xtls_state
& a_XTLS_S_ALGO_LOAD
)){
553 a_xtls_state
|= a_XTLS_S_ALGO_LOAD
;
554 OpenSSL_add_all_algorithms();
556 if(!(a_xtls_state
& a_XTLS_S_EXIT_HDL
)){
557 a_xtls_state
|= a_XTLS_S_EXIT_HDL
;
558 atexit(&a_xtls_atexit
); /* TODO generic program-wide event mech. */
565 # if defined HAVE_XTLS_CONFIG || defined HAVE_TLS_ALL_ALGORITHMS
569 # ifdef HAVE_XTLS_CONFIG
570 if(a_xtls_state
& a_XTLS_S_CONF_LOAD
)
574 # ifdef HAVE_TLS_ALL_ALGORITHMS
575 if(a_xtls_state
& a_XTLS_S_ALGO_LOAD
)
581 #endif /* HAVE_XTLS_OPENSSL < 0x10100 */
584 a_xtls_parse_asn1_time(ASN1_TIME
const *atp
, char *bdat
, size_t blen
)
591 mbp
= BIO_new(BIO_s_mem());
593 if (ASN1_TIME_print(mbp
, atp
) && (l
= BIO_get_mem_data(mbp
, &mcp
)) > 0)
594 snprintf(bdat
, blen
, "%.*s", (int)l
, mcp
);
596 snprintf(bdat
, blen
, _("Bogus certificate date: %.*s"),
597 /*is (int)*/atp
->length
, (char const*)atp
->data
);
603 return (mcp
!= NULL
);
607 a_xtls_verify_cb(int success
, X509_STORE_CTX
*store
)
614 if (success
&& !(n_poption
& n_PO_D_V
))
617 if (a_xtls_msgno
!= 0) {
618 n_err(_("Message %lu:\n"), (ul_i
)a_xtls_msgno
);
621 n_err(_(" Certificate depth %d %s\n"),
622 X509_STORE_CTX_get_error_depth(store
), (success
? n_empty
: V_(n_error
)));
624 if ((cert
= X509_STORE_CTX_get_current_cert(store
)) != NULL
) {
625 X509_NAME_oneline(X509_get_subject_name(cert
), data
, sizeof data
);
626 n_err(_(" subject = %s\n"), data
);
628 a_xtls_parse_asn1_time(a_xtls_X509_get_notBefore(cert
),
630 n_err(_(" notBefore = %s\n"), data
);
632 a_xtls_parse_asn1_time(a_xtls_X509_get_notAfter(cert
),
634 n_err(_(" notAfter = %s\n"), data
);
636 X509_NAME_oneline(X509_get_issuer_name(cert
), data
, sizeof data
);
637 n_err(_(" issuer = %s\n"), data
);
641 int err
= X509_STORE_CTX_get_error(store
);
643 n_err(_(" err %i: %s\n"), err
, X509_verify_cert_error_string(err
));
644 a_xtls_state
|= a_XTLS_S_VERIFY_ERROR
;
648 rv
= n_tls_verify_decide();
655 a_xtls_digest_find(char const *name
,
656 EVP_MD
const **mdp
, char const **normalized_name_or_null
){
665 nn
= cp
= n_lofi_alloc(i
+1);
666 while((c
= *name
++) != '\0')
667 *cp
++ = upperconv(c
);
670 if(normalized_name_or_null
!= NULL
)
671 *normalized_name_or_null
= savestrbuf(nn
, PTR2SIZE(cp
- nn
));
674 for(i
= 0; i
< n_NELEM(a_xtls_digests
); ++i
)
675 if(!strcmp(a_xtls_digests
[i
].xd_name
, nn
)){
676 *mdp
= (*a_xtls_digests
[i
].xd_fun
)();
680 /* Not a built-in algorithm, but we may have dynamic support for more */
681 #ifdef HAVE_TLS_ALL_ALGORITHMS
682 if((*mdp
= EVP_get_digestbyname(nn
)) != NULL
)
686 n_err(_("Invalid message digest: %s\n"), n_shexp_quote_cp(nn
, FAL0
));
692 return (*mdp
!= NULL
);
696 a_xtls_ca_flags(X509_STORE
*store
, char const *flags
){
701 iolist
= savestr(flags
);
703 while((cp
= n_strsep(&iolist
, ',', TRU1
)) != NULL
){
704 struct a_xtls_x509_v_flags
const *xvfp
;
706 for(xvfp
= &a_xtls_x509_v_flags
[0];
707 xvfp
< &a_xtls_x509_v_flags
[n_NELEM(a_xtls_x509_v_flags
)];
709 if(!asccasecmp(cp
, xvfp
->xxvf_name
)){
710 if(xvfp
->xxvf_flag
!= -1){
711 #ifdef a_XTLS_X509_V_ANY
712 X509_STORE_set_flags(store
, xvfp
->xxvf_flag
);
714 }else if(n_poption
& n_PO_D_V
)
715 n_err(_("*{smime,tls}-ca-flags*: "
716 "directive not supported: %s\n"), cp
);
719 n_err(_("*{smime,tls}-ca-flags*: invalid directive: %s\n"), cp
);
725 #ifdef HAVE_XTLS_CONF_CTX
727 a_xtls_conf_setup(SSL_CTX
*ctxp
, struct url
const *urlp
){
734 if((cp
= xok_vlook(tls_config_module
, urlp
, OXM_ALL
)) != NULL
||
735 (cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
736 # ifdef HAVE_XTLS_CTX_CONFIG
737 if(!(a_xtls_state
& a_XTLS_S_CONF_LOAD
)){
738 n_err(_("*tls-config-module*: no *tls-config-file* loaded: %s\n"),
739 n_shexp_quote_cp(cp
, FAL0
));
741 }else if(!SSL_CTX_config(ctxp
, cp
)){
742 ssl_gen_err(_("*tls-config-module*: load error for %s, section [%s]"),
743 n_uagent
, n_shexp_quote_cp(cp
, FAL0
));
747 n_err(_("*tls-config-module*: set but not supported: %s\n"),
748 n_shexp_quote_cp(cp
, FAL0
));
753 if((sccp
= SSL_CONF_CTX_new()) != NULL
){
754 SSL_CONF_CTX_set_flags(sccp
,
755 SSL_CONF_FLAG_FILE
| SSL_CONF_FLAG_CLIENT
|
756 SSL_CONF_FLAG_CERTIFICATE
| SSL_CONF_FLAG_SHOW_ERRORS
);
758 SSL_CONF_CTX_set_ssl_ctx(sccp
, ctxp
);
760 ssl_gen_err(_("SSL_CONF_CTX_new() failed"));
767 a_xtls_conf(void *confp
, char const *cmd
, char const *value
){
772 if(n_poption
& n_PO_D_V
)
773 n_err(_("TLS: applying config: %s = %s\n"),
774 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
776 rv
= SSL_CONF_cmd(sccp
= confp
, cmd
, value
);
780 cmd
= n_shexp_quote_cp(cmd
, FAL0
);
781 value
= n_shexp_quote_cp(value
, FAL0
);
783 ssl_gen_err(_("TLS: config failure: %s = %s"), cmd
, value
);
788 case -2: err
= N_("TLS: config command not recognized"); break;
789 case -3: err
= N_("TLS: missing required config argument"); break;
790 default: err
= N_("TLS: unspecified config error"); break;
793 n_err(_("%s (%d): %s = %s\n"), err
, rv
, cmd
, value
);
802 a_xtls_conf_finish(void **confp
, bool_t error
){
807 sccp
= (SSL_CONF_CTX
*)*confp
;
811 rv
= (SSL_CONF_CTX_finish(sccp
) != 0);
813 SSL_CONF_CTX_free(sccp
);
818 #else /* HAVE_XTLS_CONF_CTX */
819 # ifdef HAVE_XTLS_CTX_CONFIG
820 # error SSL_CTX_config(3) support unexpected without SSL_CONF_CTX support
824 a_xtls_conf_setup(SSL_CTX
* ctxp
, struct url
const *urlp
){
828 if((cp
= xok_vlook(tls_config_module
, urlp
, OXM_ALL
)) != NULL
||
829 (cp
= xok_vlook(ssl_config_module
, urlp
, OXM_ALL
)) != NULL
){
830 n_err(_("*tls-config-module*: set but not supported: %s\n"),
831 n_shexp_quote_cp(cp
, FAL0
));
839 a_xtls_conf(void *confp
, char const *cmd
, char const *value
){
840 char const *xcmd
, *emsg
;
844 if(n_poption
& n_PO_D_V
)
845 n_err(_("TLS: applying config: %s = %s\n"),
846 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(value
, FAL0
));
850 if(!asccasecmp(cmd
, xcmd
= "Certificate")){
851 if(SSL_CTX_use_certificate_chain_file(ctxp
, value
) != 1){
852 emsg
= N_("TLS: %s: cannot load from file %s\n");
855 }else if(!asccasecmp(cmd
, xcmd
= "CipherString") ||
856 !asccasecmp(cmd
, xcmd
= "CipherList")/* grr, bad fault in past! */){
857 if(SSL_CTX_set_cipher_list(ctxp
, value
) != 1){
858 emsg
= N_("TLS: %s: invalid: %s\n");
861 }else if(!asccasecmp(cmd
, xcmd
= "Ciphersuites")){
862 #ifdef HAVE_XTLS_SET_CIPHERSUITES
863 if(SSL_CTX_set_ciphersuites(ctxp
, value
) != 1){
864 emsg
= N_("TLS: %s: invalid: %s\n");
869 emsg
= N_("TLS: %s: directive not supported\n");
872 }else if(!asccasecmp(cmd
, xcmd
= "Curves")){
873 #ifdef SSL_CTRL_SET_CURVES_LIST
874 if(SSL_CTX_set1_curves_list(ctxp
, n_UNCONST(value
)) != 1){
875 emsg
= N_("TLS: %s: invalid: %s\n");
880 emsg
= N_("TLS: %s: directive not supported\n");
883 }else if((emsg
= NULL
, !asccasecmp(cmd
, xcmd
= "MaxProtocol")) ||
884 (emsg
= (char*)-1, !asccasecmp(cmd
, xcmd
= "MinProtocol"))){
885 #ifndef HAVE_XTLS_SET_MIN_PROTO_VERSION
887 emsg
= N_("TLS: %s: directive not supported\n");
890 struct a_xtls_protocol
const *xpp
;
893 for(i
= 1 /* [0] == ALL */;;){
894 xpp
= &a_xtls_protocols
[i
];
896 if(xpp
->xp_ok_minmaxproto
&& !asccasecmp(value
, xpp
->xp_name
))
899 if(++i
>= n_NELEM(a_xtls_protocols
)){
900 emsg
= N_("TLS: %s: unsupported element: %s\n");
905 if((emsg
== NULL
? SSL_CTX_set_max_proto_version(ctxp
, xpp
->xp_version
)
906 : SSL_CTX_set_min_proto_version(ctxp
, xpp
->xp_version
)) != 1){
907 emsg
= N_("TLS: %s: invalid protocol: %s\n");
910 #endif /* !HAVE_XTLS_SET_MIN_PROTO_VERSION */
911 }else if(!asccasecmp(cmd
, xcmd
= "Options")){
912 if(asccasecmp(value
, "Bugs")){
913 emsg
= N_("TLS: %s: fallback only supports value \"Bugs\": %s\n");
916 SSL_CTX_set_options(ctxp
, SSL_OP_ALL
);
917 }else if(!asccasecmp(cmd
, xcmd
= "PrivateKey")){
918 if(SSL_CTX_use_PrivateKey_file(ctxp
, value
, SSL_FILETYPE_PEM
) != 1){
919 emsg
= N_("%s: cannot load from file %s\n");
922 }else if(!asccasecmp(cmd
, xcmd
= "Protocol")){
923 char *iolist
, *cp
, addin
;
929 for(iolist
= cp
= savestr(value
);
930 (cp
= n_strsep(&iolist
, ',', FAL0
)) != NULL
;){
933 emsg
= N_("TLS: %s: empty elements are not supported\n");
939 case '-': addin
= FAL0
; /* FALLTHRU */
940 case '+': ++cp
; /* FALLTHRU */
945 struct a_xtls_protocol
const *xpp
;
947 xpp
= &a_xtls_protocols
[i
];
949 if(xpp
->xp_ok_proto
&& !asccasecmp(cp
, xpp
->xp_name
)){
950 /* We need to inverse the meaning of the _NO_s */
952 opts
|= xpp
->xp_op_no
;
954 opts
&= ~xpp
->xp_op_no
;
958 if(++i
>= n_NELEM(a_xtls_protocols
)){
959 emsg
= N_("TLS: %s: unsupported element: %s\n");
965 SSL_CTX_clear_options(ctxp
, SSL_OP_NO_SSL_MASK
);
966 SSL_CTX_set_options(ctxp
, opts
);
968 xcmd
= n_shexp_quote_cp(cmd
, FAL0
);
969 emsg
= N_("TLS: unsupported directive: %s: value: %s\n");
975 return (confp
!= NULL
);
977 ssl_gen_err(V_(emsg
), xcmd
, n_shexp_quote_cp(value
, FAL0
));
982 value
= n_shexp_quote_cp(value
, FAL0
);
983 n_err(V_(emsg
), xcmd
, value
);
989 a_xtls_conf_finish(void **confp
, bool_t error
){
995 #endif /* !HAVE_XTLS_CONF_CTX */
998 a_xtls_obsolete_conf_vars(void *confp
, struct url
const *urlp
){
999 char const *cp
, *cp_base
, *certchain
;
1005 /* Certificate via ssl-cert */
1006 if((certchain
= cp
= xok_vlook(ssl_cert
, urlp
, OXM_ALL
)) != NULL
){
1007 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-cert*"));
1008 if((cp_base
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
1009 n_err(_("*ssl-cert* value expansion failed: %s\n"),
1010 n_shexp_quote_cp(cp
, FAL0
));
1013 if(!a_xtls_conf(confp
, "Certificate", certchain
= cp_base
))
1017 /* CipherString via ssl-ciper-list */
1018 if((cp
= xok_vlook(ssl_cipher_list
, urlp
, OXM_ALL
)) != NULL
){
1019 n_OBSOLETE(_("please use *tls-config-pairs* instead of "
1020 "*ssl-cipher-list*"));
1021 if(!a_xtls_conf(confp
, "CipherString", cp
))
1025 /* Curves via ssl-curves */
1026 if((cp
= xok_vlook(ssl_curves
, urlp
, OXM_ALL
)) != NULL
){
1027 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-curves*"));
1028 if(!a_xtls_conf(confp
, "Curves", cp
))
1032 /* PrivateKey via ssl-key */
1033 if((cp
= xok_vlook(ssl_key
, urlp
, OXM_ALL
)) != NULL
){
1034 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-key*"));
1035 if((cp_base
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
1036 n_err(_("*ssl-key* value expansion failed: %s\n"),
1037 n_shexp_quote_cp(cp
, FAL0
));
1041 if(certchain
== NULL
){
1042 n_err(_("*ssl-key* can only be used together with *ssl-cert*! "
1043 "And use *ssl-config-pairs*!\n"));
1047 if((cp
!= NULL
|| (cp
= certchain
) != NULL
) &&
1048 !a_xtls_conf(confp
, "PrivateKey", cp
))
1051 /* Protocol via ssl-method or ssl-protocol */
1052 if((cp
= xok_vlook(ssl_method
, urlp
, OXM_ALL
)) != NULL
){
1055 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-method*"));
1057 if(!asccasecmp(_ssl_methods
[i
].sm_name
, cp
)){
1058 cp
= _ssl_methods
[i
].sm_map
;
1061 if(++i
== n_NELEM(_ssl_methods
)){
1062 n_err(_("Unsupported SSL method: %s\n"), cp
);
1067 if((cp_base
= xok_vlook(ssl_protocol
, urlp
, OXM_ALL
)) != NULL
){
1068 n_OBSOLETE(_("please use *tls-config-pairs* instead of *ssl-protocol*"));
1069 if(cp
!= NULL
&& (n_poption
& n_PO_D_V
))
1070 n_err(_("*ssl-protocol* overrides *ssl-method*! "
1071 "And please use *tls-config-pairs* instead!\n"));
1074 if(cp
!= NULL
&& !a_xtls_conf(confp
, "Protocol", cp
))
1084 a_xtls_config_pairs(void *confp
, struct url
const *urlp
){
1085 /* Due to interdependencies some commands have to be delayed a bit */
1086 static char const cmdcert
[] = "Certificate", cmdprivkey
[] = "PrivateKey";
1087 char const *valcert
, *valprivkey
;
1088 char *pairs
, *cp
, *cmd
, *val
;
1091 if((pairs
= n_UNCONST(xok_vlook(tls_config_pairs
, urlp
, OXM_ALL
))
1093 (pairs
= n_UNCONST(xok_vlook(ssl_config_pairs
, urlp
, OXM_ALL
))
1096 pairs
= savestr(pairs
);
1098 valcert
= valprivkey
= NULL
;
1100 while((cp
= n_strsep_esc(&pairs
, ',', FAL0
)) != NULL
){
1107 a_EXPAND_MASK
= a_EXPAND
| a_CERT
| a_PRIVKEY
1110 /* Directive, space trimmed */
1111 if((cmd
= strchr(cp
, '=')) == NULL
){
1114 pairs
= n_UNCONST(n_empty
);
1115 n_err(_("*tls-config-pairs*: missing directive: %s; rest: %s\n"),
1116 n_shexp_quote_cp(cp
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1121 if((cmd
> cp
&& cmd
[-1] == '*')){
1126 while(cmd
> cp
&& (c
= cmd
[-1], blankspacechar(c
)))
1133 /* Command with special treatment? */
1134 if(!asccasecmp(cmd
, cmdcert
))
1136 else if(!asccasecmp(cmd
, cmdprivkey
))
1139 /* Value, space trimmed */
1140 while((c
= *val
) != '\0' && blankspacechar(c
))
1142 cp
= &val
[strlen(val
)];
1143 while(cp
> val
&& (c
= cp
[-1], blankspacechar(c
)))
1148 pairs
= n_UNCONST(n_empty
);
1149 n_err(_("*tls-config-pairs*: missing value: %s; rest: %s\n"),
1150 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(pairs
, FAL0
));
1154 /* Filename transformations to be applied? */
1155 if(f
& a_EXPAND_MASK
){
1156 if((cp
= fexpand(val
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
){
1158 pairs
= n_UNCONST(n_empty
);
1159 n_err(_("*tls-config-pairs*: value expansion failed: %s: %s; "
1161 n_shexp_quote_cp(cmd
, FAL0
), n_shexp_quote_cp(val
, FAL0
),
1162 n_shexp_quote_cp(pairs
, FAL0
));
1168 /* Some things have to be delayed */
1171 else if(f
& a_PRIVKEY
)
1173 else if(!a_xtls_conf(confp
, cmd
, val
)){
1174 pairs
= n_UNCONST(n_empty
);
1179 /* Work the delayed ones */
1180 if((valcert
!= NULL
&& !a_xtls_conf(confp
, cmdcert
, valcert
)) ||
1181 ((valprivkey
!= NULL
|| (valprivkey
= valcert
) != NULL
) &&
1182 !a_xtls_conf(confp
, cmdprivkey
, valprivkey
)))
1183 pairs
= n_UNCONST(n_empty
);
1187 return (pairs
== NULL
);
1191 a_xtls_load_verifications(SSL_CTX
*ctxp
, struct url
const *urlp
){
1192 char *ca_dir
, *ca_file
;
1197 if(n_tls_verify_level
== n_TLS_VERIFY_IGNORE
){
1203 if((ca_dir
= xok_vlook(tls_ca_dir
, urlp
, OXM_ALL
)) != NULL
||
1204 (ca_dir
= xok_vlook(ssl_ca_dir
, urlp
, OXM_ALL
)) != NULL
)
1205 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
1206 if((ca_file
= xok_vlook(tls_ca_file
, urlp
, OXM_ALL
)) != NULL
||
1207 (ca_file
= xok_vlook(ssl_ca_file
, urlp
, OXM_ALL
)) != NULL
)
1208 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
1210 if((ca_dir
!= NULL
|| ca_file
!= NULL
) &&
1211 SSL_CTX_load_verify_locations(ctxp
, ca_file
, ca_dir
) != 1){
1212 char const *m1
, *m2
, *m3
;
1216 m2
= (ca_file
!= NULL
) ? _(" or ") : n_empty
;
1219 m3
= (ca_file
!= NULL
) ? ca_file
: n_empty
;
1220 ssl_gen_err(_("Error loading %s%s%s\n"), m1
, m2
, m3
);
1227 if((xv15
= ok_blook(ssl_no_default_ca
)))
1228 n_OBSOLETE(_("please use *tls-ca-no-defaults*, "
1229 "not *ssl-no-default-ca*"));
1230 if(!xok_blook(tls_ca_no_defaults
, urlp
, OXM_ALL
) &&
1231 !xok_blook(ssl_ca_no_defaults
, urlp
, OXM_ALL
) && !xv15
&&
1232 SSL_CTX_set_default_verify_paths(ctxp
) != 1) {
1233 ssl_gen_err(_("Error loading built-in default CA locations\n"));
1238 a_xtls_state
&= ~a_XTLS_S_VERIFY_ERROR
;
1240 SSL_CTX_set_verify(ctxp
, SSL_VERIFY_PEER
, &a_xtls_verify_cb
);
1241 store
= SSL_CTX_get_cert_store(ctxp
);
1242 load_crls(store
, ok_v_tls_crl_file
, ok_v_tls_crl_dir
);
1243 a_xtls_ca_flags(store
, xok_vlook(tls_ca_flags
, urlp
, OXM_ALL
));
1244 a_xtls_ca_flags(store
, xok_vlook(ssl_ca_flags
, urlp
, OXM_ALL
));
1253 a_xtls_check_host(struct sock
*sp
, X509
*peercert
, struct url
const *urlp
){
1255 n_XTLS_STACKOF(GENERAL_NAME
) *gens
;
1264 if((gens
= X509_get_ext_d2i(peercert
, NID_subject_alt_name
, NULL
, NULL
)
1268 for(i
= 0; i
< sk_GENERAL_NAME_num(gens
); ++i
){
1269 gen
= sk_GENERAL_NAME_value(gens
, i
);
1270 if(gen
->type
== GEN_DNS
){
1271 if(n_poption
& n_PO_D_V
)
1272 n_err(_("Comparing subject_alt_name: need<%s> is<%s>\n"),
1273 urlp
->url_host
.s
, (char*)gen
->d
.ia5
->data
);
1274 if((rv
= n_tls_rfc2595_hostname_match(urlp
->url_host
.s
,
1275 (char*)gen
->d
.ia5
->data
)))
1281 if((subj
= X509_get_subject_name(peercert
)) != NULL
&&
1282 X509_NAME_get_text_by_NID(subj
, NID_commonName
, data
, sizeof data
1284 data
[sizeof data
- 1] = '\0';
1285 if(n_poption
& n_PO_D_V
)
1286 n_err(_("Comparing commonName: need<%s> is<%s>\n"),
1287 urlp
->url_host
.s
, data
);
1288 rv
= n_tls_rfc2595_hostname_match(urlp
->url_host
.s
, data
);
1296 smime_verify(struct message
*m
, int n
, n_XTLS_STACKOF(X509
) *chain
,
1299 char data
[LINESIZE
], *sender
, *to
, *cc
, *cnttype
;
1306 n_XTLS_STACKOF(X509
) *certs
;
1307 n_XTLS_STACKOF(GENERAL_NAME
) *gens
;
1318 a_xtls_state
&= ~a_XTLS_S_VERIFY_ERROR
;
1319 a_xtls_msgno
= (size_t)n
;
1322 sender
= getsender(m
);
1323 to
= hfield1("to", m
);
1324 cc
= hfield1("cc", m
);
1325 cnttype
= hfield1("content-type", m
);
1329 #define _X (sizeof("application/") -1)
1330 #define _Y(X) X, sizeof(X) -1
1331 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
1332 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
1333 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
1336 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
1338 if (x
!= (struct message
*)-1) {
1344 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
1350 if ((fp
= Ftmp(NULL
, "smimever", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
1352 n_perr(_("tempfile"), 0);
1355 while (size
-- > 0) {
1361 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
1363 "Error creating BIO verification object for message %d"), n
);
1367 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
1368 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
1371 if (PKCS7_verify(pkcs7
, chain
, store
, pb
, NULL
, 0) != 1) {
1372 ssl_gen_err(_("Error verifying message %d"), n
);
1376 if (sender
== NULL
) {
1377 n_err(_("Warning: Message %d has no sender\n"), n
);
1382 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
1383 if (certs
== NULL
) {
1384 n_err(_("No certificates found in message %d\n"), n
);
1388 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
1389 cert
= sk_X509_value(certs
, i
);
1390 gens
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
1392 for (j
= 0; j
< sk_GENERAL_NAME_num(gens
); ++j
) {
1393 gen
= sk_GENERAL_NAME_value(gens
, j
);
1394 if (gen
->type
== GEN_EMAIL
) {
1395 if (n_poption
& n_PO_D_V
)
1396 n_err(_("Comparing subject_alt_name: need<%s> is<%s>)\n"),
1397 sender
, (char*)gen
->d
.ia5
->data
);
1398 if (!asccasecmp((char*)gen
->d
.ia5
->data
, sender
))
1404 if ((subj
= X509_get_subject_name(cert
)) != NULL
&&
1405 X509_NAME_get_text_by_NID(subj
, NID_pkcs9_emailAddress
,
1406 data
, sizeof data
) > 0) {
1407 data
[sizeof data
-1] = '\0';
1408 if (n_poption
& n_PO_D_V
)
1409 n_err(_("Comparing emailAddress: need<%s> is<%s>\n"),
1411 if (!asccasecmp(data
, sender
))
1415 n_err(_("Message %d: certificate does not match <%s>\n"), n
, sender
);
1418 rv
= ((a_xtls_state
& a_XTLS_S_VERIFY_ERROR
) != 0);
1420 fprintf(n_stdout
, _("Message %d was verified successfully\n"), n
);
1423 sk_X509_free(certs
);
1436 static EVP_CIPHER
const *
1437 _smime_cipher(char const *name
)
1439 EVP_CIPHER
const *cipher
;
1445 vn
= n_lofi_alloc(i
= strlen(name
) + sizeof("smime-cipher-") -1 +1);
1446 snprintf(vn
, (int)i
, "smime-cipher-%s", name
);
1447 cp
= n_var_vlook(vn
, FAL0
);
1450 if (cp
== NULL
&& (cp
= ok_vlook(smime_cipher
)) == NULL
) {
1451 cipher
= a_XTLS_SMIME_DEFAULT_CIPHER();
1456 for(i
= 0; i
< n_NELEM(a_xtls_ciphers
); ++i
)
1457 if(!asccasecmp(a_xtls_ciphers
[i
].xc_name
, cp
)){
1458 cipher
= (*a_xtls_ciphers
[i
].xc_fun
)();
1461 #ifndef OPENSSL_NO_AES
1462 for (i
= 0; i
< n_NELEM(a_xtls_smime_ciphers_obs
); ++i
) /* TODO obsolete */
1463 if (!asccasecmp(a_xtls_smime_ciphers_obs
[i
].xc_name
, cp
)) {
1464 n_OBSOLETE2(_("*smime-cipher* names with hyphens will vanish"), cp
);
1465 cipher
= (*a_xtls_smime_ciphers_obs
[i
].xc_fun
)();
1470 /* Not a built-in algorithm, but we may have dynamic support for more */
1471 #ifdef HAVE_TLS_ALL_ALGORITHMS
1472 if((cipher
= EVP_get_cipherbyname(cp
)) != NULL
)
1476 n_err(_("Invalid S/MIME cipher(s): %s\n"), cp
);
1483 ssl_password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
1492 if(userdata
!= NULL
){
1496 if(url_parse(&url
, CPROTO_CCRED
, userdata
)){
1497 if(ccred_lookup(&cred
, &url
)){
1500 if((slen
= n_strscpy(buf
, cred
.cc_pass
.s
, size
)) >= 0){
1511 if ((pass
= getpassword("PEM pass phrase:")) != NULL
) {
1513 if (UICMP(z
, len
, >=, size
))
1515 memcpy(buf
, pass
, len
);
1526 smime_sign_cert(char const *xname
, char const *xname2
, bool_t dowarn
,
1532 char const *name
= xname
, *name2
= xname2
, *cp
;
1538 np
= lextract(name
, GTO
| GSKIN
);
1539 while (np
!= NULL
) {
1540 /* This needs to be more intelligent since it will currently take the
1541 * first name for which a private key is available regardless of
1542 * whether it is the right one for the message */
1543 vn
= n_lofi_alloc(vs
= strlen(np
->n_name
) + 30);
1544 snprintf(vn
, vs
, "smime-sign-cert-%s", np
->n_name
);
1545 cp
= n_var_vlook(vn
, FAL0
);
1549 *match
= np
->n_name
;
1554 if (name2
!= NULL
) {
1561 if ((cp
= ok_vlook(smime_sign_cert
)) == NULL
)
1566 if ((cp
= fexpand(cp
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
1568 if ((fp
= Fopen(cp
, "r")) == NULL
)
1575 n_err(_("Could not find a certificate for %s%s%s\n"),
1576 xname
, (xname2
!= NULL
? _("or ") : n_empty
),
1577 (xname2
!= NULL
? xname2
: n_empty
));
1582 _smime_sign_include_certs(char const *name
)
1587 /* See comments in smime_sign_cert() for algorithm pitfalls */
1591 for (np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
) {
1595 vn
= n_lofi_alloc(vs
= strlen(np
->n_name
) + 30);
1596 snprintf(vn
, vs
, "smime-sign-include-certs-%s", np
->n_name
);
1597 rv
= n_var_vlook(vn
, FAL0
);
1603 rv
= ok_vlook(smime_sign_include_certs
);
1610 _smime_sign_include_chain_creat(n_XTLS_STACKOF(X509
) **chain
,
1611 char const *cfiles
, char const *addr
)
1615 char *nfield
, *cfield
, *x
;
1618 *chain
= sk_X509_new_null();
1620 for (nfield
= savestr(cfiles
);
1621 (cfield
= n_strsep(&nfield
, ',', TRU1
)) != NULL
;) {
1622 if ((x
= fexpand(cfield
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1623 (fp
= Fopen(cfield
= x
, "r")) == NULL
) {
1627 if ((tmp
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, n_UNCONST(addr
))
1629 ssl_gen_err(_("Error reading certificate from %s"),
1630 n_shexp_quote_cp(cfield
, FAL0
));
1634 sk_X509_push(*chain
, tmp
);
1638 if (sk_X509_num(*chain
) == 0) {
1639 n_err(_("*smime-sign-include-certs* defined but empty\n"));
1644 return (*chain
!= NULL
);
1646 sk_X509_pop_free(*chain
, X509_free
);
1651 static EVP_MD
const *
1652 a_xtls_smime_sign_digest(char const *name
, char const **digname
){
1653 EVP_MD
const *digest
;
1657 /* See comments in smime_sign_cert() for algorithm pitfalls */
1661 for(np
= lextract(name
, GTO
| GSKIN
); np
!= NULL
; np
= np
->n_flink
){
1665 vn
= n_lofi_alloc(vs
= strlen(np
->n_name
) + 30);
1666 snprintf(vn
, vs
, "smime-sign-digest-%s", np
->n_name
);
1667 if((cp
= n_var_vlook(vn
, FAL0
)) == NULL
){
1668 snprintf(vn
, vs
, "smime-sign-message-digest-%s",np
->n_name
);/*v15*/
1669 cp
= n_var_vlook(vn
, FAL0
);
1677 if((cp
= ok_vlook(smime_sign_digest
)) != NULL
||
1678 (cp
= ok_vlook(smime_sign_message_digest
)/* v15 */) != NULL
)
1680 if(a_xtls_digest_find(cp
, &digest
, digname
))
1683 digest
= a_XTLS_SMIME_DEFAULT_DIGEST();
1684 *digname
= a_XTLS_SMIME_DEFAULT_DIGEST_S
;
1690 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1692 load_crl1(X509_STORE
*store
, char const *name
)
1694 X509_LOOKUP
*lookup
;
1695 enum okay rv
= STOP
;
1698 if (n_poption
& n_PO_D_V
)
1699 n_err(_("Loading CRL from %s\n"), n_shexp_quote_cp(name
, FAL0
));
1700 if ((lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file())) == NULL
) {
1701 ssl_gen_err(_("Error creating X509 lookup object"));
1704 if (X509_load_crl_file(lookup
, name
, X509_FILETYPE_PEM
) != 1) {
1705 ssl_gen_err(_("Error loading CRL from %s"),
1706 n_shexp_quote_cp(name
, FAL0
));
1714 #endif /* new OpenSSL */
1717 load_crls(X509_STORE
*store
, enum okeys fok
, enum okeys dok
)/*TODO nevertried*/
1719 char *crl_file
, *crl_dir
;
1720 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1734 if ((crl_file
= n_var_oklook(fok
)) != NULL
) {
1735 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1736 if ((crl_file
= fexpand(crl_file
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1737 load_crl1(store
, crl_file
) != OKAY
)
1741 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1746 if ((crl_dir
= n_var_oklook(dok
)) != NULL
) {
1747 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1749 if ((x
= fexpand(crl_dir
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
||
1750 (dirp
= opendir(crl_dir
= x
)) == NULL
) {
1755 ds
= strlen(crl_dir
);
1756 fn
= n_alloc(fs
= ds
+ 20);
1757 memcpy(fn
, crl_dir
, ds
);
1759 while ((dp
= readdir(dirp
)) != NULL
) {
1760 if (dp
->d_name
[0] == '.' && (dp
->d_name
[1] == '\0' ||
1761 (dp
->d_name
[1] == '.' && dp
->d_name
[2] == '\0')))
1763 if (dp
->d_name
[0] == '.')
1765 if (ds
+ (es
= strlen(dp
->d_name
)) + 2 < fs
)
1766 fn
= n_realloc(fn
, fs
= ds
+ es
+ 20);
1767 memcpy(fn
+ ds
+ 1, dp
->d_name
, es
+ 1);
1768 if (load_crl1(store
, fn
) != OKAY
) {
1777 #else /* old OpenSSL */
1778 n_err(_("This OpenSSL version is too old to use CRLs\n"));
1783 if(fok
== ok_v_tls_crl_file
){
1784 fok
= ok_v_ssl_crl_file
;
1785 dok
= ok_v_ssl_crl_dir
;
1788 #if defined X509_V_FLAG_CRL_CHECK && defined X509_V_FLAG_CRL_CHECK_ALL
1790 X509_STORE_set_flags(store
, X509_V_FLAG_CRL_CHECK
|
1791 X509_V_FLAG_CRL_CHECK_ALL
);
1799 #if HAVE_RANDOM == n_RANDOM_IMPL_TLS
1801 n_tls_rand_bytes(void *buf
, size_t blen
){
1804 if(!(a_xtls_state
& a_XTLS_S_RAND_INIT
))
1810 i
= n_MIN(SI32_MAX
, blen
);
1813 buf
= (ui8_t
*)buf
+ i
;
1820 n_tls_open(struct url
*urlp
, struct sock
*sp
){
1823 const EVP_MD
*fprnt_mdp
;
1824 char const *fprnt
, *fprnt_namep
;
1828 n_tls_set_verify_level(urlp
); /* TODO should come in via URL! */
1831 if(urlp
->url_cproto
!= CPROTO_CERTINFO
)
1832 fprnt
= xok_vlook(tls_fingerprint
, urlp
, OXM_ALL
);
1838 if(fprnt
!= NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
1839 (n_poption
& n_PO_D_V
)){
1840 if((fprnt_namep
= xok_vlook(tls_fingerprint_digest
, urlp
,
1841 OXM_ALL
)) == NULL
||
1842 !a_xtls_digest_find(fprnt_namep
, &fprnt_mdp
, &fprnt_namep
)){
1843 fprnt_mdp
= a_XTLS_FINGERPRINT_DEFAULT_DIGEST();
1844 fprnt_namep
= a_XTLS_FINGERPRINT_DEFAULT_DIGEST_S
;
1848 if((ctxp
= SSL_CTX_new(n_XTLS_CLIENT_METHOD())) == NULL
){
1849 ssl_gen_err(_("SSL_CTX_new() failed"));
1853 /* Available with OpenSSL 0.9.6 or later */
1854 #ifdef SSL_MODE_AUTO_RETRY
1855 SSL_CTX_set_mode(ctxp
, SSL_MODE_AUTO_RETRY
);
1858 if((confp
= a_xtls_conf_setup(ctxp
, urlp
)) == NULL
)
1861 if(!a_xtls_obsolete_conf_vars(confp
, urlp
))
1863 if(!a_xtls_config_pairs(confp
, urlp
))
1865 if((fprnt
== NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
) &&
1866 !a_xtls_load_verifications(ctxp
, urlp
))
1869 /* Done with context setup, create our new per-connection structure */
1870 if(!a_xtls_conf_finish(&confp
, FAL0
))
1872 assert(confp
== NULL
);
1874 if((sp
->s_tls
= SSL_new(ctxp
)) == NULL
){
1875 ssl_gen_err(_("SSL_new() failed"));
1879 /* Try establish SNI extension; even though this is a TLS extension the
1880 * protocol isn't checked by OpenSSL once the host name is set, and
1881 * therefore i refrained from changing so much code just to check out
1882 * whether we are using SSLv3, which should become more and more rare */
1883 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1884 if((urlp
->url_flags
& n_URL_TLS_MASK
) &&
1885 (urlp
->url_flags
& n_URL_HOST_IS_NAME
)){
1886 if(!SSL_set_tlsext_host_name(sp
->s_tls
, urlp
->url_host
.s
) &&
1887 (n_poption
& n_PO_D_V
))
1888 n_err(_("Hostname cannot be used with ServerNameIndication "
1889 "TLS extension: %s\n"),
1890 n_shexp_quote_cp(urlp
->url_host
.s
, FAL0
));
1894 SSL_set_fd(sp
->s_tls
, sp
->s_fd
);
1896 if(SSL_connect(sp
->s_tls
) < 0){
1897 ssl_gen_err(_("could not initiate TLS connection"));
1901 if(fprnt
!= NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
1902 n_tls_verify_level
!= n_TLS_VERIFY_IGNORE
){
1906 if((peercert
= SSL_get_peer_certificate(sp
->s_tls
)) == NULL
){
1907 n_err(_("TLS: no certificate from peer: %s\n"), urlp
->url_h_p
.s
);
1914 if(!a_xtls_check_host(sp
, peercert
, urlp
)){
1915 n_err(_("TLS certificate does not match: %s\n"), urlp
->url_h_p
.s
);
1916 stay
= n_tls_verify_decide();
1918 if(n_poption
& n_PO_D_V
)
1919 n_err(_("TLS certificate ok\n"));
1924 if(fprnt
!= NULL
|| urlp
->url_cproto
== CPROTO_CERTINFO
||
1925 (n_poption
& n_PO_D_V
)){
1926 char fpmdhexbuf
[EVP_MAX_MD_SIZE
* 3], *cp
;
1927 unsigned char fpmdbuf
[EVP_MAX_MD_SIZE
], *ucp
;
1928 unsigned int fpmdlen
;
1930 if(!X509_digest(peercert
, fprnt_mdp
, fpmdbuf
, &fpmdlen
)){
1931 ssl_gen_err(_("TLS %s fingerprint creation failed"), fprnt_namep
);
1934 assert(fpmdlen
<= EVP_MAX_MD_SIZE
);
1936 for(cp
= fpmdhexbuf
, ucp
= fpmdbuf
; fpmdlen
> 0; --fpmdlen
){
1937 n_c_to_hex_base16(cp
, (char)*ucp
++);
1943 if(n_poption
& n_PO_D_V
)
1944 n_err(_("TLS %s fingerprint: %s\n"), fprnt_namep
, fpmdhexbuf
);
1946 if(!(stay
= !strcmp(fprnt
, fpmdhexbuf
))){
1947 n_err(_("TLS fingerprint does not match: %s\n"
1948 " Expected: %s\n Detected: %s\n"),
1949 urlp
->url_h_p
.s
, fprnt
, fpmdhexbuf
);
1950 stay
= n_tls_verify_decide();
1951 }else if(n_poption
& n_PO_D_V
)
1952 n_err(_("TLS fingerprint ok\n"));
1954 }else if(urlp
->url_cproto
== CPROTO_CERTINFO
)
1955 sp
->s_tls_finger
= savestrbuf(fpmdhexbuf
,
1956 PTR2SIZE(cp
- fpmdhexbuf
));
1960 X509_free(peercert
);
1967 /* We're fully setup: since we don't reuse the SSL_CTX (pooh) keep it local
1968 * and free it right now -- it is reference counted by sp->s_tls.. */
1972 return (sp
->s_tls
!= NULL
);
1974 SSL_free(sp
->s_tls
);
1978 a_xtls_conf_finish(&confp
, TRU1
);
1983 ssl_gen_err(char const *fmt
, ...)
1992 n_err(_(": %s\n"), ERR_error_string(ERR_get_error(), NULL
));
1999 int *msgvec
= vp
, *ip
, ec
= 0, rv
= 1;
2000 X509_STORE
*store
= NULL
;
2001 char *ca_dir
, *ca_file
;
2006 n_tls_verify_level
= n_TLS_VERIFY_STRICT
;
2007 if ((store
= X509_STORE_new()) == NULL
) {
2008 ssl_gen_err(_("Error creating X509 store"));
2011 X509_STORE_set_verify_cb_func(store
, &a_xtls_verify_cb
);
2013 if ((ca_dir
= ok_vlook(smime_ca_dir
)) != NULL
)
2014 ca_dir
= fexpand(ca_dir
, FEXP_LOCAL
| FEXP_NOPROTO
);
2015 if ((ca_file
= ok_vlook(smime_ca_file
)) != NULL
)
2016 ca_file
= fexpand(ca_file
, FEXP_LOCAL
| FEXP_NOPROTO
);
2018 if((ca_dir
!= NULL
|| ca_file
!= NULL
) &&
2019 X509_STORE_load_locations(store
, ca_file
, ca_dir
) != 1){
2020 char const *m1
, *m2
, *m3
;
2024 m2
= (ca_file
!= NULL
) ? _(" or ") : n_empty
;
2027 m3
= (ca_file
!= NULL
) ? ca_file
: n_empty
;
2028 ssl_gen_err(_("Error loading %s%s%s\n"), m1
, m2
, m3
);
2035 if((xv15
= ok_blook(smime_no_default_ca
)))
2036 n_OBSOLETE(_("please use *smime-ca-no-defaults*, "
2037 "not *smime-no-default-ca*"));
2038 if(!ok_blook(smime_ca_no_defaults
) && !xv15
&&
2039 X509_STORE_set_default_paths(store
) != 1) {
2040 ssl_gen_err(_("Error loading built-in default CA locations\n"));
2045 if (load_crls(store
, ok_v_smime_crl_file
, ok_v_smime_crl_dir
) != OKAY
)
2048 a_xtls_ca_flags(store
, ok_vlook(smime_ca_flags
));
2051 for (ip
= msgvec
; *ip
!= 0; ++ip
) {
2052 struct message
*mp
= message
+ *ip
- 1;
2054 ec
|= smime_verify(mp
, *ip
, NULL
, store
);
2060 n_exit_status
|= n_EXIT_ERR
;
2063 X509_STORE_free(store
);
2069 smime_sign(FILE *ip
, char const *addr
)
2071 FILE *rv
, *sp
, *fp
, *bp
, *hp
;
2073 n_XTLS_STACKOF(X509
) *chain
= NULL
;
2074 EVP_PKEY
*pkey
= NULL
;
2082 assert(addr
!= NULL
);
2083 rv
= sp
= fp
= bp
= hp
= NULL
;
2088 n_err(_("No *from* address for signing specified\n"));
2091 if ((fp
= smime_sign_cert(addr
, NULL
, 1, NULL
)) == NULL
)
2094 if ((pkey
= PEM_read_PrivateKey(fp
, NULL
, &ssl_password_cb
,
2095 savecat(addr
, ".smime-cert-key"))) == NULL
) {
2096 ssl_gen_err(_("Error reading private key from"));
2101 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
,
2102 savecat(addr
, ".smime-cert-cert"))) == NULL
) {
2103 ssl_gen_err(_("Error reading signer certificate from"));
2109 if ((name
= _smime_sign_include_certs(addr
)) != NULL
&&
2110 !_smime_sign_include_chain_creat(&chain
, name
,
2111 savecat(addr
, ".smime-include-certs")))
2115 if ((md
= a_xtls_smime_sign_digest(addr
, &name
)) == NULL
)
2118 if ((sp
= Ftmp(NULL
, "smimesign", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2120 n_perr(_("tempfile"), 0);
2125 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
2131 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
2132 (sb
= BIO_new_fp(sp
, BIO_NOCLOSE
)) == NULL
) {
2133 ssl_gen_err(_("Error creating BIO signing objects"));
2139 #define _X PKCS7_DETACHED | PKCS7_PARTIAL
2140 if ((pkcs7
= PKCS7_sign(NULL
, NULL
, chain
, bb
, _X
)) == NULL
) {
2141 ssl_gen_err(_("Error creating the PKCS#7 signing object"));
2145 if (PKCS7_sign_add_signer(pkcs7
, cert
, pkey
, md
, _X
) == NULL
) {
2146 ssl_gen_err(_("Error setting PKCS#7 signing object signer"));
2150 if (!PKCS7_final(pkcs7
, bb
, _X
)) {
2151 ssl_gen_err(_("Error finalizing the PKCS#7 signing object"));
2157 if (PEM_write_bio_PKCS7(sb
, pkcs7
) == 0) {
2158 ssl_gen_err(_("Error writing signed S/MIME data"));
2172 rv
= smime_sign_assemble(hp
, bp
, sp
, name
);
2173 hp
= bp
= sp
= NULL
;
2178 sk_X509_pop_free(chain
, X509_free
);
2182 EVP_PKEY_free(pkey
);
2196 smime_encrypt(FILE *ip
, char const *xcertfile
, char const *to
)
2198 FILE *rv
, *yp
, *fp
, *bp
, *hp
;
2202 n_XTLS_STACKOF(X509
) *certs
;
2203 EVP_CIPHER
const *cipher
;
2209 rv
= yp
= fp
= bp
= hp
= NULL
;
2211 if ((certfile
= fexpand(xcertfile
, FEXP_LOCAL
| FEXP_NOPROTO
)) == NULL
)
2216 if ((cipher
= _smime_cipher(to
)) == NULL
)
2219 if ((fp
= Fopen(certfile
, "r")) == NULL
) {
2220 n_perr(certfile
, 0);
2223 if ((cert
= PEM_read_X509(fp
, NULL
, &ssl_password_cb
, NULL
)) == NULL
) {
2224 ssl_gen_err(_("Error reading encryption certificate from %s"),
2225 n_shexp_quote_cp(certfile
, FAL0
));
2234 certs
= sk_X509_new_null();
2235 sk_X509_push(certs
, cert
);
2237 if ((yp
= Ftmp(NULL
, "smimeenc", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2239 n_perr(_("tempfile"), 0);
2244 if (smime_split(ip
, &hp
, &bp
, -1, 0) == STOP
)
2248 if ((bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
||
2249 (yb
= BIO_new_fp(yp
, BIO_NOCLOSE
)) == NULL
) {
2250 ssl_gen_err(_("Error creating BIO encryption objects"));
2254 if ((pkcs7
= PKCS7_encrypt(certs
, bb
, cipher
, 0)) == NULL
) {
2255 ssl_gen_err(_("Error creating the PKCS#7 encryption object"));
2259 if (PEM_write_bio_PKCS7(yb
, pkcs7
) == 0) {
2260 ssl_gen_err(_("Error writing encrypted S/MIME data"));
2275 rv
= smime_encrypt_assemble(hp
, yp
);
2279 sk_X509_pop_free(certs
, X509_free
);
2294 smime_decrypt(struct message
*m
, char const *to
, char const *cc
,
2310 ob
= bb
= pb
= NULL
;
2312 bp
= hp
= op
= NULL
;
2316 if((yp
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2321 if((op
= smime_sign_cert(to
, cc
, 0, &myaddr
)) != NULL
){
2322 pkey
= PEM_read_PrivateKey(op
, NULL
, &ssl_password_cb
,
2323 savecat(myaddr
, ".smime-cert-key"));
2325 ssl_gen_err(_("Error reading private key"));
2330 if((cert
= PEM_read_X509(op
, NULL
, &ssl_password_cb
,
2331 savecat(myaddr
, ".smime-cert-cert"))) == NULL
){
2332 ssl_gen_err(_("Error reading decryption certificate"));
2340 if((op
= Ftmp(NULL
, "smimed", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) == NULL
){
2341 n_perr(_("tempfile"), 0);
2345 if(smime_split(yp
, &hp
, &bp
, size
, 1) == STOP
)
2348 if((ob
= BIO_new_fp(op
, BIO_NOCLOSE
)) == NULL
||
2349 (bb
= BIO_new_fp(bp
, BIO_NOCLOSE
)) == NULL
){
2350 ssl_gen_err(_("Error creating BIO decryption objects"));
2354 if((pkcs7
= SMIME_read_PKCS7(bb
, &pb
)) == NULL
){
2355 ssl_gen_err(_("Error reading PKCS#7 object"));
2359 if(PKCS7_type_is_signed(pkcs7
)){
2361 setinput(&mb
, m
, NEED_BODY
);
2362 rv
= (struct message
*)-1;
2365 if(PKCS7_verify(pkcs7
, NULL
, NULL
, NULL
, ob
,
2366 PKCS7_NOVERIFY
| PKCS7_NOSIGS
) != 1)
2368 fseek(hp
, 0L, SEEK_END
);
2369 fprintf(hp
, "X-Encryption-Cipher: none\n");
2371 }else if(pkey
== NULL
){
2372 n_err(_("No appropriate private key found\n"));
2374 }else if(cert
== NULL
){
2375 n_err(_("No appropriate certificate found\n"));
2377 }else if(PKCS7_decrypt(pkcs7
, pkey
, cert
, ob
, 0) != 1){
2379 ssl_gen_err(_("Error decrypting PKCS#7 object"));
2386 rv
= smime_decrypt_assemble(m
, hp
, op
);
2387 hp
= op
= NULL
; /* xxx closed by decrypt_assemble */
2404 EVP_PKEY_free(pkey
);
2410 smime_certsave(struct message
*m
, int n
, FILE *op
)
2413 char *to
, *cc
, *cnttype
;
2419 n_XTLS_STACKOF(X509
) *certs
, *chain
= NULL
;
2421 enum okay rv
= STOP
;
2426 a_xtls_msgno
= (size_t)n
;
2428 to
= hfield1("to", m
);
2429 cc
= hfield1("cc", m
);
2430 cnttype
= hfield1("content-type", m
);
2432 if ((ip
= setinput(&mb
, m
, NEED_BODY
)) == NULL
)
2437 #define _X (sizeof("application/") -1)
2438 #define _Y(X) X, sizeof(X) -1
2439 if (cnttype
&& is_asccaseprefix("application/", cnttype
) &&
2440 (!ascncasecmp(cnttype
+ _X
, _Y("pkcs7-mime")) ||
2441 !ascncasecmp(cnttype
+ _X
, _Y("x-pkcs7-mime")))) {
2444 if ((x
= smime_decrypt(m
, to
, cc
, 1)) == NULL
)
2446 if (x
!= (struct message
*)-1) {
2453 if ((fp
= Ftmp(NULL
, "smimecert", OF_RDWR
| OF_UNLINK
| OF_REGISTER
)) ==
2455 n_perr(_("tempfile"), 0);
2459 while (size
-- > 0) {
2466 if ((fb
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
) {
2467 ssl_gen_err("Error creating BIO object for message %d", n
);
2472 if ((pkcs7
= SMIME_read_PKCS7(fb
, &pb
)) == NULL
) {
2473 ssl_gen_err(_("Error reading PKCS#7 object for message %d"), n
);
2481 certs
= PKCS7_get0_signers(pkcs7
, chain
, 0);
2482 if (certs
== NULL
) {
2483 n_err(_("No certificates found in message %d\n"), n
);
2487 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
2488 cert
= sk_X509_value(certs
, i
);
2489 if (X509_print_fp(op
, cert
) == 0 || PEM_write_X509(op
, cert
) == 0) {
2490 ssl_gen_err(_("Error writing certificate %d from message %d"),
2502 #endif /* HAVE_XTLS */