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 | New Features | ||||||
| ------------ | ------------ | ||||||
|  |  | ||||||
|  | * SSL: support subjectAltName. | ||||||
|  |  | ||||||
| Changes | Changes | ||||||
| ------- | ------- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,10 +17,9 @@ | |||||||
|  |  | ||||||
| import re, socket, time, subprocess | import re, socket, time, subprocess | ||||||
| from offlineimap.ui import getglobalui | from offlineimap.ui import getglobalui | ||||||
| from imaplib import * |  | ||||||
|  |  | ||||||
| # Import the symbols we need that aren't exported by default | # 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: | try: | ||||||
|     import ssl |     import ssl | ||||||
| @@ -149,22 +148,35 @@ class WrappedIMAP4_SSL(IMAP4_SSL): | |||||||
|  |  | ||||||
|     def _verifycert(self, cert, hostname): |     def _verifycert(self, cert, hostname): | ||||||
|         '''Verify that cert (in socket.getpeercert() format) matches 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. |         Returns error message if any problems are found and None on success. | ||||||
|         ''' |         ''' | ||||||
|         if not cert: |         if not cert: | ||||||
|             return ('no certificate received') |             return ('no certificate received') | ||||||
|         dnsname = hostname.lower() |         dnsname = hostname.lower() | ||||||
|  |         certnames = [] | ||||||
|  |  | ||||||
|  |         # First read commonName | ||||||
|         for s in cert.get('subject', []): |         for s in cert.get('subject', []): | ||||||
|             key, value = s[0] |             key, value = s[0] | ||||||
|             if key == 'commonName': |             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 |             if (certname == dnsname or | ||||||
|                 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]): |                 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]): | ||||||
|                 return None |                 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): |     def _read_upto (self, n): | ||||||
|         """Read up to n bytes, emptying existing _readbuffer first""" |         """Read up to n bytes, emptying existing _readbuffer first""" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user