130 #ifdef STRCASECMP_IN_STRINGS_H
157 #define STR vstring_str
158 #define LEN VSTRING_LEN
162 static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext)
164 const char *myname =
"load_clnt_session";
165 SSL_SESSION *session = 0;
171 if (TLScontext->log_mask & TLS_LOG_CACHE)
173 msg_info(
"looking for session %s in %s cache",
174 TLScontext->serverid, TLScontext->cache_type);
181 if (TLScontext->cache_type == 0)
182 msg_panic(
"%s: null client session cache type in session lookup",
191 session = tls_session_activate(
STR(session_data),
LEN(session_data));
193 if (TLScontext->log_mask & TLS_LOG_CACHE)
195 msg_info(
"reloaded session %s from %s cache",
196 TLScontext->serverid, TLScontext->cache_type);
210 static int new_client_session_cb(SSL *ssl, SSL_SESSION *session)
212 const char *myname =
"new_client_session_cb";
213 TLS_SESS_STATE *TLScontext;
221 if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0)
222 msg_panic(
"%s: null TLScontext in new session callback", myname);
229 if (TLScontext->cache_type == 0)
230 msg_panic(
"%s: null session cache type in new session callback",
233 if (TLScontext->log_mask & TLS_LOG_CACHE)
235 msg_info(
"save session %s to %s cache",
236 TLScontext->serverid, TLScontext->cache_type);
242 if ((session_data = tls_session_passivate(session)) != 0) {
244 STR(session_data),
LEN(session_data));
251 SSL_SESSION_free(session);
258 static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext)
260 SSL_SESSION *session = SSL_get_session(TLScontext->con);
262 SSL_CTX_remove_session(ctx, session);
263 if (TLScontext->cache_type == 0 || TLScontext->serverid == 0)
266 if (TLScontext->log_mask & TLS_LOG_CACHE)
268 msg_info(
"remove session %s from client cache", TLScontext->serverid);
275 TLS_APPL_STATE *tls_client_init(
const TLS_CLIENT_INIT_PROPS *props)
281 TLS_APPL_STATE *app_ctx;
287 log_mask = tls_log_mask(props->log_param, props->log_level);
289 if (log_mask & TLS_LOG_VERBOSE)
290 msg_info(
"initializing the client-side TLS engine");
302 #if OPENSSL_VERSION_NUMBER < 0x10100000L
309 SSL_load_error_strings();
310 OpenSSL_add_ssl_algorithms();
318 if (TLScontext_index < 0) {
319 if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0) {
320 msg_warn(
"Cannot allocate SSL application data index: "
321 "disabling TLS support");
330 if (!tls_validate_digest(props->mdalg)) {
341 msg_warn(
"no entropy for TLS key generation: disabling TLS support");
355 client_ctx = SSL_CTX_new(TLS_client_method());
356 if (client_ctx == 0) {
357 msg_warn(
"cannot allocate client SSL_CTX: disabling TLS support");
361 #ifdef SSL_SECOP_PEER
363 SSL_CTX_set_security_level(client_ctx, 0);
369 SSL_CTX_set_verify_depth(client_ctx, props->verifydepth + 1);
375 off |= tls_bug_bits();
376 SSL_CTX_set_options(client_ctx, off);
381 if (log_mask & TLS_LOG_DEBUG)
382 SSL_CTX_set_info_callback(client_ctx, tls_info_callback);
395 if (tls_set_ca_certificate_info(client_ctx,
396 props->CAfile, props->CApath) < 0) {
398 SSL_CTX_free(client_ctx);
421 if (tls_set_my_certificate_key_info(client_ctx,
427 props->eckey_file) < 0) {
429 SSL_CTX_free(client_ctx);
436 #if OPENSSL_VERSION_NUMBER < 0x10100000L
443 SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb);
451 tls_auto_eecdh_curves(client_ctx);
457 SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE,
458 tls_verify_certificate_callback);
474 if (scache_timeout <= 0)
481 app_ctx = tls_alloc_app_context(client_ctx, log_mask);
488 app_ctx->cache_type =
mystrdup(props->cache_type);
504 #ifndef SSL_SESS_CACHE_NO_INTERNAL_STORE
505 #define SSL_SESS_CACHE_NO_INTERNAL_STORE 0
508 SSL_CTX_set_session_cache_mode(client_ctx,
509 SSL_SESS_CACHE_CLIENT |
510 SSL_SESS_CACHE_NO_INTERNAL_STORE |
511 SSL_SESS_CACHE_NO_AUTO_CLEAR);
512 SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);
521 SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
528 static int match_servername(
const char *certid,
529 const TLS_CLIENT_START_PROPS *props)
531 const ARGV *cmatch_argv;
532 const char *nexthop = props->nexthop;
533 const char *hname = props->host;
542 if ((cmatch_argv = props->matchargv) == 0)
561 msg_info(
"%s asciified to %s", nexthop, aname);
569 for (i = 0; i < cmatch_argv->
argc; ++i) {
579 domain = cmatch_argv->
argv[i];
580 if (*domain ==
'.') {
603 unsigned char *cp = (
unsigned char *) domain;
605 if ((cp[0] == 0xe3 && cp[1] == 0x80 && cp[2] == 0x82)
606 || (cp[0] == 0xef && cp[1] == 0xbc && cp[2] == 0x8e)
607 || (cp[0] == 0xef && cp[1] == 0xbd && cp[2] == 0xa1)) {
617 msg_info(
"%s asciified to %s", domain, aname);
626 if (match_subdomain) {
627 if ((idlen = strlen(certid)) > (domlen = strlen(domain)) + 1
628 && certid[idlen - domlen - 1] ==
'.'
629 && !
strcasecmp(certid + (idlen - domlen), domain))
642 || (certid[0] ==
'*' && certid[1] ==
'.' && certid[2] != 0
643 && (parent = strchr(domain,
'.')) != 0
644 && (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
646 parent + domlen - idlen,
655 static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
656 const TLS_CLIENT_START_PROPS *props)
662 int verify_peername = 0;
666 const GENERAL_NAME *gn;
667 general_name_stack_t *gens;
672 TLScontext->issuer_CN = tls_issuer_CN(peercert, TLScontext);
677 if (SSL_get_verify_result(TLScontext->con) == X509_V_OK)
678 TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED;
684 if (!TLS_CERT_IS_MATCHED(TLScontext)
685 && TLS_CERT_IS_TRUSTED(TLScontext)
690 log_certmatch = TLScontext->log_mask & TLS_LOG_CERTMATCH;
693 verbose = log_certmatch || (TLScontext->log_mask & TLS_LOG_VERBOSE);
695 if (verify_peername || log_certmatch) {
716 gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0);
718 r = sk_GENERAL_NAME_num(gens);
719 for (i = 0; i < r; ++i) {
720 gn = sk_GENERAL_NAME_value(gens, i);
721 if (gn->type != GEN_DNS)
734 TLScontext->peer_status |= TLS_CERT_FLAG_ALTNAME;
735 dnsname = tls_dns_name(gn, TLScontext);
736 if (dnsname && *dnsname) {
737 if ((dnsname_match = match_servername(dnsname, props)) != 0)
740 if (TLScontext->peer_CN
741 && ((dnsname_match && matched == 1)
742 || *TLScontext->peer_CN == 0)) {
743 myfree(TLScontext->peer_CN);
744 TLScontext->peer_CN = 0;
747 msg_info(
"%s: %ssubjectAltName: %s", props->namaddr,
748 dnsname_match ?
"Matched " :
"", dnsname);
750 if (TLScontext->peer_CN == 0)
751 TLScontext->peer_CN =
mystrdup(dnsname ? dnsname :
"");
752 if (matched && !log_certmatch)
755 if (verify_peername && matched)
756 TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
762 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
768 if (TLScontext->peer_CN == 0) {
769 TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext);
770 if (*TLScontext->peer_CN)
771 matched = match_servername(TLScontext->peer_CN, props);
772 if (verify_peername && matched)
773 TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
775 msg_info(
"%s %sCommonName %s", props->namaddr,
776 matched ?
"Matched " :
"", TLScontext->peer_CN);
777 }
else if (verbose) {
778 char *tmpcn = tls_peer_CN(peercert, TLScontext);
784 msg_info(
"%s CommonName %s", TLScontext->namaddr, tmpcn);
788 TLScontext->peer_CN = tls_peer_CN(peercert, TLScontext);
796 if (!TLS_CERT_IS_TRUSTED(TLScontext)
797 && (TLScontext->log_mask & TLS_LOG_UNTRUSTED)) {
798 if (TLScontext->session_reused == 0)
799 tls_log_verify_error(TLScontext);
801 msg_info(
"%s: re-using session with untrusted certificate, "
802 "look for details earlier in the log", props->namaddr);
808 static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert,
809 const TLS_CLIENT_START_PROPS *props)
811 TLScontext->peer_cert_fprint = tls_cert_fprint(peercert, props->mdalg);
812 TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->mdalg);
823 if (TLS_DANE_HASEE(props->dane)
824 && tls_dane_match(TLScontext, TLS_DANE_EE, peercert, 0))
825 TLScontext->peer_status |=
826 TLS_CERT_FLAG_TRUSTED | TLS_CERT_FLAG_MATCHED;
834 TLS_SESS_STATE *tls_client_start(
const TLS_CLIENT_START_PROPS *props)
838 const char *cipher_list;
839 SSL_SESSION *session = 0;
840 SSL_CIPHER_const SSL_CIPHER *cipher;
842 TLS_SESS_STATE *TLScontext;
843 TLS_APPL_STATE *app_ctx = props->ctx;
845 int log_mask = app_ctx->log_mask;
853 && (!
TLS_DANE_BASED(props->tls_level) || TLS_DANE_HASTA(props->dane)))
854 log_mask |= TLS_LOG_UNTRUSTED;
856 if (log_mask & TLS_LOG_VERBOSE)
857 msg_info(
"setting up TLS connection to %s", props->namaddr);
865 protomask = tls_protocol_mask(props->protocols);
866 if (protomask == TLS_PROTOCOL_INVALID) {
868 msg_warn(
"%s: Invalid TLS protocol list \"%s\": aborting TLS session",
869 props->namaddr, props->protocols);
874 protomask |= TLS_PROTOCOL_SSLv2;
883 cipher_list = tls_set_ciphers(app_ctx,
"TLS", props->cipher_grade,
884 props->cipher_exclusions);
885 if (cipher_list == 0) {
886 msg_warn(
"%s: %s: aborting TLS session",
890 if (log_mask & TLS_LOG_VERBOSE)
891 msg_info(
"%s: TLS cipher list \"%s\"", props->namaddr, cipher_list);
916 myserverid = tls_serverid_digest(props, protomask, cipher_list);
926 TLScontext = tls_alloc_sess_context(log_mask, props->namaddr);
927 TLScontext->cache_type = app_ctx->cache_type;
929 TLScontext->serverid = myserverid;
930 TLScontext->stream = props->stream;
931 TLScontext->mdalg = props->mdalg;
934 TLScontext->dane = props->dane;
936 if ((TLScontext->con = SSL_new(app_ctx->ssl_ctx)) == NULL) {
937 msg_warn(
"Could not allocate 'TLScontext->con' with SSL_new()");
939 tls_free_context(TLScontext);
942 if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) {
943 msg_warn(
"Could not set application data for 'TLScontext->con'");
945 tls_free_context(TLScontext);
953 SSL_set_options(TLScontext->con, TLS_SSL_OP_PROTOMASK(protomask));
955 #ifdef SSL_SECOP_PEER
958 SSL_set_security_level(TLScontext->con, 1);
966 if (TLScontext->cache_type) {
967 session = load_clnt_session(TLScontext);
969 SSL_set_session(TLScontext->con, session);
970 SSL_SESSION_free(session);
973 #ifdef TLSEXT_MAXLEN_host_name
975 && strlen(props->host) <= TLSEXT_MAXLEN_host_name) {
993 if (!SSL_set_tlsext_host_name(TLScontext->con, props->host)) {
994 msg_warn(
"%s: error setting SNI hostname to: %s", props->namaddr,
996 tls_free_context(TLScontext);
999 if (log_mask & TLS_LOG_DEBUG)
1000 msg_info(
"%s: SNI hostname: %s", props->namaddr, props->host);
1016 SSL_set_connect_state(TLScontext->con);
1021 if (SSL_set_fd(TLScontext->con,
vstream_fileno(props->stream)) != 1) {
1022 msg_info(
"SSL_set_fd error to %s", props->namaddr);
1024 uncache_session(app_ctx->ssl_ctx, TLScontext);
1025 tls_free_context(TLScontext);
1044 if (log_mask & TLS_LOG_TLSPKTS)
1045 BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
1047 tls_dane_set_callback(app_ctx->ssl_ctx, TLScontext);
1056 sts = tls_bio_connect(
vstream_fileno(props->stream), props->timeout,
1059 if (ERR_peek_error() != 0) {
1060 msg_info(
"SSL_connect error to %s: %d", props->namaddr, sts);
1062 }
else if (errno != 0) {
1063 msg_info(
"SSL_connect error to %s: %m", props->namaddr);
1065 msg_info(
"SSL_connect error to %s: lost connection",
1068 uncache_session(app_ctx->ssl_ctx, TLScontext);
1069 tls_free_context(TLScontext);
1073 if ((log_mask & TLS_LOG_ALLPKTS) == 0)
1074 BIO_set_callback(SSL_get_rbio(TLScontext->con), 0);
1080 TLScontext->session_reused = SSL_session_reused(TLScontext->con);
1081 if ((log_mask & TLS_LOG_CACHE) && TLScontext->session_reused)
1082 msg_info(
"%s: Reusing old session", TLScontext->namaddr);
1088 if ((peercert = SSL_get_peer_certificate(TLScontext->con)) != 0) {
1089 TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT;
1097 verify_extract_print(TLScontext, peercert, props);
1098 verify_extract_name(TLScontext, peercert, props);
1100 if (TLScontext->log_mask &
1101 (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
1102 msg_info(
"%s: subject_CN=%s, issuer_CN=%s, "
1103 "fingerprint=%s, pkey_fingerprint=%s", props->namaddr,
1104 TLScontext->peer_CN, TLScontext->issuer_CN,
1105 TLScontext->peer_cert_fprint,
1106 TLScontext->peer_pkey_fprint);
1107 X509_free(peercert);
1109 TLScontext->issuer_CN =
mystrdup(
"");
1110 TLScontext->peer_CN =
mystrdup(
"");
1111 TLScontext->peer_cert_fprint =
mystrdup(
"");
1112 TLScontext->peer_pkey_fprint =
mystrdup(
"");
1118 TLScontext->protocol = SSL_get_version(TLScontext->con);
1119 cipher = SSL_get_current_cipher(TLScontext->con);
1120 TLScontext->cipher_name = SSL_CIPHER_get_name(cipher);
1121 TLScontext->cipher_usebits = SSL_CIPHER_get_bits(cipher,
1122 &(TLScontext->cipher_algbits));
1128 tls_stream_start(props->stream, TLScontext);
1136 if (TLS_CERT_IS_PRESENT(TLScontext)
1137 && TLS_CERT_IS_TRUSTED(TLScontext)
1138 && TLS_CERT_IS_MATCHED(TLScontext)
1140 TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
1145 if (log_mask & TLS_LOG_SUMMARY)
1146 msg_info(
"%s TLS connection established to %s: %s with cipher %s "
1148 !TLS_CERT_IS_PRESENT(TLScontext) ?
"Anonymous" :
1149 TLS_CERT_IS_SECURED(TLScontext) ?
"Verified" :
1150 TLS_CERT_IS_TRUSTED(TLScontext) ?
"Trusted" :
"Untrusted",
1151 props->namaddr, TLScontext->protocol, TLScontext->cipher_name,
1152 TLScontext->cipher_usebits, TLScontext->cipher_algbits);
1156 return (TLScontext);
char * mystrdup(const char *str)
NORETURN msg_panic(const char *fmt,...)
#define TLS_DANE_BASED(l)
int tls_mgr_lookup(const char *, const char *, VSTRING *)
int tls_mgr_update(const char *, const char *, const char *, ssize_t)
#define TLS_MUST_TRUST(l)
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
int var_tls_daemon_rand_bytes
int tls_mgr_delete(const char *, const char *)
#define TLS_NEVER_SECURED(l)
int tls_mgr_policy(const char *, int *, int *)
int strcasecmp(const char *s1, const char *s2)
int non_blocking(int, int)
const char * midna_domain_to_ascii(const char *name)
VSTRING * vstring_free(VSTRING *vp)
#define TLS_MUST_MATCH(l)
#define vstream_fileno(vp)
bool var_tls_multi_wildcard
void msg_info(const char *fmt,...)