| 2598 | |
| 2599 | #[pymethod] |
| 2600 | fn get_verified_chain(&self, vm: &VirtualMachine) -> PyResult<Option<PyListRef>> { |
| 2601 | let stream = self.connection.read(); |
| 2602 | unsafe { |
| 2603 | let chain = sys::SSL_get0_verified_chain(stream.ssl().as_ptr()); |
| 2604 | if chain.is_null() { |
| 2605 | return Ok(None); |
| 2606 | } |
| 2607 | |
| 2608 | let num_certs = sys::OPENSSL_sk_num(chain as *const _); |
| 2609 | |
| 2610 | let mut certs = Vec::with_capacity(num_certs as usize); |
| 2611 | // Return Certificate objects |
| 2612 | for i in 0..num_certs { |
| 2613 | let cert_ptr = sys::OPENSSL_sk_value(chain as *const _, i) as *mut sys::X509; |
| 2614 | if cert_ptr.is_null() { |
| 2615 | continue; |
| 2616 | } |
| 2617 | // Clone the X509 certificate to create an owned copy |
| 2618 | sys::X509_up_ref(cert_ptr); |
| 2619 | let owned_cert = X509::from_ptr(cert_ptr); |
| 2620 | let cert_obj = cert_to_certificate(vm, owned_cert)?; |
| 2621 | certs.push(cert_obj); |
| 2622 | } |
| 2623 | |
| 2624 | Ok(if certs.is_empty() { |
| 2625 | None |
| 2626 | } else { |
| 2627 | Some(vm.ctx.new_list(certs)) |
| 2628 | }) |
| 2629 | } |
| 2630 | } |
| 2631 | |
| 2632 | #[pymethod] |
| 2633 | fn version(&self) -> Option<&'static str> { |