Repository: bottlerocket-os/bottlerocket
File: sources/api/certdog/src/main.rs (Rust)

Code before:
    trusted_store: String,
    #[argh(option, default = "DEFAULT_SOURCE_BUNDLE.to_string()", short = 'b')]
    /// source-bundle path to source bundle
    source_bundle: String,
}

struct CertBundle {
    trusted_certs: Vec<x509_parser::pem::Pem>,
    distrusted_certs: Vec<x509_parser::pem::Pem>,
}

/// Query the API for the certificate bundles, returns a tuple with trusted
/// and distrusted PEM certificates
async fn get_certificate_bundles<P>(config_path: P) -> Result<CertBundle>
where
    P: AsRef<Path>,
{
    debug!("Loading certdog configuration");
    if config_path.as_ref().exists() {
        let config_str =
            fs::read_to_string(config_path.as_ref()).context(error::ConfigReadSnafu {
                config: config_path.as_ref().to_str().unwrap(),
            })?;
        let pki: HashMap<Identifier, PemCertificate> = toml::from_str(config_str.as_str())
            .context(error::ConfigDeserializationSnafu {
                config: config_path.as_ref().to_str().unwrap(),
            })?;

        split_bundles(pki)
    } else {
        split_bundles(HashMap::new())
    }
}

/// Returns a tuple with two lists, for trusted and distrusted certificates
fn split_bundles(certificates_bundle: HashMap<Identifier, PemCertificate>) -> Result<CertBundle> {
    let mut trusted_certs: Vec<x509_parser::pem::Pem> = Vec::new();
    let mut distrusted_certs: Vec<x509_parser::pem::Pem> = Vec::new();

    for (name, bundle) in certificates_bundle.iter() {
        let data = bundle.data.clone().unwrap_or_default();

        // Empty data means the certificate bundle was disabled in the API
        if data.trim() == "" {
            debug!("Found empty bundle: {}", name);
            continue;
        }

        let name = name.as_ref();
        let decoded = base64::decode(data.as_bytes()).context(error::Base64DecodeSnafu { name })?;
        // Each record in the API could include one or more certificates

Review comment (suggestion):
If what you want is the path string, you can try:

```suggestion
                config: format!("{:?}", config_path),
```

With:

```rust
println!("{:?}", &Path::new("My").join("Cool").join("Path"));
```

You will see:

```
"My/Cool/Path"
```

Code after:
    trusted_store: String,
    #[argh(option, default = "DEFAULT_SOURCE_BUNDLE.to_string()", short = 'b')]
    /// source-bundle path to source bundle
    source_bundle: String,
}

#[derive(Default)]
struct CertBundle {
    trusted_certs: Vec<x509_parser::pem::Pem>,
    distrusted_certs: Vec<x509_parser::pem::Pem>,
}

/// Query the API for the certificate bundles, returns a tuple with trusted
/// and distrusted PEM certificates
async fn get_certificate_bundles<P>(config_path: P) -> Result<CertBundle>
where
    P: AsRef<Path>,
{
    debug!("Loading certdog configuration");
    let config_path = config_path.as_ref();
    if !config_path.exists() {
        return Ok(CertBundle::default());
    }

    let config_str = fs::read_to_string(config_path).context(error::ConfigReadSnafu {
        config: format!("{:?}", config_path),
    })?;
    let pki: HashMap<Identifier, PemCertificate> =
        toml::from_str(config_str.as_str()).context(error::ConfigDeserializationSnafu {
            config: format!("{:?}", config_path),
        })?;

    split_bundles(pki)
}

/// Returns a tuple with two lists, for trusted and distrusted certificates
fn split_bundles(certificates_bundle: HashMap<Identifier, PemCertificate>) -> Result<CertBundle> {
    let mut trusted_certs: Vec<x509_parser::pem::Pem> = Vec::new();
    let mut distrusted_certs: Vec<x509_parser::pem::Pem> = Vec::new();

    for (name, bundle) in certificates_bundle.iter() {
        let data = bundle.data.clone().unwrap_or_default();

        // Empty data means the certificate bundle was disabled in the API
        if data.trim() == "" {
            debug!("Found empty bundle: {}", name);
            continue;
        }

        let name = name.as_ref();
        let decoded = base64::decode(data.as_bytes()).context(error::Base64DecodeSnafu { name })?;