Author: kgiusti
Date: Fri Dec 14 19:17:25 2012
New Revision: 1422046

URL: http://svn.apache.org/viewvc?rev=1422046&view=rev
Log:
PROTON-161: add code to check SubjectAltName

Modified:
    qpid/proton/trunk/proton-c/src/ssl/openssl.c

Modified: qpid/proton/trunk/proton-c/src/ssl/openssl.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/ssl/openssl.c?rev=1422046&r1=1422045&r2=1422046&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/ssl/openssl.c (original)
+++ qpid/proton/trunk/proton-c/src/ssl/openssl.c Fri Dec 14 19:17:25 2012
@@ -28,6 +28,7 @@
 #include <openssl/ssl.h>
 #include <openssl/dh.h>
 #include <openssl/err.h>
+#include <openssl/x509v3.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -194,9 +195,42 @@ static int verify_callback(int preverify
 
   _log( ssl, "Checking commonName in peer cert against host pattern (%s)\n", 
ssl->peer_match_pattern);
 
+  bool matched = false;
+
+  /* first check any SubjectAltName entries, as per RFC2818 */
+  GENERAL_NAMES *sans = (GENERAL_NAMES *) X509_get_ext_d2i(cert, 
NID_subject_alt_name, NULL, NULL);
+  if (sans) {
+    int name_ct = sk_GENERAL_NAME_num( sans );
+    int i;
+    for (i = 0; !matched && i < name_ct; ++i) {
+      GENERAL_NAME *name = sk_GENERAL_NAME_value( sans, i );
+      if (name->type == GEN_DNS) {
+        ASN1_STRING *asn1 = name->d.dNSName;
+        if (asn1 && asn1->data && asn1->length) {
+          unsigned char *str;
+          int len = ASN1_STRING_to_UTF8( &str, asn1 );
+          if (len >= 0) {
+            _log( ssl, "SubjectAltName (dns) from peer cert = '%.*s'\n", len, 
str );
+            switch (ssl->match_type) {
+            case PN_SSL_MATCH_EXACT:
+              matched = (len == strlen(ssl->peer_match_pattern) &&
+                         strncasecmp( (const char *)str, 
ssl->peer_match_pattern, len ) == 0);
+              break;
+            case PN_SSL_MATCH_WILDCARD:
+              // TBD
+              break;
+            }
+            OPENSSL_free( str );
+          }
+        }
+      }
+    }
+    GENERAL_NAMES_free( sans );
+  }
+
+  /* if no general names match, try the CommonName from the subject */
   X509_NAME *name = X509_get_subject_name(cert);
   int i = -1;
-  bool matched = false;
   while (!matched && (i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) 
>= 0) {
     X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
     ASN1_STRING *name_asn1 = X509_NAME_ENTRY_get_data(ne);
@@ -220,7 +254,7 @@ static int verify_callback(int preverify
   }
 
   if (!matched) {
-    _log( ssl, "Error: no commonName matching %s found - peer is invalid.\n",
+    _log( ssl, "Error: no name matching %s found in peer cert - rejecting 
handshake.\n",
           ssl->peer_match_pattern);
     preverify_ok = 0;
 #ifdef X509_V_ERR_APPLICATION_VERIFICATION



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to