RequestSeal.PublicKey (RequestSeal v0.2.0)

Copy Markdown View Source

Public-only RSA, P-256, P-384, and Ed25519 key formats and algorithm binding.

Formats follow RFC 7517, RFC 7518, RFC 8037, RFC 4055, RFC 5480, and RFC 8410.

import/2 and export/2 support public JWK maps (:jwk), PEM (:pem), DER SubjectPublicKeyInfo (:der), and explicit components (:raw): {:rsa, n, e}, {:rsa_pss, n, e}, {:ec, "P-256" | "P-384", uncompressed_point}, or {:ed25519, public_bytes}. PEM also accepts PKCS #1 RSA public keys. Private and symmetric JWK/PEM material rejects. No secret or key ID is retained.

JWK alg, use, and key_ops are retained and checked on every verification. Algorithm names are printable ASCII; simultaneous use/operation restrictions must agree. JWK alg uses exact JOSE identifiers even for an HTTP algorithm. Absent metadata imposes no additional restriction; it does not establish trust. Export preserves restrictions; restricted JWKs cannot export to formats without metadata. RSA-PSS SubjectPublicKeyInfo with absent parameters retains its PSS-only type; parameter-constrained PSS keys reject instead of discarding constraints. PSS-only keys cannot export to JWK, which has no equivalent key-type restriction.

RSA moduli are odd, 2048–8192 bits; public exponents are odd, 3–2^32-1 and smaller than the modulus. EC points must have the exact uncompressed width and pass OTP point validation. Ed25519 keys are 32 bytes with canonical encoded y and reject all eight small-order points with :invalid_key in every format. The check ignores the encoded x sign, following the libsodium small-order blocklist (ge25519_has_small_order in ed25519_ref10.c at tag 1.0.18). PEM/DER inputs are limited to 16,384 bytes. JWK maps have at most 32 entries; encoded components are bounded. Supplied structs are revalidated at each use.

Summary

Functions

Export a validated public key without dropping algorithm or operation restrictions.

Import bounded, explicit public key material, preserving JWK restrictions.

Compute the RFC 7638 / RFC 8037 SHA-256 thumbprint of required public members.

Types

t()

@type t() :: %RequestSeal.PublicKey{
  algorithm: binary() | nil,
  material: tuple(),
  operations: [binary()] | nil,
  use: binary() | nil
}

Functions

export(key, format)

@spec export(t(), :jwk | :pem | :der | :raw) ::
  {:ok, term()} | {:error, RequestSeal.Crypto.Error.t()}

Export a validated public key without dropping algorithm or operation restrictions.

import(value, format)

@spec import(term(), :jwk | :pem | :der | :raw) ::
  {:ok, t()} | {:error, RequestSeal.Crypto.Error.t()}

Import bounded, explicit public key material, preserving JWK restrictions.

thumbprint(key)

@spec thumbprint(t()) :: {:ok, binary()} | {:error, RequestSeal.Crypto.Error.t()}

Compute the RFC 7638 / RFC 8037 SHA-256 thumbprint of required public members.