From 50dbd3f841056675b7d7dd63332f2779d9ef9800 Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Wed, 25 Sep 2024 13:10:01 +0200 Subject: [PATCH] tpm: check if EK certificate has valid ASN.1 DER encoding Further this removes padding found on some TPMs in the NV indices. If this is not valid, we still use it, but output a warning. Signed-off-by: Thore Sommer --- keylime/src/tpm.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/keylime/src/tpm.rs b/keylime/src/tpm.rs index 54913424..753f96a3 100644 --- a/keylime/src/tpm.rs +++ b/keylime/src/tpm.rs @@ -7,6 +7,7 @@ use crate::algorithms::{ use base64::{engine::general_purpose, Engine as _}; use log::*; use std::convert::{TryFrom, TryInto}; +use std::io::Read; use std::str::FromStr; use thiserror::Error; @@ -338,6 +339,10 @@ pub enum TpmError { #[error("Error finishing Hasher")] OpenSSLHasherFinish { source: openssl::error::ErrorStack }, + /// Error when trying to decode the EK certificate + #[error("EK certificate parsing error")] + EKCertParsing(#[from] picky_asn1_der::Asn1DerError), + /// Number conversion error #[error("Error converting number")] TryFromInt(#[from] std::num::TryFromIntError), @@ -490,6 +495,13 @@ impl Context { }) } + // Tries to parse the EK certificate and re-encodes it to remove potential padding + fn check_ek_cert(&mut self, cert: &[u8]) -> Result> { + let parsed_cert: picky_asn1_der::Asn1RawDer = + picky_asn1_der::from_bytes(cert)?; + Ok(picky_asn1_der::to_vec(&parsed_cert)?) + } + /// Creates an EK, returns the key handle and public certificate /// in `EKResult`. /// @@ -551,7 +563,13 @@ impl Context { }; let cert = match ek::retrieve_ek_pubcert(&mut self.inner, alg.into()) { - Ok(v) => Some(v), + Ok(cert) => match self.check_ek_cert(&cert) { + Ok(cert_checked) => Some(cert_checked), + Err(_) => { + warn!("EK certificate in TPM NVRAM is not ASN.1 DER encoded"); + Some(cert) + } + }, Err(_) => { warn!("No EK certificate found in TPM NVRAM"); None