| 137 | |
| 138 | |
| 139 | class _EncryptionIO(AsyncMongoCryptCallback): # type: ignore[misc] |
| 140 | def __init__( |
| 141 | self, |
| 142 | client: Optional[AsyncMongoClient[_DocumentTypeArg]], |
| 143 | key_vault_coll: AsyncCollection[_DocumentTypeArg], |
| 144 | mongocryptd_client: Optional[AsyncMongoClient[_DocumentTypeArg]], |
| 145 | opts: AutoEncryptionOpts, |
| 146 | ): |
| 147 | """Internal class to perform I/O on behalf of pymongocrypt.""" |
| 148 | self.client_ref: Any |
| 149 | # Use a weak ref to break reference cycle. |
| 150 | if client is not None: |
| 151 | self.client_ref = weakref.ref(client) |
| 152 | else: |
| 153 | self.client_ref = None |
| 154 | self.key_vault_coll: Optional[AsyncCollection[RawBSONDocument]] = cast( |
| 155 | AsyncCollection[RawBSONDocument], |
| 156 | key_vault_coll.with_options( |
| 157 | codec_options=_KEY_VAULT_OPTS, |
| 158 | read_concern=ReadConcern(level="majority"), |
| 159 | write_concern=WriteConcern(w="majority"), |
| 160 | ), |
| 161 | ) |
| 162 | self.mongocryptd_client = mongocryptd_client |
| 163 | self.opts = opts |
| 164 | self._spawned = False |
| 165 | self._kms_ssl_contexts = opts._kms_ssl_contexts(_IS_SYNC) |
| 166 | |
| 167 | async def kms_request(self, kms_context: MongoCryptKmsContext) -> None: |
| 168 | """Complete a KMS request. |
| 169 | |
| 170 | :param kms_context: A :class:`MongoCryptKmsContext`. |
| 171 | |
| 172 | :return: None |
| 173 | """ |
| 174 | endpoint = kms_context.endpoint |
| 175 | message = kms_context.message |
| 176 | provider = kms_context.kms_provider |
| 177 | ctx = self._kms_ssl_contexts.get(provider) |
| 178 | if ctx is None: |
| 179 | # Enable strict certificate verification, OCSP, match hostname, and |
| 180 | # SNI using the system default CA certificates. |
| 181 | ctx = get_ssl_context( |
| 182 | None, # certfile |
| 183 | None, # passphrase |
| 184 | None, # ca_certs |
| 185 | None, # crlfile |
| 186 | False, # allow_invalid_certificates |
| 187 | False, # allow_invalid_hostnames |
| 188 | False, # disable_ocsp_endpoint_check |
| 189 | _IS_SYNC, |
| 190 | ) |
| 191 | # CSOT: set timeout for socket creation. |
| 192 | connect_timeout = max(_csot.clamp_remaining(_KMS_CONNECT_TIMEOUT), 0.001) |
| 193 | opts = PoolOptions( |
| 194 | connect_timeout=connect_timeout, |
| 195 | socket_timeout=connect_timeout, |
| 196 | ssl_context=ctx, |