proofmode 0.9.0

Capture, share, and preserve verifiable photos and videos
Documentation
use base64::{engine::general_purpose::STANDARD, Engine};

use super::error::{Result, SignError};
use super::types::C2PAConfiguration;

/// Load the certificate chain for a specific platform.
/// Reads from environment variables C2PA_CERT_IOS or C2PA_CERT_ANDROID.
/// The certificate must be base64 encoded in the environment variable.
pub fn load_cert_chain(platform: &str) -> Result<String> {
    if platform != "ios" && platform != "android" {
        return Err(SignError::InvalidPlatform(format!(
            "Invalid platform: {}. Must be 'ios' or 'android'",
            platform
        )));
    }

    let env_var = format!("C2PA_CERT_{}", platform.to_uppercase());

    let cert_b64 = std::env::var(&env_var).map_err(|_| {
        SignError::ConfigError(format!(
            "Environment variable {} is required but not set",
            env_var
        ))
    })?;

    let cert_bytes = STANDARD.decode(&cert_b64).map_err(|e| {
        SignError::CertificateError(format!(
            "Failed to decode base64 certificate from {}: {}",
            env_var, e
        ))
    })?;

    let cert_pem = String::from_utf8(cert_bytes).map_err(|e| {
        SignError::CertificateError(format!(
            "Certificate from {} is not valid UTF-8: {}",
            env_var, e
        ))
    })?;

    Ok(cert_pem)
}

/// Build a C2PA configuration for the given platform and signing URL.
pub fn build_c2pa_configuration(platform: &str, signing_url: &str) -> Result<C2PAConfiguration> {
    let cert_chain = load_cert_chain(platform)?;
    let cert_chain_base64 = STANDARD.encode(cert_chain.as_bytes());

    Ok(C2PAConfiguration {
        algorithm: "es256".to_string(),
        timestamp_url: "http://timestamp.digicert.com".to_string(),
        signing_url: signing_url.to_string(),
        certificate_chain: cert_chain_base64,
    })
}