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:
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"""
|
||||||
|
Loading…
Reference in New Issue
Block a user