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