1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#![cfg_attr(feature = "docs", feature(doc_cfg))]
#![warn(missing_docs)]
#![warn(missing_debug_implementations, rust_2018_idioms)]
#![doc(test(attr(deny(rust_2018_idioms, warnings))))]
#![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
#[macro_use]
extern crate log;
#[cfg(all(feature = "io-tokio", feature = "io-async-std"))]
compile_error!("only one of 'async-std' or 'async-tokio' features must be enabled");
#[cfg(any(feature = "io-tokio", feature = "io-async-std"))]
#[cfg_attr(feature = "docs", doc(cfg(any(feature = "io-tokio", feature = "io-async-std"))))]
pub mod async_io;
pub mod sync_io;
mod certificate;
mod error;
mod identity;
pub use certificate::Certificate;
pub use error::{Error, HandshakeError};
pub use identity::Identity;
use openssl::{error::ErrorStack, ssl::SslContextBuilder};
use std::result;
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug, Copy, Clone)]
#[non_exhaustive]
pub enum Protocol {
Sslv3,
Tlsv10,
Tlsv11,
Tlsv12,
}
#[cfg(have_min_max_version)]
fn supported_protocols(
min: Option<Protocol>,
max: Option<Protocol>,
ctx: &mut SslContextBuilder,
) -> std::result::Result<(), ErrorStack> {
use openssl::ssl::SslVersion;
fn cvt(p: Protocol) -> SslVersion {
match p {
Protocol::Sslv3 => SslVersion::SSL3,
Protocol::Tlsv10 => SslVersion::TLS1,
Protocol::Tlsv11 => SslVersion::TLS1_1,
Protocol::Tlsv12 => SslVersion::TLS1_2,
}
}
ctx.set_min_proto_version(min.map(cvt))?;
ctx.set_max_proto_version(max.map(cvt))?;
Ok(())
}
#[cfg(not(have_min_max_version))]
fn supported_protocols(
min: Option<Protocol>,
max: Option<Protocol>,
ctx: &mut SslContextBuilder,
) -> std::result::Result<(), ErrorStack> {
use openssl::ssl::SslOptions;
let no_ssl_mask = SslOptions::NO_SSLV2
| SslOptions::NO_SSLV3
| SslOptions::NO_TLSV1
| SslOptions::NO_TLSV1_1
| SslOptions::NO_TLSV1_2;
ctx.clear_options(no_ssl_mask);
let mut options = SslOptions::empty();
options |= match min {
None => SslOptions::empty(),
Some(Protocol::Sslv3) => SslOptions::NO_SSLV2,
Some(Protocol::Tlsv10) => SslOptions::NO_SSLV2 | SslOptions::NO_SSLV3,
Some(Protocol::Tlsv11) => SslOptions::NO_SSLV2 | SslOptions::NO_SSLV3 | SslOptions::NO_TLSV1,
Some(Protocol::Tlsv12) => {
SslOptions::NO_SSLV2 | SslOptions::NO_SSLV3 | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1
}
};
options |= match max {
None | Some(Protocol::Tlsv12) => SslOptions::empty(),
Some(Protocol::Tlsv11) => SslOptions::NO_TLSV1_2,
Some(Protocol::Tlsv10) => SslOptions::NO_TLSV1_1 | SslOptions::NO_TLSV1_2,
Some(Protocol::Sslv3) => SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1 | SslOptions::NO_TLSV1_2,
};
ctx.set_options(options);
Ok(())
}