Skip to content

Commit

Permalink
add integer overflow check
Browse files Browse the repository at this point in the history
Signed-off-by: OuyangHang33 <[email protected]>
  • Loading branch information
OuyangHang33 committed Apr 7, 2024
1 parent c5e0bbe commit 10677d5
Showing 1 changed file with 77 additions and 11 deletions.
88 changes: 77 additions & 11 deletions spdmlib/src/crypto/x509v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ fn check_tbs_certificate(
// extensions [3] EXPLICIT Extensions OPTIONAL

// key_usage EXTENSIONS,
let (find_key_usage, key_usage_value) = get_key_usage_value(&data[t_walker..])?;
let (bytes_consumed, extension_data) = check_and_get_extensions(&data[t_walker..])?;
let (find_key_usage, key_usage_value) = get_key_usage_value(extension_data)?;
// The digitalSignature bit SHOULD asserted when subject public key is used for verifying digital signatures
// in an entity authentication service, a data origin authentication service, and/or an integrity service.
let check_extensions_success = !(find_key_usage
Expand All @@ -179,7 +180,6 @@ fn check_tbs_certificate(
// when key usage digitalSignature bit unset, it SHOULD return false.

//extensions EXTENSIONS,
let (bytes_consumed, extension_data) = check_and_get_extensions(&data[t_walker..])?;
let check_extn_spdm_success = check_extensions_spdm_oid(extension_data, is_leaf_cert)?;
t_walker += bytes_consumed;

Expand Down Expand Up @@ -381,18 +381,26 @@ fn get_key_usage_value(data: &[u8]) -> SpdmResult<(bool, u8)> {
let mut find_key_usage = false;
let len = data.len();
let key_usage_oid_len = OID_KEY_USAGE.len();
if len < 1 {
if len < 1 || data[0] != ASN1_TAG_SEQUENCE {
return Err(SPDM_STATUS_VERIF_FAIL);
}
let (data_length, bytes_consumed) = check_length(&data[1..])?;
if len < 1 + data_length + bytes_consumed {
Err(SPDM_STATUS_VERIF_FAIL)
} else {
let mut index = 1 + bytes_consumed;
while index < data_length {
// search KEY_Usage OID in Extensions Sequence
while index < len {
if index + 1 > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
let (payload_length, bytes_consumed) = check_length(&data[index + 1..])?;
if index + 1 + bytes_consumed + payload_length > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
// search in sequence, skip bytes consumed
if data[index] == ASN1_TAG_SEQUENCE {
index += 1 + payload_length;
index += 1 + bytes_consumed;
continue;
} else if data[index] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER
&& payload_length == key_usage_oid_len
Expand All @@ -402,23 +410,45 @@ fn get_key_usage_value(data: &[u8]) -> SpdmResult<(bool, u8)> {
)
{
index += 1 + bytes_consumed + payload_length;
if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

if data[index] == ASN1_TAG_EXTN_VALUE {
if index + 1 > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
let (_, extnvalue_consumed) = check_length(&data[index + 1..])?;
index += 1 + extnvalue_consumed;

if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

if data[index] == ASN1_TAG_BIT_STRING {
if index + 1 > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
let (string_length, string_consumed) = check_length(&data[index + 1..])?;
index += string_consumed + string_length;

if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
find_key_usage = true;
} else {
find_key_usage = false;
}
break;
} else {
index += 1 + bytes_consumed + payload_length;
continue;
return Err(SPDM_STATUS_VERIF_FAIL);
}
} else {
// if not Sequence or OID tag, skip
index += 1 + bytes_consumed + payload_length;
if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
continue;
}
}
Expand Down Expand Up @@ -446,6 +476,9 @@ fn check_extensions_spdm_oid(extensions: &[u8], is_leaf_cert: bool) -> SpdmResul
let mut index = 0;
while index < payload_length {
let (extnid, extn_sequence_len) = check_and_get_extn_id(&extn_sequences[index..])?;
if index + extn_sequence_len > sequences_len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
// find the first level extension identifiy from extensions sequence
if object_identifiers_are_same(extnid, OID_SUBJECT_ALTERNATIVE_NAME) {
if find_target_object_identifier_in_single_extension(
Expand Down Expand Up @@ -508,12 +541,21 @@ fn find_target_object_identifier_in_single_extension(
let mut target_oid_find_success = false;
let len = data.len();
let target_oid_len = target_oid.len();
if len < target_oid_len {
if len < 1 {
Err(SPDM_STATUS_VERIF_FAIL)
} else if len < target_oid_len {
target_oid_find_success = false;
Ok(target_oid_find_success)
} else {
let mut index = 0;
while index < len - target_oid_len {
if index + 1 > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
let (payload_length, bytes_consumed) = check_length(&data[index + 1..])?;
if index + 1 + bytes_consumed + payload_length > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
if data[index] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
if object_identifiers_are_same(
&data[index + 1 + bytes_consumed..index + 1 + bytes_consumed + payload_length],
Expand All @@ -524,18 +566,27 @@ fn find_target_object_identifier_in_single_extension(
break;
} else {
index += 1 + bytes_consumed + payload_length;
if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
continue;
}
} else if data[index] == ASN1_TAG_SEQUENCE || data[index] == ASN1_TAG_EXTN_VALUE {
index += 1 + bytes_consumed;
if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
continue;
} else {
index += 1 + bytes_consumed + payload_length;
if index > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
continue;
}
}
Ok(target_oid_find_success)
}
Ok(target_oid_find_success)
}

// IN extension sequences slice
Expand Down Expand Up @@ -1359,10 +1410,12 @@ mod tests {
#[test]
fn test_case0_get_key_usage_value() {
let key_usage1 = &[
0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x05, 0xE0,
0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x05,
0xE0,
];
let key_usage2_wrong = &[
0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x04, 0x03, 0x02, 0x05, 0xE0,
0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x04, 0x03, 0x02, 0x05,
0xE0,
];
let key_usage3_wrong = &[0x30, 0x0B];
let key_usage4_wrong = &[
Expand All @@ -1380,6 +1433,19 @@ mod tests {
);
}

#[test]
fn test_case1_get_key_usage_value() {
let key_usage1 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
.expect("unable to read leaf cert!");
let key_usage2 = std::fs::read("../test_key/rsa2048/end_requester_with_spdm_rsp_eku.cert.der")
.expect("unable to read leaf cert!");
let key_usage3 = std::fs::read("../test_key/rsa2048/end_responder_with_spdm_req_eku.cert.der")
.expect("unable to read leaf cert!");
assert_eq!(get_key_usage_value(&key_usage1[280..],), Ok((true, key_usage1[309])));
assert_eq!(get_key_usage_value(&key_usage2[450..],), Ok((true, key_usage2[478])));
assert_eq!(get_key_usage_value(&key_usage3[450..],), Ok((true, key_usage3[478])));
}

#[test]
fn test_case0_check_extensions_spdm_oid() {
let e1 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
Expand Down

0 comments on commit 10677d5

Please sign in to comment.