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::verify;
12 use crate::verify::ServerCertVerifier;
13 use crate::key;
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 Fsetup: Fn() -> S,
24 Ftest: Fn(S)
25 {
26 let mut times = Vec::new();
27
28 for _ in 0..count {
29 let state = f_setup();
30 let start = Instant::now();
31 f_test(state);
32 times.push(duration_nanos(Instant::now().duration_since(start)));
33 }
34
35 println!("{}: min {:?}us",
36 name,
37 times.iter().min().unwrap() / 1000);
38 }
39
fixed_time() -> Result<webpki::Time, TLSError>40 fn fixed_time() -> Result<webpki::Time, TLSError> {
41 Ok(webpki::Time::from_seconds_since_unix_epoch(1500000000))
42 }
43
44 static V: &'static verify::WebPKIVerifier = &verify::WebPKIVerifier {
45 time: fixed_time,
46 };
47
48 #[test]
test_reddit_cert()49 fn test_reddit_cert() {
50 let cert0 = key::Certificate(include_bytes!("testdata/cert-reddit.0.der").to_vec());
51 let cert1 = key::Certificate(include_bytes!("testdata/cert-reddit.1.der").to_vec());
52 let chain = [ cert0, cert1 ];
53 let mut anchors = anchors::RootCertStore::empty();
54 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
55 bench(100, "verify_server_cert(reddit)",
56 || (),
57 |_| {
58 let dns_name = webpki::DNSNameRef::try_from_ascii_str("reddit.com")
59 .unwrap();
60 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
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(100, "verify_server_cert(github)",
72 || (),
73 |_| {
74 let dns_name = webpki::DNSNameRef::try_from_ascii_str("github.com")
75 .unwrap();
76 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
77 });
78 }
79
80 #[test]
test_arstechnica_cert()81 fn test_arstechnica_cert() {
82 let cert0 = key::Certificate(include_bytes!("testdata/cert-arstechnica.0.der").to_vec());
83 let cert1 = key::Certificate(include_bytes!("testdata/cert-arstechnica.1.der").to_vec());
84 let cert2 = key::Certificate(include_bytes!("testdata/cert-arstechnica.2.der").to_vec());
85 let chain = [ cert0, cert1, cert2 ];
86 let mut anchors = anchors::RootCertStore::empty();
87 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
88 bench(100, "verify_server_cert(arstechnica)",
89 || (),
90 |_| {
91 let dns_name = webpki::DNSNameRef::try_from_ascii_str("arstechnica.com")
92 .unwrap();
93 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
94 });
95 }
96
97 #[test]
test_servo_cert()98 fn test_servo_cert() {
99 let cert0 = key::Certificate(include_bytes!("testdata/cert-servo.0.der").to_vec());
100 let cert1 = key::Certificate(include_bytes!("testdata/cert-servo.1.der").to_vec());
101 let cert2 = key::Certificate(include_bytes!("testdata/cert-servo.2.der").to_vec());
102 let chain = [ cert0, cert1, cert2 ];
103 let mut anchors = anchors::RootCertStore::empty();
104 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
105 bench(100, "verify_server_cert(servo)",
106 || (),
107 |_| {
108 let dns_name = webpki::DNSNameRef::try_from_ascii_str("servo.org")
109 .unwrap();
110 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
111 });
112 }
113
114 #[test]
test_twitter_cert()115 fn test_twitter_cert() {
116 let cert0 = key::Certificate(include_bytes!("testdata/cert-twitter.0.der").to_vec());
117 let cert1 = key::Certificate(include_bytes!("testdata/cert-twitter.1.der").to_vec());
118 let chain = [ cert0, cert1 ];
119 let mut anchors = anchors::RootCertStore::empty();
120 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
121 bench(100, "verify_server_cert(twitter)",
122 || (),
123 |_| {
124 let dns_name = webpki::DNSNameRef::try_from_ascii_str("twitter.com")
125 .unwrap();
126 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap(); });
127 }
128
129 #[test]
test_wikipedia_cert()130 fn test_wikipedia_cert() {
131 let cert0 = key::Certificate(include_bytes!("testdata/cert-wikipedia.0.der").to_vec());
132 let cert1 = key::Certificate(include_bytes!("testdata/cert-wikipedia.1.der").to_vec());
133 let chain = [ cert0, cert1 ];
134 let mut anchors = anchors::RootCertStore::empty();
135 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
136 bench(100, "verify_server_cert(wikipedia)",
137 || (),
138 |_| {
139 let dns_name = webpki::DNSNameRef::try_from_ascii_str("wikipedia.org")
140 .unwrap();
141 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
142 });
143 }
144
145 #[test]
test_google_cert()146 fn test_google_cert() {
147 let cert0 = key::Certificate(include_bytes!("testdata/cert-google.0.der").to_vec());
148 let cert1 = key::Certificate(include_bytes!("testdata/cert-google.1.der").to_vec());
149 let cert2 = key::Certificate(include_bytes!("testdata/cert-google.2.der").to_vec());
150 let chain = [ cert0, cert1, cert2 ];
151 let mut anchors = anchors::RootCertStore::empty();
152 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
153 bench(100, "verify_server_cert(google)",
154 || (),
155 |_| {
156 let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com")
157 .unwrap();
158 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
159 });
160 }
161
162 #[test]
test_hn_cert()163 fn test_hn_cert() {
164 let cert0 = key::Certificate(include_bytes!("testdata/cert-hn.0.der").to_vec());
165 let cert1 = key::Certificate(include_bytes!("testdata/cert-hn.1.der").to_vec());
166 let cert2 = key::Certificate(include_bytes!("testdata/cert-hn.2.der").to_vec());
167 let chain = [ cert0, cert1, cert2 ];
168 let mut anchors = anchors::RootCertStore::empty();
169 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
170 bench(100, "verify_server_cert(hn)",
171 || (),
172 |_| {
173 let dns_name = webpki::DNSNameRef::try_from_ascii_str("news.ycombinator.com")
174 .unwrap();
175 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
176 });
177 }
178
179 #[test]
test_stackoverflow_cert()180 fn test_stackoverflow_cert() {
181 let cert0 = key::Certificate(include_bytes!("testdata/cert-stackoverflow.0.der").to_vec());
182 let cert1 = key::Certificate(include_bytes!("testdata/cert-stackoverflow.1.der").to_vec());
183 let chain = [ cert0, cert1 ];
184 let mut anchors = anchors::RootCertStore::empty();
185 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
186 bench(100, "verify_server_cert(stackoverflow)",
187 || (),
188 |_| {
189 let dns_name = webpki::DNSNameRef::try_from_ascii_str("stackoverflow.com")
190 .unwrap();
191 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
192 });
193 }
194
195 #[test]
test_duckduckgo_cert()196 fn test_duckduckgo_cert() {
197 let cert0 = key::Certificate(include_bytes!("testdata/cert-duckduckgo.0.der").to_vec());
198 let cert1 = key::Certificate(include_bytes!("testdata/cert-duckduckgo.1.der").to_vec());
199 let chain = [ cert0, cert1 ];
200 let mut anchors = anchors::RootCertStore::empty();
201 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
202 bench(100, "verify_server_cert(duckduckgo)",
203 || (),
204 |_| {
205 let dns_name = webpki::DNSNameRef::try_from_ascii_str("duckduckgo.com")
206 .unwrap();
207 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
208 });
209 }
210
211 #[test]
test_rustlang_cert()212 fn test_rustlang_cert() {
213 let cert0 = key::Certificate(include_bytes!("testdata/cert-rustlang.0.der").to_vec());
214 let cert1 = key::Certificate(include_bytes!("testdata/cert-rustlang.1.der").to_vec());
215 let cert2 = key::Certificate(include_bytes!("testdata/cert-rustlang.2.der").to_vec());
216 let chain = [ cert0, cert1, cert2 ];
217 let mut anchors = anchors::RootCertStore::empty();
218 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
219 bench(100, "verify_server_cert(rustlang)",
220 || (),
221 |_| {
222 let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.rust-lang.org")
223 .unwrap();
224 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
225 });
226 }
227
228 #[test]
test_wapo_cert()229 fn test_wapo_cert() {
230 let cert0 = key::Certificate(include_bytes!("testdata/cert-wapo.0.der").to_vec());
231 let cert1 = key::Certificate(include_bytes!("testdata/cert-wapo.1.der").to_vec());
232 let cert2 = key::Certificate(include_bytes!("testdata/cert-wapo.2.der").to_vec());
233 let chain = [ cert0, cert1, cert2 ];
234 let mut anchors = anchors::RootCertStore::empty();
235 anchors.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
236 bench(100, "verify_server_cert(wapo)",
237 || (),
238 |_| {
239 let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.washingtonpost.com")
240 .unwrap();
241 V.verify_server_cert(&anchors, &chain[..], dns_name, &[]).unwrap();
242 });
243 }
244
245