1 // This program does benchmarking of the functions in verify.rs,
2 // that do certificate chain validation and signature verification.
3 //
4 // Note: we don't use any of the standard 'cargo bench', 'test::Bencher',
5 // etc. because it's unstable at the time of writing.
6
7 use std::time::{Duration, Instant};
8
9 use crate::anchors;
10 use crate::error::TLSError;
11 use crate::key;
12 use crate::verify;
13 use crate::verify::ServerCertVerifier;
14 use webpki;
15
16 use webpki_roots;
17
duration_nanos(d: Duration) -> u6418 fn duration_nanos(d: Duration) -> u64 {
19 ((d.as_secs() as f64) * 1e9 + (d.subsec_nanos() as f64)) as u64
20 }
21
bench<Fsetup, Ftest, S>(count: usize, name: &'static str, f_setup: Fsetup, f_test: Ftest) where Fsetup: Fn() -> S, Ftest: Fn(S),22 fn bench<Fsetup, Ftest, S>(count: usize, name: &'static str, f_setup: Fsetup, f_test: Ftest)
23 where
24 Fsetup: Fn() -> S,
25 Ftest: Fn(S),
26 {
27 let mut times = Vec::new();
28
29 for _ in 0..count {
30 let state = f_setup();
31 let start = Instant::now();
32 f_test(state);
33 times.push(duration_nanos(Instant::now().duration_since(start)));
34 }
35
36 println!("{}: min {:?}us", name, times.iter().min().unwrap() / 1000);
37 }
38
fixed_time() -> Result<webpki::Time, TLSError>39 fn fixed_time() -> Result<webpki::Time, TLSError> {
40 Ok(webpki::Time::from_seconds_since_unix_epoch(1500000000))
41 }
42
43 static V: &'static verify::WebPKIVerifier = &verify::WebPKIVerifier { time: fixed_time };
44
45 #[test]
test_reddit_cert()46 fn test_reddit_cert() {
47 let cert0 = key::Certificate(include_bytes!("testdata/cert-reddit.0.der").to_vec());
48 let cert1 = key::Certificate(include_bytes!("testdata/cert-reddit.1.der").to_vec());
49 let chain = [cert0, cert1];
50 let mut anchors = anchors::RootCertStore::empty();
51 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
52 bench(
53 100,
54 "verify_server_cert(reddit)",
55 || (),
56 |_| {
57 let dns_name = webpki::DNSNameRef::try_from_ascii_str("reddit.com").unwrap();
58 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
59 .unwrap();
60 },
61 );
62 }
63
64 #[test]
test_github_cert()65 fn test_github_cert() {
66 let cert0 = key::Certificate(include_bytes!("testdata/cert-github.0.der").to_vec());
67 let cert1 = key::Certificate(include_bytes!("testdata/cert-github.1.der").to_vec());
68 let chain = [cert0, cert1];
69 let mut anchors = anchors::RootCertStore::empty();
70 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
71 bench(
72 100,
73 "verify_server_cert(github)",
74 || (),
75 |_| {
76 let dns_name = webpki::DNSNameRef::try_from_ascii_str("github.com").unwrap();
77 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
78 .unwrap();
79 },
80 );
81 }
82
83 #[test]
test_arstechnica_cert()84 fn test_arstechnica_cert() {
85 let cert0 = key::Certificate(include_bytes!("testdata/cert-arstechnica.0.der").to_vec());
86 let cert1 = key::Certificate(include_bytes!("testdata/cert-arstechnica.1.der").to_vec());
87 let cert2 = key::Certificate(include_bytes!("testdata/cert-arstechnica.2.der").to_vec());
88 let chain = [cert0, cert1, cert2];
89 let mut anchors = anchors::RootCertStore::empty();
90 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
91 bench(
92 100,
93 "verify_server_cert(arstechnica)",
94 || (),
95 |_| {
96 let dns_name = webpki::DNSNameRef::try_from_ascii_str("arstechnica.com").unwrap();
97 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
98 .unwrap();
99 },
100 );
101 }
102
103 #[test]
test_servo_cert()104 fn test_servo_cert() {
105 let cert0 = key::Certificate(include_bytes!("testdata/cert-servo.0.der").to_vec());
106 let cert1 = key::Certificate(include_bytes!("testdata/cert-servo.1.der").to_vec());
107 let cert2 = key::Certificate(include_bytes!("testdata/cert-servo.2.der").to_vec());
108 let chain = [cert0, cert1, cert2];
109 let mut anchors = anchors::RootCertStore::empty();
110 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
111 bench(
112 100,
113 "verify_server_cert(servo)",
114 || (),
115 |_| {
116 let dns_name = webpki::DNSNameRef::try_from_ascii_str("servo.org").unwrap();
117 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
118 .unwrap();
119 },
120 );
121 }
122
123 #[test]
test_twitter_cert()124 fn test_twitter_cert() {
125 let cert0 = key::Certificate(include_bytes!("testdata/cert-twitter.0.der").to_vec());
126 let cert1 = key::Certificate(include_bytes!("testdata/cert-twitter.1.der").to_vec());
127 let chain = [cert0, cert1];
128 let mut anchors = anchors::RootCertStore::empty();
129 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
130 bench(
131 100,
132 "verify_server_cert(twitter)",
133 || (),
134 |_| {
135 let dns_name = webpki::DNSNameRef::try_from_ascii_str("twitter.com").unwrap();
136 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
137 .unwrap();
138 },
139 );
140 }
141
142 #[test]
test_wikipedia_cert()143 fn test_wikipedia_cert() {
144 let cert0 = key::Certificate(include_bytes!("testdata/cert-wikipedia.0.der").to_vec());
145 let cert1 = key::Certificate(include_bytes!("testdata/cert-wikipedia.1.der").to_vec());
146 let chain = [cert0, cert1];
147 let mut anchors = anchors::RootCertStore::empty();
148 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
149 bench(
150 100,
151 "verify_server_cert(wikipedia)",
152 || (),
153 |_| {
154 let dns_name = webpki::DNSNameRef::try_from_ascii_str("wikipedia.org").unwrap();
155 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
156 .unwrap();
157 },
158 );
159 }
160
161 #[test]
test_google_cert()162 fn test_google_cert() {
163 let cert0 = key::Certificate(include_bytes!("testdata/cert-google.0.der").to_vec());
164 let cert1 = key::Certificate(include_bytes!("testdata/cert-google.1.der").to_vec());
165 let cert2 = key::Certificate(include_bytes!("testdata/cert-google.2.der").to_vec());
166 let chain = [cert0, cert1, cert2];
167 let mut anchors = anchors::RootCertStore::empty();
168 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
169 bench(
170 100,
171 "verify_server_cert(google)",
172 || (),
173 |_| {
174 let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
175 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
176 .unwrap();
177 },
178 );
179 }
180
181 #[test]
test_hn_cert()182 fn test_hn_cert() {
183 let cert0 = key::Certificate(include_bytes!("testdata/cert-hn.0.der").to_vec());
184 let cert1 = key::Certificate(include_bytes!("testdata/cert-hn.1.der").to_vec());
185 let cert2 = key::Certificate(include_bytes!("testdata/cert-hn.2.der").to_vec());
186 let chain = [cert0, cert1, cert2];
187 let mut anchors = anchors::RootCertStore::empty();
188 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
189 bench(
190 100,
191 "verify_server_cert(hn)",
192 || (),
193 |_| {
194 let dns_name = webpki::DNSNameRef::try_from_ascii_str("news.ycombinator.com").unwrap();
195 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
196 .unwrap();
197 },
198 );
199 }
200
201 #[test]
test_stackoverflow_cert()202 fn test_stackoverflow_cert() {
203 let cert0 = key::Certificate(include_bytes!("testdata/cert-stackoverflow.0.der").to_vec());
204 let cert1 = key::Certificate(include_bytes!("testdata/cert-stackoverflow.1.der").to_vec());
205 let chain = [cert0, cert1];
206 let mut anchors = anchors::RootCertStore::empty();
207 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
208 bench(
209 100,
210 "verify_server_cert(stackoverflow)",
211 || (),
212 |_| {
213 let dns_name = webpki::DNSNameRef::try_from_ascii_str("stackoverflow.com").unwrap();
214 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
215 .unwrap();
216 },
217 );
218 }
219
220 #[test]
test_duckduckgo_cert()221 fn test_duckduckgo_cert() {
222 let cert0 = key::Certificate(include_bytes!("testdata/cert-duckduckgo.0.der").to_vec());
223 let cert1 = key::Certificate(include_bytes!("testdata/cert-duckduckgo.1.der").to_vec());
224 let chain = [cert0, cert1];
225 let mut anchors = anchors::RootCertStore::empty();
226 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
227 bench(
228 100,
229 "verify_server_cert(duckduckgo)",
230 || (),
231 |_| {
232 let dns_name = webpki::DNSNameRef::try_from_ascii_str("duckduckgo.com").unwrap();
233 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
234 .unwrap();
235 },
236 );
237 }
238
239 #[test]
test_rustlang_cert()240 fn test_rustlang_cert() {
241 let cert0 = key::Certificate(include_bytes!("testdata/cert-rustlang.0.der").to_vec());
242 let cert1 = key::Certificate(include_bytes!("testdata/cert-rustlang.1.der").to_vec());
243 let cert2 = key::Certificate(include_bytes!("testdata/cert-rustlang.2.der").to_vec());
244 let chain = [cert0, cert1, cert2];
245 let mut anchors = anchors::RootCertStore::empty();
246 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
247 bench(
248 100,
249 "verify_server_cert(rustlang)",
250 || (),
251 |_| {
252 let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.rust-lang.org").unwrap();
253 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
254 .unwrap();
255 },
256 );
257 }
258
259 #[test]
test_wapo_cert()260 fn test_wapo_cert() {
261 let cert0 = key::Certificate(include_bytes!("testdata/cert-wapo.0.der").to_vec());
262 let cert1 = key::Certificate(include_bytes!("testdata/cert-wapo.1.der").to_vec());
263 let cert2 = key::Certificate(include_bytes!("testdata/cert-wapo.2.der").to_vec());
264 let chain = [cert0, cert1, cert2];
265 let mut anchors = anchors::RootCertStore::empty();
266 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
267 bench(
268 100,
269 "verify_server_cert(wapo)",
270 || (),
271 |_| {
272 let dns_name =
273 webpki::DNSNameRef::try_from_ascii_str("www.washingtonpost.com").unwrap();
274 V.verify_server_cert(&anchors, &chain[..], dns_name, &[])
275 .unwrap();
276 },
277 );
278 }
279