gen_certs.rs
Overview
This file provides a command-line utility for generating X.509 self-signed certificates and their corresponding private keys. It supports specifying multiple certificate subjects, output directory management, and integration with Ed25519 signing keys used for certificate signing. The utility outputs PEM-encoded certificate and key files, with options to overwrite existing files.
The core functionality revolves around certificate generation using the transport_layer::generate_self_signed_cert method and PEM encoding of DER-formatted keys and certificates. The CLI interface employs the clap crate to parse user inputs. The file also includes a test module validating certificate generation and verification workflows.
Structs and Functions
Struct Cli
A command-line argument parser struct leveraging clap::Parser. It defines the options for the certificate generation command.
Fields
subjects: Vec<String>
A comma-separated list of certificate subjects (e.g., hostnames or IP addresses).
Usage:-s localhost,*.example.com,127.0.0.1name: String
Certificate base filename (e.g., "client"). Used for naming output files.output_dir: Option<PathBuf>
Optional output directory for the certificate and key files. Defaults to the current directory.ed_key_secret: Vec<String>
Optional Ed25519 secret key represented as a 64-character hex string. Mutually exclusive withed_key_path.ed_key_path: Vec<String>
Optional path(s) to JSON-formatted Ed25519 key files containing public and secret keys. Mutually exclusive withed_key_secret.force: bool
Overwrite existing files if set; otherwise, existing files prevent overwriting.
Usage Example
gen_certs -s localhost,127.0.0.1 -n server -o ./certs --force
main() -> Result<(), Box<dyn std::error::Error>>
Entry point of the CLI utility.
Parses arguments into
Clistruct.Resolves Ed25519 signing keys using
transport_layer::resolve_signing_keys.Invokes
generate_certswith parsed parameters.
Returns an error if parsing, key resolution, or certificate generation fails.
generate_certs
fn generate_certs(
name: String,
subjects: Vec<String>,
ed_sing_keys: &[transport_layer::SigningKey],
output_dir: Option<PathBuf>,
force: bool,
) -> Result<(), Box<dyn std::error::Error>>
Generates a self-signed certificate and private key, writes them to disk in PEM format.
Parameters
name
Base name for output files.subjects
List of certificate subjects.ed_sing_keys
Slice of Ed25519 signing keys used for signing the certificate.output_dir
Optional output directory; defaults to current working directory.force
If false, prevents overwriting existing files.
Behavior
Ensures output directory exists.
Calls
generate_self_signed_cert(fromtransport_layer) providing subjects and signing keys.Constructs output filenames:
{name}.ca.pemfor certificate and{name}.key.pemfor private key.Checks file existence and respects the
forceflag.Writes PEM-encoded certificate and key files using helper functions.
Returns
Ok(())on success.Errwith error information on failure.
PEM Encoding Helper Functions
These functions convert DER-encoded certificates and private keys to PEM format.
cert_der_to_pem
fn cert_der_to_pem(cert: &CertificateDer<'_>) -> String
Converts a certificate DER byte slice to a PEM string with header/footer
CERTIFICATE.
key_der_to_pem
fn key_der_to_pem(key: &PrivateKeyDer<'_>) -> String
Converts a private key DER byte slice to a PEM string with header/footer
PRIVATE KEY.
der_to_pem
fn der_to_pem(name: &str, der: &[u8]) -> String
Generic helper encoding DER bytes into base64 PEM format.
Splits base64 output into 64-character lines.
Formats with
-----BEGIN {name}-----and-----END {name}-----markers.
Important Implementation Details
Uses
LazyLockto lazily initialize a static stringLONG_VERSIONcontaining detailed build metadata, injected into the CLI help/version output.Mutual exclusivity is enforced between
ed_key_secretanded_key_pathto avoid conflicting signing key sources.File existence checks before writing certificates or keys help avoid accidental overwrites unless
--forceis specified.Relies on the external crate
transport_layerfor critical operations like key resolution and certificate generation, abstracting cryptographic details.PEM encoding is done manually via base64 encoding and formatted string output, ensuring compatibility with common certificate tools.
Interaction with Other System Components
transport_layercrate:Provides
generate_self_signed_certto create self-signed certificates with optional Ed25519 signing keys.Provides
resolve_signing_keysto parse and load Ed25519 keys either from hex secrets or JSON files.Provides
verify_certused in tests to validate generated certificates.
rustls::pki_typescrate:Supplies types
CertificateDerandPrivateKeyDerfor working with DER-encoded certificates and keys.
clapcrate:Used for CLI argument parsing and command metadata.
Standard Library:
Used for file system operations (
std::fs), path handling (PathBuf), and error management.
Test Module
The tests module validates the certificate generation and verification process:
Generates client and server certificates with different Ed25519 keys.
Loads PEM files back into DER types.
Creates
RootCertStoreinstances and verifies client certificates using Rustls'sWebPkiClientVerifier.Tests both positive and negative verification cases, including validation against unknown keys.
Demonstrates usage of
verify_certfromtransport_layer.
Visual Diagram of File Structure and Workflows
flowchart TD
A["main()"] --> B["Cli::parse()"]
B --> C["resolve_signing_keys()"]
C --> D["generate_certs()"]
D --> E["generate_self_signed_cert()"]
D --> F["cert_der_to_pem()"]
D --> G["key_der_to_pem()"]
F --> H["der_to_pem()"]
G --> H
E --> I[Ed25519 Signing Keys]
D --> J[File System Writes]
subgraph PEM Encoding Helpers
F & G & H
end
subgraph CLI Parsing
B
end
subgraph Certificate Generation
E & I
end
This flowchart illustrates the high-level function calls and data flow during execution:
The
mainfunction parses CLI arguments.Signing keys are resolved.
Certificate and key generation is performed.
DER-encoded outputs are converted to PEM format.
Files are written to disk.
For further details on cryptographic signing and certificate verification, see X.509 Certificates and Ed25519 Signing. For command-line argument parsing, refer to CLI Argument Parsing with Clap.