1#![feature(test)]
8
9#[macro_use]
10extern crate log;
11
12extern crate test;
13
14use std::any;
15use std::str;
16
17#[macro_use]
18mod t;
19
20mod alpn;
21pub mod benches;
22mod client_server;
23mod client_server_dyn;
24mod google;
25mod version;
26
27pub use alpn::test_alpn;
28pub use client_server::test_client_server_der;
29pub use client_server::test_client_server_pkcs12;
30pub use client_server_dyn::test_client_server_dyn_der;
31pub use client_server_dyn::test_client_server_dyn_pkcs12;
32pub use google::test_google;
33pub use version::test_version;
34
35mod gen;
36pub use gen::gen_tests_and_benches;
37
38use tls_api::TlsAcceptor;
39use tls_api::TlsAcceptorBox;
40use tls_api::TlsAcceptorBuilder;
41use tls_api::TlsAcceptorBuilderBox;
42use tls_api::TlsAcceptorType;
43use tls_api::TlsConnector;
44use tls_api::TlsConnectorBox;
45use tls_api::TlsConnectorBuilder;
46use tls_api::TlsConnectorBuilderBox;
47use tls_api::TlsConnectorType;
48
49use std::net::ToSocketAddrs;
50
51#[cfg(feature = "runtime-async-std")]
52pub use async_std::net::TcpListener;
53#[cfg(feature = "runtime-async-std")]
54pub use async_std::net::TcpStream;
55
56#[cfg(feature = "runtime-tokio")]
57pub use tokio::net::TcpListener;
58#[cfg(feature = "runtime-tokio")]
59pub use tokio::net::TcpStream;
60
61#[cfg(feature = "runtime-async-std")]
62pub use async_std::task::block_on;
63
64#[cfg(feature = "runtime-tokio")]
65pub fn block_on<F, T>(future: F) -> T
66where
67 F: std::future::Future<Output = T>,
68{
69 t!(tokio::runtime::Runtime::new()).block_on(future)
70}
71
72async fn connect_bad_hostname_impl<C: TlsConnector, F: FnOnce(anyhow::Error)>(check_error: F) {
73 drop(env_logger::try_init());
74
75 if !C::IMPLEMENTED {
76 eprintln!(
77 "connector {} is not implemented; skipping",
78 any::type_name::<C>()
79 );
80 return;
81 }
82
83 let addr = t!("google.com:443".to_socket_addrs()).next().unwrap();
85
86 let connector: C = C::builder().expect("builder").build().expect("build");
87 let tcp_stream = t!(TcpStream::connect(addr).await);
88 let error = connector
89 .connect("goggle.com", tcp_stream)
90 .await
91 .unwrap_err();
92 check_error(error);
93}
94
95pub fn connect_bad_hostname<C: TlsConnector, F: FnOnce(anyhow::Error)>(check_error: F) {
96 block_on(connect_bad_hostname_impl::<C, F>(check_error))
97}
98
99async fn connect_bad_hostname_ignored_impl<C: TlsConnector>() {
100 drop(env_logger::try_init());
101
102 if !C::IMPLEMENTED {
103 eprintln!(
104 "connector {} is not implemented; skipping",
105 any::type_name::<C>()
106 );
107 return;
108 }
109
110 let addr = t!("google.com:443".to_socket_addrs()).next().unwrap();
112
113 let tcp_stream = t!(TcpStream::connect(addr).await);
114
115 let mut builder = C::builder().expect("builder");
116 builder
117 .set_verify_hostname(false)
118 .expect("set_verify_hostname");
119 let connector: C = builder.build().expect("build");
120 t!(connector.connect("ignore", tcp_stream).await);
121}
122
123pub fn connect_bad_hostname_ignored<C: TlsConnector>() {
124 block_on(connect_bad_hostname_ignored_impl::<C>())
125}
126
127fn new_acceptor_builder_from_pkcs12_keys<A>() -> A::Builder
128where
129 A: TlsAcceptor,
130{
131 t!(A::builder_from_pkcs12(
132 &test_cert_gen::keys().server.cert_and_key_pkcs12.pkcs12.0,
133 &test_cert_gen::keys().server.cert_and_key_pkcs12.password,
134 ))
135}
136
137fn new_acceptor_builder_from_der_keys<A>() -> A::Builder
138where
139 A: TlsAcceptor,
140{
141 let keys = &test_cert_gen::keys().server.cert_and_key;
142 t!(A::builder_from_der_key(
143 keys.cert.get_der(),
144 keys.key.get_der()
145 ))
146}
147
148#[allow(dead_code)]
149fn new_acceptor_from_der_keys<A: TlsAcceptor>() -> A {
150 new_acceptor_builder_from_der_keys::<A>().build().unwrap()
151}
152
153fn new_acceptor_builder_dyn_from_pkcs12_keys(
154 acceptor: &dyn TlsAcceptorType,
155) -> TlsAcceptorBuilderBox {
156 t!(acceptor.builder_from_pkcs12(
157 &test_cert_gen::keys().server.cert_and_key_pkcs12.pkcs12.0,
158 &test_cert_gen::keys().server.cert_and_key_pkcs12.password,
159 ))
160}
161
162fn new_acceptor_builder_dyn_from_der_keys(acceptor: &dyn TlsAcceptorType) -> TlsAcceptorBuilderBox {
163 let keys = &test_cert_gen::keys().server.cert_and_key;
164 t!(acceptor.builder_from_der_key(keys.cert.get_der(), keys.key.get_der()))
165}
166
167#[allow(dead_code)]
168fn new_acceptor_dyn_from_der_keys(acceptor: &dyn TlsAcceptorType) -> TlsAcceptorBox {
169 new_acceptor_builder_dyn_from_der_keys(acceptor)
170 .build()
171 .unwrap()
172}
173
174pub enum AcceptorKeyKind {
175 Pkcs12,
176 Der,
177}
178
179fn new_acceptor<A>(key: Option<AcceptorKeyKind>) -> A::Builder
180where
181 A: TlsAcceptor,
182{
183 match key {
184 Some(AcceptorKeyKind::Der) => new_acceptor_builder_from_der_keys::<A>(),
185 Some(AcceptorKeyKind::Pkcs12) => new_acceptor_builder_from_pkcs12_keys::<A>(),
186 None => {
187 if A::SUPPORTS_PKCS12_KEYS {
188 new_acceptor_builder_from_pkcs12_keys::<A>()
189 } else if A::SUPPORTS_DER_KEYS {
190 new_acceptor_builder_from_der_keys::<A>()
191 } else {
192 panic!(
193 "no constructor supported for acceptor {}",
194 any::type_name::<A>()
195 );
196 }
197 }
198 }
199}
200
201fn new_acceptor_dyn(
202 acceptor: &dyn TlsAcceptorType,
203 key: Option<AcceptorKeyKind>,
204) -> TlsAcceptorBuilderBox {
205 match key {
206 Some(AcceptorKeyKind::Der) => new_acceptor_builder_dyn_from_der_keys(acceptor),
207 Some(AcceptorKeyKind::Pkcs12) => new_acceptor_builder_dyn_from_pkcs12_keys(acceptor),
208 None => {
209 if acceptor.supports_pkcs12_keys() {
210 new_acceptor_builder_dyn_from_pkcs12_keys(acceptor)
211 } else if acceptor.supports_der_keys() {
212 new_acceptor_builder_dyn_from_der_keys(acceptor)
213 } else {
214 panic!("no constructor supported for acceptor {}", acceptor);
215 }
216 }
217 }
218}
219
220fn new_connector_builder_with_root_ca<C: TlsConnector>() -> C::Builder {
221 let keys = test_cert_gen::keys();
222 let root_ca = &keys.client.ca;
223
224 let mut connector = C::builder().expect("connector builder");
225 t!(connector.add_root_certificate(root_ca.get_der()));
226 connector
227}
228
229fn new_connector_with_root_ca<C: TlsConnector>() -> C {
230 new_connector_builder_with_root_ca::<C>().build().unwrap()
231}
232
233fn new_connector_builder_dyn_with_root_ca(
234 connector: &dyn TlsConnectorType,
235) -> TlsConnectorBuilderBox {
236 let keys = test_cert_gen::keys();
237 let root_ca = &keys.client.ca;
238
239 let mut connector = connector.builder().expect("connector builder");
240 t!(connector.add_root_certificate(root_ca.get_der()));
241 connector
242}
243
244#[allow(dead_code)]
245fn new_connector_dyn_with_root_ca(connector: &dyn TlsConnectorType) -> TlsConnectorBox {
246 new_connector_builder_dyn_with_root_ca(connector)
247 .build()
248 .unwrap()
249}
250
251pub const BIND_HOST: &str = "127.0.0.1";