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