Re: [PATCH v3 19/21] lib: rspdm: Support SPDM certificate validation
From: Jonathan Cameron
Date: Tue Sep 08 2026 - 20:46:53 EST
On Tue, 1 Sep 2026 11:03:45 +1000
alistair23@xxxxxxxxx wrote:
> From: Alistair Francis <alistair@xxxxxxxxxxxxx>
>
> Support validating the SPDM certificate chain. This only performs basic
> sanity checks on the chain before we continue on. This does not ensure
> that the root CA is trusted, we leave that for userspace to check and
> enforce. Instead we just make sure that the chain is correct, uses
> supported signatures and that it isn't blacklisted in the kernel.
>
> We then store the first leaf certificate for use later.
>
> Signed-off-by: Alistair Francis <alistair@xxxxxxxxxxxxx>
One small thing inline
>
> @@ -846,4 +858,136 @@ pub(crate) fn get_certificate(&mut self, slot: u8) -> Result<(), Error> {
>
> Ok(())
> }
> +
> + pub(crate) fn validate_cert_chain(&mut self, slot: u8) -> Result<(), Error> {
> + let cert_chain_buf = &self.certs[slot as usize];
> + let cert_chain_len = cert_chain_buf.len();
...
> + if let Some(prev) = prev_cert {
> + if let Some(validate) = self.validate {
> + // SAFETY: Call the `validate` function provided.
> + let rc = unsafe { validate(self.dev, slot, prev) };
> + if let Err(e) = to_result(rc) {
> + // SAFETY: `prev_cert` is the previously parsed
> + // certificate from a prior loop iteration.
> + unsafe { bindings::x509_free_certificate(prev) };
> + return Err(e);
> + }
> + }
> +
> + // The leaf key is the same for all slots, so just store the first one.
I'd be tempted to call out MULT_KEY_CAP == 0 for this comment.
> + if self.leaf_key.is_none() {
> + // SAFETY: `prev_cert` is the previously parsed
> + // certificate from a prior loop iteration.
> + self.leaf_key = unsafe { Some((*prev).pub_) };
> + // SAFETY: `prev_cert` is the previously parsed
> + // certificate from a prior loop iteration. We are setting
> + // the `pub` key to null so it isn't freed below
> + unsafe { (*prev).pub_ = core::ptr::null_mut() };
> + }
> +
> + // SAFETY: `prev_cert` is the previously parsed
> + // certificate from a prior loop iteration.
> + unsafe { bindings::x509_free_certificate(prev) };
> + }
> +
> + Ok(())
> + }
> }