diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-31 18:07:38 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-31 18:10:23 +0200 |
commit | c8114799861902948a1d013a252e6ed6b199c921 (patch) | |
tree | f3d59a15ed9856e5f7c13347f0eb95be03e2cd76 /src/libtls/tls_peer.c | |
parent | 36eafea232f0b5e8cfe89a8a69f915a1e21a4369 (diff) | |
download | strongswan-c8114799861902948a1d013a252e6ed6b199c921.tar.bz2 strongswan-c8114799861902948a1d013a252e6ed6b199c921.tar.xz |
Strictly check if the server certificate matches the TLS server identity
Diffstat (limited to 'src/libtls/tls_peer.c')
-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'", |