Skip to content

CSR Generation

Create CSRs and private keys using Rust or the language bindings.

Example

pub fn main() {
    use fatoora_core::config::EnvironmentType;
    use fatoora_core::csr::{CsrProperties, SigningKey};

    let csr_props_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("tests/fixtures/csr-configs/csr-config-example-EN.properties");
    let csr_props = std::fs::read_to_string(&csr_props_path).expect("read csr props");
    let props = CsrProperties::from_properties_str(&csr_props).expect("parse csr props");
    let key = SigningKey::generate();
    let csr = props
        .build(&key, EnvironmentType::NonProduction)
        .expect("build csr");

    let csr_pem = csr.to_pem().expect("csr pem");
    let key_pem = key.to_pem().expect("key pem");
    let csr_b64 = csr.to_base64().expect("csr base64");
    assert!(!csr_b64.is_empty());
    assert!(key_pem.contains("BEGIN PRIVATE KEY"));
    let _ = csr_pem;
}
from fatoora.config import Environment
from fatoora.csr import CsrProperties, SigningKey

# csr_props_path = "path/to/csr.properties"
props = CsrProperties.parse_csr_config_file(str(csr_props_path))
key = SigningKey.generate()
csr = props.build(key, Environment.NON_PRODUCTION)

csr_b64 = csr.to_base64()
key_pem = key.to_pem()
assert csr_b64.startswith("MIIC")
assert "BEGIN PRIVATE KEY" in key_pem
import { CsrProperties, SigningKey } from 'fatoority';

export function generateCsr(propertiesText) {
  const key = SigningKey.generate();
  const csr = CsrProperties.fromPropertiesStr(propertiesText).build(key, 0);
  return { csrPem: csr.toPem(), keyPem: key.toPem() };
}
    public static (string CsrPem, string KeyPem) GenerateCsr(string propertiesText)
    {
        using var properties = CsrProperties.FromPropertiesStr(propertiesText);
        using var key = SigningKey.Generate();
        using var csr = properties.Build(key, 0); // Nonproduction.
        return (csr.ToPem(), key.ToPem());
    }
#include "fatoora.h"
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s csr.properties\n", argv[0]);
        return 1;
    }
    FatooraCsrProperties *properties = NULL;
    FatooraSigningKey *key = NULL;
    FatooraCsr *csr = NULL;
    FatooraError *error = NULL;
    char *csr_pem = NULL, *key_pem = NULL;
    FatooraStatus status = FATOORA_OK;
    int exit_code = 1;
#define TRY(call) do { status = (call); if (status != FATOORA_OK) goto cleanup; } while (0)
    TRY(fatoora_csr_properties_parse_csr_config_file(argv[1], &properties, &error));
    TRY(fatoora_signing_key_generate(&key, &error));
    TRY(fatoora_csr_properties_build(properties, key, FATOORA_NON_PRODUCTION, &csr, &error));
    TRY(fatoora_csr_to_pem(csr, &csr_pem, &error));
    TRY(fatoora_signing_key_to_pem(key, &key_pem, &error));
    /* Save the private key securely; it is needed when signing invoices. */
    printf("%s\n%s\n", key_pem, csr_pem);
    exit_code = 0;
cleanup:
    if (exit_code) fprintf(stderr, "Error %d: %s\n", (int)status, fatoora_error_message(error));
    fatoora_string_free(key_pem);
    fatoora_string_free(csr_pem);
    fatoora_csr_free(csr);
    fatoora_signing_key_free(key);
    fatoora_csr_properties_free(properties);
    fatoora_error_free(error);
    return exit_code;
}

Notes

  • CsrProperties::from_properties_str expects a properties string with keys: csr.common.name, csr.serial.number, csr.organization.identifier, csr.organization.unit.name, csr.organization.name, csr.country.name, csr.invoice.type, csr.location.address, and csr.industry.business.category.
  • Use CsrProperties::parse_csr_config_file for a file-based helper.
  • Output includes the CSR plus its private key. Choose PEM or base64 DER depending on your target workflow.

See also: CSR Reference

C examples include fatoora.h; compile the adapter once with your application. See the C build instructions.

See the JavaScript / TypeScript reference for installation and runtime contracts.

See the C# / .NET reference for installation, imports, and ownership rules.