kryptos/x509/certificate
X.509 Certificate generation and parsing.
This module provides a builder for creating X.509 certificates. Certificates can be self-signed. CA-signing is not currently supported.
Example
import gleam/option.{None}
import gleam/time/duration
import gleam/time/timestamp
import kryptos/ec
import kryptos/hash
import kryptos/x509
import kryptos/x509/certificate
let #(private_key, _) = ec.generate_key_pair(ec.P256)
let subject =
x509.name([
x509.cn("example.com"),
x509.organization("Acme Inc"),
])
let now = timestamp.system_time()
// 86,400 seconds per day per CA/Browser Forum definition
let one_year_later = timestamp.add(now, duration.seconds(86_400 * 365))
let validity = x509.Validity(not_before: now, not_after: one_year_later)
let assert Ok(builder) =
certificate.new()
|> certificate.with_subject(subject)
|> certificate.with_validity(validity)
|> certificate.with_basic_constraints(ca: False, path_len_constraint: None)
|> certificate.with_key_usage(x509.DigitalSignature)
|> certificate.with_extended_key_usage(x509.ServerAuth)
|> certificate.with_dns_name("example.com")
let assert Ok(cert) =
certificate.self_signed_with_ecdsa(builder, private_key, hash.Sha256)
Parsing Certificates
import kryptos/x509/certificate
let pem = "-----BEGIN CERTIFICATE-----
MIIBkTCB+wIJAK...
-----END CERTIFICATE-----"
let assert Ok([cert]) = certificate.from_pem(pem)
// Access certificate fields
let subject = certificate.subject(cert)
let validity = certificate.validity(cert)
let public_key = certificate.public_key(cert)
// Verify a self-signed certificate
let assert Ok(Nil) = certificate.verify_self_signed(cert)
Types
Configuration for the Authority Key Identifier extension.
pub type AuthorityKeyIdentifierConfig {
AkiAuto
AkiExplicit(BitArray)
AkiExclude
}
Constructors
-
AkiAutoAutomatically compute AKI as SHA-1 hash of the signing key (default).
-
AkiExplicit(BitArray)Use a custom AKI keyIdentifier value.
-
AkiExcludeExclude the AKI extension entirely.
A builder for constructing X.509 certificates.
Create a builder with new(), configure it with with_* functions, then
sign with one of the signing functions:
self_signed_with_ecdsa()for ECDSA keysself_signed_with_rsa()for RSA keysself_signed_with_eddsa()for Ed25519/Ed448 keys
pub opaque type Builder
An X.509 Certificate.
The phantom type parameter tracks how the certificate was created:
Certificate(Built)- created viaself_signed_with_ecdsaetc.Certificate(Parsed)- created viafrom_pemorfrom_der
Export functions (to_pem, to_der) work on any Certificate(a).
Accessor functions (version, subject, etc.) require Certificate(Parsed).
pub opaque type Certificate(status)
Error type for certificate parsing failures.
pub type CertificateError {
ParseError
UnsupportedAlgorithm(x509.Oid)
SignatureVerificationFailed
UnrecognizedCriticalExtension(x509.Oid)
}
Constructors
-
ParseErrorFailed to parse the certificate data.
-
UnsupportedAlgorithm(x509.Oid)The certificate uses an algorithm or key type that is not supported.
-
SignatureVerificationFailedCryptographic signature verification failed.
-
UnrecognizedCriticalExtension(x509.Oid)The certificate contains an unrecognized extension marked as critical.
Per RFC 5280 §4.2, certificates with unknown critical extensions must be rejected. Non-critical unknown extensions are allowed.
Configuration for the Subject Key Identifier extension.
pub type SubjectKeyIdentifierConfig {
SkiAuto
SkiExplicit(BitArray)
}
Constructors
-
SkiAutoAutomatically compute SKI as SHA-1 hash of the public key (RFC 5280 method 1).
-
SkiExplicit(BitArray)Use a custom SKI value.
Values
pub fn authority_key_identifier(
cert: Certificate(Parsed),
) -> Result(x509.AuthorityKeyIdentifier, Nil)
Returns the Authority Key Identifier (AKI) from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
Ok(AuthorityKeyIdentifier)if extension is presentError(Nil)if extension is not present
pub fn basic_constraints(
cert: Certificate(Parsed),
) -> Result(x509.BasicConstraints, Nil)
Returns the Basic Constraints extension from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
Ok(BasicConstraints)if the extension is presentError(Nil)if the extension is not present
pub fn extended_key_usage(
cert: Certificate(Parsed),
) -> List(x509.ExtendedKeyUsage)
Returns the Extended Key Usage purposes from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
List of extended key usage purposes, or empty list if extension not present.
pub fn extensions(
cert: Certificate(Parsed),
) -> List(#(x509.Oid, Bool, BitArray))
Returns all extensions as raw (OID, critical, value) tuples.
This returns every extension present in the certificate, including those that kryptos also parses into typed representations (Basic Constraints, Key Usage, Extended Key Usage, Subject Alt Names, etc).
This is useful for inspecting extension criticality or accessing the raw DER-encoded value of any extension.
The Bool indicates whether the extension was marked as critical per RFC 5280.
Parameters
cert: A parsed certificate
Returns
List of all extension tuples #(Oid, Bool, BitArray).
pub fn from_der(
der: BitArray,
) -> Result(Certificate(Parsed), CertificateError)
Parse a DER-encoded X.509 certificate.
Validates the ASN.1 structure and extracts all standard fields and extensions. Unknown non-critical extensions are preserved but not parsed.
Note: This function does NOT verify the certificate’s cryptographic
signature. To verify a certificate was signed by an issuer, use verify().
For self-signed certificates, use verify_self_signed().
Parameters
der: Raw DER-encoded certificate bytes
Returns
Ok(Certificate(Parsed))if parsing succeedsError(ParseError)if the ASN.1 structure is malformedError(UnsupportedAlgorithm(oid))if the signature algorithm or key type is not supportedError(UnrecognizedCriticalExtension(oid))if an unknown extension is marked critical (per RFC 5280)
pub fn from_pem(
pem: String,
) -> Result(List(Certificate(Parsed)), CertificateError)
Parse all PEM-encoded certificates from a string.
Extracts and parses all -----BEGIN CERTIFICATE----- blocks from the input.
Certificates are returned in the order they appear.
Note: This function does NOT verify the certificates’ cryptographic
signatures. To verify a certificate was signed by an issuer, use verify().
For self-signed certificates, use verify_self_signed().
Parameters
pem: A string containing one or more PEM-encoded certificates
Returns
Ok(List(Certificate(Parsed)))with parsed certificates (empty list if no certificates found)Error(ParseError)if base64 decoding fails or certificate structure is invalidError(UnsupportedAlgorithm(oid))if any certificate uses an unsupported algorithmError(UnrecognizedCriticalExtension(oid))if any certificate has unknown critical extensions
pub fn issuer(cert: Certificate(Parsed)) -> x509.Name
Returns the issuer distinguished name.
The issuer identifies the CA that signed this certificate. For self-signed certificates, issuer equals subject.
Parameters
cert: A parsed certificate
Returns
The issuer as a distinguished name.
pub fn key_usage(
cert: Certificate(Parsed),
) -> List(x509.KeyUsage)
Returns the Key Usage flags from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
List of key usage flags, or empty list if extension not present.
pub fn new() -> Builder
Creates a new certificate builder with default values.
Use the with_* functions to configure the builder, then call
a signing function to generate the certificate.
Returns
A new Builder ready for configuration.
pub fn public_key(cert: Certificate(Parsed)) -> x509.PublicKey
Returns the public key embedded in the certificate.
Parameters
cert: A parsed certificate
Returns
The subject’s public key (RSA, EC, Ed, or XDH).
pub fn self_signed_with_ecdsa(
builder: Builder,
key: ec.PrivateKey,
hash: hash.HashAlgorithm,
) -> Result(Certificate(Built), Nil)
Signs a self-signed certificate with an ECDSA private key.
The public key is derived from the private key and used as both the issuer and subject public key.
Parameters
builder: The configured certificate builderkey: An EC private key fromec.generate_key_pairhash: The hash algorithm for signing.
Returns
Ok(Certificate(Built))containing the signed certificateError(Nil)if the hash algorithm is not supported, validity is missing, or the public key cannot be encoded
pub fn self_signed_with_eddsa(
builder: Builder,
key: eddsa.PrivateKey,
) -> Result(Certificate(Built), Nil)
Signs a self-signed certificate with an EdDSA private key.
The public key is derived from the private key and used as both the issuer and subject public key. EdDSA has built-in hashing, so no hash algorithm parameter is needed.
Parameters
builder: The configured certificate builderkey: An EdDSA private key fromeddsa.generate_key_pair
Returns
Ok(Certificate(Built))containing the signed certificateError(Nil)if validity is missing or the public key cannot be encoded
pub fn self_signed_with_rsa(
builder: Builder,
key: rsa.PrivateKey,
hash: hash.HashAlgorithm,
) -> Result(Certificate(Built), Nil)
Signs a self-signed certificate with an RSA private key using PKCS#1 v1.5 padding.
The public key is derived from the private key and used as both the issuer and subject public key.
Parameters
builder: The configured certificate builderkey: An RSA private key fromrsa.generate_key_pairhash: The hash algorithm for signing.
Returns
Ok(Certificate(Built))containing the signed certificateError(Nil)if the hash algorithm is not supported, validity is missing, or the public key cannot be encoded
pub fn serial_number(cert: Certificate(Parsed)) -> BitArray
Returns the serial number of a parsed certificate.
Serial numbers are unique within a CA and encoded as unsigned integers.
Parameters
cert: A parsed certificate
Returns
The serial number as raw bytes.
pub fn signature_algorithm(
cert: Certificate(Parsed),
) -> x509.SignatureAlgorithm
Returns the signature algorithm used to sign the certificate.
Parameters
cert: A parsed certificate
Returns
The signature algorithm identifier.
pub fn subject(cert: Certificate(Parsed)) -> x509.Name
Returns the subject distinguished name.
The subject identifies the entity the certificate was issued to.
Parameters
cert: A parsed certificate
Returns
The subject as a distinguished name.
pub fn subject_alt_names(
cert: Certificate(Parsed),
) -> List(x509.SubjectAltName)
Returns the Subject Alternative Names (SA) from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
List of SANs (DNS names, emails, IPs), or empty list if extension not present.
pub fn subject_key_identifier(
cert: Certificate(Parsed),
) -> Result(BitArray, Nil)
Returns the Subject Key Identifier (SKI) from a parsed certificate.
Parameters
cert: A parsed certificate
Returns
Ok(BitArray)with the SKI bytes if extension is presentError(Nil)if extension is not present
pub fn to_der(cert: Certificate(a)) -> BitArray
Exports the certificate as DER-encoded bytes.
DER (Distinguished Encoding Rules) is a binary format commonly used for programmatic certificate handling.
Parameters
cert: The signed certificate
Returns
The raw DER-encoded certificate bytes.
pub fn to_pem(cert: Certificate(a)) -> String
Exports the certificate as a PEM-encoded string.
PEM (Privacy-Enhanced Mail) is a Base64-encoded format with header and footer lines.
Parameters
cert: The signed certificate
Returns
A PEM-encoded string with -----BEGIN CERTIFICATE----- headers.
pub fn validity(cert: Certificate(Parsed)) -> x509.Validity
Returns the validity period of the certificate.
Parameters
cert: A parsed certificate
Returns
The validity period with not_before and not_after timestamps.
pub fn verify(
cert: Certificate(Parsed),
issuer_public_key: x509.PublicKey,
) -> Result(Nil, CertificateError)
Verify a certificate’s signature against an issuer’s public key.
This verifies that the certificate was signed by the private key corresponding to the provided public key.
Parameters
cert: The parsed certificate to verifyissuer_public_key: The public key to verify against (must be RSA, ECDSA, or EdDSA)
Returns
Ok(Nil)if the signature is validError(SignatureVerificationFailed)if the signature is invalidError(UnsupportedAlgorithm)if the key cannot be used for verification
pub fn verify_self_signed(
cert: Certificate(Parsed),
) -> Result(Nil, CertificateError)
Verify a self-signed certificate against its own public key.
This is a convenience function that extracts the public key from the certificate and verifies the signature against it.
Parameters
cert: The parsed self-signed certificate to verify
Returns
Ok(Nil)if the signature is validError(SignatureVerificationFailed)if the signature is invalidError(UnsupportedAlgorithm)if the certificate contains a key that cannot sign (e.g., XDH)
pub fn version(cert: Certificate(Parsed)) -> Int
Returns the version of a parsed certificate.
X.509 certificates use:
- Version 1 = value 0
- Version 2 = value 1
- Version 3 = value 2 (most common, supports extensions)
Parameters
cert: A parsed certificate
Returns
The version number (0, 1, or 2).
pub fn with_authority_key_identifier(
builder: Builder,
aki: AuthorityKeyIdentifierConfig,
) -> Builder
Configures the Authority Key Identifier extension for the certificate.
By default, self-signed certificates include an AKI with keyIdentifier computed as the SHA-1 hash of the signing public key.
Parameters
builder: The certificate builderaki: The AKI configuration:AkiAuto- compute from the public key (default)AkiExplicit(bytes)- use provided keyIdentifier bytesAkiExclude- omit the AKI extension
Returns
The updated builder.
pub fn with_basic_constraints(
builder: Builder,
ca ca: Bool,
path_len_constraint path_len_constraint: option.Option(Int),
) -> Builder
Sets the Basic Constraints extension.
This extension indicates whether the certificate is a CA certificate and optionally limits the path length of the certification chain.
Parameters
builder: The certificate builderca: True if this is a CA certificatepath_len_constraint: Maximum path length (only valid for CA certs)
Returns
The updated builder.
Notes
Per RFC 5280, path_len_constraint is only meaningful when ca is True. If ca is False and path_len_constraint is present, the constraint is ignored.
pub fn with_dns_name(
builder: Builder,
name: String,
) -> Result(Builder, Nil)
Adds a DNS name to the Subject Alternative Names extension.
SANs allow a certificate to be valid for multiple hostnames.
Parameters
builder: The certificate buildername: A DNS hostname (e.g., “example.com” or “*.example.com”)
Returns
Ok(Builder)with the updated builderError(Nil)if the DNS name contains non-ASCII characters
pub fn with_email(
builder: Builder,
email: String,
) -> Result(Builder, Nil)
Adds an email address to the Subject Alternative Names extension.
Parameters
builder: The certificate builderemail: An email address (e.g., “user@example.com”)
Returns
Ok(Builder)with the updated builderError(Nil)if the email contains non-ASCII characters
pub fn with_extended_key_usage(
builder: Builder,
usage: x509.ExtendedKeyUsage,
) -> Builder
Adds an Extended Key Usage purpose to the certificate.
Extended Key Usage provides more specific purposes than Key Usage, such as server authentication or code signing.
Parameters
builder: The certificate builderusage: The extended key usage purpose to add
Returns
The updated builder.
pub fn with_ip(
builder: Builder,
ip: String,
) -> Result(Builder, Nil)
Adds an IP address to the Subject Alternative Names extension.
Parameters
builder: The certificate builderip: An IPv4 address (e.g., “192.168.1.1”) or IPv6 address (e.g., “2001:db8::1”, “::1”)
Returns
Ok(Builder)with the updated builderError(Nil)if the IP address cannot be parsed
pub fn with_key_usage(
builder: Builder,
usage: x509.KeyUsage,
) -> Builder
Adds a Key Usage flag to the certificate.
Key Usage defines the cryptographic operations the key may be used for. Multiple usages can be added by chaining calls.
Parameters
builder: The certificate builderusage: The key usage flag to add
Returns
The updated builder.
pub fn with_serial_number(
builder: Builder,
serial: BitArray,
) -> Builder
Sets the serial number for the certificate.
If not set, a random serial number will be generated during signing.
Parameters
builder: The certificate builderserial: The serial number as raw bytes
Returns
The updated builder.
pub fn with_subject(
builder: Builder,
subject: x509.Name,
) -> Builder
Sets the distinguished name subject for the certificate.
The subject identifies who the certificate is issued to.
Parameters
builder: The certificate buildersubject: A distinguished name created withx509.name
Returns
The updated builder.
pub fn with_subject_key_identifier(
builder: Builder,
ski: SubjectKeyIdentifierConfig,
) -> Builder
Enables the Subject Key Identifier extension in the certificate.
If not called, the SKI extension will not be included in the certificate.
Parameters
builder: The certificate builderski: The SKI configuration - useSkiAutoto compute from the public key (SHA-1 hash per RFC 5280 method 1) orSkiExplicit(bytes)for a custom value
Returns
The updated builder.
pub fn with_validity(
builder: Builder,
validity: x509.Validity,
) -> Builder
Sets the validity period for the certificate.
Parameters
builder: The certificate buildervalidity: The validity period with not_before and not_after timestamps
Returns
The updated builder.