Keys & Certificates

Coercion is uniform, and applies to key:, certificate:, certificates: everywhere in the API.

key: accepts:

certificate: / certificates: accept the same, plus OpenSSL::X509::Certificate.

Convenience constructors

All pure Ruby over OpenSSL:

HankoXml::Key.from_pem(pem, password: nil)
HankoXml::Key.from_der(der)
HankoXml::Key.from_file(path, password: nil)

PKCS#12 bundles

PKCS#12 / PFX bundles (Windows-exported keys, A1-style software certificates). Returns key + leaf certificate + CA chain in one go.

bundle = HankoXml::Key.from_pkcs12("cert.pfx", password: ENV["PFX_PASSWORD"])
bundle.key           # => HankoXml::Key (the private key)
bundle.certificate   # => HankoXml::Key (the leaf certificate)
bundle.certificates  # => [leaf, *ca_chain], each a HankoXml::Key

signer = HankoXml::Signer.new(**bundle.to_h)   # key:, certificate:, certificates:

Everything crossing into Rust is PEM

No key_format parameter exists in the public API or in the native contract: Ruby normalizes with OpenSSL::PKey#to_pem / OpenSSL::X509::Certificate#to_pem, which is unambiguous, covers PKCS#1 and PKCS#8, and means decryption and PKCS#12 unwrapping happen in Ruby with OpenSSL rather than in Rust with xmlsec’s format enum.

Key material handling

HankoXml::Key holds PEM bytes in a Ruby String. Ruby strings are GC-managed and not zeroized, and this cannot be promised otherwise. What is promised:

See the Key reference for the full API surface.