diff --git a/src/crypto/tls.h b/src/crypto/tls.h index c8b1a824e..09fb73b1a 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -670,4 +670,18 @@ int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len); */ u16 tls_connection_get_cipher_suite(struct tls_connection *conn); +/** + * tls_connection_get_peer_subject - Get peer subject + * @conn: Connection context data from tls_connection_init() + * Returns: Peer subject or %NULL if not authenticated or not available + */ +const char * tls_connection_get_peer_subject(struct tls_connection *conn); + +/** + * tls_connection_get_own_cert_used - Was own certificate used + * @conn: Connection context data from tls_connection_init() + * Returns: true if own certificate was used during authentication + */ +bool tls_connection_get_own_cert_used(struct tls_connection *conn); + #endif /* TLS_H */ diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 29c7688a5..0f9664ec5 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -265,6 +265,7 @@ struct tls_connection { X509 *peer_cert; X509 *peer_issuer; X509 *peer_issuer_issuer; + char *peer_subject; /* peer subject info for authenticated peer */ unsigned char client_random[SSL3_RANDOM_SIZE]; unsigned char server_random[SSL3_RANDOM_SIZE]; @@ -1629,6 +1630,7 @@ void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) os_free(conn->domain_match); os_free(conn->check_cert_subject); os_free(conn->session_ticket); + os_free(conn->peer_subject); os_free(conn); } @@ -2579,6 +2581,11 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_SUCCESS, NULL); + if (depth == 0 && preverify_ok) { + os_free(conn->peer_subject); + conn->peer_subject = os_strdup(buf); + } + return preverify_ok; } @@ -3180,7 +3187,11 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, if (conn == NULL) return -1; - if (verify_peer) { + if (verify_peer == 2) { + conn->ca_cert_verify = 1; + SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | + SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); + } else if (verify_peer) { conn->ca_cert_verify = 1; SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | @@ -5683,3 +5694,19 @@ u16 tls_connection_get_cipher_suite(struct tls_connection *conn) return SSL_CIPHER_get_id(cipher) & 0xFFFF; #endif } + + +const char * tls_connection_get_peer_subject(struct tls_connection *conn) +{ + if (conn) + return conn->peer_subject; + return NULL; +} + + +bool tls_connection_get_own_cert_used(struct tls_connection *conn) +{ + if (conn) + return SSL_get_certificate(conn->ssl) != NULL; + return false; +}