mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat: add option to trust any TLS certificate for IMAP connections
This commit is contained in:
@@ -55,7 +55,7 @@ use crate::modules::rest::response::DataPage;
|
||||
use crate::modules::token::AccessToken;
|
||||
use crate::raise_error;
|
||||
|
||||
pub type AccountModel = AccountV1;
|
||||
pub type AccountModel = AccountV2;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize, Enum)]
|
||||
pub enum AccountType {
|
||||
@@ -86,11 +86,41 @@ pub struct AccountV1 {
|
||||
pub updated_at: i64,
|
||||
pub use_proxy: Option<u64>,
|
||||
}
|
||||
|
||||
impl AccountV1 {
|
||||
fn pk(&self) -> String {
|
||||
format!("{}_{}", self.created_at, self.id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize, Object)]
|
||||
#[native_model(id = 4, version = 2, from = AccountV1)]
|
||||
#[native_db(primary_key(pk -> String))]
|
||||
pub struct AccountV2 {
|
||||
#[secondary_key(unique)]
|
||||
pub id: u64,
|
||||
pub imap: Option<ImapConfig>,
|
||||
pub enabled: bool,
|
||||
#[oai(validator(custom = "crate::modules::common::validator::EmailValidator"))]
|
||||
pub email: String,
|
||||
pub name: Option<String>,
|
||||
pub capabilities: Option<Vec<String>>,
|
||||
pub date_since: Option<DateSince>,
|
||||
pub folder_limit: Option<u32>,
|
||||
pub sync_folders: Option<Vec<String>>,
|
||||
pub account_type: AccountType,
|
||||
pub sync_interval_min: Option<i64>,
|
||||
pub known_folders: Option<BTreeSet<String>>,
|
||||
pub created_at: i64,
|
||||
pub updated_at: i64,
|
||||
pub use_proxy: Option<u64>,
|
||||
pub use_dangerous: bool,
|
||||
pub pgp_key: Option<String>,
|
||||
}
|
||||
|
||||
impl AccountV2 {
|
||||
fn pk(&self) -> String {
|
||||
format!("{}_{}", self.created_at, self.id)
|
||||
}
|
||||
|
||||
pub fn new(request: AccountCreateRequest) -> BichonResult<Self> {
|
||||
Ok(Self {
|
||||
@@ -109,12 +139,14 @@ impl AccountV1 {
|
||||
updated_at: utc_now!(),
|
||||
use_proxy: request.use_proxy,
|
||||
folder_limit: request.folder_limit,
|
||||
use_dangerous: request.use_dangerous,
|
||||
pgp_key: request.pgp_key,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn check_account_exists(account_id: u64) -> BichonResult<AccountModel> {
|
||||
let account =
|
||||
secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV1Key::id, account_id)
|
||||
secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV2Key::id, account_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
raise_error!(
|
||||
@@ -144,7 +176,7 @@ impl AccountV1 {
|
||||
}
|
||||
|
||||
pub async fn find(account_id: u64) -> BichonResult<Option<AccountModel>> {
|
||||
secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV1Key::id, account_id)
|
||||
secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV2Key::id, account_id)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -198,7 +230,7 @@ impl AccountV1 {
|
||||
|
||||
async fn delete_account(account_id: u64) -> BichonResult<()> {
|
||||
delete_impl(DB_MANAGER.meta_db(), move|rw|{
|
||||
rw.get().secondary::<AccountModel>(AccountV1Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
rw.get().secondary::<AccountModel>(AccountV2Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(||raise_error!(format!("The account entity with id={account_id} that you want to delete was not found."), ErrorCode::ResourceNotFound))
|
||||
}).await
|
||||
}
|
||||
@@ -228,7 +260,7 @@ impl AccountV1 {
|
||||
sync_folders: Vec<String>,
|
||||
) -> BichonResult<()> {
|
||||
update_impl(DB_MANAGER.meta_db(), move |rw| {
|
||||
rw.get().secondary::<AccountModel>(AccountV1Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
rw.get().secondary::<AccountModel>(AccountV2Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| raise_error!(format!("When trying to update account sync_folders, the corresponding record was not found. account_id={}", account_id), ErrorCode::ResourceNotFound))
|
||||
}, |current|{
|
||||
let mut updated = current.clone();
|
||||
@@ -243,7 +275,7 @@ impl AccountV1 {
|
||||
known_folders: BTreeSet<String>,
|
||||
) -> BichonResult<()> {
|
||||
update_impl(DB_MANAGER.meta_db(), move |rw| {
|
||||
rw.get().secondary::<AccountModel>(AccountV1Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
rw.get().secondary::<AccountModel>(AccountV2Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| raise_error!(format!("When trying to update account known_folders, the corresponding record was not found. account_id={}", account_id), ErrorCode::ResourceNotFound))
|
||||
}, |current|{
|
||||
let mut updated = current.clone();
|
||||
@@ -258,7 +290,7 @@ impl AccountV1 {
|
||||
capabilities: Vec<String>,
|
||||
) -> BichonResult<()> {
|
||||
update_impl(DB_MANAGER.meta_db(), move |rw| {
|
||||
rw.get().secondary::<AccountModel>(AccountV1Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
rw.get().secondary::<AccountModel>(AccountV2Key::id, account_id).map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| raise_error!(format!("When trying to update account capabilities, the corresponding record was not found. account_id={}", account_id), ErrorCode::ResourceNotFound))
|
||||
}, |current|{
|
||||
let mut updated = current.clone();
|
||||
@@ -287,7 +319,7 @@ impl AccountV1 {
|
||||
}
|
||||
|
||||
pub async fn count() -> BichonResult<usize> {
|
||||
count_by_unique_secondary_key_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV1Key::id)
|
||||
count_by_unique_secondary_key_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV2Key::id)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -355,7 +387,62 @@ impl AccountV1 {
|
||||
if let Some(enabled) = request.enabled {
|
||||
new.enabled = enabled;
|
||||
}
|
||||
|
||||
if let Some(use_dangerous) = request.use_dangerous {
|
||||
new.use_dangerous = use_dangerous;
|
||||
}
|
||||
|
||||
if let Some(pgp_key) = request.pgp_key {
|
||||
new.pgp_key = Some(pgp_key);
|
||||
}
|
||||
|
||||
new.updated_at = utc_now!();
|
||||
Ok(new)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AccountV1> for AccountV2 {
|
||||
fn from(value: AccountV1) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
imap: value.imap,
|
||||
enabled: value.enabled,
|
||||
email: value.email,
|
||||
name: value.name,
|
||||
capabilities: value.capabilities,
|
||||
date_since: value.date_since,
|
||||
folder_limit: value.folder_limit,
|
||||
sync_folders: value.sync_folders,
|
||||
account_type: value.account_type,
|
||||
sync_interval_min: value.sync_interval_min,
|
||||
known_folders: value.known_folders,
|
||||
created_at: value.created_at,
|
||||
updated_at: value.updated_at,
|
||||
use_proxy: value.use_proxy,
|
||||
use_dangerous: false,
|
||||
pgp_key: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AccountV2> for AccountV1 {
|
||||
fn from(value: AccountV2) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
imap: value.imap,
|
||||
enabled: value.enabled,
|
||||
email: value.email,
|
||||
name: value.name,
|
||||
capabilities: value.capabilities,
|
||||
date_since: value.date_since,
|
||||
folder_limit: value.folder_limit,
|
||||
sync_folders: value.sync_folders,
|
||||
account_type: value.account_type,
|
||||
sync_interval_min: value.sync_interval_min,
|
||||
known_folders: value.known_folders,
|
||||
created_at: value.created_at,
|
||||
updated_at: value.updated_at,
|
||||
use_proxy: value.use_proxy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::modules::account::entity::ImapConfig;
|
||||
@@ -43,6 +42,8 @@ pub struct AccountCreateRequest {
|
||||
#[oai(validator(minimum(value = "10"), maximum(value = "480")))]
|
||||
pub sync_interval_min: Option<i64>,
|
||||
pub use_proxy: Option<u64>,
|
||||
pub use_dangerous: bool,
|
||||
pub pgp_key: Option<String>,
|
||||
}
|
||||
|
||||
impl AccountCreateRequest {
|
||||
@@ -132,6 +133,10 @@ pub struct AccountUpdateRequest {
|
||||
/// - If `None` or not provided, the client will connect directly to the API server.
|
||||
/// - If `Some(proxy_id)`, the client will use the pre-configured proxy with the given ID for API requests.
|
||||
pub use_proxy: Option<u64>,
|
||||
|
||||
pub use_dangerous: Option<bool>,
|
||||
|
||||
pub pgp_key: Option<String>,
|
||||
}
|
||||
|
||||
impl AccountUpdateRequest {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::modules::account::migration::AccountModel;
|
||||
use crate::modules::cache::imap::MAILBOX_MODELS;
|
||||
use crate::modules::error::{code::ErrorCode, BichonError};
|
||||
use crate::modules::settings::cli::SETTINGS;
|
||||
@@ -71,6 +71,8 @@ impl DatabaseManager {
|
||||
let rw = database
|
||||
.rw_transaction()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
rw.migrate::<AccountModel>()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
rw.commit()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::modules::account::migration::AccountV1;
|
||||
use crate::modules::account::migration::{AccountV1, AccountV2};
|
||||
use crate::modules::autoconfig::CachedMailSettings;
|
||||
use crate::modules::error::code::ErrorCode;
|
||||
use crate::modules::error::BichonResult;
|
||||
@@ -63,6 +62,7 @@ impl ModelsAdapter {
|
||||
self.register_model::<SystemSetting>();
|
||||
self.register_model::<CachedMailSettings>();
|
||||
self.register_model::<AccountV1>();
|
||||
self.register_model::<AccountV2>();
|
||||
self.register_model::<OAuth2>();
|
||||
self.register_model::<OAuth2PendingEntity>();
|
||||
self.register_model::<OAuth2AccessToken>();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::modules::account::entity::Encryption;
|
||||
use crate::modules::error::code::ErrorCode;
|
||||
use crate::modules::error::BichonResult;
|
||||
@@ -100,15 +99,17 @@ impl Client {
|
||||
encryption: &Encryption,
|
||||
port: u16,
|
||||
use_proxy: Option<u64>,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<Self> {
|
||||
let resolved_addr = Self::resolve_to_socket_addr(domain, port)?;
|
||||
debug!("Attempting IMAP connection to {domain} ({resolved_addr}).");
|
||||
match encryption {
|
||||
Encryption::Ssl => {
|
||||
Self::establish_secure_connection(resolved_addr, domain, use_proxy).await
|
||||
Self::establish_secure_connection(resolved_addr, domain, use_proxy, dangerous).await
|
||||
}
|
||||
Encryption::StartTls => {
|
||||
Self::establish_starttls_connection(resolved_addr, domain, use_proxy).await
|
||||
Self::establish_starttls_connection(resolved_addr, domain, use_proxy, dangerous)
|
||||
.await
|
||||
}
|
||||
Encryption::None => Self::establish_insecure_connection(resolved_addr, use_proxy).await,
|
||||
}
|
||||
@@ -118,11 +119,17 @@ impl Client {
|
||||
address: SocketAddr,
|
||||
server_hostname: &str,
|
||||
use_proxy: Option<u64>,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<Self> {
|
||||
// Establish the TLS connection with the specified parameters
|
||||
let tls_stream =
|
||||
establish_tls_connection(address, server_hostname, alpn(address.port()), use_proxy)
|
||||
.await?;
|
||||
let tls_stream = establish_tls_connection(
|
||||
address,
|
||||
server_hostname,
|
||||
alpn(address.port()),
|
||||
use_proxy,
|
||||
dangerous,
|
||||
)
|
||||
.await?;
|
||||
let stats_stream = StatsWrapper::new(tls_stream);
|
||||
// Wrap the TLS stream in a buffered writer for efficient IO
|
||||
let buffered_stream = BufWriter::new(stats_stream);
|
||||
@@ -180,6 +187,7 @@ impl Client {
|
||||
address: SocketAddr,
|
||||
server_hostname: &str,
|
||||
use_proxy: Option<u64>,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<Self> {
|
||||
// Establish the initial TCP connection
|
||||
let tcp_stream = establish_tcp_connection_with_timeout(address, use_proxy).await?;
|
||||
@@ -217,7 +225,7 @@ impl Client {
|
||||
let buffered_tcp_stream = client.into_inner();
|
||||
let tcp_stream = buffered_tcp_stream.into_inner();
|
||||
// Wrap the TCP stream in TLS encryption
|
||||
let tls_stream = establish_tls_stream(server_hostname, &[], tcp_stream).await?;
|
||||
let tls_stream = establish_tls_stream(server_hostname, &[], tcp_stream, dangerous).await?;
|
||||
// Wrap the TLS stream in a buffered writer
|
||||
let buffered_stream = BufWriter::new(tls_stream);
|
||||
// Create a SessionStream trait object for further communication
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::modules::account::dispatcher::STATUS_DISPATCHER;
|
||||
use crate::modules::account::entity::AuthType;
|
||||
use crate::modules::account::migration::{AccountModel, AccountType};
|
||||
@@ -51,7 +50,14 @@ impl ImapConnectionManager {
|
||||
async fn create_client(&self, account: &AccountModel) -> BichonResult<Client> {
|
||||
assert_eq!(account.account_type, AccountType::IMAP);
|
||||
let imap = account.imap.as_ref().unwrap();
|
||||
Client::connection(&imap.host, &imap.encryption, imap.port, imap.use_proxy).await
|
||||
Client::connection(
|
||||
&imap.host,
|
||||
&imap.encryption,
|
||||
imap.port,
|
||||
imap.use_proxy,
|
||||
account.use_dangerous,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn authenticate(
|
||||
|
||||
@@ -16,19 +16,21 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use mail_parser::MessageParser;
|
||||
|
||||
use crate::{base64_encode_url_safe, modules::{account::entity::Encryption, imap::client::Client}};
|
||||
use crate::{
|
||||
base64_encode_url_safe,
|
||||
modules::{account::entity::Encryption, imap::client::Client},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn testxx() {
|
||||
rustls::crypto::CryptoProvider::install_default(rustls::crypto::ring::default_provider())
|
||||
.unwrap();
|
||||
let client = Client::connection("imap.zoho.com".into(), &Encryption::Ssl, 993, None)
|
||||
let client = Client::connection("imap.zoho.com".into(), &Encryption::Ssl, 993, None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
let mut session = client.login("pollybase@zohomail.com", "xxx").await.unwrap();
|
||||
let mut session = client.login("xx@zohomail.com", "xxx").await.unwrap();
|
||||
session.select("INBOX").await.unwrap();
|
||||
let result = session.uid_search("LARGER 1024").await.unwrap();
|
||||
println!("{:#?}", result);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::modules::error::code::ErrorCode;
|
||||
use crate::modules::settings::proxy::Proxy;
|
||||
use crate::modules::utils::tls::establish_tls_stream;
|
||||
@@ -56,17 +55,19 @@ pub(crate) async fn establish_tcp_connection_with_timeout(
|
||||
Ok(Box::pin(timeout_stream))
|
||||
}
|
||||
|
||||
pub(crate) async fn establish_tls_connection(
|
||||
pub async fn establish_tls_connection(
|
||||
address: SocketAddr,
|
||||
server_hostname: &str,
|
||||
alpn_protocols: &[&str],
|
||||
use_proxy: Option<u64>,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<impl SessionStream> {
|
||||
// Establish the TCP connection with timeout
|
||||
let tcp_stream = establish_tcp_connection_with_timeout(address, use_proxy).await?;
|
||||
|
||||
// Wrap the TCP stream with TLS encryption
|
||||
let tls_stream = establish_tls_stream(server_hostname, alpn_protocols, tcp_stream).await?;
|
||||
let tls_stream =
|
||||
establish_tls_stream(server_hostname, alpn_protocols, tcp_stream, dangerous).await?;
|
||||
|
||||
// Return the TLS stream wrapped in a SessionStream
|
||||
Ok(tls_stream)
|
||||
|
||||
+72
-14
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use crate::{
|
||||
modules::{
|
||||
error::{code::ErrorCode, BichonResult},
|
||||
@@ -24,38 +23,44 @@ use crate::{
|
||||
},
|
||||
raise_error,
|
||||
};
|
||||
use rustls::RootCertStore;
|
||||
use rustls::{
|
||||
client::danger::{ServerCertVerified, ServerCertVerifier},
|
||||
RootCertStore,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub async fn establish_tls_stream(
|
||||
server_hostname: &str,
|
||||
alpn_protocols: &[&str],
|
||||
stream: impl SessionStream + 'static,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<impl SessionStream> {
|
||||
let tls_stream = establish_rustls_stream(server_hostname, alpn_protocols, stream).await?;
|
||||
let tls_stream =
|
||||
establish_rustls_stream(server_hostname, alpn_protocols, stream, dangerous).await?;
|
||||
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
|
||||
Ok(boxed_stream)
|
||||
}
|
||||
|
||||
pub async fn establish_rustls_stream(
|
||||
async fn establish_rustls_stream(
|
||||
server_hostname: &str,
|
||||
alpn_protocols: &[&str],
|
||||
stream: impl SessionStream,
|
||||
dangerous: bool,
|
||||
) -> BichonResult<impl SessionStream> {
|
||||
// Create a root certificate store and add default trusted roots
|
||||
let root_store = RootCertStore {
|
||||
roots: webpki_roots::TLS_SERVER_ROOTS.into(),
|
||||
};
|
||||
|
||||
// Configure the Rustls client with the root certs and no client authentication
|
||||
let mut config = rustls::ClientConfig::builder()
|
||||
//builder_with_provider(
|
||||
// rustls::crypto::ring::default_provider().into(),
|
||||
// )
|
||||
// .with_protocol_versions(&[&rustls::version::TLS13])
|
||||
// .unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
let mut config = if dangerous {
|
||||
rustls::ClientConfig::builder()
|
||||
.dangerous()
|
||||
.with_custom_certificate_verifier(Arc::new(SkipCertVerification))
|
||||
.with_no_client_auth()
|
||||
} else {
|
||||
rustls::ClientConfig::builder()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth()
|
||||
};
|
||||
|
||||
// Set the ALPN protocols
|
||||
config.alpn_protocols = alpn_protocols
|
||||
@@ -76,3 +81,56 @@ pub async fn establish_rustls_stream(
|
||||
|
||||
Ok(tls_stream)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SkipCertVerification;
|
||||
|
||||
impl ServerCertVerifier for SkipCertVerification {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_end_entity: &rustls::pki_types::CertificateDer<'_>,
|
||||
_intermediates: &[rustls::pki_types::CertificateDer<'_>],
|
||||
_server_name: &rustls::pki_types::ServerName<'_>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: rustls::pki_types::UnixTime,
|
||||
) -> Result<ServerCertVerified, rustls::Error> {
|
||||
// Always return a valid certificate verification result
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &rustls::pki_types::CertificateDer<'_>,
|
||||
_dss: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &rustls::pki_types::CertificateDer<'_>,
|
||||
_dss: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||
vec![
|
||||
rustls::SignatureScheme::RSA_PKCS1_SHA1,
|
||||
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
|
||||
rustls::SignatureScheme::RSA_PKCS1_SHA256,
|
||||
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
rustls::SignatureScheme::RSA_PKCS1_SHA384,
|
||||
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
rustls::SignatureScheme::RSA_PKCS1_SHA512,
|
||||
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
rustls::SignatureScheme::RSA_PSS_SHA256,
|
||||
rustls::SignatureScheme::RSA_PSS_SHA384,
|
||||
rustls::SignatureScheme::RSA_PSS_SHA512,
|
||||
rustls::SignatureScheme::ED25519,
|
||||
rustls::SignatureScheme::ED448,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user