-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replaced serde_cbor with ciborium #56
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,16 +16,14 @@ use std::result; | |
|
||
use serde::{Deserialize, Serialize}; | ||
use serde_bytes::ByteBuf; | ||
use serde_cbor::error::Error as CborError; | ||
use serde_cbor::{from_slice, to_vec}; | ||
|
||
#[derive(Debug)] | ||
/// Possible error types return from this library. | ||
pub enum Error { | ||
/// An IO error of type `std::io::Error` | ||
Io(IoError), | ||
/// A CBOR ser/de error of type `serde_cbor::error::Error`. | ||
Cbor(CborError), | ||
/// A CBOR de error of type `ciborium::de::Error<std::io::Error>`. | ||
Cbor(ciborium::de::Error<std::io::Error>), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This (
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The second alternative would be to allow downstream consumers to provide their own A couple problems with that:
I threw that idea out pretty early but felt like I'd include it here for group consensus. |
||
} | ||
|
||
/// Result type return nsm-io::Error on failure. | ||
|
@@ -37,12 +35,6 @@ impl From<IoError> for Error { | |
} | ||
} | ||
|
||
impl From<CborError> for Error { | ||
fn from(error: CborError) -> Self { | ||
Error::Cbor(error) | ||
} | ||
} | ||
|
||
/// List of error codes that the NSM module can return as part of a Response | ||
#[repr(C)] | ||
#[derive(Debug, Serialize, Deserialize)] | ||
|
@@ -290,13 +282,15 @@ impl AttestationDoc { | |
/// Helper function that converts an AttestationDoc structure to its CBOR representation | ||
pub fn to_binary(&self) -> Vec<u8> { | ||
// This should not fail | ||
to_vec(self).unwrap() | ||
let mut buf = Vec::with_capacity(1024); | ||
ciborium::into_writer(self, &mut buf).unwrap(); | ||
buf | ||
} | ||
|
||
/// Helper function that parses a CBOR representation of an AttestationDoc and creates the | ||
/// structure from it, if possible. | ||
pub fn from_binary(bin: &[u8]) -> Result<Self> { | ||
from_slice(bin).map_err(Error::Cbor) | ||
ciborium::from_reader(bin).map_err(Error::Cbor) | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ use nix::request_code_readwrite; | |
use nix::unistd::close; | ||
|
||
use std::fs::OpenOptions; | ||
use std::io::{IoSlice, IoSliceMut}; | ||
use std::io::IoSlice; | ||
use std::mem; | ||
use std::os::unix::io::{IntoRawFd, RawFd}; | ||
|
||
|
@@ -35,29 +35,29 @@ struct NsmMessage<'a> { | |
/// User-provided data for the request | ||
pub request: IoSlice<'a>, | ||
/// Response data provided by the NSM pipeline | ||
pub response: IoSliceMut<'a>, | ||
pub response: IoSlice<'a>, | ||
} | ||
|
||
/// Encode an NSM `Request` value into a vector. | ||
/// *Argument 1 (input)*: The NSM request. | ||
/// *Returns*: The vector containing the CBOR encoding. | ||
fn nsm_encode_request_to_cbor(request: Request) -> Vec<u8> { | ||
serde_cbor::to_vec(&request).unwrap() | ||
/// Encode an NSM `Request` value into a vector. | ||
/// *Argument 1 (input)*: The NSM request. | ||
/// *Argument 2 (input)*: The buffer that will have the CBOR written into it. | ||
fn nsm_encode_request_to_cbor(request: Request, buf: &mut Vec<u8>) { | ||
ciborium::into_writer(&request, buf).expect("buf's Writer returned an unexpected error"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative to this The current flow looks like this:
This could be turned on its head so that |
||
} | ||
|
||
/// Decode an NSM `Response` value from a raw memory buffer. | ||
/// *Argument 1 (input)*: The `iovec` holding the memory buffer. | ||
/// Decode an NSM `Response` value from a raw memory buffer. | ||
/// *Argument 1 (input)*: The `iovec` holding the memory buffer. | ||
/// *Returns*: The decoded NSM response. | ||
fn nsm_decode_response_from_cbor(response_data: &IoSliceMut<'_>) -> Response { | ||
match serde_cbor::from_slice(response_data) { | ||
fn nsm_decode_response_from_cbor(response_data: &IoSlice<'_>) -> Response { | ||
match ciborium::from_reader(response_data.as_ref()) { | ||
Ok(response) => response, | ||
Err(_) => Response::Error(ErrorCode::InternalError), | ||
} | ||
} | ||
|
||
/// Do an `ioctl()` of a given type for a given message. | ||
/// *Argument 1 (input)*: The descriptor to the device file. | ||
/// *Argument 2 (input/output)*: The message to be sent and updated via `ioctl()`. | ||
/// Do an `ioctl()` of a given type for a given message. | ||
/// *Argument 1 (input)*: The descriptor to the device file. | ||
/// *Argument 2 (input/output)*: The message to be sent and updated via `ioctl()`. | ||
/// *Returns*: The status of the operation. | ||
fn nsm_ioctl(fd: i32, message: &mut NsmMessage) -> Option<Errno> { | ||
let status = unsafe { | ||
|
@@ -80,22 +80,23 @@ fn nsm_ioctl(fd: i32, message: &mut NsmMessage) -> Option<Errno> { | |
|
||
/// Create a message with input data and output capacity from a given | ||
/// request, then send it to the NSM driver via `ioctl()` and wait | ||
/// for the driver's response. | ||
/// *Argument 1 (input)*: The descriptor to the NSM device file. | ||
/// *Argument 2 (input)*: The NSM request. | ||
/// for the driver's response. | ||
/// *Argument 1 (input)*: The descriptor to the NSM device file. | ||
/// *Argument 2 (input)*: The NSM request. | ||
/// *Returns*: The corresponding NSM response from the driver. | ||
pub fn nsm_process_request(fd: i32, request: Request) -> Response { | ||
let cbor_request = nsm_encode_request_to_cbor(request); | ||
let mut cbor_request = Vec::with_capacity(NSM_REQUEST_MAX_SIZE); | ||
nsm_encode_request_to_cbor(request, &mut cbor_request); | ||
|
||
// Check if the request is too large | ||
if cbor_request.len() > NSM_REQUEST_MAX_SIZE { | ||
return Response::Error(ErrorCode::InputTooLarge); | ||
} | ||
|
||
let mut cbor_response: [u8; NSM_RESPONSE_MAX_SIZE] = [0; NSM_RESPONSE_MAX_SIZE]; | ||
let cbor_response: [u8; NSM_RESPONSE_MAX_SIZE] = [0; NSM_RESPONSE_MAX_SIZE]; | ||
let mut message = NsmMessage { | ||
request: IoSlice::new(&cbor_request), | ||
response: IoSliceMut::new(&mut cbor_response), | ||
response: IoSlice::new(&cbor_response), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This didn't appear to need to be |
||
}; | ||
let status = nsm_ioctl(fd, &mut message); | ||
|
||
|
@@ -108,7 +109,7 @@ pub fn nsm_process_request(fd: i32, request: Request) -> Response { | |
} | ||
} | ||
|
||
/// NSM library initialization function. | ||
/// NSM library initialization function. | ||
/// *Returns*: A descriptor for the opened device file. | ||
pub fn nsm_init() -> i32 { | ||
let mut open_options = OpenOptions::new(); | ||
|
@@ -126,7 +127,7 @@ pub fn nsm_init() -> i32 { | |
} | ||
} | ||
|
||
/// NSM library exit function. | ||
/// NSM library exit function. | ||
/// *Argument 1 (input)*: The descriptor for the opened device file, as | ||
/// obtained from `nsm_init()`. | ||
pub fn nsm_exit(fd: i32) { | ||
|
@@ -136,3 +137,21 @@ pub fn nsm_exit(fd: i32) { | |
Err(e) => error!("File of descriptor {} failed to close: {}", fd, e), | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::{Request, NSM_REQUEST_MAX_SIZE}; | ||
#[test] | ||
fn test_nsm_encode_request_to_cbor_exceed_max_size_without_panic() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just here to ensure if anyone in the future decides to try to get clever with the |
||
let request = Request::ExtendPCR { | ||
index: 0, | ||
data: vec![0u8; NSM_REQUEST_MAX_SIZE], | ||
}; | ||
|
||
let mut buf = Vec::with_capacity(NSM_REQUEST_MAX_SIZE); | ||
super::nsm_encode_request_to_cbor(request, &mut buf); | ||
|
||
// Ensure the buffer increased its capacity without panicking | ||
assert!(buf.len() > NSM_REQUEST_MAX_SIZE); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My formatter noticed that the cargo.toml was inconsistent here. Happy to revert these changes if they're view as a problem.