aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtls/tls_peer.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-08-31 18:07:38 +0200
committerMartin Willi <martin@revosec.ch>2010-08-31 18:10:23 +0200
commitc8114799861902948a1d013a252e6ed6b199c921 (patch)
treef3d59a15ed9856e5f7c13347f0eb95be03e2cd76 /src/libtls/tls_peer.c
parent36eafea232f0b5e8cfe89a8a69f915a1e21a4369 (diff)
downloadstrongswan-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.c44
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'",