Skip to content

Commit

Permalink
fix hardware identity oid check logic.
Browse files Browse the repository at this point in the history
fix #14

Signed-off-by: Yang, Longlong <[email protected]>
  • Loading branch information
longlongyang committed Jan 29, 2024
1 parent f9b4c5a commit 5879a2c
Showing 1 changed file with 172 additions and 4 deletions.
176 changes: 172 additions & 4 deletions spdmlib/src/crypto/x509v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ const ASN1_TAG_CLASS_CONTEXT_SPECIFIC_MASK: u8 = 0x80;

const ASN1_FORM_CONSTRUCTED_MASK: u8 = 0x20;

const ASN1_TAG_BOOLEAN: u8 = 0x1;
const ASN1_TAG_NUMBER_INTEGER: u8 = 0x2;
const ASN1_TAG_BIT_STRING: u8 = 0x3;
const ASN1_TAG_OCTET_STRING: u8 = 0x4;
const ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: u8 = 0x6;
const ASN1_TAG_NUMBER_SEQUENCE: u8 = 0x10;

Expand Down Expand Up @@ -224,6 +226,36 @@ fn check_tag_is_sequence(data: &[u8]) -> SpdmResult {
}
}

fn check_tag_is_num_oid(data: &[u8]) -> SpdmResult {
if data.is_empty() {
Err(SPDM_STATUS_VERIF_FAIL)
} else if data[0] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
Ok(())
} else {
Err(SPDM_STATUS_VERIF_FAIL)
}
}

fn check_tag_is_bool(data: &[u8]) -> SpdmResult {
if data.is_empty() {
Err(SPDM_STATUS_VERIF_FAIL)
} else if data[0] == ASN1_TAG_BOOLEAN {
Ok(())
} else {
Err(SPDM_STATUS_VERIF_FAIL)
}
}

fn check_tag_is_octet_string(data: &[u8]) -> SpdmResult {
if data.is_empty() {
Err(SPDM_STATUS_VERIF_FAIL)
} else if data[0] == ASN1_TAG_OCTET_STRING {
Ok(())
} else {
Err(SPDM_STATUS_VERIF_FAIL)
}
}

// IN bytes slice
// OUT Ok (length, bytes consumed)
// OUT Error Mulformed certificate found
Expand Down Expand Up @@ -470,6 +502,144 @@ fn find_target_object_identifiers(data: &[u8], target_oid: &[u8]) -> SpdmResult<
Ok(target_oid_find_success)
}

// IN extension sequences slice
// OUT true when find hardware oid
// OUT false when not find hardware oid
fn find_hardware_object_identifiers_in_extensions(data: &[u8]) -> SpdmResult<bool> {
let len = data.len();
let mut walker = 0usize;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

check_tag_is_sequence(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (payload_length, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker + payload_length > len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let data = &data[walker..walker + payload_length];
let len = payload_length;
walker = 0;
while walker < len {
check_tag_is_sequence(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (extension_length, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let next_ext_walker = walker + extension_length;

check_tag_is_num_oid(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (payload_length, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

if walker + payload_length < len
&& object_identifiers_are_same(
&data[walker..walker + payload_length],
OID_DMTF_SPDM_EXTENSION,
)
{
walker += payload_length;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

// check critical, it is optional
if check_tag_is_bool(&data[walker..]).is_ok() {
walker += 3; // tag, length, value
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}
}

// next find hardware oid
check_tag_is_octet_string(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (_, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

// sequence
check_tag_is_sequence(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (_, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

// sequence
check_tag_is_sequence(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (_, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

check_tag_is_num_oid(&data[walker..])?;
walker += 1;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

let (target_oid_length, bytes_consumed) = check_length(&data[walker..])?;
walker += bytes_consumed;
if walker >= len {
return Err(SPDM_STATUS_VERIF_FAIL);
}

if walker + target_oid_length <= len
&& object_identifiers_are_same(
&data[walker..walker + target_oid_length],
OID_DMTF_SPDM_HARDWARE_IDENTITY,
)
{
return Ok(true);
}
}

walker = next_ext_walker;
}

Ok(false)
}

// IN extension sequence slice
// OUT Ok (extnID, extn sequence length)
// OUT Error not found extnID, verify fail
Expand Down Expand Up @@ -692,13 +862,11 @@ pub fn check_leaf_certificate(cert: &[u8], is_alias_cert_model: bool) -> SpdmRes
//extensions EXTENSIONS,
let (_, extension_data) = check_and_get_extensions(&data[t_walker..])?;

if is_alias_cert_model
&& find_target_object_identifiers(extension_data, OID_DMTF_SPDM_HARDWARE_IDENTITY)?
{
if is_alias_cert_model && find_hardware_object_identifiers_in_extensions(extension_data)? {
info!("Hardware identity OID shall not be present in alias cert!\n");
Err(SPDM_STATUS_VERIF_FAIL)
} else if !is_alias_cert_model
&& !find_target_object_identifiers(extension_data, OID_DMTF_SPDM_HARDWARE_IDENTITY)?
&& !find_hardware_object_identifiers_in_extensions(extension_data)?
{
info!("Hardware identity OID should be present in device cert!\n");
Ok(())
Expand Down

0 comments on commit 5879a2c

Please sign in to comment.