codekingpro/portable-devtools
114k
1"""2`pyOpenSSL <https://github.com/pyca/pyopenssl>`_-specific code.3"""4 5from __future__ import annotations6 7import contextlib8import warnings9 10from typing import Sequence11 12from .cryptography import extract_patterns as _cryptography_extract_patterns13from .hazmat import (14 DNS_ID,15 CertificatePattern,16 IPAddress_ID,17 verify_service_identity,18)19 20 21with contextlib.suppress(ImportError):22 # We only use it for docstrings -- `if TYPE_CHECKING`` does not work.23 from OpenSSL.crypto import X50924 from OpenSSL.SSL import Connection25 26 27__all__ = ["verify_hostname"]28 29 30def verify_hostname(connection: Connection, hostname: str) -> None:31 r"""32 Verify whether the certificate of *connection* is valid for *hostname*.33 34 Args:35 connection: A pyOpenSSL connection object.36 37 hostname: The hostname that *connection* should be connected to.38 39 Raises:40 service_identity.VerificationError:41 If *connection* does not provide a certificate that is valid for42 *hostname*.43 44 service_identity.CertificateError:45 If certificate provided by *connection* contains invalid /46 unexpected data. This includes the case where the certificate47 contains no ``subjectAltName``\ s.48 49 .. versionchanged:: 24.1.050 :exc:`~service_identity.CertificateError` is raised if the certificate51 contains no ``subjectAltName``\ s instead of52 :exc:`~service_identity.VerificationError`.53 """54 verify_service_identity(55 cert_patterns=extract_patterns(56 connection.get_peer_certificate() # type:ignore[arg-type]57 ),58 obligatory_ids=[DNS_ID(hostname)],59 optional_ids=[],60 )61 62 63def verify_ip_address(connection: Connection, ip_address: str) -> None:64 r"""65 Verify whether the certificate of *connection* is valid for *ip_address*.66 67 Args:68 connection: A pyOpenSSL connection object.69 70 ip_address:71 The IP address that *connection* should be connected to. Can be an72 IPv4 or IPv6 address.73 74 Raises:75 service_identity.VerificationError:76 If *connection* does not provide a certificate that is valid for77 *ip_address*.78 79 service_identity.CertificateError:80 If the certificate chain of *connection* contains a certificate81 that contains invalid/unexpected data.82 83 .. versionadded:: 18.1.084 85 .. versionchanged:: 24.1.086 :exc:`~service_identity.CertificateError` is raised if the certificate87 contains no ``subjectAltName``\ s instead of88 :exc:`~service_identity.VerificationError`.89 """90 verify_service_identity(91 cert_patterns=extract_patterns(92 connection.get_peer_certificate() # type:ignore[arg-type]93 ),94 obligatory_ids=[IPAddress_ID(ip_address)],95 optional_ids=[],96 )97 98 99def extract_patterns(cert: X509) -> Sequence[CertificatePattern]:100 """101 Extract all valid ID patterns from a certificate for service verification.102 103 Args:104 cert: The certificate to be dissected.105 106 Returns:107 List of IDs.108 109 .. versionchanged:: 23.1.0110 ``commonName`` is not used as a fallback anymore.111 """112 return _cryptography_extract_patterns(cert.to_cryptography())113 114 115def extract_ids(cert: X509) -> Sequence[CertificatePattern]:116 """117 Deprecated and never public API. Use :func:`extract_patterns` instead.118 119 .. deprecated:: 23.1.0120 """121 warnings.warn(122 category=DeprecationWarning,123 message="`extract_ids()` is deprecated, please use `extract_patterns()`.",124 stacklevel=2,125 )126 return extract_patterns(cert)127 