]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
Strictly check if the server certificate matches the TLS server identity
authorMartin Willi <martin@revosec.ch>
Tue, 31 Aug 2010 16:07:38 +0000 (18:07 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 31 Aug 2010 16:10:23 +0000 (18:10 +0200)
src/libtls/tls_peer.c

index 94448bbf752f558085ebb3c6dc3a72f478635abf..a7b23f76d11a7dbcb15262f27f50b4912721e21e 100644 (file)
@@ -16,6 +16,7 @@
 #include "tls_peer.h"
 
 #include <debug.h>
+#include <credentials/certificates/x509.h>
 
 #include <time.h>
 
@@ -152,6 +153,42 @@ static status_t process_server_hello(private_tls_peer_t *this,
        return NEED_MORE;
 }
 
+/**
+ * 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
  */
@@ -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'",