(&self, vm: &VirtualMachine)
| 3321 | |
| 3322 | #[pymethod] |
| 3323 | fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> { |
| 3324 | // Check if handshake already done |
| 3325 | if *self.handshake_done.lock() { |
| 3326 | return Ok(()); |
| 3327 | } |
| 3328 | |
| 3329 | let mut conn_guard = self.connection.lock(); |
| 3330 | |
| 3331 | // Initialize connection if not already done |
| 3332 | if conn_guard.is_none() { |
| 3333 | // Check for pending context change (from SNI callback) |
| 3334 | if let Some(new_ctx) = self.pending_context.write().take() { |
| 3335 | *self.context.write() = new_ctx; |
| 3336 | } |
| 3337 | |
| 3338 | if self.server_side { |
| 3339 | // Server-side connection - delegate to helper method |
| 3340 | self.initialize_server_connection(&mut conn_guard, vm)?; |
| 3341 | } else { |
| 3342 | // Client-side connection |
| 3343 | let ctx = self.context.read(); |
| 3344 | |
| 3345 | // Prepare common protocol settings (TLS versions, ECDH curve, cipher suites, ALPN) |
| 3346 | let protocol_settings = self.prepare_protocol_settings(vm)?; |
| 3347 | |
| 3348 | // Clone values we need before building config |
| 3349 | let verify_mode = *ctx.verify_mode.read(); |
| 3350 | let root_store_clone = ctx.root_certs.read().clone(); |
| 3351 | let ca_certs_der_clone = ctx.ca_certs_der.read().clone(); |
| 3352 | |
| 3353 | // For client mTLS: extract cert_chain and private_key from first cert_key (if any) |
| 3354 | // Now we store both CertifiedKey and PrivateKeyDer as tuple |
| 3355 | let cert_keys_guard = ctx.cert_keys.read(); |
| 3356 | let (cert_chain_clone, private_key_opt) = if !cert_keys_guard.is_empty() { |
| 3357 | let (first_cert_key, private_key) = &cert_keys_guard[0]; |
| 3358 | let certs = first_cert_key.cert.clone(); |
| 3359 | (certs, Some(private_key.clone_key())) |
| 3360 | } else { |
| 3361 | (Vec::new(), None) |
| 3362 | }; |
| 3363 | drop(cert_keys_guard); |
| 3364 | |
| 3365 | let check_hostname = *ctx.check_hostname.read(); |
| 3366 | let verify_flags = *ctx.verify_flags.read(); |
| 3367 | |
| 3368 | // Get session store before dropping ctx |
| 3369 | let session_store = ctx.rustls_session_store.clone(); |
| 3370 | |
| 3371 | // Get CRLs for revocation checking |
| 3372 | let crls_clone = ctx.crls.read().clone(); |
| 3373 | |
| 3374 | // Drop ctx early to avoid borrow conflicts |
| 3375 | drop(ctx); |
| 3376 | |
| 3377 | // Build client config using compat helper |
| 3378 | let config_options = ClientConfigOptions { |
| 3379 | protocol_settings, |
| 3380 | root_store: if verify_mode != CERT_NONE { |
no test coverage detected