Files
TEESimulator-RS/native-certgen/src/error.rs
T
Enginex0 ba0628c687 fix(attestation): reject oversized challenges and rewrite cert DER encoding
DuckDetector flagged two issues:
1. Oversized challenge accepted — 256-byte attestation challenge should
   return INVALID_INPUT_LENGTH (-21) like real KeyMint. Added early check
   in handleGenerateKey before any path decision.
2. Issuer/subject chain mismatch — rcgen's HashMap loses DN attribute
   ordering and converts PrintableString to UTF8String, producing
   different DER bytes. Replaced rcgen with manual DER assembly that
   injects raw keybox issuer_dn_der bytes directly.

Verified on device: TX_ID 315 rejects 256-byte challenge, TX_ID 501
generates valid 4-cert chain with correct issuer linkage.
2026-03-09 21:52:06 +01:00

76 lines
2.5 KiB
Rust

use std::fmt;
#[derive(Debug)]
pub enum CertGenError {
Jni(String),
NullParam(&'static str),
UnsupportedAlgorithm(i32),
UnsupportedEcCurve(i32),
KeyGenFailed(String),
CertBuildFailed(String),
KeyboxParseFailed(String),
AttestationBuildFailed(String),
DerError(der::Error),
EmptyKeyboxChain,
ChallengeTooLong(usize),
InvalidParameter(String),
SigningFailed(String),
SerializationFailed(String),
}
impl fmt::Display for CertGenError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Jni(msg) => write!(f, "JNI error: {}", msg),
Self::NullParam(name) => write!(f, "null required parameter: {}", name),
Self::UnsupportedAlgorithm(v) => write!(f, "unsupported algorithm: {}", v),
Self::UnsupportedEcCurve(v) => write!(f, "unsupported EC curve: {}", v),
Self::KeyGenFailed(msg) => write!(f, "key generation failed: {}", msg),
Self::CertBuildFailed(msg) => write!(f, "certificate build failed: {}", msg),
Self::KeyboxParseFailed(msg) => write!(f, "keybox parse failed: {}", msg),
Self::AttestationBuildFailed(msg) => write!(f, "attestation build failed: {}", msg),
Self::DerError(e) => write!(f, "DER error: {}", e),
Self::EmptyKeyboxChain => write!(f, "keybox certificate chain is empty"),
Self::ChallengeTooLong(len) => write!(f, "attestation challenge too long: {} bytes (max 128)", len),
Self::InvalidParameter(msg) => write!(f, "invalid parameter: {}", msg),
Self::SigningFailed(msg) => write!(f, "signing failed: {}", msg),
Self::SerializationFailed(msg) => write!(f, "serialization failed: {}", msg),
}
}
}
impl std::error::Error for CertGenError {}
impl From<jni::errors::Error> for CertGenError {
fn from(e: jni::errors::Error) -> Self {
Self::Jni(e.to_string())
}
}
impl From<der::Error> for CertGenError {
fn from(e: der::Error) -> Self {
Self::DerError(e)
}
}
impl From<ring::error::Unspecified> for CertGenError {
fn from(e: ring::error::Unspecified) -> Self {
Self::KeyGenFailed(e.to_string())
}
}
impl From<ring::error::KeyRejected> for CertGenError {
fn from(e: ring::error::KeyRejected) -> Self {
Self::KeyGenFailed(e.to_string())
}
}
impl From<rsa::Error> for CertGenError {
fn from(e: rsa::Error) -> Self {
Self::KeyGenFailed(e.to_string())
}
}
pub type Result<T> = std::result::Result<T, CertGenError>;