Mercurial > hg
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 |