mirror of
https://github.com/Devolutions/IronRDP.git
synced 2025-12-23 12:26:46 +00:00
feat(ironrdp-tls)!: return x509_cert::Certificate from upgrade() (#1054)
Some checks failed
CI / Check formatting (push) Has been cancelled
CI / Check typos (push) Has been cancelled
Coverage / Coverage Report (push) Has been cancelled
Release crates / Open release PR (push) Has been cancelled
Release crates / Release crates (push) Has been cancelled
CI / Fuzzing (push) Has been cancelled
CI / Web Client (push) Has been cancelled
CI / FFI (push) Has been cancelled
CI / Success (push) Has been cancelled
CI / Checks [linux] (push) Has been cancelled
CI / Checks [macos] (push) Has been cancelled
CI / Checks [windows] (push) Has been cancelled
Some checks failed
CI / Check formatting (push) Has been cancelled
CI / Check typos (push) Has been cancelled
Coverage / Coverage Report (push) Has been cancelled
Release crates / Open release PR (push) Has been cancelled
Release crates / Release crates (push) Has been cancelled
CI / Fuzzing (push) Has been cancelled
CI / Web Client (push) Has been cancelled
CI / FFI (push) Has been cancelled
CI / Success (push) Has been cancelled
CI / Checks [linux] (push) Has been cancelled
CI / Checks [macos] (push) Has been cancelled
CI / Checks [windows] (push) Has been cancelled
This allows client applications to verify details of the certificate, possibly with the user, when connecting to a server using TLS.
This commit is contained in:
parent
b50b648344
commit
bd2aed7686
6 changed files with 25 additions and 27 deletions
|
|
@ -229,7 +229,7 @@ async fn connect(
|
|||
// Ensure there is no leftover
|
||||
let (initial_stream, leftover_bytes) = framed.into_inner();
|
||||
|
||||
let (upgraded_stream, server_public_key) = ironrdp_tls::upgrade(initial_stream, config.destination.name())
|
||||
let (upgraded_stream, tls_cert) = ironrdp_tls::upgrade(initial_stream, config.destination.name())
|
||||
.await
|
||||
.map_err(|e| connector::custom_err!("TLS upgrade", e))?;
|
||||
|
||||
|
|
@ -238,13 +238,15 @@ async fn connect(
|
|||
let erased_stream: Box<dyn AsyncReadWrite + Unpin + Send + Sync> = Box::new(upgraded_stream);
|
||||
let mut upgraded_framed = ironrdp_tokio::TokioFramed::new_with_leftover(erased_stream, leftover_bytes);
|
||||
|
||||
let server_public_key = ironrdp_tls::extract_tls_server_public_key(&tls_cert)
|
||||
.ok_or_else(|| connector::general_err!("unable to extract tls server public key"))?;
|
||||
let connection_result = ironrdp_tokio::connect_finalize(
|
||||
upgraded,
|
||||
connector,
|
||||
&mut upgraded_framed,
|
||||
&mut ReqwestNetworkClient::new(),
|
||||
(&config.destination).into(),
|
||||
server_public_key,
|
||||
server_public_key.to_owned(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
|
|
|||
|
|
@ -205,18 +205,20 @@ where
|
|||
.await
|
||||
.expect("begin connection");
|
||||
let initial_stream = framed.into_inner_no_leftover();
|
||||
let (upgraded_stream, server_public_key) = ironrdp_tls::upgrade(initial_stream, "localhost")
|
||||
let (upgraded_stream, tls_cert) = ironrdp_tls::upgrade(initial_stream, "localhost")
|
||||
.await
|
||||
.expect("TLS upgrade");
|
||||
let upgraded = ironrdp_tokio::mark_as_upgraded(should_upgrade, &mut connector);
|
||||
let mut upgraded_framed = ironrdp_tokio::TokioFramed::new(upgraded_stream);
|
||||
let server_public_key =
|
||||
ironrdp_tls::extract_tls_server_public_key(&tls_cert).expect("extract server public key");
|
||||
let connection_result = ironrdp_async::connect_finalize(
|
||||
upgraded,
|
||||
connector,
|
||||
&mut upgraded_framed,
|
||||
&mut ironrdp_tokio::reqwest::ReqwestNetworkClient::new(),
|
||||
"localhost".into(),
|
||||
server_public_key,
|
||||
server_public_key.to_owned(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ stub = []
|
|||
|
||||
[dependencies]
|
||||
tokio = { version = "1.47" }
|
||||
x509-cert = { version = "0.2", default-features = false, features = ["std"], optional = true }
|
||||
x509-cert = { version = "0.2", default-features = false, features = ["std"], optional = true } # public
|
||||
tokio-native-tls = { version = "0.3", optional = true } # public
|
||||
tokio-rustls = { version = "0.26", optional = true } # public
|
||||
|
||||
|
|
|
|||
|
|
@ -25,21 +25,9 @@ compile_error!("a TLS backend must be selected by enabling a single feature out
|
|||
#[cfg(any(feature = "stub", feature = "native-tls", feature = "rustls"))]
|
||||
pub use impl_::{upgrade, TlsStream};
|
||||
|
||||
#[cfg(any(feature = "native-tls", feature = "rustls"))]
|
||||
pub(crate) fn extract_tls_server_public_key(cert: &[u8]) -> std::io::Result<Vec<u8>> {
|
||||
use std::io;
|
||||
|
||||
use x509_cert::der::Decode as _;
|
||||
|
||||
let cert = x509_cert::Certificate::from_der(cert).map_err(io::Error::other)?;
|
||||
|
||||
let server_public_key = cert
|
||||
.tbs_certificate
|
||||
pub fn extract_tls_server_public_key(cert: &x509_cert::Certificate) -> Option<&[u8]> {
|
||||
cert.tbs_certificate
|
||||
.subject_public_key_info
|
||||
.subject_public_key
|
||||
.as_bytes()
|
||||
.ok_or_else(|| io::Error::other("subject public key BIT STRING is not aligned"))?
|
||||
.to_owned();
|
||||
|
||||
Ok(server_public_key)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt as _};
|
|||
|
||||
pub type TlsStream<S> = tokio_native_tls::TlsStream<S>;
|
||||
|
||||
pub async fn upgrade<S>(stream: S, server_name: &str) -> io::Result<(TlsStream<S>, Vec<u8>)>
|
||||
pub async fn upgrade<S>(stream: S, server_name: &str) -> io::Result<(TlsStream<S>, x509_cert::Certificate)>
|
||||
where
|
||||
S: Unpin + AsyncRead + AsyncWrite,
|
||||
{
|
||||
|
|
@ -24,15 +24,18 @@ where
|
|||
|
||||
tls_stream.flush().await?;
|
||||
|
||||
let server_public_key = {
|
||||
let tls_cert = {
|
||||
use x509_cert::der::Decode as _;
|
||||
|
||||
let cert = tls_stream
|
||||
.get_ref()
|
||||
.peer_certificate()
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "peer certificate is missing"))?;
|
||||
let cert = cert.to_der().map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
||||
crate::extract_tls_server_public_key(&cert)?
|
||||
|
||||
x509_cert::Certificate::from_der(&cert).map_err(io::Error::other)?
|
||||
};
|
||||
|
||||
Ok((tls_stream, server_public_key))
|
||||
Ok((tls_stream, tls_cert))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use tokio_rustls::rustls::pki_types::ServerName;
|
|||
|
||||
pub type TlsStream<S> = tokio_rustls::client::TlsStream<S>;
|
||||
|
||||
pub async fn upgrade<S>(stream: S, server_name: &str) -> io::Result<(TlsStream<S>, Vec<u8>)>
|
||||
pub async fn upgrade<S>(stream: S, server_name: &str) -> io::Result<(TlsStream<S>, x509_cert::Certificate)>
|
||||
where
|
||||
S: Unpin + AsyncRead + AsyncWrite,
|
||||
{
|
||||
|
|
@ -35,17 +35,20 @@ where
|
|||
|
||||
tls_stream.flush().await?;
|
||||
|
||||
let server_public_key = {
|
||||
let tls_cert = {
|
||||
use x509_cert::der::Decode as _;
|
||||
|
||||
let cert = tls_stream
|
||||
.get_ref()
|
||||
.1
|
||||
.peer_certificates()
|
||||
.and_then(|certificates| certificates.first())
|
||||
.ok_or_else(|| io::Error::other("peer certificate is missing"))?;
|
||||
crate::extract_tls_server_public_key(cert)?
|
||||
|
||||
x509_cert::Certificate::from_der(cert).map_err(io::Error::other)?
|
||||
};
|
||||
|
||||
Ok((tls_stream, server_public_key))
|
||||
Ok((tls_stream, tls_cert))
|
||||
}
|
||||
|
||||
mod danger {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue