""" Android net.ssl 组件 — SSLSessionCache, SSLEngine, SSLSession, SSLContext, SSLParameters 等 方法签名完全对齐 Android SDK """ from __future__ import annotations import os import ssl import threading import time as _time from typing import Any, Dict, List, Optional, Set, Tuple from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) # ═══════════════════════════════════════════════════════════════ # SSLSessionCache # ═══════════════════════════════════════════════════════════════ class SSLSessionCache(Stub): """SSLSessionCache — SSL 会话缓存""" def __init__(self, path: Optional[str] = None): super().__init__() self._path = path self._cache: Dict[str, Any] = {} self._lock = threading.Lock() def install(self, ssl_context: "SSLContext"): pass @staticmethod def get(ssl_session: Any) -> Optional["SSLSessionCache"]: return None def toString(self) -> str: return f"SSLSessionCache@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # SSLSession # ═══════════════════════════════════════════════════════════════ class SSLSession(Stub): """SSLSession — SSL 会话""" def __init__(self): super().__init__() self._creation_time: int = int(_time.time() * 1000) self._last_accessed_time: int = self._creation_time self._application_buffer_size: int = 16384 self._packet_buffer_size: int = 16640 self._cipher_suite: str = "TLS_AES_128_GCM_SHA256" self._protocol: str = "TLSv1.3" self._id: bytes = os.urandom(32) self._peer_host: str = "" self._peer_port: int = 443 self._local_certificates: Optional[List[Any]] = None self._peer_certificates: Optional[List[Any]] = None self._local_principal: Any = None self._peer_principal: Any = None self._values: Dict[str, Any] = {} self._session_context: Optional["SSLContext"] = None def getApplicationBufferSize(self) -> int: return self._application_buffer_size def getCipherSuite(self) -> str: return self._cipher_suite def getCreationTime(self) -> int: return self._creation_time def getId(self) -> bytes: return self._id def getLastAccessedTime(self) -> int: return self._last_accessed_time def getLocalCertificates(self) -> Optional[List[Any]]: return self._local_certificates def getLocalPrincipal(self) -> Any: return self._local_principal def getPacketBufferSize(self) -> int: return self._packet_buffer_size def getPeerCertificates(self) -> Optional[List[Any]]: return self._peer_certificates def getPeerHost(self) -> str: return self._peer_host def getPeerPort(self) -> int: return self._peer_port def getPeerPrincipal(self) -> Any: return self._peer_principal def getProtocol(self) -> str: return self._protocol def getSessionContext(self) -> Optional["SSLContext"]: return self._session_context def getValue(self, name: str) -> Any: return self._values.get(name) def getValueNames(self) -> List[str]: return list(self._values.keys()) def invalidate(self): self._last_accessed_time = 0 self._values.clear() def putValue(self, name: str, value: Any): self._values[name] = value def removeValue(self, name: str): self._values.pop(name, None) def toString(self) -> str: return f"SSLSession{{protocol={self._protocol}, cipher={self._cipher_suite}}}" # ═══════════════════════════════════════════════════════════════ # SSLParameters # ═══════════════════════════════════════════════════════════════ class SSLParameters(Stub): """SSLParameters — SSL 参数""" def __init__(self): super().__init__() self._cipher_suites: List[str] = [] self._protocols: List[str] = [] self._want_client_auth: bool = False self._need_client_auth: bool = False self._algorithm_constraints: Any = None self._endpoint_identification_algorithm: Optional[str] = None self._server_names: List[Any] = [] self._sni_matchers: List[Any] = [] self._named_groups: List[str] = [] def getCipherSuites(self) -> List[str]: return list(self._cipher_suites) def setCipherSuites(self, cipherSuites: List[str]): self._cipher_suites = list(cipherSuites) def getProtocols(self) -> List[str]: return list(self._protocols) def setProtocols(self, protocols: List[str]): self._protocols = list(protocols) def getWantClientAuth(self) -> bool: return self._want_client_auth def setWantClientAuth(self, wantClientAuth: bool): self._want_client_auth = wantClientAuth def getNeedClientAuth(self) -> bool: return self._need_client_auth def setNeedClientAuth(self, needClientAuth: bool): self._need_client_auth = needClientAuth def getAlgorithmConstraints(self) -> Any: return self._algorithm_constraints def setAlgorithmConstraints(self, constraints: Any): self._algorithm_constraints = constraints def getEndpointIdentificationAlgorithm(self) -> Optional[str]: return self._endpoint_identification_algorithm def setEndpointIdentificationAlgorithm(self, algorithm: Optional[str]): self._endpoint_identification_algorithm = algorithm def getServerNames(self) -> List[Any]: return list(self._server_names) def setServerNames(self, serverNames: List[Any]): self._server_names = list(serverNames) def getSNIMatchers(self) -> List[Any]: return list(self._sni_matchers) def setSNIMatchers(self, sniMatchers: List[Any]): self._sni_matchers = list(sniMatchers) def getNamedGroups(self) -> List[str]: return list(self._named_groups) def setNamedGroups(self, namedGroups: List[str]): self._named_groups = list(namedGroups) def toString(self) -> str: return f"SSLParameters@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # SSLContext # ═══════════════════════════════════════════════════════════════ class SSLContext(Stub): """SSLContext — SSL 上下文""" def __init__(self, protocol: str = "TLS"): super().__init__() self._protocol = protocol self._ssl_context = ssl.create_default_context() self._socket_factory: Any = None self._server_socket_factory: Any = None self._default_ssl_params: Optional[SSLParameters] = None self._supported_ssl_params: Optional[SSLParameters] = None @staticmethod def getInstance(protocol: str = "TLS") -> "SSLContext": ctx = SSLContext(protocol) ctx._default_ssl_params = SSLParameters() ctx._supported_ssl_params = SSLParameters() return ctx def init(self, keyManager: Any, trustManager: Any, random: Any): pass def getSocketFactory(self) -> Any: if not self._socket_factory: self._socket_factory = self._ssl_context.wrap_socket return self._socket_factory def getServerSocketFactory(self) -> Any: if not self._server_socket_factory: self._server_socket_factory = self._ssl_context.wrap_socket return self._server_socket_factory def createSSLEngine(self) -> "SSLEngine": return SSLEngine(self) def createSSLEngine(self, peerHost: str, peerPort: int) -> "SSLEngine": return SSLEngine(self, peerHost, peerPort) def getProtocol(self) -> str: return self._protocol def getSupportedSSLParameters(self) -> SSLParameters: if not self._supported_ssl_params: self._supported_ssl_params = SSLParameters() return self._supported_ssl_params def getDefaultSSLParameters(self) -> SSLParameters: if not self._default_ssl_params: self._default_ssl_params = SSLParameters() return self._default_ssl_params def toString(self) -> str: return f"SSLContext{{protocol={self._protocol}}}" # ═══════════════════════════════════════════════════════════════ # SSLEngine # ═══════════════════════════════════════════════════════════════ class SSLEngine(Stub): """SSLEngine — SSL 引擎""" HANDSHAKE_STATUS_NOT_STARTED = 0 HANDSHAKE_STATUS_IN_PROGRESS = 1 HANDSHAKE_STATUS_NEED_WRAP = 2 HANDSHAKE_STATUS_NEED_UNWRAP = 3 HANDSHAKE_STATUS_FINISHED = 4 HANDSHAKE_STATUS_NEED_TASK = 5 def __init__(self, context: SSLContext, peerHost: str = "", peerPort: int = 443): super().__init__() self._context = context self._peer_host = peerHost self._peer_port = peerPort self._handshake_status = self.HANDSHAKE_STATUS_NOT_STARTED self._use_client_mode: bool = True self._need_client_auth: bool = False self._want_client_auth: bool = False self._enabled_cipher_suites: List[str] = [ "TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256", ] self._enabled_protocols: List[str] = ["TLSv1.3", "TLSv1.2"] self._session = SSLSession() self._delegated_tasks: List[Any] = [] self._application_protocol: Optional[str] = None self._handshake_application_protocol: Optional[str] = None self._hs_protocol_selector: Any = None def beginHandshake(self): self._handshake_status = self.HANDSHAKE_STATUS_IN_PROGRESS def closeInbound(self): pass def closeOutbound(self): pass def getDelegatedTask(self) -> Optional[Any]: if self._delegated_tasks: return self._delegated_tasks.pop(0) return None def getEnabledCipherSuites(self) -> List[str]: return list(self._enabled_cipher_suites) def getEnabledProtocols(self) -> List[str]: return list(self._enabled_protocols) def getHandshakeStatus(self) -> int: return self._handshake_status def getNeedClientAuth(self) -> bool: return self._need_client_auth def getSession(self) -> SSLSession: return self._session def getSupportedCipherSuites(self) -> List[str]: return list(self._enabled_cipher_suites) def getSupportedProtocols(self) -> List[str]: return list(self._enabled_protocols) def getUseClientMode(self) -> bool: return self._use_client_mode def getWantClientAuth(self) -> bool: return self._want_client_auth def setEnabledCipherSuites(self, suites: List[str]): self._enabled_cipher_suites = list(suites) def setEnabledProtocols(self, protocols: List[str]): self._enabled_protocols = list(protocols) def setNeedClientAuth(self, needClientAuth: bool): self._need_client_auth = needClientAuth def setUseClientMode(self, useClientMode: bool): self._use_client_mode = useClientMode def setWantClientAuth(self, wantClientAuth: bool): self._want_client_auth = wantClientAuth def setSSLParameters(self, params: SSLParameters): if params.getCipherSuites(): self._enabled_cipher_suites = params.getCipherSuites() if params.getProtocols(): self._enabled_protocols = params.getProtocols() self._need_client_auth = params.getNeedClientAuth() self._want_client_auth = params.getWantClientAuth() def getSSLParameters(self) -> SSLParameters: params = SSLParameters() params.setCipherSuites(self._enabled_cipher_suites) params.setProtocols(self._enabled_protocols) params.setNeedClientAuth(self._need_client_auth) params.setWantClientAuth(self._want_client_auth) return params def wrap(self, src: Any, dst: Any) -> Any: return src def unwrap(self, src: Any, dst: Any) -> Any: return src def getApplicationProtocol(self) -> Optional[str]: return self._application_protocol def getHandshakeApplicationProtocol(self) -> Optional[str]: return self._handshake_application_protocol def setHandshakeApplicationProtocolSelector(self, selector: Any): self._hs_protocol_selector = selector def getHandshakeApplicationProtocolSelector(self) -> Any: return self._hs_protocol_selector def toString(self) -> str: return f"SSLEngine{{handshake={self._handshake_status}, client={self._use_client_mode}}}" # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "SSLSessionCache", "SSLEngine", "SSLSession", "SSLContext", "SSLParameters", ]