tiny_ca.storage package

class tiny_ca.storage.BaseStorage[source]

Bases: ABC

Abstract contract for certificate artefact storage backends.

Subclasses persist cryptographic objects (certificates, keys, CSRs, CRLs) to some durable medium and provide a way to remove an entire issuance folder in a single atomic call.

The two operations map directly to the two storage events in the certificate lifecycle:

  • Issuancesave_certificate is called once per artefact (.pem, .key, .csr) with the same uuid_str so all three files end up in the same directory.

  • Revocation / overwritedelete_certificate_folder removes the entire UUID directory in one call, avoiding orphaned files.

abstractmethod delete_certificate_folder(uuid_str, cert_path=None)[source]

Remove the directory that contains all artefacts for a given UUID.

Implementations must be idempotent: if the target directory does not exist, return True (no action was needed) rather than raising an error. Only genuine unexpected failures (permission errors, I/O errors) should return False.

Parameters:
  • uuid_str (str) – UUID string that identifies the sub-directory to delete. This is the value returned as the second element by save_certificate.

  • cert_path (str | Path | None) – Optional sub-path prepended before uuid_str, matching the cert_path used when the artefacts were saved. None means uuid_str is directly under the backend’s root folder.

Returns:

True — the directory was deleted, or did not exist (idempotent). False — an unexpected error occurred during deletion; the

implementation must log the exception.

Return type:

bool

abstractmethod save_certificate(cert, file_name, cert_path=None, uuid_str=None, encoding=None, private_format=None, public_format=None, encryption_algorithm=None, is_add_uuid=True, is_overwrite=False)[source]

Serialise cert and persist it to the storage backend.

The implementation must: 1. Determine the correct serialisation format and file extension from

the type of cert (certificate → .pem, private key → .key, CSR → .csr, public key → .pub, CRL → .pem).

  1. Assemble the output path from cert_path, the UUID directory (when is_add_uuid is True), and file_name + extension.

  2. Auto-generate a UUID when uuid_str is None and is_add_uuid is True; reuse uuid_str when provided (so that multiple calls for the same issuance all land in the same folder).

  3. Honour is_overwrite: raise FileAlreadyExists when False and the target path already exists; silently replace when True.

  4. Return the absolute path to the saved file and the UUID used.

Parameters:
  • cert (CryptoObject) – The cryptographic object to serialise and save.

  • file_name (str) – Base filename without extension (e.g. "ca", "my-service").

  • cert_path (str | Path | None) – Optional sub-directory appended after the backend’s root folder. None saves directly under the root.

  • uuid_str (str | None) – Explicit UUID for the issuance sub-directory. Pass the UUID returned by a previous call to group multiple artefacts in the same folder. None triggers auto-generation. Ignored when is_add_uuid is False.

  • encoding (serialization.Encoding | None) – Serialisation encoding override. None falls back to the implementation’s default (typically PEM).

  • private_format (serialization.PrivateFormat | None) – Format for private-key serialisation (e.g. TraditionalOpenSSL, PKCS8). None uses the implementation default.

  • public_format (serialization.PublicFormat | None) – Format for public-key serialisation (e.g. SubjectPublicKeyInfo). None uses the implementation default.

  • encryption_algorithm (serialization.KeySerializationEncryption | None) – Encryption wrapper for private keys (e.g. NoEncryption, BestAvailableEncryption). None uses the implementation default.

  • is_add_uuid (bool) – When True (default), a UUID subdirectory is inserted into the path. Set to False for singleton files such as CRLs that are regenerated in-place (crl.pem).

  • is_overwrite (bool) – When True, silently replace an existing file at the computed path. When False (default), raise FileAlreadyExists.

Returns:

(absolute_path_to_saved_file, uuid_str_used). The second element is the UUID that was used (auto-generated or the value of uuid_str), or None when is_add_uuid is False.

Return type:

tuple[Path, str | None]

Raises:
  • FileAlreadyExists – If the target file already exists and is_overwrite is False.

  • TypeError – If cert is not a recognised cryptographic type.

class tiny_ca.storage.LocalStorage(base_folder='./certs', base_encoding=Encoding.PEM, base_private_format=PrivateFormat.TraditionalOpenSSL, base_public_format=PublicFormat.SubjectPublicKeyInfo, base_encryption_algorithm=<cryptography.hazmat.primitives._serialization.NoEncryption object>, logger=None)[source]

Bases: BaseStorage

Local filesystem storage backend for certificate artefacts.

Writes serialised cryptographic objects to a configurable directory tree. Each issuance group (certificate + key + CSR) is placed in a dedicated UUID subdirectory so that all artefacts for a given certificate can be found and deleted together.

Directory layout

<base_folder>/
└── [cert_path/]
    └── [<uuid>/]
        ├── <file_name>.pem   # x509.Certificate or CRL
        ├── <file_name>.key   # RSA private key
        ├── <file_name>.csr   # certificate signing request
        └── <file_name>.pub   # RSA public key (if applicable)
type base_folder:

str | Path

param base_folder:

Root directory under which all certificates are stored. The directory is created on first write if it does not exist. Default: "./certs".

type base_folder:

str | Path

type base_encoding:

Encoding

param base_encoding:

Default encoding for all serialised objects. Default: Encoding.PEM.

type base_encoding:

serialization.Encoding

type base_private_format:

PrivateFormat

param base_private_format:

Default format for RSA private-key files. Default: PrivateFormat.TraditionalOpenSSL (PKCS#1, OpenSSL-compatible).

type base_private_format:

serialization.PrivateFormat

type base_public_format:

PublicFormat

param base_public_format:

Default format for RSA public-key files. Default: PublicFormat.SubjectPublicKeyInfo (PKCS#8 / X.509 SubjectPublicKeyInfo).

type base_public_format:

serialization.PublicFormat

type base_encryption_algorithm:

KeySerializationEncryption

param base_encryption_algorithm:

Default encryption applied to private-key files. Default: NoEncryption() — keys are stored in plaintext.

type base_encryption_algorithm:

serialization.KeySerializationEncryption

type logger:

Logger | None

param logger:

Logger for diagnostic messages. Falls back to DEFAULT_LOGGER.

type logger:

Logger | None

__init__(base_folder='./certs', base_encoding=Encoding.PEM, base_private_format=PrivateFormat.TraditionalOpenSSL, base_public_format=PublicFormat.SubjectPublicKeyInfo, base_encryption_algorithm=<cryptography.hazmat.primitives._serialization.NoEncryption object>, logger=None)[source]
Parameters:
Return type:

None

delete_certificate_folder(uuid_str, cert_path=None)[source]

Recursively remove the directory identified by uuid_str.

The target path is resolved as:

<base_folder> / [cert_path/] / <uuid_str>

The operation is idempotent: if the directory does not exist a UserWarning is emitted and True is returned (no action needed). If the path exists but is a regular file rather than a directory, a UserWarning is emitted and True is returned (not our directory). Only a genuine OSError during shutil.rmtree causes False.

Parameters:
  • uuid_str (str) – UUID sub-directory name to remove.

  • cert_path (str | Path | None) – Optional sub-path under base_folder containing uuid_str.

Returns:

True — directory removed, or path was already absent. FalseOSError occurred; check logs for details.

Return type:

bool

Warns:

UserWarning – If the target path does not exist or is not a directory.

save_certificate(cert, file_name, cert_path=None, uuid_str=None, encoding=None, private_format=None, public_format=None, encryption_algorithm=None, is_add_uuid=True, is_overwrite=False)[source]

Serialise cert and write the result to the local filesystem.

Assembles the output path as:

<base_folder> / [cert_path/] / [<uuid>/] / <file_name><ext>

Where ext is determined automatically from the type of cert.

Parameters:
  • cert (CryptoObject) – Cryptographic object to serialise and persist.

  • file_name (str) – Base filename without extension (e.g. "ca", "nginx").

  • cert_path (str | Path | None) – Optional sub-directory appended after base_folder.

  • uuid_str (str | None) – Reuse an existing UUID directory by passing the value returned by a previous save_certificate call. None auto-generates a new UUID. Ignored when is_add_uuid is False.

  • encoding (serialization.Encoding | None) – Encoding override. None uses base_encoding.

  • private_format (serialization.PrivateFormat | None) – Private-key format override. None uses base_private_format.

  • public_format (serialization.PublicFormat | None) – Public-key format override. None uses base_public_format.

  • encryption_algorithm (serialization.KeySerializationEncryption | None) – Private-key encryption override. None uses base_encryption_algorithm.

  • is_add_uuid (bool) – When True (default), a UUID subdirectory is inserted. Set to False for singleton files such as CRL that are regenerated in-place.

  • is_overwrite (bool) – When True, silently replace an existing file. When False (default), raise FileAlreadyExists.

Returns:

(absolute_path_to_written_file, uuid_used). uuid_used is None when is_add_uuid is False.

Return type:

tuple[Path, str | None]

Raises:
  • FileAlreadyExists – If the computed target path already exists and is_overwrite is False.

  • TypeError – If cert is not a supported cryptographic type.

Parameters:
  • base_folder (str | Path)

  • base_encoding (serialization.Encoding)

  • base_private_format (serialization.PrivateFormat)

  • base_public_format (serialization.PublicFormat)

  • base_encryption_algorithm (serialization.KeySerializationEncryption)

  • logger (Logger | None)

Submodules