Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Add SPDM extensions OID check #166

Merged
merged 1 commit into from
Jan 1, 2024
Merged

Add SPDM extensions OID check #166

merged 1 commit into from
Jan 1, 2024

Conversation

OuyangHang33
Copy link
Contributor

@OuyangHang33 OuyangHang33 commented Dec 11, 2023

Fix: #32
Add OID check for spdm extension:

  1. Add SPDM extensions check after SubjectPublicKeyInfo in TBS cert.
  2. Check if SPDM responder/requester auth OIDs appear in the leaf cert.

Find responder auth oid OID;
Find requester auth oid OID;
Check if these 2 OIDs appear in the leaf cert;

  1. Check if Hardware Identity OID present in spdm extension:

Find the SPDM extensions OID;
Find Hardware/Mutable cert Identity OID;
Check if Hardware/Mutable Identity OID present in spdm extension;

let mut requester_auth_oid_find_success: bool = false;
let mut spdm_extension_oid_find_success: bool = false;
let mut hardware_identity_oid_find_success: bool = false;
for index in 0..extensions_end_index_oid {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check should be more detailed, because the scope of the extension is relatively large and there may be coincidences(the data is same as OID, but is not actual OID).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you Wenxing, I will add OID TAG check after detect the target OID.

Copy link
Member

@Wenxing-hou Wenxing-hou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check logic is look good to me. The code detail need to be check by others.

//key_usage EXTENSIONS,
let (find_key_usage, key_usage_value) = get_key_usage_value(&data[t_walker..])?;
let mut check_extensions_success =
!(find_key_usage && (LIBSPDM_CRYPTO_X509_KU_DIGITAL_SIGNATURE & key_usage_value == 0x00));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the key usage value 0x00 mean?
if key usage value has just several candidates, I would recommend use Enum for them.

Copy link
Contributor Author

@OuyangHang33 OuyangHang33 Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here only need to check key_usage value bit0-digitalSignature. If find the key usage value but get bit0 unset, then return false. It means subject public key in the cert SHOULD used for verifying digital signatures in an entity authentication service, a data origin authentication service, and/or an integrity service. Base on RFC5280 page 30-31:

The digitalSignature bit is asserted when the subject public key is used for verifying digital signatures, other than signatures on certificates (bit 5) and CRLs (bit 6), such as those used in an entity authentication service, a data origin authentication service, and/or an integrity service.

If the subject public key is only to be used for verifying signatures on certificates and/or CRLs, then the digitalSignature and nonRepudiation bits SHOULD NOT be set.

In libspdm, it doesn't check any other key_usage bits except bit0-digitalSignature. I follow the libspdm logic:
https://github.com/DMTF/libspdm/blob/3bbcb24dbae81a25cb04dd185b0fe948e6ac6b25/library/spdm_crypt_lib/libspdm_crypt_cert.c#L1082-L1093

Bit String Mapping:
Wenxing-hou/libspdm@f9e1dcf

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check only bit0-digitalSignature looks good to me now, one more suggestion:
define a macro for bit0-digitalSignature or add a comment besides it.

fn check_extensions_spdm_oid(data: &[u8], is_leaf_cert: bool) -> bool {
let len = data.len();
let oid_len = 10;
let extensions_end_index_oid = len - oid_len;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if len < oid_len, this statement will introduce overflow panic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the length check before let extensions_end_index_oid = len - oid_len;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me.

let mut responder_auth_oid_find_success: bool = false;
let mut requester_auth_oid_find_success: bool = false;
for index in 2..extensions_end_index_oid {
if object_identifiers_are_same(&data[index..index + oid_len], OID_DMTF_SPDM_DEVICE_INFO)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to make sure index + oid_len is still a valid index.

Copy link
Contributor Author

@OuyangHang33 OuyangHang33 Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the lenght check before loop, and when execution this loop, data.len() is bigger than 12, and index + oid_len can be caculated as:

2+10 <= index + oid_len < extensions_end_index_oid +10 = data.len() ;

In another world, data[index..index + oid_len] belong to:

data[2..12]~ data[data.len()-10..data.len()]

let mut hardware_identity_oid_find_success: bool = false;
let mut responder_auth_oid_find_success: bool = false;
let mut requester_auth_oid_find_success: bool = false;
if len < 2 + oid_len {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the length check before checking spdm oids via loop.
Because the head of spdm OID cost 2 bytes for descripte TYPE and LEN, so I use len < 2 + oid_len as a condition to determine whether it's possable to find the spdm OIDs in extensions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me.

let mut hardware_identity_oid_find_success: bool = false;
let mut responder_auth_oid_find_success: bool = false;
let mut requester_auth_oid_find_success: bool = false;
if len < 2 + oid_len {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me.

Copy link
Contributor

@longlongyang longlongyang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

let extensions_end_index_oid = len - oid_len;
for index in 2..extensions_end_index_oid {
if object_identifiers_are_same(&data[index..index + oid_len], OID_DMTF_SPDM_DEVICE_INFO)
&& (data[index - 2] == ASN1_TAG_OID)
Copy link
Contributor

@jyao1 jyao1 Dec 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. It is quite unusual that use negative value as index - [index - 2].
  2. It redundant to have data[index - 2] check in each if.
  3. It is not efficient to move index by 1 in for, and also dangerous to mis-compare.

My expectation is:
Find the first tag, skip the tag-length and move to the next tag.
In case of anything wrong, stop the parsing and return error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have changed the check_extensions_spdm_oid logic:
-Get extensions data from cert first
---Get the extnID of the first extension sequence, if not the target, then jump to next extension sequence
-----Search the target id-DMTF-spdm belong to this extension sequence
When didn't find the extension identify under the extension sequence or some length check fail, it will return error

RFC 5280 Page 17 extnID under extension sequence:
image

The id-DMTF-spdm should under the following extension sequence base on the SPDM spec, and I follow this to search the target id-DMTF-spdm OID to ensure they are in the right place:
image


fn check_extensions_spdm_oid(data: &[u8], is_leaf_cert: bool) -> bool {
let len = data.len();
let oid_len = 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why oid_len is 10?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this line now. The new code based on the target SPDM-OID to check the oid_len automatically.

target_oid_find_success = false;
} else {
for index in 0..len - target_oid_len {
if data[index] == ASN1_TAG_OID {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please dont use 1 by 1 search.

} else {
let mut find_key_usage: bool = false;
for index in 0..len - key_usage_oid_len {
if object_identifiers_are_same(&data[index..index + key_usage_oid_len], OID_KEY_USAGE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please dont use 1 by 1 search.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aleady clean all 1 by 1 search.

Signed-off-by: Ouyang, Hang <hang.ouyang@intel.com>
@jyao1 jyao1 merged commit a34daa3 into intel:main Jan 1, 2024
47 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

the certificate chain verification does not have OID check
4 participants