comparison tests/test-url.py @ 29451:676f4d0e3a7b stable

tests: import CPython's hostname matching tests CPython has a more comprehensive test suite for it's built-in hostname matching functionality. This patch adds its tests so we can improve our hostname matching functionality. Many of the tests have different results from CPython. These will be addressed in a subsequent commit.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 26 Jun 2016 19:16:54 -0700
parents 63fe5ddb8715
children 26a5d605b868
comparison
equal deleted inserted replaced
29450:66c709b5af4b 29451:676f4d0e3a7b
1 # coding=utf-8
1 from __future__ import absolute_import, print_function 2 from __future__ import absolute_import, print_function
2 3
3 import doctest 4 import doctest
4 import os 5 import os
5 6
60 'no certificate received') 61 'no certificate received')
61 62
62 # Unicode (IDN) certname isn't supported 63 # Unicode (IDN) certname isn't supported
63 check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), 64 check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'),
64 'IDN in certificate not supported') 65 'IDN in certificate not supported')
66
67 # The following tests are from CPython's test_ssl.py.
68 check(_verifycert(cert('example.com'), 'example.com'), None)
69 check(_verifycert(cert('example.com'), 'ExAmple.cOm'), None)
70 check(_verifycert(cert('example.com'), 'www.example.com'),
71 'certificate is for example.com')
72 check(_verifycert(cert('example.com'), '.example.com'),
73 'certificate is for example.com')
74 check(_verifycert(cert('example.com'), 'example.org'),
75 'certificate is for example.com')
76 check(_verifycert(cert('example.com'), 'exampleXcom'),
77 'certificate is for example.com')
78 check(_verifycert(cert('*.a.com'), 'foo.a.com'), None)
79 check(_verifycert(cert('*.a.com'), 'bar.foo.a.com'),
80 'certificate is for *.a.com')
81 check(_verifycert(cert('*.a.com'), 'a.com'),
82 'certificate is for *.a.com')
83 check(_verifycert(cert('*.a.com'), 'Xa.com'),
84 'certificate is for *.a.com')
85 check(_verifycert(cert('*.a.com'), '.a.com'), None)
86
87 # only match one left-most wildcard
88 check(_verifycert(cert('f*.com'), 'foo.com'),
89 'certificate is for f*.com')
90 check(_verifycert(cert('f*.com'), 'f.com'),
91 'certificate is for f*.com')
92 check(_verifycert(cert('f*.com'), 'bar.com'),
93 'certificate is for f*.com')
94 check(_verifycert(cert('f*.com'), 'foo.a.com'),
95 'certificate is for f*.com')
96 check(_verifycert(cert('f*.com'), 'bar.foo.com'),
97 'certificate is for f*.com')
98
99 # NULL bytes are bad, CVE-2013-4073
100 check(_verifycert(cert('null.python.org\x00example.org'),
101 'null.python.org\x00example.org'), None)
102 check(_verifycert(cert('null.python.org\x00example.org'),
103 'example.org'),
104 'certificate is for null.python.org\x00example.org')
105 check(_verifycert(cert('null.python.org\x00example.org'),
106 'null.python.org'),
107 'certificate is for null.python.org\x00example.org')
108
109 # error cases with wildcards
110 check(_verifycert(cert('*.*.a.com'), 'bar.foo.a.com'),
111 'certificate is for *.*.a.com')
112 check(_verifycert(cert('*.*.a.com'), 'a.com'),
113 'certificate is for *.*.a.com')
114 check(_verifycert(cert('*.*.a.com'), 'Xa.com'),
115 'certificate is for *.*.a.com')
116 check(_verifycert(cert('*.*.a.com'), '.a.com'),
117 'certificate is for *.*.a.com')
118
119 check(_verifycert(cert('a.*.com'), 'a.foo.com'),
120 'certificate is for a.*.com')
121 check(_verifycert(cert('a.*.com'), 'a..com'),
122 'certificate is for a.*.com')
123 check(_verifycert(cert('a.*.com'), 'a.com'),
124 'certificate is for a.*.com')
125
126 # wildcard doesn't match IDNA prefix 'xn--'
127 idna = u'püthon.python.org'.encode('idna').decode('ascii')
128 check(_verifycert(cert(idna), idna), None)
129 check(_verifycert(cert('x*.python.org'), idna),
130 'certificate is for x*.python.org')
131 check(_verifycert(cert('xn--p*.python.org'), idna),
132 'certificate is for xn--p*.python.org')
133
134 # wildcard in first fragment and IDNA A-labels in sequent fragments
135 # are supported.
136 idna = u'www*.pythön.org'.encode('idna').decode('ascii')
137 check(_verifycert(cert(idna),
138 u'www.pythön.org'.encode('idna').decode('ascii')),
139 'certificate is for www*.xn--pythn-mua.org')
140 check(_verifycert(cert(idna),
141 u'www1.pythön.org'.encode('idna').decode('ascii')),
142 'certificate is for www*.xn--pythn-mua.org')
143 check(_verifycert(cert(idna),
144 u'ftp.pythön.org'.encode('idna').decode('ascii')),
145 'certificate is for www*.xn--pythn-mua.org')
146 check(_verifycert(cert(idna),
147 u'pythön.org'.encode('idna').decode('ascii')),
148 'certificate is for www*.xn--pythn-mua.org')
149
150 c = {
151 'notAfter': 'Jun 26 21:41:46 2011 GMT',
152 'subject': (((u'commonName', u'linuxfrz.org'),),),
153 'subjectAltName': (
154 ('DNS', 'linuxfr.org'),
155 ('DNS', 'linuxfr.com'),
156 ('othername', '<unsupported>'),
157 )
158 }
159 check(_verifycert(c, 'linuxfr.org'), None)
160 check(_verifycert(c, 'linuxfr.com'), None)
161 # Not a "DNS" entry
162 check(_verifycert(c, '<unsupported>'),
163 'certificate is for linuxfr.org, linuxfr.com')
164 # When there is a subjectAltName, commonName isn't used
165 check(_verifycert(c, 'linuxfrz.org'),
166 'certificate is for linuxfr.org, linuxfr.com')
167
168 # A pristine real-world example
169 c = {
170 'notAfter': 'Dec 18 23:59:59 2011 GMT',
171 'subject': (
172 ((u'countryName', u'US'),),
173 ((u'stateOrProvinceName', u'California'),),
174 ((u'localityName', u'Mountain View'),),
175 ((u'organizationName', u'Google Inc'),),
176 ((u'commonName', u'mail.google.com'),),
177 ),
178 }
179 check(_verifycert(c, 'mail.google.com'), None)
180 check(_verifycert(c, 'gmail.com'), 'certificate is for mail.google.com')
181
182 # Only commonName is considered
183 check(_verifycert(c, 'California'), 'certificate is for mail.google.com')
184
185 # Neither commonName nor subjectAltName
186 c = {
187 'notAfter': 'Dec 18 23:59:59 2011 GMT',
188 'subject': (
189 ((u'countryName', u'US'),),
190 ((u'stateOrProvinceName', u'California'),),
191 ((u'localityName', u'Mountain View'),),
192 ((u'organizationName', u'Google Inc'),),
193 ),
194 }
195 check(_verifycert(c, 'mail.google.com'),
196 'no commonName or subjectAltName found in certificate')
197
198 # No DNS entry in subjectAltName but a commonName
199 c = {
200 'notAfter': 'Dec 18 23:59:59 2099 GMT',
201 'subject': (
202 ((u'countryName', u'US'),),
203 ((u'stateOrProvinceName', u'California'),),
204 ((u'localityName', u'Mountain View'),),
205 ((u'commonName', u'mail.google.com'),),
206 ),
207 'subjectAltName': (('othername', 'blabla'),),
208 }
209 check(_verifycert(c, 'mail.google.com'), None)
210
211 # No DNS entry subjectAltName and no commonName
212 c = {
213 'notAfter': 'Dec 18 23:59:59 2099 GMT',
214 'subject': (
215 ((u'countryName', u'US'),),
216 ((u'stateOrProvinceName', u'California'),),
217 ((u'localityName', u'Mountain View'),),
218 ((u'organizationName', u'Google Inc'),),
219 ),
220 'subjectAltName': (('othername', 'blabla'),),
221 }
222 check(_verifycert(c, 'google.com'),
223 'no commonName or subjectAltName found in certificate')
224
225 # Empty cert / no cert
226 check(_verifycert(None, 'example.com'), 'no certificate received')
227 check(_verifycert({}, 'example.com'), 'no certificate received')
228
229 # avoid denials of service by refusing more than one
230 # wildcard per fragment.
231 check(_verifycert({'subject': (((u'commonName', u'a*b.com'),),)},
232 'axxb.com'), 'certificate is for a*b.com')
233 check(_verifycert({'subject': (((u'commonName', u'a*b.co*'),),)},
234 'axxb.com'), 'certificate is for a*b.co*')
235 check(_verifycert({'subject': (((u'commonName', u'a*b*.com'),),)},
236 'axxbxxc.com'), 'certificate is for a*b*.com')
65 237
66 def test_url(): 238 def test_url():
67 """ 239 """
68 >>> from mercurial.util import url 240 >>> from mercurial.util import url
69 241