gose
A Gleam library for JOSE (JSON Object Signing and Encryption) and COSE (CBOR Object Signing and Encryption).
Core:
gose: error type, algorithm identifiers, and key management (types, generators, builders, accessors, serializers)gose/cbor: CBOR encoding for COSE
gose/key, gose/algorithm, gose/jose/algorithm, gose/cose/key, and
gose/cose/algorithm are deprecated shims retained for the v2.x migration
window. They will be removed in v3.0. New code should import gose,
gose/jose, and gose/cose directly.
JOSE:
gose/jose: JOSE algorithm string conversion (RFC 7518)gose/jose/jws: JSON Web Signature (RFC 7515)gose/jose/jws_multi: JWS JSON Serialization for multi-signer workflowsgose/jose/jwe: JSON Web Encryption (RFC 7516)gose/jose/jwe_multi: JWE JSON Serialization for multi-recipient workflowsgose/jose/jwk: JSON Web Key serialization (RFC 7517)gose/jose/key_set: JWK Set (RFC 7517 Section 5)gose/jose/encrypted_key: encrypted JWK export/importgose/jose/jwt: JSON Web Token (RFC 7519)gose/jose/encrypted_jwt: encrypted JWT (JWE-based)
COSE:
gose/cose: header parameters, theKeyalias, COSE_Key CBOR serialization, and COSE algorithm ID mapping (RFC 9052, RFC 9053)gose/cose/sign1: COSE_Sign1 (RFC 9052)gose/cose/sign: COSE_Sign multi-signer (RFC 9052)gose/cose/encrypt0: COSE_Encrypt0 (RFC 9052)gose/cose/encrypt: COSE_Encrypt multi-recipient (RFC 9052)gose/cose/mac0: COSE_Mac0 (RFC 9052)gose/cose/cwt: CBOR Web Token (RFC 8392)gose/cose/encrypted_cwt: encrypted CWT (Encrypt0-wrapped Sign1)
Types
AES key sizes.
pub type AesKeySize {
Aes128
Aes192
Aes256
}
Constructors
-
Aes128128-bit AES key
-
Aes192192-bit AES key
-
Aes256256-bit AES key
AES key wrapping modes.
pub type AesKwMode {
AesKw
AesGcmKw
}
Constructors
-
AesKwAES Key Wrap (RFC 3394)
-
AesGcmKwAES-GCM Key Wrap
Algorithm union type for the key alg field.
A key can specify either a signing algorithm or a key encryption algorithm.
pub type Alg {
SigningAlg(SigningAlg)
KeyEncryptionAlg(KeyEncryptionAlg)
ContentAlg(ContentAlg)
}
Constructors
-
SigningAlg(SigningAlg)Signing algorithm
-
KeyEncryptionAlg(KeyEncryptionAlg)Key encryption algorithm
-
ContentAlg(ContentAlg)Content encryption algorithm
ChaCha20-Poly1305 key wrapping variants.
pub type ChaCha20Kw {
C20PKw
XC20PKw
}
Constructors
-
C20PKwChaCha20-Poly1305 Key Wrap (12-byte nonce)
-
XC20PKwXChaCha20-Poly1305 Key Wrap (24-byte nonce)
Content encryption algorithms.
pub type ContentAlg {
AesGcm(AesKeySize)
AesCbcHmac(AesKeySize)
ChaCha20Poly1305
XChaCha20Poly1305
}
Constructors
-
AesGcm(AesKeySize)AES-GCM content encryption
-
AesCbcHmac(AesKeySize)AES-CBC with HMAC composite AEAD (CEK is double the AES key size)
-
ChaCha20Poly1305ChaCha20-Poly1305
-
XChaCha20Poly1305XChaCha20-Poly1305
Asymmetric signature algorithms.
pub type DigitalSignatureAlg {
RsaPkcs1(RsaPkcs1Alg)
RsaPss(RsaPssAlg)
Ecdsa(EcdsaAlg)
Eddsa
}
Constructors
-
RsaPkcs1(RsaPkcs1Alg)RSA PKCS#1 v1.5 signing
-
RsaPss(RsaPssAlg)RSA-PSS signing
-
Ecdsa(EcdsaAlg)ECDSA signing
-
EddsaEdDSA (Ed25519 or Ed448, curve determined by key)
ECDH-ES key agreement algorithm variants.
pub type EcdhEsAlg {
EcdhEsDirect
EcdhEsAesKw(AesKeySize)
EcdhEsChaCha20Kw(ChaCha20Kw)
}
Constructors
-
EcdhEsDirectECDH-ES direct key agreement
-
EcdhEsAesKw(AesKeySize)ECDH-ES with AES Key Wrap
-
EcdhEsChaCha20Kw(ChaCha20Kw)ECDH-ES with ChaCha20-Poly1305 Key Wrap
ECDSA signing algorithm variants.
pub type EcdsaAlg {
EcdsaP256
EcdsaP384
EcdsaP521
EcdsaSecp256k1
}
Constructors
-
EcdsaP256ECDSA using P-256 and SHA-256
-
EcdsaP384ECDSA using P-384 and SHA-384
-
EcdsaP521ECDSA using P-521 and SHA-512
-
EcdsaSecp256k1ECDSA using secp256k1 and SHA-256 (RFC 8812)
Error type for JOSE and COSE operations.
Used by low-level JOSE/COSE primitives. The JWT and CWT layers wrap these errors in their own domain-specific variants for token validation.
pub type GoseError {
ParseError(String)
CryptoError(String)
InvalidState(String)
VerificationFailed
}
Constructors
-
ParseError(String)Parsing failed: invalid base64, malformed JSON, unexpected structure, etc. The
Stringprovides a human-readable description of what went wrong. -
CryptoError(String)A cryptographic operation failed: signature verification, decryption, key derivation, etc. The
Stringdescribes the failure. -
InvalidState(String)An operation was attempted in an invalid state: wrong key type for the chosen algorithm, missing required header field, etc. The
Stringexplains which invariant was violated. -
VerificationFailedSignature or MAC verification failed. Intentionally carries no detail to avoid leaking information that could enable oracle attacks.
HMAC signing algorithm variants.
pub type HmacAlg {
HmacSha256
HmacSha384
HmacSha512
}
Constructors
-
HmacSha256HMAC using SHA-256
-
HmacSha384HMAC using SHA-384
-
HmacSha512HMAC using SHA-512
A cryptographic key.
Use constructor functions like from_octet_bits, from_der,
from_pem, or generate_* to create keys.
pub opaque type Key(kid)
Key encryption algorithms.
pub type KeyEncryptionAlg {
Direct
AesKeyWrap(AesKwMode, AesKeySize)
ChaCha20KeyWrap(ChaCha20Kw)
RsaEncryption(RsaEncryptionAlg)
EcdhEs(EcdhEsAlg)
Pbes2(Pbes2Alg)
}
Constructors
-
DirectDirect use of a shared symmetric key
-
AesKeyWrap(AesKwMode, AesKeySize)AES Key Wrap (standard or GCM mode)
-
ChaCha20KeyWrap(ChaCha20Kw)ChaCha20-Poly1305 Key Wrap
-
RsaEncryption(RsaEncryptionAlg)RSA key encryption
-
EcdhEs(EcdhEsAlg)ECDH-ES key agreement
-
Pbes2(Pbes2Alg)PBES2 password-based encryption
Key Operations parameter.
Identifies the operation(s) for which the key is intended.
pub type KeyOp {
Sign
Verify
Encrypt
Decrypt
WrapKey
UnwrapKey
DeriveKey
DeriveBits
}
Constructors
-
SignCompute digital signature or MAC
-
VerifyVerify digital signature or MAC
-
EncryptEncrypt content
-
DecryptDecrypt content and validate decryption
-
WrapKeyEncrypt key
-
UnwrapKeyDecrypt key and validate decryption
-
DeriveKeyDerive key
-
DeriveBitsDerive bits not to be used as a key
Key type identifier (kty parameter).
pub type KeyType {
OctKeyType
RsaKeyType
EcKeyType
OkpKeyType
}
Constructors
-
OctKeyTypeSymmetric key (oct)
-
RsaKeyTypeRSA key
-
EcKeyTypeElliptic Curve key
-
OkpKeyTypeOctet Key Pair (EdDSA, XDH)
Public Key Use parameter.
Indicates whether the key is for signing or encryption.
pub type KeyUse {
Signing
Encrypting
}
Constructors
-
SigningKey is used for signature operations
-
EncryptingKey is used for encryption operations
PBES2 key encryption algorithm variants.
pub type Pbes2Alg {
Pbes2Sha256Aes128Kw
Pbes2Sha384Aes192Kw
Pbes2Sha512Aes256Kw
}
Constructors
-
Pbes2Sha256Aes128KwPBES2 with HMAC-SHA-256 and A128KW wrapping
-
Pbes2Sha384Aes192KwPBES2 with HMAC-SHA-384 and A192KW wrapping
-
Pbes2Sha512Aes256KwPBES2 with HMAC-SHA-512 and A256KW wrapping
RSA key encryption algorithm variants.
pub type RsaEncryptionAlg {
RsaPkcs1v15
RsaOaepSha1
RsaOaepSha256
}
Constructors
-
RsaPkcs1v15RSAES PKCS1 v1.5 key encryption.
Security Warning: Vulnerable to padding oracle attacks (Bleichenbacher). Use only for interoperability with legacy systems that require RSA1_5. Prefer
RsaOaepSha256for new applications.Note: Decryption may fail on Node.js 20.x (CVE-2023-46809).
-
RsaOaepSha1RSAES OAEP using default parameters
-
RsaOaepSha256RSAES OAEP using SHA-256 and MGF1 with SHA-256
RSA PKCS#1 v1.5 signing algorithm variants.
pub type RsaPkcs1Alg {
RsaPkcs1Sha256
RsaPkcs1Sha384
RsaPkcs1Sha512
}
Constructors
-
RsaPkcs1Sha256RSA PKCSv1.5 using SHA-256
-
RsaPkcs1Sha384RSA PKCSv1.5 using SHA-384
-
RsaPkcs1Sha512RSA PKCSv1.5 using SHA-512
RSA-PSS signing algorithm variants.
pub type RsaPssAlg {
RsaPssSha256
RsaPssSha384
RsaPssSha512
}
Constructors
-
RsaPssSha256RSA-PSS using SHA-256 (RSASSA-PSS)
-
RsaPssSha384RSA-PSS using SHA-384 (RSASSA-PSS)
-
RsaPssSha512RSA-PSS using SHA-512 (RSASSA-PSS)
Signing and MAC algorithms (union of asymmetric signatures and MACs).
pub type SigningAlg {
DigitalSignature(DigitalSignatureAlg)
Mac(MacAlg)
}
Constructors
-
DigitalSignature(DigitalSignatureAlg)Asymmetric digital signature algorithm
-
Mac(MacAlg)MAC algorithm
Values
pub fn ec_curve(key: Key(kid)) -> Result(ec.Curve, GoseError)
Get the curve used by an EC key.
Returns an error if the key is not an EC key.
pub fn ec_public_key(
key: Key(kid),
) -> Result(ec.PublicKey, GoseError)
Extract the EC public key.
Works with both EC private keys (extracts the public component) and EC public keys.
Returns an error if the key is not an EC key.
pub fn ec_public_key_coordinates(
key: Key(kid),
) -> Result(#(BitArray, BitArray), GoseError)
Get the x and y coordinates from an EC public key.
The coordinates are returned as raw big-endian bytes, padded to the coordinate size for the curve.
Returns an error if the key is not an EC key.
pub fn ec_public_key_from_coordinates(
curve: ec.Curve,
x x: BitArray,
y y: BitArray,
) -> Result(Key(kid), GoseError)
Create an EC public key from curve and x,y coordinates (big-endian bytes).
pub fn eddsa_curve(
key: Key(kid),
) -> Result(eddsa.Curve, GoseError)
Get the curve used by an EdDSA key.
Returns an error if the key is not an EdDSA key.
pub fn eddsa_public_key(
key: Key(kid),
) -> Result(eddsa.PublicKey, GoseError)
Extract the EdDSA public key.
Works with both EdDSA private keys (extracts the public component) and EdDSA public keys.
Returns an error if the key is not an EdDSA key.
pub fn error_message(error: GoseError) -> String
Extract the message string from a GoseError, regardless of variant.
pub fn from_der(der: BitArray) -> Result(Key(kid), GoseError)
Create a key from DER-encoded data.
Auto-detects key type (RSA, EC, EdDSA, XDH) and format (PKCS#1, PKCS#8, SPKI). Supports both private and public keys.
pub fn from_eddsa_bits(
curve: eddsa.Curve,
private_bits private_bits: BitArray,
) -> Result(Key(kid), GoseError)
Create an EdDSA key pair from raw private key bytes.
The public key is derived from the private key.
This is the inverse of to_octet_bits for EdDSA private keys.
pub fn from_eddsa_public_bits(
curve: eddsa.Curve,
public_bits public_bits: BitArray,
) -> Result(Key(kid), GoseError)
Create an EdDSA public key from raw bytes.
This is the inverse of to_octet_bits for EdDSA public keys.
pub fn from_octet_bits(
secret: BitArray,
) -> Result(Key(kid), GoseError)
Create a symmetric key from raw bytes.
Used for HMAC signing (HS256/384/512) and direct encryption. Returns an error if the secret is empty.
Example
let secret = crypto.random_bytes(32)
let assert Ok(key) = gose.from_octet_bits(secret)
pub fn from_pem(pem: String) -> Result(Key(kid), GoseError)
Create a key from PEM-encoded data.
Auto-detects key type (RSA, EC, EdDSA, XDH) and format (PKCS#1, PKCS#8, SPKI). Supports both private and public keys.
pub fn from_xdh_bits(
curve: xdh.Curve,
private_bits private_bits: BitArray,
) -> Result(Key(kid), GoseError)
Create an XDH key pair from raw private key bytes.
The public key is derived from the private key.
This is the inverse of to_octet_bits for XDH private keys.
pub fn from_xdh_public_bits(
curve: xdh.Curve,
public_bits public_bits: BitArray,
) -> Result(Key(kid), GoseError)
Create an XDH public key from raw bytes.
This is the inverse of to_octet_bits for XDH public keys.
pub fn generate_aes_kw_key(size: AesKeySize) -> Key(kid)
Generate a symmetric key for AES Key Wrap.
The key size is derived from the AES variant:
Aes128→ 16 bytesAes192→ 24 bytesAes256→ 32 bytes
pub fn generate_chacha20_kw_key() -> Key(kid)
Generate a symmetric key for ChaCha20-Poly1305 Key Wrap (C20PKW / XC20PKW).
Always generates a 32-byte key, as both ChaCha20 and XChaCha20 use 256-bit keys.
pub fn generate_ec(curve: ec.Curve) -> Key(kid)
Generate a new EC key pair for the given curve.
Supported curves: P256, P384, P521, Secp256k1.
pub fn generate_eddsa(curve: eddsa.Curve) -> Key(kid)
Generate a new EdDSA key pair for the given curve.
Supported curves: Ed25519, Ed448.
pub fn generate_enc_key(enc: ContentAlg) -> Key(kid)
Generate a symmetric key for JWE content encryption.
The key size is derived from the encryption algorithm:
AesGcm(Aes128)→ 16 bytesAesGcm(Aes192)→ 24 bytesAesGcm(Aes256)→ 32 bytesAesCbcHmac(Aes128)→ 32 bytes (16 + 16 for MAC)AesCbcHmac(Aes192)→ 48 bytes (24 + 24 for MAC)AesCbcHmac(Aes256)→ 64 bytes (32 + 32 for MAC)ChaCha20Poly1305→ 32 bytesXChaCha20Poly1305→ 32 bytes
pub fn generate_hmac_key(alg: HmacAlg) -> Key(kid)
Generate a symmetric key for HMAC signing.
The key size is derived from the algorithm:
HmacSha256→ 32 bytesHmacSha384→ 48 bytesHmacSha512→ 64 bytes
pub fn generate_rsa(bits: Int) -> Result(Key(kid), GoseError)
Generate a new RSA key pair with the given key size in bits. Common sizes are 2048, 3072, and 4096. Keys smaller than 2048 bits are not recommended for security.
pub fn generate_xdh(curve: xdh.Curve) -> Key(kid)
Generate a new XDH key pair for key agreement.
Supported curves: X25519, X448.
pub fn kid(key: Key(kid)) -> Result(kid, Nil)
Get the key ID (kid) parameter.
The return type depends on the key’s kid type parameter:
Key(String)(from JWK) →Result(String, Nil)Key(BitArray)(from COSE) →Result(BitArray, Nil)
pub fn octet_key_size(key: Key(kid)) -> Result(Int, GoseError)
Get the size of an octet (symmetric) key in bytes.
Returns an error if the key is not an octet key.
pub fn public_key(key: Key(kid)) -> Result(Key(kid), GoseError)
Extract the public key from an asymmetric key.
For private keys, extracts the corresponding public key. For public keys, returns the key unchanged. Returns an error for symmetric octet keys.
When extracting a public key, key_ops are filtered to public-safe operations:
Signis mapped toVerifyDecryptandUnwrapKeyare removed (private-only)- Other operations are preserved
Example
let private_key = gose.generate_ec(ec.P256)
let assert Ok(pub_key) = gose.public_key(private_key)
pub fn rsa_public_key(
key: Key(kid),
) -> Result(rsa.PublicKey, GoseError)
Extract the RSA public key.
Works with both RSA private keys (extracts the public component) and RSA public keys.
Returns an error if the key is not an RSA key.
pub fn to_der(key: Key(kid)) -> Result(BitArray, GoseError)
Serialize a key to DER format.
Supports RSA, EC, EdDSA, and XDH keys (both private and public). Uses PKCS#8 for private keys and SPKI for public keys.
pub fn to_octet_bits(
key: Key(kid),
) -> Result(BitArray, GoseError)
Export the raw bytes of a key.
Supported key types:
- Octet keys: returns the secret bytes
- EdDSA/XDH private keys: returns the private key bytes (d)
- EdDSA/XDH public keys: returns the public key bytes (x)
pub fn to_pem(key: Key(kid)) -> Result(String, GoseError)
Serialize a key to PEM format.
Supports RSA, EC, EdDSA, and XDH keys (both private and public). Uses PKCS#8 for private keys and SPKI for public keys.
pub fn with_alg(key: Key(kid), alg: Alg) -> Key(kid)
Set the algorithm (alg) metadata parameter on a key.
pub fn with_key_ops(
key: Key(kid),
ops: List(KeyOp),
) -> Result(Key(kid), GoseError)
Set the key operations parameter.
Per RFC 7517, the values should be consistent with key_use if both are present:
Signinguse impliesSignand/orVerifyoperationsEncryptinguse impliesEncrypt,Decrypt,WrapKey,UnwrapKey,DeriveKey,DeriveBits
Returns an error if the list is empty, contains duplicates, or is
incompatible with the key’s existing key_use.
pub fn with_key_use(
key: Key(kid),
use_: KeyUse,
) -> Result(Key(kid), GoseError)
Set the public key use parameter.
Returns an error if the key already has key_ops that are incompatible with
the specified use, or if the use is incompatible with the key type per RFC
8037 (EdDSA keys can only be used for signing, XDH keys can only be used for
encryption).
pub fn with_kid(key: Key(a), kid: String) -> Key(String)
Set the key ID (kid) metadata parameter on a key.
pub fn with_kid_bits(key: Key(a), kid: BitArray) -> Key(BitArray)
Set the key ID (kid) metadata parameter on a key using raw bytes.
In COSE (RFC 9052), kid is a bstr that may contain arbitrary bytes.
For JWK interoperability where kid is a JSON string, use with_kid.
pub fn xdh_curve(key: Key(kid)) -> Result(xdh.Curve, GoseError)
Get the curve used by an XDH key.
Returns an error if the key is not an XDH key.
pub fn xdh_public_key(
key: Key(kid),
) -> Result(xdh.PublicKey, GoseError)
Extract the XDH public key (X25519/X448).
Works with both XDH private keys (extracts the public component) and XDH public keys.
Returns an error if the key is not an XDH key.