diff --git a/include/hal/library/cryptlib/cryptlib_cert.h b/include/hal/library/cryptlib/cryptlib_cert.h index c3cf7b5ae28..dbcd5ecce22 100644 --- a/include/hal/library/cryptlib/cryptlib_cert.h +++ b/include/hal/library/cryptlib/cryptlib_cert.h @@ -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, @@ -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, @@ -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, @@ -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); diff --git a/library/spdm_crypt_lib/libspdm_crypt_cert.c b/library/spdm_crypt_lib/libspdm_crypt_cert.c index 41d4cd3a2d5..c082d00b64d 100644 --- a/library/spdm_crypt_lib/libspdm_crypt_cert.c +++ b/library/spdm_crypt_lib/libspdm_crypt_cert.c @@ -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*/ @@ -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*/ diff --git a/os_stub/cryptlib_mbedtls/pk/x509.c b/os_stub/cryptlib_mbedtls/pk/x509.c index 245874f60cb..2c6e01b7c05 100644 --- a/os_stub/cryptlib_mbedtls/pk/x509.c +++ b/os_stub/cryptlib_mbedtls/pk/x509.c @@ -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, @@ -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; } @@ -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: @@ -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, @@ -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; } @@ -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: @@ -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; @@ -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: @@ -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) @@ -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; } @@ -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); diff --git a/os_stub/cryptlib_null/pk/x509.c b/os_stub/cryptlib_null/pk/x509.c index 799ec573593..73d637e8a5e 100644 --- a/os_stub/cryptlib_null/pk/x509.c +++ b/os_stub/cryptlib_null/pk/x509.c @@ -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, @@ -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, @@ -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) diff --git a/os_stub/cryptlib_openssl/pk/x509.c b/os_stub/cryptlib_openssl/pk/x509.c index d5793d27706..c77ab4cfe4b 100644 --- a/os_stub/cryptlib_openssl/pk/x509.c +++ b/os_stub/cryptlib_openssl/pk/x509.c @@ -301,10 +301,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, @@ -315,31 +315,31 @@ bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size, X509_NAME *x509_name; size_t x509_name_size; - /* Check input parameters.*/ - - if (cert == NULL || subject_size == NULL) { + if (cert == NULL || cert == 0 || subject_size == NULL) { + if (subject_size != NULL) { + *subject_size = 0; + } return false; } x509_cert = NULL; - /* Read DER-encoded X509 Certificate and Construct X509 object.*/ - res = libspdm_x509_construct_certificate(cert, cert_size, (uint8_t **)&x509_cert); if ((x509_cert == NULL) || (!res)) { + *subject_size = 0; res = false; goto done; } res = false; - /* Retrieve subject name from certificate object.*/ - x509_name = X509_get_subject_name(x509_cert); if (x509_name == NULL) { + *subject_size = 0; + res = true; goto done; } @@ -357,7 +357,6 @@ bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size, done: /* Release Resources.*/ - if (x509_cert != NULL) { X509_free(x509_cert); } @@ -847,10 +846,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, @@ -862,31 +861,31 @@ bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size, X509_NAME *x509_name; size_t x509_name_size; - /* Check input parameters.*/ - - if (cert == NULL || issuer_size == NULL) { + if (cert == NULL || cert_size == 0 || issuer_size == NULL) { + if (issuer_size != NULL) { + *issuer_size = 0; + } return false; } x509_cert = NULL; - /* Read DER-encoded X509 Certificate and Construct X509 object.*/ - res = libspdm_x509_construct_certificate(cert, cert_size, (uint8_t **)&x509_cert); if ((x509_cert == NULL) || (!res)) { res = false; + *issuer_size = 0; goto done; } res = false; - /* Retrieve issuer name from certificate object.*/ - x509_name = X509_get_issuer_name(x509_cert); if (x509_name == NULL) { + *issuer_size = 0; + res = true; goto done; } @@ -904,7 +903,6 @@ bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size, done: /* Release Resources.*/ - if (x509_cert != NULL) { X509_free(x509_cert); } @@ -1101,38 +1099,45 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size, size_t t_size; size_t f_size; - /* 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; } x509_cert = NULL; res = false; - /* Read DER-encoded X509 Certificate and Construct X509 object.*/ - res = libspdm_x509_construct_certificate(cert, cert_size, (uint8_t **)&x509_cert); if ((x509_cert == NULL) || (!res)) { + *from_size = 0; + *to_size = 0; + res = false; goto done; } - /* Retrieve Validity from/to from certificate object.*/ - f_time = X509_get0_notBefore(x509_cert); t_time = X509_get0_notAfter(x509_cert); if (f_time == NULL || t_time == NULL) { + *from_size = 0; + *to_size = 0; + res = true; goto done; } f_size = sizeof(ASN1_TIME) + f_time->length; if (*from_size < f_size) { *from_size = f_size; + res = false; goto done; } if (from != NULL) { @@ -1147,6 +1152,7 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size, t_size = sizeof(ASN1_TIME) + t_time->length; if (*to_size < t_size) { *to_size = t_size; + res = false; goto done; } if (to != NULL) { @@ -1163,7 +1169,6 @@ bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size, done: /* Release Resources.*/ - if (x509_cert != NULL) { X509_free(x509_cert); } @@ -1268,9 +1273,9 @@ int32_t libspdm_x509_compare_date_time(const void *date_time1, const void *date_ * @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) @@ -1278,37 +1283,32 @@ bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size, bool res; X509 *x509_cert; - /* Check input parameters.*/ - - if (cert == NULL || usage == NULL) { + if (cert == NULL || cert_size == 0 || usage == NULL) { + if (usage != NULL) { + *usage = 0; + } return false; } x509_cert = NULL; res = false; - /* Read DER-encoded X509 Certificate and Construct X509 object.*/ - res = libspdm_x509_construct_certificate(cert, cert_size, (uint8_t **)&x509_cert); if ((x509_cert == NULL) || (!res)) { + res = false; + *usage = 0; goto done; } - - /* Retrieve subject name from certificate object.*/ - + /* Retrieve key usage from certificate object.*/ *usage = X509_get_key_usage(x509_cert); - if (*usage == NID_undef) { - goto done; - } res = true; done: /* Release Resources.*/ - if (x509_cert != NULL) { X509_free(x509_cert); }