Show More
@@ -488,13 +488,26 b' class httphandler(keepalive.HTTPHandler)' | |||||
488 |
|
488 | |||
489 | def _verifycert(cert, hostname): |
|
489 | def _verifycert(cert, hostname): | |
490 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
|
490 | '''Verify that cert (in socket.getpeercert() format) matches hostname. | |
491 |
CRLs |
|
491 | CRLs is not handled. | |
492 |
|
492 | |||
493 | Returns error message if any problems are found and None on success. |
|
493 | Returns error message if any problems are found and None on success. | |
494 | ''' |
|
494 | ''' | |
495 | if not cert: |
|
495 | if not cert: | |
496 | return _('no certificate received') |
|
496 | return _('no certificate received') | |
497 | dnsname = hostname.lower() |
|
497 | dnsname = hostname.lower() | |
|
498 | def matchdnsname(certname): | |||
|
499 | return (certname == dnsname or | |||
|
500 | '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]) | |||
|
501 | ||||
|
502 | san = cert.get('subjectAltName', []) | |||
|
503 | if san: | |||
|
504 | certnames = [value.lower() for key, value in san if key == 'DNS'] | |||
|
505 | for name in certnames: | |||
|
506 | if matchdnsname(name): | |||
|
507 | return None | |||
|
508 | return _('certificate is for %s') % ', '.join(certnames) | |||
|
509 | ||||
|
510 | # subject is only checked when subjectAltName is empty | |||
498 | for s in cert.get('subject', []): |
|
511 | for s in cert.get('subject', []): | |
499 | key, value = s[0] |
|
512 | key, value = s[0] | |
500 | if key == 'commonName': |
|
513 | if key == 'commonName': | |
@@ -503,11 +516,10 b' def _verifycert(cert, hostname):' | |||||
503 | certname = value.lower().encode('ascii') |
|
516 | certname = value.lower().encode('ascii') | |
504 | except UnicodeEncodeError: |
|
517 | except UnicodeEncodeError: | |
505 | return _('IDN in certificate not supported') |
|
518 | return _('IDN in certificate not supported') | |
506 |
if (certname |
|
519 | if matchdnsname(certname): | |
507 | '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]): |
|
|||
508 | return None |
|
520 | return None | |
509 | return _('certificate is for %s') % certname |
|
521 | return _('certificate is for %s') % certname | |
510 | return _('no commonName found in certificate') |
|
522 | return _('no commonName or subjectAltName found in certificate') | |
511 |
|
523 | |||
512 | if has_https: |
|
524 | if has_https: | |
513 | class BetterHTTPS(httplib.HTTPSConnection): |
|
525 | class BetterHTTPS(httplib.HTTPSConnection): |
@@ -25,6 +25,18 b" check(_verifycert(cert('*.example.com')," | |||||
25 | check(_verifycert(cert('*.example.com'), 'w.w.example.com'), |
|
25 | check(_verifycert(cert('*.example.com'), 'w.w.example.com'), | |
26 | 'certificate is for *.example.com') |
|
26 | 'certificate is for *.example.com') | |
27 |
|
27 | |||
|
28 | # Test subjectAltName | |||
|
29 | san_cert = {'subject': ((('commonName', 'example.com'),),), | |||
|
30 | 'subjectAltName': (('DNS', '*.example.net'), | |||
|
31 | ('DNS', 'example.net'))} | |||
|
32 | check(_verifycert(san_cert, 'example.net'), | |||
|
33 | None) | |||
|
34 | check(_verifycert(san_cert, 'foo.example.net'), | |||
|
35 | None) | |||
|
36 | # subject is only checked when subjectAltName is empty | |||
|
37 | check(_verifycert(san_cert, 'example.com'), | |||
|
38 | 'certificate is for *.example.net, example.net') | |||
|
39 | ||||
28 | # Avoid some pitfalls |
|
40 | # Avoid some pitfalls | |
29 | check(_verifycert(cert('*.foo'), 'foo'), |
|
41 | check(_verifycert(cert('*.foo'), 'foo'), | |
30 | 'certificate is for *.foo') |
|
42 | 'certificate is for *.foo') | |
@@ -33,7 +45,7 b" check(_verifycert(cert('*o'), 'foo')," | |||||
33 |
|
45 | |||
34 | check(_verifycert({'subject': ()}, |
|
46 | check(_verifycert({'subject': ()}, | |
35 | 'example.com'), |
|
47 | 'example.com'), | |
36 | 'no commonName found in certificate') |
|
48 | 'no commonName or subjectAltName found in certificate') | |
37 | check(_verifycert(None, 'example.com'), |
|
49 | check(_verifycert(None, 'example.com'), | |
38 | 'no certificate received') |
|
50 | 'no certificate received') | |
39 |
|
51 |
General Comments 0
You need to be logged in to leave comments.
Login now