Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 920fa0f0e28c0a57d683a2dc3f252bab > files > 10

m2crypto-0.16-9.el5.src.rpm

diff -up m2crypto-0.16/M2Crypto/SSL/Checker.py.multisubject m2crypto-0.16/M2Crypto/SSL/Checker.py
--- m2crypto-0.16/M2Crypto/SSL/Checker.py.multisubject	2006-03-20 20:26:28.000000000 +0100
+++ m2crypto-0.16/M2Crypto/SSL/Checker.py	2008-01-06 08:16:08.000000000 +0100
@@ -1,11 +1,11 @@
 """
-M2Crypto.SSL.Checker
+SSL peer certificate checking routines
 
-Copyright (c) 2004-2005 Open Source Applications Foundation.
+Copyright (c) 2004-2007 Open Source Applications Foundation.
 All rights reserved.
 """
 
-from M2Crypto import util, EVP
+from M2Crypto import util, EVP, m2
 import re
 
 class SSLVerificationError(Exception):
@@ -75,12 +75,12 @@ class Checker:
 
         if self.host:
             hostValidationPassed = False
+            self.useSubjectAltNameOnly = False
 
-            # XXX subjectAltName might contain multiple fields
-            # subjectAltName=DNS:somehost
+            # subjectAltName=DNS:somehost[, ...]*
             try:
                 subjectAltName = peerCert.get_ext('subjectAltName').get_value()
-                if not self._match(self.host, subjectAltName, True):
+                if not self._splitSubjectAltName(self.host, subjectAltName):
                     raise WrongHost(expectedHost=self.host, 
                                     actualHost=subjectAltName,
                                     fieldName='subjectAltName')
@@ -88,30 +88,74 @@ class Checker:
             except LookupError:
                 pass
 
-            # commonName=somehost
-            if not hostValidationPassed:
-                try:
-                    commonName = peerCert.get_subject().CN
-                    if not self._match(self.host, commonName):
-                        raise WrongHost(expectedHost=self.host,
-                                        actualHost=commonName,
-                                        fieldName='commonName')
-                except AttributeError:
+            # commonName=somehost[, ...]*
+            if not self.useSubjectAltNameOnly and not hostValidationPassed:
+                hasCommonName = False
+                commonNames = ''
+                for entry in peerCert.get_subject().get_entries_by_nid(m2.NID_commonName):
+                    hasCommonName = True
+                    commonName = entry.get_data().as_text()
+                    if not commonNames:
+                        commonNames = commonName
+                    else:
+                        commonNames += ',' + commonName
+                    if self._match(self.host, commonName):
+                        hostValidationPassed = True
+                        break
+
+                if not hasCommonName:
                     raise WrongCertificate('no commonName in peer certificate')
 
+                if not hostValidationPassed:
+                    raise WrongHost(expectedHost=self.host,
+                                    actualHost=commonNames,
+                                    fieldName='commonName')
+
         return True
 
-    def _match(self, host, certHost, subjectAltName=False):
+    def _splitSubjectAltName(self, host, subjectAltName):
         """
         >>> check = Checker()
-        >>> check._match(host='my.example.com', certHost='DNS:my.example.com', subjectAltName=True)
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:my.example.com')
+        True
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:*.example.com')
+        True
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*.example.com')
+        True
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com')
+        False
+        >>> check.useSubjectAltNameOnly
+        True
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, othername:<unsupported>')
+        False
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, DNS:my.example.org')
+        False
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, DNS:my.example.com')
         True
-        >>> check._match(host='my.example.com', certHost='DNS:*.example.com', subjectAltName=True)
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:my.example.com, DNS:my.example.org')
         True
-        >>> check._match(host='my.example.com', certHost='DNS:m*.example.com', subjectAltName=True)
+        >>> check.useSubjectAltNameOnly
         True
-        >>> check._match(host='my.example.com', certHost='DNS:m*ample.com', subjectAltName=True)
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='')
         False
+        >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='othername:<unsupported>')
+        False
+        >>> check.useSubjectAltNameOnly
+        False
+        """
+        self.useSubjectAltNameOnly = False
+        for certHost in subjectAltName.split(','):
+            certHost = certHost.lower().strip()
+            if certHost[:4] == 'dns:':
+                self.useSubjectAltNameOnly = True
+                if self._match(host, certHost[4:]):
+                    return True
+        return False
+        
+
+    def _match(self, host, certHost):
+        """
+        >>> check = Checker()
         >>> check._match(host='my.example.com', certHost='my.example.com')
         True
         >>> check._match(host='my.example.com', certHost='*.example.com')
@@ -131,17 +175,12 @@ class Checker:
         >>> check._match(host='1234', certHost='1234')
         True
         """
-        # XXX See RFC 2818 and 3280 for matching rules, this is not
-        # XXX yet complete.
+        # XXX See RFC 2818 and 3280 for matching rules, this is may not
+        # XXX yet be complete.
 
         host = host.lower()
         certHost = certHost.lower()
 
-        if subjectAltName:
-            if certHost[:4] != 'dns:':
-                return False
-            certHost = certHost[4:]
-        
         if host == certHost:
             return True
 
diff -up m2crypto-0.16/M2Crypto/X509.py.multisubject m2crypto-0.16/M2Crypto/X509.py
--- m2crypto-0.16/M2Crypto/X509.py.multisubject	2006-04-12 07:50:51.000000000 +0200
+++ m2crypto-0.16/M2Crypto/X509.py	2008-01-06 08:21:16.000000000 +0100
@@ -173,6 +173,8 @@ class X509_Name_Entry:
     def set_object(self, asn1obj):
         return m2.x509_name_entry_set_object( self.x509_name_entry, asn1obj._ptr() )
 
+    def get_data(self):
+        return ASN1.ASN1_String(m2.x509_name_entry_get_data(self.x509_name_entry))
     def create_by_txt( self, field, type, entry, len):
         return m2.x509_name_entry_create_by_txt( self.x509_name_entry._ptr(), field, type, entry, len )
 
@@ -241,6 +243,15 @@ class X509_Name:
 
     def __len__(self):
         return m2.x509_name_entry_count(self.x509_name)
+    
+    def __getitem__(self, idx):
+        if not 0 <= idx < self.entry_count():
+            raise IndexError("index out of range")
+        return X509_Name_Entry(m2.x509_name_get_entry(self.x509_name, idx))
+
+    def __iter__(self):
+        for i in xrange(self.entry_count()):
+            yield self[i]
 
     def _ptr(self):
         #assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error" 
@@ -253,6 +264,20 @@ class X509_Name:
     def entry_count( self ):
         return m2.x509_name_entry_count( self.x509_name )
     
+    def get_entries_by_nid(self, nid):
+        ret = []
+        lastpos = -1
+
+        while True:
+            lastpos = m2.x509_name_get_index_by_nid(self.x509_name, nid,
+                                                    lastpos)
+            if lastpos == -1:
+                break
+            
+            ret.append(self[lastpos])
+        
+        return ret
+    
     def as_text(self, indent=0, flags=m2.XN_FLAG_COMPAT):
         """
         as_text returns the name as a string.
diff -up m2crypto-0.16/SWIG/_x509.i.multisubject m2crypto-0.16/SWIG/_x509.i
--- m2crypto-0.16/SWIG/_x509.i.multisubject	2006-05-02 23:00:53.000000000 +0200
+++ m2crypto-0.16/SWIG/_x509.i	2008-01-06 08:16:08.000000000 +0100
@@ -132,6 +132,8 @@ extern int X509_NAME_add_entry_by_NID(X5
 extern int X509_NAME_print_ex(BIO *, X509_NAME *, int, unsigned long);
 %rename(x509_name_print_ex_fp) X509_NAME_print_ex_fp;
 extern int X509_NAME_print_ex_fp(FILE *, X509_NAME *, int, unsigned long);
+%rename(x509_name_get_index_by_nid) X509_NAME_get_index_by_NID;
+extern int X509_NAME_get_index_by_NID(X509_NAME *, int, int);
 
 %rename(x509_name_entry_new) X509_NAME_ENTRY_new;
 extern X509_NAME_ENTRY *X509_NAME_ENTRY_new( void );