static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert, const TLS_CLIENT_START_PROPS *props) { TLScontext->peer_cert_fprint = tls_cert_fprint(peercert, props->mdalg); TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->mdalg); /* * Whether the level is "dane" or "fingerprint" when the peer certificate * is matched without resorting to a separate CA, we set both the trusted * and matched bits. This simplifies logic in smtp_proto.c where "dane" * must be trusted and matched, since some "dane" TLSA RRsets do use CAs. * * This also suppresses spurious logging of the peer certificate as * untrusted in verify_extract_name(). */ if (TLS_DANE_HASEE(props->dane) && tls_dane_match(TLScontext, TLS_DANE_EE, peercert, 0)) TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED | TLS_CERT_FLAG_MATCHED; }
static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert, const TLS_CLIENT_START_PROPS *props) { char **cpp; /* Non-null by contract */ TLScontext->peer_fingerprint = tls_fingerprint(peercert, props->fpt_dgst); TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->fpt_dgst); /* * Compare the fingerprint against each acceptable value, ignoring * upper/lower case differences. */ if (props->tls_level == TLS_LEV_FPRINT) { for (cpp = props->matchargv->argv; *cpp; ++cpp) { if (strcasecmp(TLScontext->peer_fingerprint, *cpp) == 0 || strcasecmp(TLScontext->peer_pkey_fprint, *cpp) == 0) { TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED; break; } } } }
TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext) { SSL_CIPHER_const SSL_CIPHER *cipher; X509 *peer; char buf[CCERT_BUFSIZ]; /* Turn off packet dump if only dumping the handshake */ if ((TLScontext->log_mask & TLS_LOG_ALLPKTS) == 0) BIO_set_callback(SSL_get_rbio(TLScontext->con), 0); /* * The caller may want to know if this session was reused or if a new * session was negotiated. */ TLScontext->session_reused = SSL_session_reused(TLScontext->con); if ((TLScontext->log_mask & TLS_LOG_CACHE) && TLScontext->session_reused) msg_info("%s: Reusing old session%s", TLScontext->namaddr, TLScontext->ticketed ? " (RFC 5077 session ticket)" : ""); /* * Let's see whether a peer certificate is available and what is the * actual information. We want to save it for later use. */ peer = SSL_get_peer_certificate(TLScontext->con); if (peer != NULL) { TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT; if (SSL_get_verify_result(TLScontext->con) == X509_V_OK) TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED; if (TLScontext->log_mask & TLS_LOG_VERBOSE) { X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf)); msg_info("subject=%s", buf); X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf)); msg_info("issuer=%s", buf); } TLScontext->peer_CN = tls_peer_CN(peer, TLScontext); TLScontext->issuer_CN = tls_issuer_CN(peer, TLScontext); TLScontext->peer_cert_fprint = tls_cert_fprint(peer, TLScontext->mdalg); TLScontext->peer_pkey_fprint = tls_pkey_fprint(peer, TLScontext->mdalg); if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) { msg_info("%s: subject_CN=%s, issuer=%s, fingerprint=%s" ", pkey_fingerprint=%s", TLScontext->namaddr, TLScontext->peer_CN, TLScontext->issuer_CN, TLScontext->peer_cert_fprint, TLScontext->peer_pkey_fprint); } X509_free(peer); } else { TLScontext->peer_CN = mystrdup(""); TLScontext->issuer_CN = mystrdup(""); TLScontext->peer_cert_fprint = mystrdup(""); TLScontext->peer_pkey_fprint = mystrdup(""); } /* * Finally, collect information about protocol and cipher for logging */ TLScontext->protocol = SSL_get_version(TLScontext->con); cipher = SSL_get_current_cipher(TLScontext->con); TLScontext->cipher_name = SSL_CIPHER_get_name(cipher); TLScontext->cipher_usebits = SSL_CIPHER_get_bits(cipher, &(TLScontext->cipher_algbits)); /* * If the library triggered the SSL handshake, switch to the * tls_timed_read/write() functions and make the TLScontext available to * those functions. Otherwise, leave control over SSL_read/write/etc. * with the application. */ if (TLScontext->stream != 0) tls_stream_start(TLScontext->stream, TLScontext); /* * All the key facts in a single log entry. */ if (TLScontext->log_mask & TLS_LOG_SUMMARY) msg_info("%s TLS connection established from %s: %s with cipher %s " "(%d/%d bits)", !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" : TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", TLScontext->namaddr, TLScontext->protocol, TLScontext->cipher_name, TLScontext->cipher_usebits, TLScontext->cipher_algbits); tls_int_seed(); return (TLScontext); }