-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathssl_conf_verify.rs
109 lines (91 loc) · 3.66 KB
/
ssl_conf_verify.rs
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
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */
#![allow(dead_code)]
// needed to have common code for `mod support` in unit and integrations tests
extern crate mbedtls;
use std::net::TcpStream;
use mbedtls::pk::Pk;
use mbedtls::rng::CtrDrbg;
use mbedtls::ssl::config::{Endpoint, Preset, Transport};
use mbedtls::ssl::{Config, Context};
use mbedtls::x509::{Certificate, VerifyError};
use mbedtls::Result as TlsResult;
use mbedtls::{error::codes, Error};
mod support;
use std::sync::Arc;
use support::entropy::entropy_new;
use support::keys;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum Test {
CallbackSetVerifyFlags,
CallbackError,
}
fn client(conn: TcpStream, test: Test) -> TlsResult<()> {
let entropy = entropy_new();
let rng = Arc::new(CtrDrbg::new(Arc::new(entropy), None)?);
let cert = Arc::new(Certificate::from_pem_multiple(keys::PEM_CERT.as_bytes())?);
let verify_test = test.clone();
let verify_callback = move |_crt: &Certificate, _depth: i32, verify_flags: &mut VerifyError| match verify_test {
Test::CallbackSetVerifyFlags => {
*verify_flags |= VerifyError::CERT_OTHER;
Ok(())
}
Test::CallbackError => Err(codes::Asn1InvalidData.into()),
};
let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default);
config.set_rng(rng);
config.set_verify_callback(verify_callback);
config.set_ca_list(cert, None);
let mut ctx = Context::new(Arc::new(config));
match (test, ctx.establish(conn, None).err().expect("should have failed")) {
(Test::CallbackSetVerifyFlags, Error::HighLevel(codes::X509CertVerifyFailed)) => {
assert_eq!(
ctx.verify_result().unwrap_err(),
VerifyError::CERT_OTHER | VerifyError::CERT_NOT_TRUSTED,
);
}
(Test::CallbackError, Error::LowLevel(codes::Asn1InvalidData)) => {}
(_, err) => assert!(false, "Unexpected error from ctx.establish(): {:?}", err),
}
Ok(())
}
fn server(conn: TcpStream) -> TlsResult<()> {
let entropy = entropy_new();
let rng = Arc::new(CtrDrbg::new(Arc::new(entropy), None)?);
let cert = Arc::new(Certificate::from_pem_multiple(keys::PEM_CERT.as_bytes())?);
let key = Arc::new(Pk::from_private_key(keys::PEM_KEY.as_bytes(), None)?);
let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default);
config.set_rng(rng);
config.push_cert(cert, key)?;
let mut ctx = Context::new(Arc::new(config));
let _ = ctx.establish(conn, None);
Ok(())
}
#[cfg(unix)]
mod test {
use crate::support::net::create_tcp_pair;
use crate::support::thread_spawn_named;
#[test]
fn callback_set_verify_flags() {
let (c, s) = create_tcp_pair().unwrap();
let c = thread_spawn_named("client", move || {
super::client(c, super::Test::CallbackSetVerifyFlags).unwrap()
});
let s = thread_spawn_named("server", move || super::server(s).unwrap());
c.join().unwrap();
s.join().unwrap();
}
#[test]
fn callback_error() {
let (c, s) = create_tcp_pair().unwrap();
let c = thread_spawn_named("client", move || super::client(c, super::Test::CallbackError).unwrap());
let s = thread_spawn_named("server", move || super::server(s).unwrap());
c.join().unwrap();
s.join().unwrap();
}
}