diff --git a/ylong_http_client/src/util/c_openssl/adapter.rs b/ylong_http_client/src/util/c_openssl/adapter.rs index 587a7c06b6551a23ab15fd1c7721b63008e8a689..7a8ce6ad6764d02df47a926efc66ba7c321be423 100644 --- a/ylong_http_client/src/util/c_openssl/adapter.rs +++ b/ylong_http_client/src/util/c_openssl/adapter.rs @@ -570,6 +570,7 @@ impl TlsFileType { /// let cert = Cert::from_der(der); /// # } /// ``` +#[derive(Clone)] pub struct Cert(X509); impl Cert { @@ -636,10 +637,12 @@ impl Cert { /// let certs = Certificate::from_pem(pem); /// } /// ``` +#[derive(Clone)] pub struct Certificate { inner: CertificateList, } +#[derive(Clone)] pub(crate) enum CertificateList { CertList(Vec), #[cfg(feature = "c_openssl_3_0")] @@ -798,6 +801,34 @@ mod ut_openssl_adapter { assert!(builder.is_ok()); } + /// UT test cases for `Certificate::clone`. + /// + /// # Brief + /// 1. Creates a `Certificate` by calling `Certificate::from_pem`. + /// 2. Creates another `Certificate` by calling `Certificate::clone`. + /// 2. Checks if the result is as expected. + #[test] + #[allow(clippy::redundant_clone)] + fn ut_certificate_clone() { + let pem = include_bytes!("../../../tests/file/root-ca.pem"); + let certificate = Certificate::from_pem(pem).unwrap(); + drop(certificate.clone()); + } + + /// UT test cases for `Cert::clone`. + /// + /// # Brief + /// 1. Creates a `Cert` by calling `Cert::from_pem`. + /// 2. Creates another `Cert` by calling `Cert::clone`. + /// 2. Checks if the result is as expected. + #[test] + #[allow(clippy::redundant_clone)] + fn ut_cert_clone() { + let pem = include_bytes!("../../../tests/file/root-ca.pem"); + let cert = Cert::from_pem(pem).unwrap(); + drop(cert.clone()); + } + /// UT test cases for `TlsConfigBuilder::build_in_root_certs`. /// /// # Brief diff --git a/ylong_http_client/src/util/c_openssl/ffi/x509.rs b/ylong_http_client/src/util/c_openssl/ffi/x509.rs index 1fb9f49efe2dbc444b016744468056b51cf60823..b74764be9dc9a5760547d098bef5b823c8b786e0 100644 --- a/ylong_http_client/src/util/c_openssl/ffi/x509.rs +++ b/ylong_http_client/src/util/c_openssl/ffi/x509.rs @@ -52,6 +52,8 @@ extern "C" { pub(crate) fn X509_get_pubkey(a: *mut C_X509) -> *mut EVP_PKEY; pub(crate) fn X509_verify(a: *mut C_X509, pkey: *mut EVP_PKEY) -> c_int; + + pub(crate) fn X509_up_ref(x: *mut C_X509) -> c_int; } pub(crate) enum X509_NAME {} diff --git a/ylong_http_client/src/util/c_openssl/x509.rs b/ylong_http_client/src/util/c_openssl/x509.rs index c64dad58ac6bd25505eab0ca5b417bbbb71551dd..6c1db70dce705c442170c351fb0274f7648c9f46 100644 --- a/ylong_http_client/src/util/c_openssl/x509.rs +++ b/ylong_http_client/src/util/c_openssl/x509.rs @@ -29,8 +29,8 @@ use super::ffi::x509::{ X509_STORE_CTX_get0_cert, X509_STORE_add_cert, X509_STORE_free, X509_STORE_new, X509_VERIFY_PARAM_free, X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_set_hostflags, X509_get_issuer_name, X509_get_pubkey, X509_get_subject_name, - X509_get_version, X509_verify, X509_verify_cert_error_string, EVP_PKEY, STACK_X509, X509_NAME, - X509_STORE, X509_STORE_CTX, X509_VERIFY_PARAM, + X509_get_version, X509_up_ref, X509_verify, X509_verify_cert_error_string, EVP_PKEY, + STACK_X509, X509_NAME, X509_STORE, X509_STORE_CTX, X509_VERIFY_PARAM, }; use super::foreign::{Foreign, ForeignRef}; use super::stack::Stackof; @@ -148,6 +148,23 @@ impl Stackof for X509 { type StackType = STACK_X509; } +impl Clone for X509 { + fn clone(&self) -> Self { + X509Ref::to_owned(self) + } +} + +impl ToOwned for X509Ref { + type Owned = X509; + + fn to_owned(&self) -> Self::Owned { + unsafe { + X509_up_ref(self.as_ptr()); + X509::from_ptr(self.as_ptr()) + } + } +} + #[derive(Copy, Clone, PartialEq, Eq)] pub(crate) struct X509VerifyResult(c_int); @@ -270,3 +287,23 @@ impl X509StoreContextRef { } } } + +#[cfg(test)] +mod ut_x509 { + + /// UT test cases for `X509::clone`. + /// + /// # Brief + /// 1. Creates a `X509` by calling `X509::from_pem`. + /// 2. Creates another `X509` by calling `X509::clone`. + /// 2. Checks if the result is as expected. + #[test] + #[allow(clippy::redundant_clone)] + fn ut_x509_clone() { + use crate::util::c_openssl::x509::X509; + + let pem = include_bytes!("../../../tests/file/root-ca.pem"); + let x509 = X509::from_pem(pem).unwrap(); + drop(x509.clone()); + } +}