Skip to content

Commit

Permalink
Make libspdm_get_certificate_choose_length[_ex]() public APIs
Browse files Browse the repository at this point in the history
fix #2909

Signed-off-by: Shital Jumbad <[email protected]>
  • Loading branch information
ShitalJumbad authored and jyao1 committed Dec 12, 2024
1 parent 793674c commit e660843
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 32 deletions.
47 changes: 47 additions & 0 deletions doc/api/requester_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,53 @@ libspdm will perform the following checks over the leaf certificate.
- If the `BasicConstraints` field exists then verify that the `cA` is false.
<br/><br/>

---
### libspdm_get_certificate_choose_length_ex
---

### Description
Sends GET_CERTIFICATE and retrieves a certificate chain in one slot from the device, allowing the Integrator to specify the size of the certificate chain blocks.

### Parameters

**spdm_context**<br/>
The SPDM context.

**session_id**<br/>
Indicates if it is a secured message (non-NULL) or an unsecured message (NULL).

**slot_id**<br/>
The certificate chain slot number.

**length**<br/>
The length of the certificate chain block to be retrieved.

**cert_chain_size**<br/>
On input, indicates the size, in bytes, of the buffer in which the certificate chain will be stored.
The maximum size of an SPDM certificate chain is given by `SPDM_MAX_CERTIFICATE_CHAIN_SIZE` and is
65535 bytes.
On output, indicates the size, in bytes, of the certificate chain.

**cert_chain**<br/>
A pointer to a buffer of size `cert_chain_size` in which the certificate chain will be stored.

**trust_anchor**<br/>
A buffer to hold the trust anchor which is used to validate the peer certificate. If NULL, the trust anchor is not stored.

**trust_anchor_size**<br/>
A buffer to hold the size of the trust anchor. If NULL, the trust anchor size is not stored.

### Details
Before calling this function the Integrator should have determined which certificate chain slots are
populated through `libspdm_get_digest`, although that is not strictly required. Once the certificate
chain has been retrieved libspdm will validate the chain and its leaf certificate. This function performs the following operations:
1. Sends the `GET_CERTIFICATE` request to the device for the specified slot.
2. Retrieves the certificate chain in blocks of the specified size (`length`).
3. Verifies the integrity of the certificate chain from the root certificate to the leaf certificate, following the structure:
- root_hash -> Root certificate -> Intermediate certificate -> Leaf certificate.
4. If a peer root certificate hash is deployed, validates the root certificate digest against the deployed root hash.
<br/><br/>

---
### libspdm_challenge
---
Expand Down
30 changes: 0 additions & 30 deletions include/internal/libspdm_requester_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,36 +177,6 @@ libspdm_return_t libspdm_get_certificate_choose_length(void *spdm_context,
uint16_t length,
size_t *cert_chain_size,
void *cert_chain);

/**
* This function sends GET_CERTIFICATE to get certificate chain in one slot from device.
*
* This function verify the integrity of the certificate chain.
* root_hash -> Root certificate -> Intermediate certificate -> Leaf certificate.
*
* If the peer root certificate hash is deployed,
* this function also verifies the digest with the root hash in the certificate chain.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_id Indicates if it is a secured message protected via SPDM session.
* If session_id is NULL, it is a normal message.
* @param slot_id The number of slot for the certificate chain.
* @param length LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN.
* @param cert_chain_size On input, indicate the size in bytes of the destination buffer to store the digest buffer.
* On output, indicate the size in bytes of the certificate chain.
* @param cert_chain A pointer to a destination buffer to store the certificate chain.
* @param trust_anchor A buffer to hold the trust_anchor which is used to validate the peer certificate, if not NULL.
* @param trust_anchor_size A buffer to hold the trust_anchor_size, if not NULL.
**/
libspdm_return_t libspdm_get_certificate_choose_length_ex(void *spdm_context,
const uint32_t *session_id,
uint8_t slot_id,
uint16_t length,
size_t *cert_chain_size,
void *cert_chain,
const void **trust_anchor,
size_t *trust_anchor_size);

#if LIBSPDM_ENABLE_CAPABILITY_MEL_CAP
/**
* This function sends GET_MEASUREMENT_EXTENSION_LOG to get MEL from device.
Expand Down
30 changes: 30 additions & 0 deletions include/library/spdm_requester_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,36 @@ libspdm_return_t libspdm_get_certificate_ex(void *spdm_context,
void *cert_chain,
const void **trust_anchor,
size_t *trust_anchor_size);

/**
* This function sends GET_CERTIFICATE to get certificate chain in one slot from the device,
* and allows the Integrator to specify the size of the certificate chain blocks.
*
* This function verify the integrity of the certificate chain.
* root_hash -> Root certificate -> Intermediate certificate -> Leaf certificate.
*
* If the peer root certificate hash is deployed,
* this function also verifies the digest with the root hash in the certificate chain.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_id Indicates if it is a secured message protected via SPDM session.
* If session_id is NULL, it is a normal message.
* @param slot_id The number of slot for the certificate chain.
* @param length The length of the certificate chain block to retrieve.
* @param cert_chain_size On input, indicate the size in bytes of the destination buffer to store the digest buffer.
* On output, indicate the size in bytes of the certificate chain.
* @param cert_chain A pointer to a destination buffer to store the certificate chain.
* @param trust_anchor A buffer to hold the trust_anchor which is used to validate the peer certificate, if not NULL.
* @param trust_anchor_size A buffer to hold the trust_anchor_size, if not NULL.
**/
libspdm_return_t libspdm_get_certificate_choose_length_ex(void *spdm_context,
const uint32_t *session_id,
uint8_t slot_id,
uint32_t length,
size_t *cert_chain_size,
void *cert_chain,
const void **trust_anchor,
size_t *trust_anchor_size);
#endif /* LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT */

/**
Expand Down
7 changes: 5 additions & 2 deletions library/spdm_requester_lib/libspdm_req_get_certificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ libspdm_return_t libspdm_get_certificate_choose_length(void *spdm_context,
libspdm_return_t libspdm_get_certificate_choose_length_ex(void *spdm_context,
const uint32_t *session_id,
uint8_t slot_id,
uint16_t length,
uint32_t length,
size_t *cert_chain_size,
void *cert_chain,
const void **trust_anchor,
Expand All @@ -482,12 +482,15 @@ libspdm_return_t libspdm_get_certificate_choose_length_ex(void *spdm_context,
uint64_t retry_delay_time;
libspdm_return_t status;

/* -=[Check Parameters Phase]=- */
LIBSPDM_ASSERT(length <= 0xFFFF);

context = spdm_context;
context->crypto_request = true;
retry = context->retry_times;
retry_delay_time = context->retry_delay_time;
do {
status = libspdm_try_get_certificate(context, session_id, slot_id, length,
status = libspdm_try_get_certificate(context, session_id, slot_id, (uint16_t)length,
cert_chain_size, cert_chain, trust_anchor,
trust_anchor_size);
if (status != LIBSPDM_STATUS_BUSY_PEER) {
Expand Down

0 comments on commit e660843

Please sign in to comment.