HankoXml::Key
Coercion is uniform, and applies to key:, certificate:, certificates: throughout the public
API.
key: accepts:
OpenSSL::PKey::PKey(RSA, EC, DSA) — used directly- a
Stringof PEM, unencrypted. For an encrypted PEM, load it withHankoXml::Key.from_pem(pem, password: ...)(orKey.from_file) and pass theKey - a
Pathname/File/ anything responding to#to_path— read from disk HankoXml::Key— the explicit wrapper
certificate: / certificates: accept the same, plus OpenSSL::X509::Certificate.
Constructors
HankoXml::Key.from_pem(pem, password: nil)
HankoXml::Key.from_der(der)
HankoXml::Key.from_file(path, password: nil)
# PKCS#12 / PFX — Windows-exported keys and 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:
from_pem decides between a key and a certificate from the -----BEGIN …----- labels. A PEM with
both a certificate and a key block (a cat key.pem cert.pem bundle) raises KeyLoadError: pass the
two parts separately as key: and certificate:.
PEM normalization
Everything crossing into Rust is PEM, always. 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.
Instance methods
key.private_key? # true only when the private half is present (false for a public key)
key.certificate? # true for an OpenSSL::X509::Certificate
key.dispose! # #to_pem / #to_openssl raise KeyLoadError from now on
Signer raises ConfigurationError at construction when key: is not a private key or
certificate: is not a certificate.
Safety
- The native layer copies what it needs and retains nothing after the call returns.
- A
Keynever appears in#inspect,#to_s, or an exception message —Signer#inspectshows#<HankoXml::Signer key=[FILTERED] …>. HankoXml::Errorand subclasses never carry key material.
#dispose! does not zeroize anything. The key bytes live in OpenSSL memory that is freed when Ruby’s
GC collects the object, and every String #to_pem has returned belongs to the caller. It stops later
accidental use of the Key; it is not a memory-hygiene guarantee.