Skip to content

Commit

Permalink
Change cert fields to optional for GenericCert model cert check
Browse files Browse the repository at this point in the history
Fix the issue: DMTF#2656

Signed-off-by: Wenxing Hou <[email protected]>
  • Loading branch information
Wenxing-hou authored and jyao1 committed Jun 13, 2024
1 parent 076c740 commit b15d4ae
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 104 deletions.
33 changes: 19 additions & 14 deletions include/hal/library/cryptlib/cryptlib_cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ extern bool libspdm_asn1_get_tag(uint8_t **ptr, const uint8_t *end, size_t *leng
* @param[in, out] subject_size The size in bytes of the cert_subject buffer on input,
* and the size of buffer returned cert_subject on output.
*
* @retval true The certificate subject retrieved successfully.
* @retval false Invalid certificate, or the subject_size is too small for the result.
* The subject_size will be updated with the required size.
* @retval false This interface is not supported.
* @retval true If the subject_size is not equal 0. The certificate subject retrieved successfully.
* @retval true If the subject_size is equal 0. The certificate parse successful. But the cert doen't have subject.
* @retval false If the subject_size is not equal 0. The certificate subject retrieved successfully.But the subject_size is too small for the result.
* @retval false If the subject_size is equal 0. Invalid certificate.
**/
extern bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_subject,
Expand Down Expand Up @@ -93,10 +93,10 @@ extern bool libspdm_x509_get_serial_number(const uint8_t *cert, size_t cert_size
* @param[in, out] issuer_size The size in bytes of the cert_issuer buffer on input,
* and the size of buffer returned cert_issuer on output.
*
* @retval true The certificate issuer retrieved successfully.
* @retval false Invalid certificate, or the issuer_size is too small for the result.
* The issuer_size will be updated with the required size.
* @retval false This interface is not supported.
* @retval true If the issuer_size is not equal 0. The certificate issuer retrieved successfully.
* @retval true If the issuer_size is equal 0. The certificate parse successful. But the cert doen't have issuer.
* @retval false If the issuer_size is not equal 0. The certificate issuer retrieved successfully. But the issuer_size is too small for the result.
* @retval false If the issuer_size is equal 0. Invalid certificate.
**/
extern bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_issuer,
Expand Down Expand Up @@ -140,9 +140,14 @@ extern bool libspdm_x509_get_extension_data(const uint8_t *cert, size_t cert_siz
* Note: libspdm_x509_compare_date_time to compare date_time oject
* x509SetDateTime to get a date_time object from a date_time_str
*
* @retval true The certificate Validity retrieved successfully.
* @retval false Invalid certificate, or Validity retrieve failed.
* @retval false This interface is not supported.
* @retval true if the from_size and from_size are not equal 0.
* The certificate Validity retrieved successfully.
* @retval true if the from_size and from_size are equal 0.
* The certificate Validity does not exist.
* @retval false if the from_size and from_size are not equal 0.
* The certificate Validity retrieved successfully, but the input buffer size is small.
* @retval false if the from_size and from_size are equal 0.
* Invalid certificate, or Validity retrieve failed.
**/
extern bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
uint8_t *from, size_t *from_size, uint8_t *to,
Expand Down Expand Up @@ -192,9 +197,9 @@ extern int32_t libspdm_x509_compare_date_time(const void *date_time1, const void
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] usage Key usage (LIBSPDM_CRYPTO_X509_KU_*)
*
* @retval true The certificate key usage retrieved successfully.
* @retval false Invalid certificate, or usage is NULL
* @retval false This interface is not supported.
* @retval true if the usage is no equal 0. The certificate key usage retrieved successfully.
* @retval true if the usage is equal 0. The certificate parse successfully, but the cert doen't have key usage.
* @retval false Invalid certificate, or usage is NULL.
**/
extern bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size, size_t *usage);

Expand Down
69 changes: 51 additions & 18 deletions library/spdm_crypt_lib/libspdm_crypt_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,31 +1095,58 @@ bool libspdm_x509_common_certificate_check(const uint8_t *cert, size_t cert_size
/* 4. issuer_name*/
asn1_buffer_len = 0;
status = libspdm_x509_get_issuer_name(cert, cert_size, NULL, &asn1_buffer_len);
if (asn1_buffer_len == 0) {
status = false;
goto cleanup;
if (status) {
if ((asn1_buffer_len == 0) &&
(cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
status = false;
goto cleanup;
}
} else {
if (asn1_buffer_len == 0) {
status = false;
goto cleanup;
}
}

/* 5. subject_name*/
asn1_buffer_len = 0;
status = libspdm_x509_get_subject_name(cert, cert_size, NULL, &asn1_buffer_len);
if (asn1_buffer_len == 0) {
status = false;
goto cleanup;
if (status) {
if ((asn1_buffer_len == 0) &&
(cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
status = false;
goto cleanup;
}
} else {
if (asn1_buffer_len == 0) {
status = false;
goto cleanup;
}
}

/* 6. validaity*/
/* 6. validity*/
status = libspdm_x509_get_validity(cert, cert_size, end_cert_from,
&end_cert_from_len, end_cert_to,
&end_cert_to_len);
if (!status) {
goto cleanup;
if (status) {
if ((end_cert_from_len == 0) &&
(cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
status = false;
goto cleanup;
}
} else {
if (end_cert_from_len == 0) {
status = false;
goto cleanup;
}
}

status = libspdm_internal_x509_date_time_check(
end_cert_from, end_cert_from_len, end_cert_to, end_cert_to_len);
if (!status) {
goto cleanup;
if (end_cert_from_len != 0) {
status = libspdm_internal_x509_date_time_check(
end_cert_from, end_cert_from_len, end_cert_to, end_cert_to_len);
if (!status) {
goto cleanup;
}
}

/* 7. subject_public_key*/
Expand All @@ -1133,12 +1160,18 @@ bool libspdm_x509_common_certificate_check(const uint8_t *cert, size_t cert_size
status = libspdm_x509_get_key_usage(cert, cert_size, &value);
if (!status) {
goto cleanup;
}
if (LIBSPDM_CRYPTO_X509_KU_DIGITAL_SIGNATURE & value) {
status = true;
} else {
status = false;
goto cleanup;
if (value == 0) {
if (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT) {
status = false;
goto cleanup;
}
} else {
if ((LIBSPDM_CRYPTO_X509_KU_DIGITAL_SIGNATURE & value) == 0) {
status = false;
goto cleanup;
}
}
}

/* 9. verify spdm defined extended key usage*/
Expand Down
69 changes: 54 additions & 15 deletions os_stub/cryptlib_mbedtls/pk/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ bool libspdm_asn1_get_tag(uint8_t **ptr, const uint8_t *end, size_t *length,
* If cert is NULL, then return false.
* If subject_size is NULL, then return false.
*
* @retval true The certificate subject retrieved successfully.
* @retval false Invalid certificate, or the subject_size is too small for the result.
* The subject_size will be updated with the required size.
*
* @retval true If the subject_size is not equal 0. The certificate subject retrieved successfully.
* @retval true If the subject_size is equal 0. The certificate parse successful. But the cert doen't have subject.
* @retval false If the subject_size is not equal 0. The certificate subject retrieved successfully.But the subject_size is too small for the result.
* @retval false If the subject_size is equal 0. Invalid certificate.
**/
bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_subject,
Expand All @@ -273,7 +273,11 @@ bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
int ret;
bool status;

if (cert == NULL) {
/* Check input parameters.*/
if (cert == NULL || cert == 0 || subject_size == NULL) {
if (subject_size != NULL) {
*subject_size = 0;
}
return false;
}

Expand All @@ -295,6 +299,8 @@ bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
}
*subject_size = crt.subject_raw.len;
status = true;
} else {
*subject_size = 0;
}

cleanup:
Expand Down Expand Up @@ -975,10 +981,10 @@ bool libspdm_x509_get_serial_number(const uint8_t *cert, size_t cert_size,
* @param[in, out] issuer_size The size in bytes of the cert_issuer buffer on input,
* and the size of buffer returned cert_issuer on output.
*
* @retval true The certificate issuer retrieved successfully.
* @retval false Invalid certificate, or the issuer_size is too small for the result.
* The issuer_size will be updated with the required size.
* @retval false This interface is not supported.
* @retval true If the issuer_size is not equal 0. The certificate issuer retrieved successfully.
* @retval true If the issuer_size is equal 0. The certificate parse successful. But the cert doen't have issuer.
* @retval false If the issuer_size is not equal 0. The certificate issuer retrieved successfully. But the issuer_size is too small for the result.
* @retval false If the issuer_size is equal 0. Invalid certificate.
*
**/
bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
Expand All @@ -989,7 +995,11 @@ bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
int ret;
bool status;

if (cert == NULL) {
/* Check input parameters.*/
if (cert == NULL || cert_size == 0 || issuer_size == NULL) {
if (issuer_size != NULL) {
*issuer_size = 0;
}
return false;
}

Expand All @@ -1010,6 +1020,8 @@ bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
}
*issuer_size = crt.issuer_raw.len;
status = true;
} else {
*issuer_size = 0;
}

cleanup:
Expand Down Expand Up @@ -1341,19 +1353,37 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
bool status;
size_t t_size;
size_t f_size;
mbedtls_x509_time zero_time;

if (cert == NULL) {
/* Check input parameters.*/
if (cert == NULL || from_size == NULL || to_size == NULL ||
cert_size == 0) {
if (from_size != NULL) {
*from_size = 0;
}
if (to_size != NULL) {
*to_size = 0;
}
return false;
}

status = false;

mbedtls_x509_crt_init(&crt);
libspdm_zero_mem(&zero_time, sizeof(mbedtls_x509_time));

ret = mbedtls_x509_crt_parse_der(&crt, cert, cert_size);

if (ret == 0) {
f_size = sizeof(mbedtls_x509_time);
if ((libspdm_consttime_is_mem_equal(&zero_time, &(crt.valid_from), f_size)) &&
(libspdm_consttime_is_mem_equal(&zero_time, &(crt.valid_to), f_size))) {
*from_size = 0;
*to_size = 0;
status = true;
goto done;
}

if (*from_size < f_size) {
*from_size = f_size;
goto done;
Expand All @@ -1374,6 +1404,9 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
}
*to_size = t_size;
status = true;
} else {
*from_size = 0;
*to_size = 0;
}

done:
Expand All @@ -1389,9 +1422,9 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
* @param[in] cert_size size of the X509 certificate in bytes.
* @param[out] usage key usage (LIBSPDM_CRYPTO_X509_KU_*)
*
* @retval true The certificate key usage retrieved successfully.
* @retval false Invalid certificate, or usage is NULL
* @retval false This interface is not supported.
* @retval true if the usage is no equal 0. The certificate key usage retrieved successfully.
* @retval true if the usage is equal 0. The certificate parse successfully, but the cert doen't have key usage.
* @retval false Invalid certificate, or usage is NULL.
**/
bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size,
size_t *usage)
Expand All @@ -1400,7 +1433,11 @@ bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size,
int ret;
bool status;

if (cert == NULL) {
/* Check input parameters.*/
if (cert == NULL || cert_size == 0 || usage == NULL) {
if (usage != NULL) {
*usage = 0;
}
return false;
}

Expand All @@ -1413,6 +1450,8 @@ bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size,
if (ret == 0) {
*usage = crt.MBEDTLS_PRIVATE(key_usage);
status = true;
} else {
*usage = 0;
}
mbedtls_x509_crt_free(&crt);

Expand Down
22 changes: 11 additions & 11 deletions os_stub/cryptlib_null/pk/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ bool libspdm_asn1_get_tag(uint8_t **ptr, const uint8_t *end, size_t *length,
* If cert is NULL, then return false.
* If subject_size is NULL, then return false.
*
* @retval true The certificate subject retrieved successfully.
* @retval false Invalid certificate, or the subject_size is too small for the result.
* The subject_size will be updated with the required size.
*
* @retval true If the subject_size is not equal 0. The certificate subject retrieved successfully.
* @retval true If the subject_size is equal 0. The certificate parse successful. But the cert doen't have subject.
* @retval false If the subject_size is not equal 0. The certificate subject retrieved successfully.But the subject_size is too small for the result.
* @retval false If the subject_size is equal 0. Invalid certificate.
**/
bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_subject,
Expand Down Expand Up @@ -450,10 +450,10 @@ bool libspdm_x509_get_serial_number(const uint8_t *cert, size_t cert_size,
* @param[in, out] issuer_size The size in bytes of the cert_issuer buffer on input,
* and the size of buffer returned cert_issuer on output.
*
* @retval true The certificate issuer retrieved successfully.
* @retval false Invalid certificate, or the issuer_size is too small for the result.
* The issuer_size will be updated with the required size.
* @retval false This interface is not supported.
* @retval true If the issuer_size is not equal 0. The certificate issuer retrieved successfully.
* @retval true If the issuer_size is equal 0. The certificate parse successful. But the cert doen't have issuer.
* @retval false If the issuer_size is not equal 0. The certificate issuer retrieved successfully. But the issuer_size is too small for the result.
* @retval false If the issuer_size is equal 0. Invalid certificate.
*
**/
bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
Expand Down Expand Up @@ -621,9 +621,9 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
* @param[in] cert_size size of the X509 certificate in bytes.
* @param[out] usage key usage (LIBSPDM_CRYPTO_X509_KU_*)
*
* @retval true The certificate key usage retrieved successfully.
* @retval false Invalid certificate, or usage is NULL
* @retval false This interface is not supported.
* @retval true if the usage is no equal 0. The certificate key usage retrieved successfully.
* @retval true if the usage is equal 0. The certificate parse successfully, but the cert doen't have key usage.
* @retval false Invalid certificate, or usage is NULL.
**/
bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size,
size_t *usage)
Expand Down
Loading

0 comments on commit b15d4ae

Please sign in to comment.