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