tls.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // SPDX-License-Identifier: AGPL-3.0-or-later
  2. //! This module contains types which contribute to the configuration of TLS.
  3. use std::sync::Arc;
  4. use btlib::{
  5. crypto::{Creds, CredsPriv, HashKind, Scheme, Sign, Verifier},
  6. BlockPath, Principal, Writecap,
  7. };
  8. use core::ops::Deref;
  9. use log::error;
  10. use quinn::{ClientConfig, ServerConfig};
  11. use rustls::{
  12. client::{HandshakeSignatureValid, ResolvesClientCert},
  13. internal::msgs::base::PayloadU16,
  14. server::{ClientCertVerified, ResolvesServerCert},
  15. sign::{CertifiedKey, SigningKey},
  16. Certificate, ConfigBuilder, ConfigSide, SignatureAlgorithm, SignatureScheme, WantsCipherSuites,
  17. WantsVerifier,
  18. };
  19. use crate::Result;
  20. pub(crate) fn server_config(resolver: Arc<CertResolver>) -> Result<ServerConfig> {
  21. let server_config = common_config(rustls::ServerConfig::builder())?
  22. .with_client_cert_verifier(Arc::new(ClientCertVerifier))
  23. .with_cert_resolver(resolver);
  24. Ok(ServerConfig::with_crypto(Arc::new(server_config)))
  25. }
  26. pub(crate) fn client_config(
  27. server_path: Arc<BlockPath>,
  28. resolver: Arc<CertResolver>,
  29. ) -> Result<ClientConfig> {
  30. let client_config = common_config(rustls::ClientConfig::builder())?
  31. .with_custom_certificate_verifier(Arc::new(ServerCertVerifier::new(server_path)))
  32. .with_client_cert_resolver(resolver);
  33. Ok(ClientConfig::new(Arc::new(client_config)))
  34. }
  35. fn common_config<Side: ConfigSide>(
  36. builder: ConfigBuilder<Side, WantsCipherSuites>,
  37. ) -> Result<ConfigBuilder<Side, WantsVerifier>> {
  38. builder
  39. .with_cipher_suites(&[rustls::cipher_suite::TLS13_AES_128_GCM_SHA256])
  40. .with_kx_groups(&[&rustls::kx_group::SECP256R1])
  41. .with_protocol_versions(&[&rustls::version::TLS13])
  42. .map_err(|err| err.into())
  43. }
  44. fn to_cert_err(err: btlib::Error) -> rustls::Error {
  45. rustls::Error::InvalidCertificateData(err.to_string())
  46. }
  47. fn verify_tls13_signature(
  48. message: &[u8],
  49. cert: &Certificate,
  50. dss: &rustls::DigitallySignedStruct,
  51. ) -> std::result::Result<(), rustls::Error> {
  52. let (_, subject_key) = Writecap::from_cert_chain(cert, &[]).map_err(to_cert_err)?;
  53. subject_key
  54. .verify(&mut std::iter::once(message), dss.signature())
  55. .map_err(|_| rustls::Error::InvalidCertificateSignature)?;
  56. Ok(())
  57. }
  58. /// Verifier for the certificate chain presented by the server.
  59. struct ServerCertVerifier {
  60. server_path: Arc<BlockPath>,
  61. }
  62. impl ServerCertVerifier {
  63. fn new(server_path: Arc<BlockPath>) -> Self {
  64. Self { server_path }
  65. }
  66. }
  67. impl rustls::client::ServerCertVerifier for ServerCertVerifier {
  68. fn verify_server_cert(
  69. &self,
  70. end_entity: &Certificate,
  71. intermediates: &[Certificate],
  72. _server_name: &rustls::ServerName,
  73. _scts: &mut dyn Iterator<Item = &[u8]>,
  74. _ocsp_response: &[u8],
  75. _now: std::time::SystemTime,
  76. ) -> std::result::Result<rustls::client::ServerCertVerified, rustls::Error> {
  77. let (writecap, ..) =
  78. Writecap::from_cert_chain(end_entity, intermediates).map_err(to_cert_err)?;
  79. let path = writecap.bind_path();
  80. if &path != self.server_path.as_ref() {
  81. return Err(rustls::Error::InvalidCertificateData(format!(
  82. "expected writecap with path '{}' got writecap with path '{path}'",
  83. self.server_path
  84. )));
  85. }
  86. writecap.assert_valid_for(&path).map_err(to_cert_err)?;
  87. Ok(rustls::client::ServerCertVerified::assertion())
  88. }
  89. fn verify_tls13_signature(
  90. &self,
  91. message: &[u8],
  92. cert: &Certificate,
  93. dss: &rustls::DigitallySignedStruct,
  94. ) -> std::result::Result<rustls::client::HandshakeSignatureValid, rustls::Error> {
  95. verify_tls13_signature(message, cert, dss)?;
  96. Ok(HandshakeSignatureValid::assertion())
  97. }
  98. }
  99. /// Verifier for the certificate chain presented by the client.
  100. struct ClientCertVerifier;
  101. impl rustls::server::ClientCertVerifier for ClientCertVerifier {
  102. fn verify_client_cert(
  103. &self,
  104. end_entity: &Certificate,
  105. intermediates: &[Certificate],
  106. _now: std::time::SystemTime,
  107. ) -> std::result::Result<rustls::server::ClientCertVerified, rustls::Error> {
  108. let (writecap, ..) =
  109. Writecap::from_cert_chain(end_entity, intermediates).map_err(to_cert_err)?;
  110. writecap
  111. .assert_valid_for(writecap.path())
  112. .map_err(to_cert_err)?;
  113. Ok(ClientCertVerified::assertion())
  114. }
  115. fn client_auth_root_subjects(&self) -> Option<rustls::DistinguishedNames> {
  116. let der = match Principal::default().to_name_der() {
  117. Ok(der) => der,
  118. Err(err) => {
  119. error!("failed to create distinguished name from root principal: {err}");
  120. return None;
  121. }
  122. };
  123. Some(vec![PayloadU16(der)])
  124. }
  125. fn verify_tls13_signature(
  126. &self,
  127. message: &[u8],
  128. cert: &Certificate,
  129. dss: &rustls::DigitallySignedStruct,
  130. ) -> std::result::Result<rustls::client::HandshakeSignatureValid, rustls::Error> {
  131. verify_tls13_signature(message, cert, dss)?;
  132. Ok(rustls::client::HandshakeSignatureValid::assertion())
  133. }
  134. }
  135. pub(crate) struct CertResolver {
  136. cert_key: Arc<CertifiedKey>,
  137. }
  138. impl CertResolver {
  139. pub(crate) fn new<C: Creds + Send + Sync + 'static>(creds: Arc<C>) -> Result<Self> {
  140. let writecap = creds.writecap().ok_or(btlib::BlockError::MissingWritecap)?;
  141. let chain = writecap.to_cert_chain(creds.public_sign())?;
  142. let mut certs = Vec::with_capacity(chain.len());
  143. for cert in chain {
  144. certs.push(Certificate(cert))
  145. }
  146. let key = Arc::new(CredRef::new(creds));
  147. let cert_key = Arc::new(CertifiedKey {
  148. cert: certs,
  149. key,
  150. ocsp: None,
  151. sct_list: None,
  152. });
  153. Ok(Self { cert_key })
  154. }
  155. }
  156. impl ResolvesClientCert for CertResolver {
  157. fn resolve(
  158. &self,
  159. _acceptable_issuers: &[&[u8]],
  160. _sigschemes: &[rustls::SignatureScheme],
  161. ) -> Option<Arc<rustls::sign::CertifiedKey>> {
  162. Some(self.cert_key.clone())
  163. }
  164. fn has_certs(&self) -> bool {
  165. true
  166. }
  167. }
  168. impl ResolvesServerCert for CertResolver {
  169. fn resolve(
  170. &self,
  171. _client_hello: rustls::server::ClientHello,
  172. ) -> Option<Arc<rustls::sign::CertifiedKey>> {
  173. Some(self.cert_key.clone())
  174. }
  175. }
  176. trait SignExt {
  177. fn as_signature_scheme(&self) -> rustls::SignatureScheme;
  178. fn as_signature_algorithm(&self) -> rustls::SignatureAlgorithm;
  179. }
  180. impl SignExt for Sign {
  181. fn as_signature_scheme(&self) -> SignatureScheme {
  182. match self {
  183. Self::RsaSsaPss(scheme) => match scheme.hash_kind() {
  184. HashKind::Sha2_256 => SignatureScheme::RSA_PSS_SHA256,
  185. HashKind::Sha2_512 => SignatureScheme::RSA_PSS_SHA512,
  186. },
  187. }
  188. }
  189. fn as_signature_algorithm(&self) -> SignatureAlgorithm {
  190. match self {
  191. Self::RsaSsaPss(..) => SignatureAlgorithm::RSA,
  192. }
  193. }
  194. }
  195. /// A new type around `Arc<C>` which allows rustls' traits to be implemented.
  196. struct CredRef<C> {
  197. creds: Arc<C>,
  198. }
  199. impl<C> CredRef<C> {
  200. fn new(creds: Arc<C>) -> Self {
  201. Self { creds }
  202. }
  203. }
  204. impl<C> Deref for CredRef<C> {
  205. type Target = C;
  206. fn deref(&self) -> &Self::Target {
  207. &self.creds
  208. }
  209. }
  210. impl<C: CredsPriv + Send + Sync + 'static> SigningKey for CredRef<C> {
  211. fn choose_scheme(
  212. &self,
  213. offered: &[rustls::SignatureScheme],
  214. ) -> Option<Box<dyn rustls::sign::Signer>> {
  215. if offered.contains(&self.sign_kind().as_signature_scheme()) {
  216. Some(Box::new(Self::new(self.creds.clone())))
  217. } else {
  218. None
  219. }
  220. }
  221. fn algorithm(&self) -> rustls::SignatureAlgorithm {
  222. self.sign_kind().as_signature_algorithm()
  223. }
  224. }
  225. impl<C: CredsPriv + Send + Sync> rustls::sign::Signer for CredRef<C> {
  226. fn sign(&self, message: &[u8]) -> std::result::Result<Vec<u8>, rustls::Error> {
  227. self.creds
  228. .sign(&mut std::iter::once(message))
  229. .map(|sig| sig.take_data())
  230. .map_err(|err| rustls::Error::General(err.to_string()))
  231. }
  232. fn scheme(&self) -> rustls::SignatureScheme {
  233. self.sign_kind().as_signature_scheme()
  234. }
  235. }