| 1024 | |
| 1025 | |
| 1026 | def _match_hostname( |
| 1027 | cert: _TYPE_PEER_CERT_RET_DICT | None, |
| 1028 | asserted_hostname: str, |
| 1029 | hostname_checks_common_name: bool = False, |
| 1030 | ) -> None: |
| 1031 | # Our upstream implementation of ssl.match_hostname() |
| 1032 | # only applies this normalization to IP addresses so it doesn't |
| 1033 | # match DNS SANs so we do the same thing! |
| 1034 | stripped_hostname = asserted_hostname.strip("[]") |
| 1035 | if is_ipaddress(stripped_hostname): |
| 1036 | asserted_hostname = stripped_hostname |
| 1037 | |
| 1038 | try: |
| 1039 | match_hostname(cert, asserted_hostname, hostname_checks_common_name) |
| 1040 | except CertificateError as e: |
| 1041 | log.warning( |
| 1042 | "Certificate did not match expected hostname: %s. Certificate: %s", |
| 1043 | asserted_hostname, |
| 1044 | cert, |
| 1045 | ) |
| 1046 | # Add cert to exception and reraise so client code can inspect |
| 1047 | # the cert when catching the exception, if they want to |
| 1048 | e._peer_cert = cert # type: ignore[attr-defined] |
| 1049 | raise |
| 1050 | |
| 1051 | |
| 1052 | def _wrap_proxy_error(err: Exception, proxy_scheme: str | None) -> ProxyError: |