1use std::sync::Arc;
7
8use foctet_core::id::NodeId;
9use rustls::{
10 client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
11 crypto::ring::cipher_suite::{
12 TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
13 },
14 pki_types::{CertificateDer, ServerName, UnixTime},
15 server::danger::{ClientCertVerified, ClientCertVerifier},
16 CertificateError, DigitallySignedStruct, DistinguishedName, OtherError, SignatureScheme,
17 SupportedCipherSuite, SupportedProtocolVersion,
18};
19
20use crate::tls::cert;
21
22pub(crate) static PROTOCOL_VERSIONS: &[&SupportedProtocolVersion] = &[&rustls::version::TLS13];
29pub(crate) static CIPHERSUITES: &[SupportedCipherSuite] = &[
33 TLS13_CHACHA20_POLY1305_SHA256,
35 TLS13_AES_256_GCM_SHA384,
36 TLS13_AES_128_GCM_SHA256,
37];
38
39#[derive(Debug)]
43pub(crate) struct FoctetCertificateVerifier {
44 remote_node_id: Option<NodeId>,
46}
47
48impl FoctetCertificateVerifier {
55 pub(crate) fn new() -> Self {
56 Self {
57 remote_node_id: None,
58 }
59 }
60 pub(crate) fn with_remote_node_id(remote_node_id: Option<NodeId>) -> Self {
61 Self { remote_node_id }
62 }
63
64 fn verification_schemes() -> Vec<SignatureScheme> {
69 vec![
70 SignatureScheme::ECDSA_NISTP384_SHA384,
72 SignatureScheme::ECDSA_NISTP256_SHA256,
73 SignatureScheme::ED25519,
75 SignatureScheme::RSA_PSS_SHA512,
78 SignatureScheme::RSA_PSS_SHA384,
79 SignatureScheme::RSA_PSS_SHA256,
80 SignatureScheme::RSA_PKCS1_SHA512,
81 SignatureScheme::RSA_PKCS1_SHA384,
82 SignatureScheme::RSA_PKCS1_SHA256,
83 ]
84 }
85}
86
87impl ServerCertVerifier for FoctetCertificateVerifier {
88 fn verify_server_cert(
89 &self,
90 end_entity: &CertificateDer,
91 intermediates: &[CertificateDer],
92 _server_name: &rustls::pki_types::ServerName,
93 _ocsp_response: &[u8],
94 _now: rustls::pki_types::UnixTime,
95 ) -> Result<ServerCertVerified, rustls::Error> {
96 let node_id = verify_presented_certs(end_entity, intermediates)?;
97
98 if let Some(remote_node_id) = self.remote_node_id {
99 if remote_node_id != node_id {
104 return Err(rustls::Error::InvalidCertificate(
105 CertificateError::ApplicationVerificationFailure,
106 ));
107 }
108 }
109
110 Ok(ServerCertVerified::assertion())
111 }
112
113 fn verify_tls12_signature(
114 &self,
115 _message: &[u8],
116 _cert: &CertificateDer,
117 _dss: &DigitallySignedStruct,
118 ) -> Result<HandshakeSignatureValid, rustls::Error> {
119 unreachable!("`PROTOCOL_VERSIONS` only allows TLS 1.3")
120 }
121
122 fn verify_tls13_signature(
123 &self,
124 message: &[u8],
125 cert: &CertificateDer,
126 dss: &DigitallySignedStruct,
127 ) -> Result<HandshakeSignatureValid, rustls::Error> {
128 verify_tls13_signature(cert, dss.scheme, message, dss.signature())
129 }
130
131 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
132 Self::verification_schemes()
133 }
134}
135
136impl ClientCertVerifier for FoctetCertificateVerifier {
144 fn offer_client_auth(&self) -> bool {
145 true
146 }
147
148 fn root_hint_subjects(&self) -> &[DistinguishedName] {
149 &[]
150 }
151
152 fn verify_client_cert(
153 &self,
154 end_entity: &CertificateDer,
155 intermediates: &[CertificateDer],
156 _now: rustls::pki_types::UnixTime,
157 ) -> Result<ClientCertVerified, rustls::Error> {
158 verify_presented_certs(end_entity, intermediates)?;
159
160 Ok(ClientCertVerified::assertion())
161 }
162
163 fn verify_tls12_signature(
164 &self,
165 _message: &[u8],
166 _cert: &CertificateDer,
167 _dss: &DigitallySignedStruct,
168 ) -> Result<HandshakeSignatureValid, rustls::Error> {
169 unreachable!("`PROTOCOL_VERSIONS` only allows TLS 1.3")
170 }
171
172 fn verify_tls13_signature(
173 &self,
174 message: &[u8],
175 cert: &CertificateDer,
176 dss: &DigitallySignedStruct,
177 ) -> Result<HandshakeSignatureValid, rustls::Error> {
178 verify_tls13_signature(cert, dss.scheme, message, dss.signature())
179 }
180
181 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
182 Self::verification_schemes()
183 }
184}
185
186fn verify_presented_certs(
193 end_entity: &CertificateDer,
194 intermediates: &[CertificateDer],
195) -> Result<NodeId, rustls::Error> {
196 if !intermediates.is_empty() {
197 return Err(rustls::Error::General(
198 "foctet-tls requires exactly one certificate".into(),
199 ));
200 }
201
202 let cert = match cert::parse(end_entity) {
203 Ok(cert) => cert,
204 Err(_) => {
205 return Err(rustls::Error::InvalidCertificate(
206 CertificateError::BadEncoding,
207 ))
208 }
209 };
210
211 Ok(cert.node_id())
212}
213
214fn verify_tls13_signature(
215 cert: &CertificateDer,
216 signature_scheme: SignatureScheme,
217 message: &[u8],
218 signature: &[u8],
219) -> Result<HandshakeSignatureValid, rustls::Error> {
220 match cert::parse(cert)?.verify_signature(signature_scheme, message, signature) {
221 Ok(()) => {}
222 Err(_) => {
223 return Err(rustls::Error::InvalidCertificate(
224 CertificateError::BadSignature,
225 ))
226 }
227 }
228
229 Ok(HandshakeSignatureValid::assertion())
230}
231
232impl From<cert::ParseError> for rustls::Error {
233 fn from(cert::ParseError(e): cert::ParseError) -> Self {
234 use webpki::Error::*;
235 match e {
236 BadDer => rustls::Error::InvalidCertificate(CertificateError::BadEncoding),
237 e => {
238 rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(Arc::new(e))))
239 }
240 }
241 }
242}
243impl From<cert::VerificationError> for rustls::Error {
244 fn from(cert::VerificationError(e): cert::VerificationError) -> Self {
245 use webpki::Error::*;
246 match e {
247 InvalidSignatureForPublicKey => {
248 rustls::Error::InvalidCertificate(CertificateError::BadSignature)
249 }
250 other => rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(
251 Arc::new(other),
252 ))),
253 }
254 }
255}
256
257#[derive(Debug)]
260pub struct SkipServerVerification(Arc<rustls::crypto::CryptoProvider>);
261
262impl SkipServerVerification {
263 #[allow(dead_code)]
264 pub fn new() -> Arc<Self> {
265 Arc::new(Self(Arc::new(rustls::crypto::ring::default_provider())))
266 }
267}
268
269impl ServerCertVerifier for SkipServerVerification {
270 fn verify_server_cert(
271 &self,
272 _end_entity: &CertificateDer<'_>,
273 _intermediates: &[CertificateDer<'_>],
274 _server_name: &ServerName<'_>,
275 _ocsp: &[u8],
276 _now: UnixTime,
277 ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
278 Ok(rustls::client::danger::ServerCertVerified::assertion())
279 }
280
281 fn verify_tls12_signature(
282 &self,
283 message: &[u8],
284 cert: &CertificateDer<'_>,
285 dss: &rustls::DigitallySignedStruct,
286 ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
287 rustls::crypto::verify_tls12_signature(
288 message,
289 cert,
290 dss,
291 &self.0.signature_verification_algorithms,
292 )
293 }
294
295 fn verify_tls13_signature(
296 &self,
297 message: &[u8],
298 cert: &CertificateDer<'_>,
299 dss: &rustls::DigitallySignedStruct,
300 ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
301 rustls::crypto::verify_tls13_signature(
302 message,
303 cert,
304 dss,
305 &self.0.signature_verification_algorithms,
306 )
307 }
308
309 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
310 self.0.signature_verification_algorithms.supported_schemes()
311 }
312}