Skip to content

Commit

Permalink
Merge pull request #236 from chrysn-pull-requests/edhocerror-no-numerics
Browse files Browse the repository at this point in the history
shared: Remove numeric value, repr(C) and UnknownError from EDHOCError
  • Loading branch information
geonnave authored Mar 8, 2024
2 parents 5b82581 + c952349 commit b977f86
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 17 deletions.
4 changes: 2 additions & 2 deletions ead/lakers-ead-authz/src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ZeroTouchAuthenticator {
let opaque_state: Option<EdhocMessageBuffer> = None; // TODO: receive as parameter

if ead_1.label != EAD_ZEROCONF_LABEL || ead_1.value.is_none() {
return Err(EDHOCError::EADError);
return Err(EDHOCError::EADUnprocessable);
}

let (loc_w, _enc_id) = parse_ead_1_value(&ead_1.value.unwrap())?;
Expand Down Expand Up @@ -92,7 +92,7 @@ fn parse_voucher_response(

let array_size = decoder.array()?;
if !(2..=3).contains(&array_size) {
return Err(EDHOCError::EADError);
return Err(EDHOCError::EADUnprocessable);
}

let message_1: EdhocMessageBuffer = decoder.bytes()?.try_into().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion ead/lakers-ead-authz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,6 @@ mod test_authz {

let voucher_response =
server.handle_voucher_request(&mut default_crypto(), &voucher_request);
assert_eq!(voucher_response.unwrap_err(), EDHOCError::EADError);
assert_eq!(voucher_response.unwrap_err(), EDHOCError::AccessDenied);
}
}
6 changes: 3 additions & 3 deletions ead/lakers-ead-authz/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl ZeroTouchServer {
let voucher_response = encode_voucher_response(&message_1, &voucher, &opaque_state);
Ok(voucher_response)
} else {
Err(EDHOCError::EADError)
Err(EDHOCError::AccessDenied)
}
}
}
Expand Down Expand Up @@ -107,7 +107,7 @@ fn parse_voucher_request(
let mut decoder = CBORDecoder::new(vreq.as_slice());
let array_size = decoder.array()?;
if array_size != 1 && array_size != 2 {
return Err(EDHOCError::EADError);
return Err(EDHOCError::EADUnprocessable);
}

let message_1: EdhocMessageBuffer = decoder.bytes()?.try_into().unwrap();
Expand Down Expand Up @@ -277,7 +277,7 @@ mod test_enrollment_server {
&mut default_crypto(),
&VOUCHER_REQUEST_TV.try_into().unwrap(),
);
assert_eq!(res.unwrap_err(), EDHOCError::EADError);
assert_eq!(res.unwrap_err(), EDHOCError::AccessDenied);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ pub fn credential_check_or_fetch<'a>(
if credentials_match {
Ok(cred_expected)
} else {
Err(EDHOCError::UnknownPeer)
Err(EDHOCError::UnexpectedCredential)
}
} else {
// 1. Does ID_CRED_X point to a stored authentication credential? NO
Expand Down
89 changes: 79 additions & 10 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub use cbor_decoder::*;
pub use edhoc_parser::*;
pub use helpers::*;

use core::num::NonZeroI16;

mod crypto;
pub use crypto::Crypto;

Expand Down Expand Up @@ -104,18 +106,85 @@ pub type BytesMac = [u8; MAC_LENGTH];
pub type BytesEncodedVoucher = [u8; ENCODED_VOUCHER_LEN];
pub type EADMessageBuffer = EdhocMessageBuffer; // TODO: make it of size MAX_EAD_SIZE_LEN

#[repr(C)]
#[derive(PartialEq, Debug)]
#[non_exhaustive]
pub enum EDHOCError {
UnknownPeer = 1,
MacVerificationFailed = 2,
UnsupportedMethod = 3,
UnsupportedCipherSuite = 4,
ParsingError = 5,
EadLabelTooLongError = 6,
EadTooLongError = 7,
EADError = 8,
UnknownError = 9,
/// In an exchange, a credential was set as "expected", but the credential configured by the
/// peer did not match what was presented. This is more an application internal than an EDHOC
/// error: When the application sets the expected credential, that process should be informed
/// by the known details.
UnexpectedCredential,
MacVerificationFailed,
UnsupportedMethod,
UnsupportedCipherSuite,
ParsingError,
EadLabelTooLongError,
EadTooLongError,
/// An EAD was received that was either not known (and critical), or not understood, or
/// otherwise erroneous.
EADUnprocessable,
/// The credential or EADs could be processed (possibly by a third party), but the decision
/// based on that was to not to continue the EDHOC session.
///
/// See also
/// <https://datatracker.ietf.org/doc/html/draft-ietf-lake-authz#name-edhoc-error-access-denied>
AccessDenied,
}

impl EDHOCError {
/// The ERR_CODE corresponding to the error
///
/// Errors that refer to internal limitations (such as EadTooLongError) are treated the same
/// way as parsing errors, and return an unspecified error: Those are equivalent to limitations
/// of the parser, and a constrained system can not be expected to differentiate between "the
/// standard allows this but my number space is too small" and "this violates the standard".
///
/// If an EDHOCError is returned through EDHOC, it will use this in its EDHOC error message.
///
/// Note that this on its own is insufficient to create an error message: Additional ERR_INFO
/// is needed, which may or may not be available with the EDHOCError alone.
///
/// TODO: Evolve the EDHOCError type such that all information needed is available.
pub fn err_code(&self) -> ErrCode {
use EDHOCError::*;
match self {
UnexpectedCredential => ErrCode::UNSPECIFIED,
MacVerificationFailed => ErrCode::UNSPECIFIED,
UnsupportedMethod => ErrCode::UNSPECIFIED,
UnsupportedCipherSuite => ErrCode::WRONG_SELECTED_CIPHER_SUITE,
ParsingError => ErrCode::UNSPECIFIED,
EadLabelTooLongError => ErrCode::UNSPECIFIED,
EadTooLongError => ErrCode::UNSPECIFIED,
EADUnprocessable => ErrCode::UNSPECIFIED,
AccessDenied => ErrCode::ACCESS_DENIED,
}
}
}

/// Representation of an EDHOC ERR_CODE
#[repr(C)]
pub struct ErrCode(pub NonZeroI16);

impl ErrCode {
// The way these are initialized will be simplified once const_option is stable

pub const UNSPECIFIED: Self = ErrCode(match NonZeroI16::new(1) {
Some(v) => v,
_ => unreachable!(),
});
pub const WRONG_SELECTED_CIPHER_SUITE: Self = ErrCode(match NonZeroI16::new(2) {
Some(v) => v,
_ => unreachable!(),
});
pub const UNKNOWN_CREDENTIAL: Self = ErrCode(match NonZeroI16::new(3) {
Some(v) => v,
_ => unreachable!(),
});
// Code requested in https://datatracker.ietf.org/doc/html/draft-ietf-lake-authz
pub const ACCESS_DENIED: Self = ErrCode(match NonZeroI16::new(3333) {
Some(v) => v,
_ => unreachable!(),
});
}

#[derive(Debug)]
Expand Down

0 comments on commit b977f86

Please sign in to comment.