diff --git a/consts/src/lib.rs b/consts/src/lib.rs index e4837b82..0a3e5b0d 100644 --- a/consts/src/lib.rs +++ b/consts/src/lib.rs @@ -227,6 +227,12 @@ mod cbor { return byte == CBOR_BYTE_STRING; } + /// Check for: a tstr denoted by two bytes, one for type the other for content length + #[inline(always)] + pub fn is_cbor_tstr_2bytes_prefix(byte: u8) -> bool { + return byte == CBOR_TEXT_STRING; + } + /// Check for: an array denoted by a single byte which encodes both type and content length #[inline(always)] pub fn is_cbor_array_1byte_prefix(byte: u8) -> bool { diff --git a/ead/edhoc-ead-zeroconf/src/lib.rs b/ead/edhoc-ead-zeroconf/src/lib.rs index e5a511f7..402970e7 100644 --- a/ead/edhoc-ead-zeroconf/src/lib.rs +++ b/ead/edhoc-ead-zeroconf/src/lib.rs @@ -77,7 +77,7 @@ pub fn i_prepare_ead_1(x: &BytesP256ElemLen, ss: u8) -> Option { let prk = compute_prk(x, &state.g_w); let enc_id = build_enc_id(&prk, &state.id_u, ss); - let value = Some(encode_ead_1(&state.loc_w, &enc_id)); + let value = Some(encode_ead_1_value(&state.loc_w, &enc_id)); let ead_1 = EADItem { label: EAD_ZEROCONF_LABEL, @@ -248,7 +248,10 @@ fn edhoc_kdf( output } -fn encode_ead_1(loc_w: &EdhocMessageBuffer, enc_id: &EdhocMessageBuffer) -> EdhocMessageBuffer { +fn encode_ead_1_value( + loc_w: &EdhocMessageBuffer, + enc_id: &EdhocMessageBuffer, +) -> EdhocMessageBuffer { let mut output = EdhocMessageBuffer::new(); output.content[0] = CBOR_BYTE_STRING; @@ -408,12 +411,29 @@ fn parse_voucher_response( fn parse_ead_1_value( value: &EdhocMessageBuffer, ) -> Result<(EdhocMessageBuffer, EdhocMessageBuffer), ()> { - let loc_w: EdhocMessageBuffer = value.content[4..4 + value.content[3] as usize] + let value_len = value.content[1] as usize; + if !is_cbor_bstr_2bytes_prefix(value.content[0]) || value_len != (value.len - 2) { + return Err(()); + } + + let loc_w_len = value.content[3] as usize; + if !is_cbor_tstr_2bytes_prefix(value.content[2]) || loc_w_len >= value_len { + return Err(()); + } + + let loc_w: EdhocMessageBuffer = value.content[4..4 + loc_w_len].try_into().unwrap(); + + let enc_id_len = (value.content[4 + loc_w_len] - CBOR_MAJOR_BYTE_STRING) as usize; + if !is_cbor_bstr_1byte_prefix(value.content[4 + loc_w_len]) + || enc_id_len >= (value_len - loc_w_len) + { + return Err(()); + } + + let enc_id: EdhocMessageBuffer = value.content[5 + loc_w_len..5 + loc_w_len + enc_id_len] .try_into() .unwrap(); - let enc_id: EdhocMessageBuffer = EdhocMessageBuffer::new(); - Ok((loc_w, enc_id)) } @@ -757,11 +777,13 @@ mod test_responder { fn test_parse_ead_1_value() { let ead_1_value_tv: EdhocMessageBuffer = EAD1_VALUE_TV.try_into().unwrap(); let loc_w_tv: EdhocMessageBuffer = LOC_W_TV.try_into().unwrap(); + let enc_id_tv: EdhocMessageBuffer = ENC_ID_TV.try_into().unwrap(); let res = parse_ead_1_value(&ead_1_value_tv); assert!(res.is_ok()); let (loc_w, enc_id) = res.unwrap(); assert_eq!(loc_w.content, loc_w_tv.content); + assert_eq!(enc_id.content, enc_id_tv.content); } #[test]