diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libtls/tls_peer.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index 94448bbf7..a7b23f76d 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -16,6 +16,7 @@ #include "tls_peer.h" #include <debug.h> +#include <credentials/certificates/x509.h> #include <time.h> @@ -153,6 +154,42 @@ static status_t process_server_hello(private_tls_peer_t *this, } /** + * Check if a server certificate is acceptable for the given server identity + */ +static bool check_certificate(private_tls_peer_t *this, certificate_t *cert) +{ + identification_t *id; + + if (cert->has_subject(cert, this->server)) + { + return TRUE; + } + id = cert->get_subject(cert); + if (id->matches(id, this->server)) + { + return TRUE; + } + if (cert->get_type(cert) == CERT_X509) + { + x509_t *x509 = (x509_t*)cert; + enumerator_t *enumerator; + + enumerator = x509->create_subjectAltName_enumerator(x509); + while (enumerator->enumerate(enumerator, &id)) + { + if (id->matches(id, this->server)) + { + enumerator->destroy(enumerator); + return TRUE; + } + } + enumerator->destroy(enumerator); + } + DBG1(DBG_TLS, "server certificate does not match to '%Y'", this->server); + return FALSE; +} + +/** * Process a Certificate message */ static status_t process_certificate(private_tls_peer_t *this, @@ -188,6 +225,13 @@ static status_t process_certificate(private_tls_peer_t *this, { if (first) { + if (!check_certificate(this, cert)) + { + cert->destroy(cert); + certs->destroy(certs); + this->alert->add(this->alert, TLS_FATAL, TLS_ACCESS_DENIED); + return NEED_MORE; + } this->server_auth->add(this->server_auth, AUTH_HELPER_SUBJECT_CERT, cert); DBG1(DBG_TLS, "received TLS server certificate '%Y'", |