Skip to content

Commit

Permalink
feat: make parsing functions access buffer via safe get
Browse files Browse the repository at this point in the history
  • Loading branch information
geonnave committed Nov 15, 2023
1 parent 425cdd1 commit 3aeb5c4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 30 deletions.
37 changes: 19 additions & 18 deletions consts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,24 +401,25 @@ mod common_edhoc_parsing {
let mut raw_suites_len;
let mut suites_i = [0u8; SUITES_LEN];
let mut suites_i_len: usize = 0;
let suites_i_start = rcvd_message_1.get(1)?;

// match based on first byte of SUITES_I, which can be either an int or an array
if is_cbor_uint_1byte(rcvd_message_1.content[1]) {
if is_cbor_uint_1byte(suites_i_start) {
// CBOR unsigned integer (0..=23)
suites_i[0] = rcvd_message_1.content[1];
suites_i[0] = suites_i_start;
suites_i_len = 1;
raw_suites_len = 1;
Ok((suites_i, suites_i_len, raw_suites_len))
} else if is_cbor_uint_2bytes(rcvd_message_1.content[1]) {
} else if is_cbor_uint_2bytes(suites_i_start) {
// CBOR unsigned integer (one-byte uint8_t follows)
suites_i[0] = rcvd_message_1.content[2];
suites_i[0] = rcvd_message_1.get(2)?;
suites_i_len = 1;
raw_suites_len = 2;
Ok((suites_i, suites_i_len, raw_suites_len))
} else if is_cbor_array_1byte_prefix(rcvd_message_1.content[1]) {
} else if is_cbor_array_1byte_prefix(suites_i_start) {
// CBOR array (0..=23 data items follow)
// the CBOR array length is encoded in the first byte, so we extract it
let suites_len: usize = (rcvd_message_1.content[1] - CBOR_MAJOR_ARRAY).into();
let suites_len: usize = (suites_i_start - CBOR_MAJOR_ARRAY).into();
raw_suites_len = 1; // account for the CBOR_MAJOR_ARRAY byte
if suites_len > 1 && suites_len <= EDHOC_SUITES.len() {
// cipher suite array must be at least 2 elements long, but not longer than the defined cipher suites
Expand All @@ -427,14 +428,14 @@ mod common_edhoc_parsing {
raw_suites_len += 1;
if !error_occurred {
// parse based on cipher suite identifier
if is_cbor_uint_1byte(rcvd_message_1.content[raw_suites_len]) {
if is_cbor_uint_1byte(rcvd_message_1.get(raw_suites_len)?) {
// CBOR unsigned integer (0..23)
suites_i[j] = rcvd_message_1.content[raw_suites_len];
suites_i[j] = rcvd_message_1.get(raw_suites_len)?;
suites_i_len += 1;
} else if is_cbor_uint_2bytes(rcvd_message_1.content[raw_suites_len]) {
} else if is_cbor_uint_2bytes(rcvd_message_1.get(raw_suites_len)?) {
// CBOR unsigned integer (one-byte uint8_t follows)
raw_suites_len += 1; // account for the 0x18 tag byte
suites_i[j] = rcvd_message_1.content[raw_suites_len];
suites_i[j] = rcvd_message_1.get(raw_suites_len)?;
suites_i_len += 1;
} else {
error = EDHOCError::ParsingError;
Expand Down Expand Up @@ -463,7 +464,7 @@ mod common_edhoc_parsing {
let mut ead_value = None::<EdhocMessageBuffer>;

// assuming label is a single byte integer (negative or positive)
let label = message.content[offset];
let label = message.get(offset)?;
let res_label = if is_cbor_uint_1byte(label) {
// CBOR unsigned integer (0..=23)
Ok((label as u8, false))
Expand All @@ -480,7 +481,7 @@ mod common_edhoc_parsing {
// EAD value is present
let mut buffer = EdhocMessageBuffer::new();
buffer.content[..message.len - (offset + 1)]
.copy_from_slice(&message.content[offset + 1..message.len]);
.copy_from_slice(&message.get_slice(offset + 1, message.len)?);
buffer.len = message.len - (offset + 1);
ead_value = Some(buffer);
}
Expand Down Expand Up @@ -516,20 +517,20 @@ mod common_edhoc_parsing {
let c_i;

// first element of CBOR sequence must be an integer
if is_cbor_uint_1byte(rcvd_message_1.content[0]) {
method = rcvd_message_1.content[0];
if is_cbor_uint_1byte(rcvd_message_1.get(0)?) {
method = rcvd_message_1.get(0)?;
let res_suites = parse_suites_i(rcvd_message_1);

if res_suites.is_ok() {
(suites_i, suites_i_len, raw_suites_len) = res_suites.unwrap();

if is_cbor_bstr_2bytes_prefix(rcvd_message_1.content[1 + raw_suites_len]) {
if is_cbor_bstr_2bytes_prefix(rcvd_message_1.get(1 + raw_suites_len)?) {
g_x.copy_from_slice(
&rcvd_message_1.content
[3 + raw_suites_len..3 + raw_suites_len + P256_ELEM_LEN],
&rcvd_message_1
.get_slice(3 + raw_suites_len, 3 + raw_suites_len + P256_ELEM_LEN)?,
);

c_i = rcvd_message_1.content[3 + raw_suites_len + P256_ELEM_LEN];
c_i = rcvd_message_1.get(3 + raw_suites_len + P256_ELEM_LEN)?;
// check that c_i is encoded as single-byte int (we still do not support bstr encoding)
if is_cbor_neg_int_1byte(c_i) || is_cbor_uint_1byte(c_i) {
// if there is still more to parse, the rest will be the EAD_1
Expand Down
22 changes: 10 additions & 12 deletions lib/src/edhoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,25 +870,22 @@ fn edhoc_kdf(
fn decode_plaintext_3(
plaintext_3: &BufferPlaintext3,
) -> Result<(IdCred, BytesMac3, Option<EADItem>), EDHOCError> {
let kid: u8;
let mut mac_3: BytesMac3 = [0x00; MAC_LENGTH_3];
let id_cred_i: IdCred;
let first_byte = plaintext_3.get(0)?;

// check ID_CRED_I and MAC_3
let res = if (is_cbor_neg_int_1byte(plaintext_3.content[0])
|| is_cbor_uint_1byte(plaintext_3.content[0]))
{
let res = if (is_cbor_neg_int_1byte(first_byte) || is_cbor_uint_1byte(first_byte)) {
// KID
kid = plaintext_3.content[0usize];
let id_cred_i = IdCred::CompactKid(plaintext_3.content[0usize]);
let id_cred_i = IdCred::CompactKid(first_byte);
Ok((1, id_cred_i))
} else if is_cbor_bstr_2bytes_prefix(plaintext_3.content[0])
&& is_cbor_uint_2bytes(plaintext_3.content[1])
&& (plaintext_3.content[2] as usize) < plaintext_3.len
} else if is_cbor_bstr_2bytes_prefix(first_byte)
&& is_cbor_uint_2bytes(plaintext_3.get(1)?)
&& (plaintext_3.get(2)? as usize) < plaintext_3.len
{
// full credential
let cred_len = plaintext_3.content[2] as usize;
id_cred_i = IdCred::FullCredential(&plaintext_3.content[3..3 + cred_len]);
let cred_len = plaintext_3.get(2)? as usize;
id_cred_i = IdCred::FullCredential(&plaintext_3.get_slice(3, 3 + cred_len)?);
Ok((3 + cred_len, id_cred_i))
} else {
// error
Expand All @@ -899,9 +896,10 @@ fn decode_plaintext_3(
let (mut offset, id_cred_i) = res.unwrap();

if (is_cbor_bstr_1byte_prefix(plaintext_3.content[1])) {
// FIXME[urgent]: should access [offset] instead of [1]
// skip the CBOR magic byte as we know how long the MAC is
offset += 1;
mac_3[..].copy_from_slice(&plaintext_3.content[offset..offset + MAC_LENGTH_3]);
mac_3[..].copy_from_slice(&plaintext_3.get_slice(offset, offset + MAC_LENGTH_3)?);

// if there is still more to parse, the rest will be the EAD_3
if plaintext_3.len > (offset + MAC_LENGTH_3) {
Expand Down

0 comments on commit 3aeb5c4

Please sign in to comment.