Skip to content

Commit cde604d

Browse files
authored
Merge pull request #3932 from Bravo555/feat/tedge-p11-server-errors
feat(tedge-p11-server): Send error to client on parse error
2 parents fbccbd5 + a5a57a4 commit cde604d

File tree

2 files changed

+71
-40
lines changed

2 files changed

+71
-40
lines changed

crates/extensions/tedge-p11-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ tokio = { workspace = true, features = [
2929
"rt-multi-thread",
3030
"signal",
3131
"net",
32+
"io-util",
3233
] }
3334
toml.workspace = true
3435
tracing.workspace = true

crates/extensions/tedge-p11-server/src/proxy/server.rs

Lines changed: 70 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ impl TedgeP11Server {
4949
}
5050

5151
fn process(&self, mut connection: Connection) -> anyhow::Result<()> {
52-
let request = connection.read_frame().context("read")?;
52+
let request = match connection.read_frame().context("read") {
53+
Ok(request) => request,
54+
Err(error) => {
55+
let _ = connection.write_frame(&Frame1::Error(ProtocolError(format!("{error:#}"))));
56+
return Err(error);
57+
}
58+
};
5359

5460
let response = match request {
5561
Frame1::Error(_)
@@ -131,10 +137,12 @@ mod tests {
131137

132138
use super::super::client::TedgeP11Client;
133139
use crate::pkcs11;
140+
use crate::proxy::frame::Frame;
134141
use crate::service::*;
135-
use std::io::Read;
136142
use std::os::unix::net::UnixStream;
137143
use std::time::Duration;
144+
use tokio::io::AsyncReadExt as _;
145+
use tokio::io::AsyncWriteExt as _;
138146

139147
const SCHEME: pkcs11::SigScheme = pkcs11::SigScheme::EcdsaNistp256Sha256;
140148
const SIGNATURE: [u8; 2] = [0x21, 0x37];
@@ -173,15 +181,7 @@ mod tests {
173181
/// connection, framing, serialization, but not PKCS#11 layer itself.
174182
#[tokio::test]
175183
async fn server_works_with_client() {
176-
let service = TestSigningService;
177-
let server = TedgeP11Server::new(service).unwrap();
178-
let tmpdir = tempfile::tempdir().unwrap();
179-
let socket_path = tmpdir.path().join("test_socket.sock");
180-
let listener = UnixListener::bind(&socket_path).unwrap();
181-
182-
tokio::spawn(async move { server.serve(listener).await });
183-
// wait until the server calls accept()
184-
tokio::time::sleep(Duration::from_millis(2)).await;
184+
let (socket_path, _s) = setup_server().await;
185185

186186
tokio::task::spawn_blocking(move || {
187187
let client = TedgeP11Client::with_ready_check(socket_path.into());
@@ -197,52 +197,82 @@ mod tests {
197197

198198
#[tokio::test]
199199
async fn server_responds_with_error_to_invalid_request() {
200-
let service = TestSigningService;
201-
let server = TedgeP11Server::new(service).unwrap();
202-
let tmpdir = tempfile::tempdir().unwrap();
203-
let socket_path = tmpdir.path().join("test_socket.sock");
204-
let listener = UnixListener::bind(&socket_path).unwrap();
205-
206-
tokio::spawn(async move { server.serve(listener).await });
207-
// wait until the server calls accept()
208-
tokio::time::sleep(Duration::from_millis(2)).await;
200+
let (socket_path, _s) = setup_server().await;
209201

210202
let response = tokio::task::spawn_blocking(move || {
211-
let mut client_connection = Connection::new(UnixStream::connect(socket_path).unwrap());
212-
client_connection
203+
let mut client = Connection::new(UnixStream::connect(socket_path).unwrap());
204+
client
213205
.write_frame(&Frame1::SignResponse(SignResponse(vec![])))
214206
.unwrap();
215-
client_connection.read_frame().unwrap()
207+
client.read_frame().unwrap()
216208
})
217209
.await
218210
.unwrap();
219-
assert!(matches!(response, Frame1::Error(_)));
211+
let Frame1::Error(ProtocolError(err_msg)) = response else {
212+
panic!("should be error");
213+
};
214+
assert_eq!(err_msg.as_str(), "invalid request");
220215
}
221216

222217
#[tokio::test]
223218
async fn server_responds_with_error_to_garbage() {
224-
use std::io::Write as _;
219+
let (mut client, _s) = setup_test().await;
220+
221+
client.write_and_close("garbage".as_bytes()).await;
222+
let response = client.read().await;
223+
224+
let response: Frame = postcard::from_bytes(&response).unwrap();
225+
let Frame::Version1(Frame1::Error(ProtocolError(err_msg))) = response else {
226+
panic!("should be error");
227+
};
225228

226-
let service = TestSigningService;
227-
let server = TedgeP11Server::new(service).unwrap();
229+
assert_eq!(
230+
err_msg.as_str(),
231+
"read: Failed to parse the received frame: Serde Deserialization Error"
232+
);
233+
}
234+
235+
async fn setup_test() -> (TestClient, tokio::task::JoinHandle<anyhow::Result<()>>) {
236+
let (socket_path, server) = setup_server().await;
237+
238+
let client_socket = TestClient(tokio::net::UnixStream::connect(socket_path).await.unwrap());
239+
(client_socket, server)
240+
}
241+
242+
async fn setup_server() -> (
243+
std::path::PathBuf,
244+
tokio::task::JoinHandle<Result<(), anyhow::Error>>,
245+
) {
228246
let tmpdir = tempfile::tempdir().unwrap();
247+
let server = TedgeP11Server::new(TestSigningService).unwrap();
229248
let socket_path = tmpdir.path().join("test_socket.sock");
230249
let listener = UnixListener::bind(&socket_path).unwrap();
231250

232-
tokio::spawn(async move { server.serve(listener).await });
251+
let server = tokio::spawn(async move {
252+
let _tmpdir = tmpdir; // keep tmpdir alive until the server is done
253+
server.serve(listener).await.unwrap();
254+
Ok(())
255+
});
256+
233257
// wait until the server calls accept()
234-
tokio::time::sleep(Duration::from_millis(2)).await;
258+
tokio::time::sleep(Duration::from_millis(100)).await;
235259

236-
// the reader should exit
237-
tokio::task::spawn_blocking(move || {
238-
let mut stream = UnixStream::connect(socket_path).unwrap();
239-
write!(stream, "garbage").unwrap();
240-
stream.shutdown(std::net::Shutdown::Write).unwrap();
241-
let mut response = Vec::new();
242-
stream.read_to_end(&mut response).unwrap();
243-
response
244-
})
245-
.await
246-
.unwrap();
260+
(socket_path, server)
261+
}
262+
263+
struct TestClient(tokio::net::UnixStream);
264+
265+
impl TestClient {
266+
async fn write_and_close(&mut self, bytes: &[u8]) {
267+
self.0.write_all(bytes).await.unwrap();
268+
self.0.flush().await.unwrap();
269+
self.0.shutdown().await.unwrap();
270+
}
271+
272+
async fn read(&mut self) -> Vec<u8> {
273+
let mut bytes = Vec::new();
274+
self.0.read_to_end(&mut bytes).await.unwrap();
275+
bytes
276+
}
247277
}
248278
}

0 commit comments

Comments
 (0)