feat(logging): UID-keyed attestation dossier
Add a debug-only per-UID diagnostic plane gated on BuildConfig.DEBUG. For apps in target.txt it records every keystore interaction and the forged attestation it produces to teesim-uid-<uid>.log: decoded cert chain (FORGE and PATCH paths), key params, keybox, and prop sources, with the calling UID threaded through the C++ binder hook and Rust certgen. Release builds stay silent (R8 strips the write plane and the runtime gate short-circuits). Adds --clear-logs to package.sh.
This commit is contained in:
@@ -64,18 +64,41 @@ fn generate_attested_inner(env: &mut JNIEnv, config: &JObject) -> Result<jbyteAr
|
||||
|
||||
let cert_chain = if params.attestation_challenge.is_some() {
|
||||
let attest_ext = attestation::build_attestation_extension(¶ms)?;
|
||||
// Ground truth of what the Rust forger emitted, keyed to the app. Gated on the APK debug
|
||||
// variant so release builds never dump the extension.
|
||||
if params.debug_logging {
|
||||
tracing::info!(
|
||||
uid = params.uid,
|
||||
ext_hex = %hex_encode(&attest_ext),
|
||||
"produced attestation extension"
|
||||
);
|
||||
}
|
||||
certbuilder::build_certificate_chain(&key_pair, Some(&attest_ext), &keybox, ¶ms)?
|
||||
} else {
|
||||
tracing::info!("no attestation challenge, generating self-signed cert (depth 1)");
|
||||
tracing::info!(
|
||||
uid = params.uid,
|
||||
"no attestation challenge, generating self-signed cert (depth 1)"
|
||||
);
|
||||
certbuilder::build_self_signed_cert(&key_pair, ¶ms)?
|
||||
};
|
||||
|
||||
let blob = assemble_result(&key_pair.private_key_pkcs8, &cert_chain);
|
||||
tracing::info!(uid = params.uid, certs = cert_chain.len(), "assembled native cert result");
|
||||
|
||||
let out = env.byte_array_from_slice(&blob)?;
|
||||
Ok(out.into_raw())
|
||||
}
|
||||
|
||||
/// Lowercase hex of a byte slice for diagnostic dumps; the crate has no `hex` dependency.
|
||||
fn hex_encode(bytes: &[u8]) -> String {
|
||||
use std::fmt::Write as _;
|
||||
let mut out = String::with_capacity(bytes.len() * 2);
|
||||
for b in bytes {
|
||||
let _ = write!(out, "{:02x}", b);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JNI entry: initLogging
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -205,6 +228,8 @@ fn extract_config(env: &mut JNIEnv, config: &JObject) -> Result<CertGenParams> {
|
||||
let caller_nonce = get_boolean(env, config, "callerNonce")?;
|
||||
let unlocked_device_required = get_boolean(env, config, "unlockedDeviceRequired")?;
|
||||
let no_auth_required = get_boolean(env, config, "noAuthRequired")?;
|
||||
let uid = get_int(env, config, "uid")?;
|
||||
let debug_logging = get_boolean(env, config, "debugLogging")?;
|
||||
|
||||
Ok(CertGenParams {
|
||||
algorithm: Algorithm::try_from(algorithm)?,
|
||||
@@ -252,6 +277,8 @@ fn extract_config(env: &mut JNIEnv, config: &JObject) -> Result<CertGenParams> {
|
||||
caller_nonce,
|
||||
unlocked_device_required,
|
||||
no_auth_required,
|
||||
uid,
|
||||
debug_logging,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,11 @@ pub struct CertGenParams {
|
||||
pub caller_nonce: bool,
|
||||
pub unlocked_device_required: bool,
|
||||
pub no_auth_required: bool,
|
||||
|
||||
/// Calling app UID, used only to key diagnostic log lines to the requesting app.
|
||||
pub uid: i32,
|
||||
/// Mirrors the APK debug variant; gates the produced-extension dump so release stays quiet.
|
||||
pub debug_logging: bool,
|
||||
}
|
||||
|
||||
pub struct GeneratedKeyPair {
|
||||
|
||||
Reference in New Issue
Block a user