Support subjectAltName in SSL certificates
Signed-off-by: Thomas Jost <schnouki@schnouki.net> Reviewed-by: Sebastian Spaeth <Sebastian@SSpaeth.de> Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
		 Thomas Jost
					Thomas Jost
				
			
				
					committed by
					
						 Nicolas Sebrecht
						Nicolas Sebrecht
					
				
			
			
				
	
			
			
			 Nicolas Sebrecht
						Nicolas Sebrecht
					
				
			
						parent
						
							37e5367966
						
					
				
				
					commit
					838a67bc40
				
			| @@ -13,6 +13,8 @@ others. | ||||
| New Features | ||||
| ------------ | ||||
|  | ||||
| * SSL: support subjectAltName. | ||||
|  | ||||
| Changes | ||||
| ------- | ||||
|  | ||||
|   | ||||
| @@ -17,10 +17,9 @@ | ||||
|  | ||||
| import re, socket, time, subprocess | ||||
| from offlineimap.ui import getglobalui | ||||
| from imaplib import * | ||||
|  | ||||
| # Import the symbols we need that aren't exported by default | ||||
| from imaplib import IMAP4_PORT, IMAP4_SSL_PORT, InternalDate, Mon2num | ||||
| from imaplib import IMAP4_PORT, IMAP4_SSL_PORT, InternalDate, Mon2num, IMAP4, IMAP4_SSL | ||||
|  | ||||
| try: | ||||
|     import ssl | ||||
| @@ -149,22 +148,35 @@ class WrappedIMAP4_SSL(IMAP4_SSL): | ||||
|  | ||||
|     def _verifycert(self, cert, hostname): | ||||
|         '''Verify that cert (in socket.getpeercert() format) matches hostname. | ||||
|         CRLs and subjectAltName are not handled. | ||||
|         CRLs are not handled. | ||||
|          | ||||
|         Returns error message if any problems are found and None on success. | ||||
|         ''' | ||||
|         if not cert: | ||||
|             return ('no certificate received') | ||||
|         dnsname = hostname.lower() | ||||
|         certnames = [] | ||||
|  | ||||
|         # First read commonName | ||||
|         for s in cert.get('subject', []): | ||||
|             key, value = s[0] | ||||
|             if key == 'commonName': | ||||
|                 certname = value.lower() | ||||
|                 certnames.append(value.lower()) | ||||
|         if len(certnames) == 0: | ||||
|             return ('no commonName found in certificate') | ||||
|  | ||||
|         # Then read subjectAltName | ||||
|         for key, value in cert.get('subjectAltName', []): | ||||
|             if key == 'DNS': | ||||
|                 certnames.append(value.lower()) | ||||
|  | ||||
|         # And finally try to match hostname with one of these names | ||||
|         for certname in certnames: | ||||
|             if (certname == dnsname or | ||||
|                 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]): | ||||
|                 return None | ||||
|                 return ('certificate is for %s') % certname | ||||
|         return ('no commonName found in certificate') | ||||
|  | ||||
|         return ('no matching domain name found in certificate') | ||||
|  | ||||
|     def _read_upto (self, n): | ||||
|         """Read up to n bytes, emptying existing _readbuffer first""" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user