Matching according to RFC 6125, section 6.4.3 - Hostnames are compared lower-case. - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE). - Partial wildcards like 'www*.example.org', multiple wildcards, sole wildcard or wildcards in labels other then the left-most
(dn, hostname)
| 278 | |
| 279 | |
| 280 | def _dnsname_match(dn, hostname): |
| 281 | """Matching according to RFC 6125, section 6.4.3 |
| 282 | |
| 283 | - Hostnames are compared lower-case. |
| 284 | - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE). |
| 285 | - Partial wildcards like 'www*.example.org', multiple wildcards, sole |
| 286 | wildcard or wildcards in labels other then the left-most label are not |
| 287 | supported and a CertificateError is raised. |
| 288 | - A wildcard must match at least one character. |
| 289 | """ |
| 290 | if not dn: |
| 291 | return False |
| 292 | |
| 293 | wildcards = dn.count('*') |
| 294 | # speed up common case w/o wildcards |
| 295 | if not wildcards: |
| 296 | return dn.lower() == hostname.lower() |
| 297 | |
| 298 | if wildcards > 1: |
| 299 | raise CertificateError( |
| 300 | "too many wildcards in certificate DNS name: {!r}.".format(dn)) |
| 301 | |
| 302 | dn_leftmost, sep, dn_remainder = dn.partition('.') |
| 303 | |
| 304 | if '*' in dn_remainder: |
| 305 | # Only match wildcard in leftmost segment. |
| 306 | raise CertificateError( |
| 307 | "wildcard can only be present in the leftmost label: " |
| 308 | "{!r}.".format(dn)) |
| 309 | |
| 310 | if not sep: |
| 311 | # no right side |
| 312 | raise CertificateError( |
| 313 | "sole wildcard without additional labels are not support: " |
| 314 | "{!r}.".format(dn)) |
| 315 | |
| 316 | if dn_leftmost != '*': |
| 317 | # no partial wildcard matching |
| 318 | raise CertificateError( |
| 319 | "partial wildcards in leftmost label are not supported: " |
| 320 | "{!r}.".format(dn)) |
| 321 | |
| 322 | hostname_leftmost, sep, hostname_remainder = hostname.partition('.') |
| 323 | if not hostname_leftmost or not sep: |
| 324 | # wildcard must match at least one char |
| 325 | return False |
| 326 | return dn_remainder.lower() == hostname_remainder.lower() |
| 327 | |
| 328 | |
| 329 | def _inet_paton(ipname): |