From f781f61f446730e252f09f5c3e6331c4bde59e23 Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Mon, 9 Mar 2026 18:16:50 +0100 Subject: [PATCH] fix(native-certgen): address production audit findings Make logging init idempotent (swallow SetGlobalDefaultError on repeat call), remove unused dumpLogs JNI params that violated the API contract, and strip dead public_key_spki field + build_ec_spki() that were computed on every keygen but never consumed by the cert builder. --- .../matrix/TEESimulator/pki/NativeCertGen.kt | 5 +- native-certgen/src/keygen.rs | 72 ------------------- native-certgen/src/lib.rs | 2 - native-certgen/src/logging/mod.rs | 5 +- native-certgen/src/types.rs | 1 - 5 files changed, 5 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/org/matrix/TEESimulator/pki/NativeCertGen.kt b/app/src/main/java/org/matrix/TEESimulator/pki/NativeCertGen.kt index f90c464..eb75b29 100644 --- a/app/src/main/java/org/matrix/TEESimulator/pki/NativeCertGen.kt +++ b/app/src/main/java/org/matrix/TEESimulator/pki/NativeCertGen.kt @@ -50,7 +50,6 @@ data class CertGenConfig( object NativeCertGen { private const val LOG_DIR = "/data/adb/tricky_store/logs" - private const val BASE_DIR = "/data/adb/tricky_store" @Volatile var isAvailable: Boolean = false @@ -71,9 +70,9 @@ object NativeCertGen { private external fun initLogging(verbose: Boolean, logDir: String): Boolean - private external fun dumpLogs(logDir: String, baseDir: String): String? + private external fun dumpLogs(): String? - fun dump(): String? = if (isAvailable) dumpLogs(LOG_DIR, BASE_DIR) else null + fun dump(): String? = if (isAvailable) dumpLogs() else null fun parseNativeResult(bytes: ByteArray): Pair> { val buf = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN) diff --git a/native-certgen/src/keygen.rs b/native-certgen/src/keygen.rs index 3b0b426..5f57a70 100644 --- a/native-certgen/src/keygen.rs +++ b/native-certgen/src/keygen.rs @@ -17,8 +17,6 @@ pub fn generate_key_pair( } fn generate_ec_key_pair(curve: EcCurve) -> Result { - use ring::signature::KeyPair; - let alg = match curve { EcCurve::P256 => &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING, EcCurve::P384 => &ring::signature::ECDSA_P384_SHA384_ASN1_SIGNING, @@ -27,79 +25,14 @@ fn generate_ec_key_pair(curve: EcCurve) -> Result { let rng = ring::rand::SystemRandom::new(); let pkcs8_doc = ring::signature::EcdsaKeyPair::generate_pkcs8(alg, &rng)?; - let key_pair = ring::signature::EcdsaKeyPair::from_pkcs8(alg, pkcs8_doc.as_ref(), &rng)?; - - let raw_point = key_pair.public_key().as_ref(); - let spki = build_ec_spki(curve, raw_point)?; Ok(GeneratedKeyPair { private_key_pkcs8: pkcs8_doc.as_ref().to_vec(), - public_key_spki: spki, }) } -/// Build SubjectPublicKeyInfo DER from a raw EC uncompressed point. -fn build_ec_spki(curve: EcCurve, raw_point: &[u8]) -> Result> { - // SPKI = SEQUENCE { AlgorithmIdentifier, BIT STRING(public key) } - // AlgorithmIdentifier = SEQUENCE { OID(ecPublicKey), OID(curve) } - // - // DER-encode manually — the prefix is fixed per curve, only the point varies. - - // OID 1.2.840.10045.2.1 (id-ecPublicKey) - const EC_PUBLIC_KEY_OID: &[u8] = &[0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01]; - - let curve_oid: &[u8] = match curve { - // OID 1.2.840.10045.3.1.7 (prime256v1 / P-256) - EcCurve::P256 => &[0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07], - // OID 1.3.132.0.34 (secp384r1 / P-384) - EcCurve::P384 => &[0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22], - _ => return Err(CertGenError::UnsupportedEcCurve(curve as i32)), - }; - - let alg_id_seq = der_sequence(EC_PUBLIC_KEY_OID, curve_oid); - - // BIT STRING: 0x03, length, 0x00 (unused bits), raw_point - let bit_string_content_len = 1 + raw_point.len(); // 0x00 byte + point - let mut bit_string = vec![0x03]; - encode_der_length(&mut bit_string, bit_string_content_len); - bit_string.push(0x00); // zero unused bits - bit_string.extend_from_slice(raw_point); - - // Outer SEQUENCE - let inner_len = alg_id_seq.len() + bit_string.len(); - let mut spki = vec![0x30]; - encode_der_length(&mut spki, inner_len); - spki.extend_from_slice(&alg_id_seq); - spki.extend_from_slice(&bit_string); - - Ok(spki) -} - -fn der_sequence(a: &[u8], b: &[u8]) -> Vec { - let content_len = a.len() + b.len(); - let mut seq = vec![0x30]; - encode_der_length(&mut seq, content_len); - seq.extend_from_slice(a); - seq.extend_from_slice(b); - seq -} - -fn encode_der_length(buf: &mut Vec, len: usize) { - if len < 0x80 { - buf.push(len as u8); - } else if len < 0x100 { - buf.push(0x81); - buf.push(len as u8); - } else { - buf.push(0x82); - buf.push((len >> 8) as u8); - buf.push(len as u8); - } -} - fn generate_rsa_key_pair(key_size: u32, rsa_public_exponent: u64) -> Result { use pkcs8::EncodePrivateKey; - use rsa::pkcs8::EncodePublicKey; if !matches!(key_size, 2048 | 3072 | 4096) { return Err(CertGenError::InvalidParameter( @@ -120,12 +53,7 @@ fn generate_rsa_key_pair(key_size: u32, rsa_public_exponent: u64) -> Result pub extern "system" fn Java_org_matrix_TEESimulator_pki_NativeCertGen_dumpLogs( mut env: JNIEnv, _class: JClass, - _log_dir: JString, - _base_dir: JString, ) -> jstring { let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { dump_logs_inner(&mut env) diff --git a/native-certgen/src/logging/mod.rs b/native-certgen/src/logging/mod.rs index 3e770ca..c4e43b2 100644 --- a/native-certgen/src/logging/mod.rs +++ b/native-certgen/src/logging/mod.rs @@ -29,12 +29,13 @@ pub fn init( let rotating_layer = rotating::RotatingFileLayer::new(log_dir, max_size, max_files); let stderr_layer = tracing_subscriber::fmt::layer().with_writer(std::io::stderr); - tracing_subscriber::registry() + // Idempotent — second call returns Ok instead of propagating SetGlobalDefaultError + let _ = tracing_subscriber::registry() .with(filter) .with(kmsg_layer) .with(rotating_layer) .with(stderr_layer) - .try_init()?; + .try_init(); Ok(()) } diff --git a/native-certgen/src/types.rs b/native-certgen/src/types.rs index 1e76542..ec77f33 100644 --- a/native-certgen/src/types.rs +++ b/native-certgen/src/types.rs @@ -118,5 +118,4 @@ pub struct CertGenParams { pub struct GeneratedKeyPair { pub private_key_pkcs8: Vec, - pub public_key_spki: Vec, }