Example #1
0
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;
}
Example #2
0
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;
	    }
	}
    }
}
Example #3
0
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);
}