Skip to content

Commit be7e569

Browse files
gowthamsk-armtgonzalezorlandoarm
authored andcommitted
e2e_tests: Add handshake support
The client and server structures with needed configuration items are added along with methods to perform the handshake. Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
1 parent 6614f98 commit be7e569

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

parsec-openssl-provider-shared/e2e_tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ foreign-types-shared = "0.1.1"
1616
parsec-openssl-provider = { path ="../../parsec-openssl-provider" }
1717
parsec-client = "0.16.0"
1818
sha2 = "0.10.8"
19+
openssl = "0.10.63"
1920

2021
[build-dependencies]
2122
pkg-config = "0.3.18"

parsec-openssl-provider-shared/e2e_tests/src/lib.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44

55
// Needed to access as_ptr function for LibCtx
66
pub use foreign_types_shared::ForeignType;
7+
pub use openssl::ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslVerifyMode};
78
pub use parsec_openssl_provider::parsec_openssl2::openssl::{lib_ctx::LibCtx, provider::Provider};
89
pub use parsec_openssl_provider::parsec_openssl2::openssl_bindings::*;
910
use parsec_openssl_provider::parsec_openssl2::openssl_returns_1;
1011
use parsec_openssl_provider::PARSEC_PROVIDER_DFLT_PROPERTIES;
12+
pub use std::io::{Read, Write};
13+
pub use std::net::{SocketAddr, TcpListener, TcpStream};
14+
pub use std::thread::{self, JoinHandle};
1115

1216
// Loads a provider into the given library context
1317
pub fn load_provider(lib_ctx: &LibCtx, provider_name: &str, provider_path: String) -> Provider {
@@ -41,3 +45,119 @@ pub unsafe fn load_key(
4145

4246
EVP_PKEY_CTX_free(evp_ctx);
4347
}
48+
49+
// Server object with configuration needed for TLS handshake
50+
pub struct Server {
51+
ssl_method: SslMethod,
52+
certificate: Option<String>,
53+
private_key: Option<String>,
54+
ca_certificate: Option<String>,
55+
ssl_mode: SslVerifyMode,
56+
}
57+
58+
impl Server {
59+
pub fn new(
60+
cert: Option<String>,
61+
key: Option<String>,
62+
ca: Option<String>,
63+
mode: SslVerifyMode,
64+
) -> Server {
65+
Server {
66+
ssl_method: SslMethod::tls_server(),
67+
certificate: cert,
68+
private_key: key,
69+
ca_certificate: ca,
70+
ssl_mode: mode,
71+
}
72+
}
73+
74+
// Uses all the Server configurations to build a SslContext object
75+
pub fn build(&mut self) -> SslContext {
76+
let mut ctx_builder = SslContext::builder(self.ssl_method).unwrap();
77+
if let Some(certificate) = &self.certificate {
78+
ctx_builder
79+
.set_certificate_file(certificate, SslFiletype::PEM)
80+
.unwrap();
81+
}
82+
if let Some(key) = &self.private_key {
83+
ctx_builder
84+
.set_private_key_file(key, SslFiletype::PEM)
85+
.unwrap();
86+
}
87+
if let Some(ca_cert) = &self.ca_certificate {
88+
ctx_builder.set_ca_file(ca_cert).unwrap();
89+
}
90+
ctx_builder.set_verify(self.ssl_mode);
91+
ctx_builder.build()
92+
}
93+
94+
// Opens a TCP stream listener and accepts any incoming SSL requests
95+
// coming from client. The server waits in a separate thread and returns
96+
// the handle to the caller.
97+
pub fn accept(mut self, listener: TcpListener) {
98+
let _handle = thread::spawn(move || {
99+
let server_context = self.build();
100+
let stream = listener.accept().unwrap().0;
101+
let ssl = Ssl::new(&server_context).unwrap();
102+
let handshake_result = ssl.accept(stream);
103+
let mut stream = handshake_result.unwrap();
104+
stream.write_all(&[0]).unwrap();
105+
});
106+
}
107+
}
108+
109+
// Client object with configuration needed for TLS handshake
110+
pub struct Client {
111+
ssl_method: SslMethod,
112+
certificate: Option<String>,
113+
private_key: Option<String>,
114+
ca_certificate: Option<String>,
115+
ssl_mode: SslVerifyMode,
116+
}
117+
118+
impl Client {
119+
pub fn new(
120+
cert: Option<String>,
121+
key: Option<String>,
122+
ca: Option<String>,
123+
mode: SslVerifyMode,
124+
) -> Client {
125+
Client {
126+
ssl_method: SslMethod::tls_client(),
127+
certificate: cert,
128+
private_key: key,
129+
ca_certificate: ca,
130+
ssl_mode: mode,
131+
}
132+
}
133+
134+
// ToDo: This needs to modified in the future to use the PKey object from parsec provider
135+
// Uses all the Client configurations to build a SslContext object
136+
pub fn build(&mut self) -> SslContext {
137+
let mut ctx_builder = SslContext::builder(self.ssl_method).unwrap();
138+
if let Some(certificate) = &self.certificate {
139+
ctx_builder
140+
.set_certificate_file(certificate, SslFiletype::PEM)
141+
.unwrap();
142+
}
143+
if let Some(key) = &self.private_key {
144+
ctx_builder
145+
.set_private_key_file(key, SslFiletype::PEM)
146+
.unwrap();
147+
}
148+
if let Some(ca_cert) = &self.ca_certificate {
149+
ctx_builder.set_ca_file(ca_cert).unwrap();
150+
}
151+
ctx_builder.set_verify(self.ssl_mode);
152+
ctx_builder.build()
153+
}
154+
155+
// Creates a TCP stream and initiates a TLS handshake to the server
156+
pub fn connect(mut self, addr: SocketAddr) {
157+
let socket = TcpStream::connect(addr).unwrap();
158+
let client_ctx = self.build();
159+
let ssl = Ssl::new(&client_ctx).unwrap();
160+
let mut channel = ssl.connect(socket).unwrap();
161+
channel.read_exact(&mut [0]).unwrap();
162+
}
163+
}

0 commit comments

Comments
 (0)