kryptos/x509/certificate
X.509 Certificate generation and parsing.
Builder for creating self-signed X.509 certificates. CA-signing is not currently supported.
Example
import gleam/option
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: option.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.
pub fn basic_constraints(
cert: Certificate(Parsed),
) -> Result(x509.BasicConstraints, Nil)
Returns the Basic Constraints extension from a parsed certificate.
pub fn extended_key_usage(
cert: Certificate(Parsed),
) -> List(x509.ExtendedKeyUsage)
Returns the Extended Key Usage purposes from a parsed certificate.
pub fn extensions(
cert: Certificate(Parsed),
) -> List(#(x509.Oid, Bool, BitArray))
Returns all extensions as raw (OID, critical, value) tuples.
Includes all extensions, even those with typed representations. The Bool indicates whether the extension was marked as critical per RFC 5280.
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().
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().
pub fn generate_serial_number() -> BitArray
Generates a random 20-byte serial number with the high bit cleared per RFC 5280.
pub fn issuer(cert: Certificate(Parsed)) -> x509.Name
Returns the issuer distinguished name.
For self-signed certificates, issuer equals subject.
pub fn key_usage(
cert: Certificate(Parsed),
) -> List(x509.KeyUsage)
Returns the Key Usage flags from a parsed certificate.
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.
pub fn public_key(cert: Certificate(Parsed)) -> x509.PublicKey
Returns the public key embedded in the certificate.
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.
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.
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.
pub fn serial_number(cert: Certificate(Parsed)) -> BitArray
Returns the serial number of a parsed certificate.
pub fn signature_algorithm(
cert: Certificate(Parsed),
) -> x509.SignatureAlgorithm
Returns the signature algorithm used to sign the certificate.
pub fn subject(cert: Certificate(Parsed)) -> x509.Name
Returns the subject distinguished name.
pub fn subject_alt_names(
cert: Certificate(Parsed),
) -> List(x509.SubjectAltName)
Returns the Subject Alternative Names (SANs) from a parsed certificate.
pub fn subject_key_identifier(
cert: Certificate(Parsed),
) -> Result(BitArray, Nil)
Returns the Subject Key Identifier (SKI) from a parsed certificate.
pub fn to_der(cert: Certificate(a)) -> BitArray
Exports the certificate as DER-encoded bytes.
pub fn to_pem(cert: Certificate(a)) -> String
Exports the certificate as a PEM-encoded string.
pub fn validity(cert: Certificate(Parsed)) -> x509.Validity
Returns the validity period of the certificate.
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.
The public key must be RSA, ECDSA, or EdDSA (XDH keys cannot sign).
pub fn verify_self_signed(
cert: Certificate(Parsed),
) -> Result(Nil, CertificateError)
Verify a self-signed certificate against its own public key.
pub fn version(cert: Certificate(Parsed)) -> Int
Returns the version of a parsed certificate (0 = v1, 1 = v2, 2 = v3).
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. Use AkiExplicit
for a custom value or AkiExclude to omit the extension.
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. Per RFC 5280, path_len_constraint is only meaningful when ca is True.
pub fn with_dns_name(
builder: Builder,
name: String,
) -> Result(Builder, Nil)
Adds a DNS name to the Subject Alternative Names extension.
The name must contain only ASCII characters.
pub fn with_email(
builder: Builder,
email: String,
) -> Result(Builder, Nil)
Adds an email address to the Subject Alternative Names extension.
The email must contain only ASCII characters.
pub fn with_extended_key_usage(
builder: Builder,
usage: x509.ExtendedKeyUsage,
) -> Builder
Adds an Extended Key Usage purpose to the certificate.
EKU narrows allowed purposes beyond Key Usage (e.g., ServerAuth, CodeSigning). Multiple usages can be added by chaining calls.
pub fn with_ip(
builder: Builder,
ip: String,
) -> Result(Builder, Nil)
Adds an IP address to the Subject Alternative Names extension.
Accepts IPv4 (e.g., “192.168.1.1”) or IPv6 (e.g., “2001:db8::1”) addresses.
pub fn with_key_usage(
builder: Builder,
usage: x509.KeyUsage,
) -> Builder
Adds a Key Usage flag to the certificate.
Multiple usages can be added by chaining calls.
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.
pub fn with_subject(
builder: Builder,
subject: x509.Name,
) -> Builder
Sets the distinguished name subject for the certificate.
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. Use SkiAuto to
compute from the public key (SHA-1 hash per RFC 5280 method 1) or
SkiExplicit(bytes) for a custom value.
pub fn with_validity(
builder: Builder,
validity: x509.Validity,
) -> Builder
Sets the validity period for the certificate.