crypto

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 19 Imported by: 0

README

go-eudi-crypto

ECCG-pinned cryptographic policy and JOSE/COSE/X.509 façades for EUDI Wallet relying-party and issuer components.

  • Algorithm policy pinned to ECCG Agreed Cryptographic Mechanisms v2.0 (EW-PIO-01-003): ES256/ES384/ES512, ECDH-ES(+A128KW/+A256KW) × A128GCM/A256GCM, COSE ES256/ES384/ES512, curves P-256/P-384/P-521. Unknown algorithm = reject.
  • KeyProvider interface with file-based (dev) and in-memory implementations.
  • JWS/JWE façade over lestrrat-go/jwx/v3 (SignJWS — incl. x5c from []*x509.Certificate, VerifyJWS, EncryptJWE, DecryptJWE); COSE_Sign1 façade over veraison/go-cose; X.509 chain validation against explicit anchors only (no system pool).
  • Hash-name policy for content formats: HashForName (SD-JWT _sd_alg, e.g. sha-256; empty name → baseline sha-256 per SD-JWT §4.1.1) and HashForMSODigestAlg (mdoc digestAlgorithm, e.g. SHA-256) over one ECCG allow-list.
  • EC JWK helpers: ParseECPublicKeyJWK([]byte) / ECPublicKeyToJWKmap[string]any (RFC 7518 §6.2; used for SD-JWT VC cnf.jwk holder keys, RFC 7800), strict + fuzzed.

Implemented specs: RFC 7515/7516/7518, RFC 9052/9053, RFC 5280, RFC 7800, HAIP 1.0 crypto profile; SD-JWT _sd_alg (IANA named-hash) and ISO/IEC 18013-5 MSO digestAlgorithm. See SPECREFS.md for pinned versions.

Status: pre-v1. API frozen no earlier than OIDF conformance pass.

Documentation

Overview

Package crypto is the single cryptographic policy and primitives layer for the gmb-eudi EUDI modules. All JOSE/COSE/X.509 operations go through this package; no other module names an algorithm (ECCG Agreed Cryptographic Mechanisms v2.0, EW-PIO-01-003).

Import with an alias to avoid clashing with the standard library:

eudicrypto "github.com/gmb-eudi/go-eudi-crypto"

Index

Constants

View Source
const ECCGVersion = "2.0"

ECCGVersion is the pinned version of the ECCG Agreed Cryptographic Mechanisms document this policy table implements (EW-PIO-01-003).

Variables

View Source
var (
	ErrAlgorithmNotAllowed = errors.New("crypto: algorithm not allowed by ECCG policy")
	ErrCurveNotAllowed     = errors.New("crypto: curve not allowed by ECCG policy")
	ErrKeyTypeNotAllowed   = errors.New("crypto: key type not allowed by ECCG policy")
	ErrKeyNotFound         = errors.New("crypto: key not found")
	ErrNoAnchors           = errors.New("crypto: no trust anchors provided")
	ErrCritUnsupported     = errors.New("crypto: unsupported critical header parameter")
	ErrAlgKeyMismatch      = errors.New("crypto: token algorithm does not match key")
	ErrProtectedHeader     = errors.New("crypto: forbidden protected header parameter")
	ErrMalformed           = errors.New("crypto: malformed input")
	ErrVerificationFailed  = errors.New("crypto: verification failed")
	ErrDecryptionFailed    = errors.New("crypto: decryption failed")
)

Sentinel errors. Callers map these to their own problem/reason codes; this library never carries HTTP semantics or framework dependencies.

Functions

func ECPublicKeyToJWK

func ECPublicKeyToJWK(pub stdcrypto.PublicKey) (map[string]any, error)

ECPublicKeyToJWK serializes an EC public key to an RFC 7518 §6.2 JWK as a map (ready to embed as an SD-JWT VC `cnf.jwk` object; RFC 7800). Rejects non-EC keys and curves not on the ECCG allow-list.

func EncryptJWE

func EncryptJWE(recipient stdcrypto.PublicKey, protected map[string]any, payload []byte) ([]byte, error)

EncryptJWE encrypts payload to an EC recipient key using ECDH-ES key agreement with A256GCM content encryption (RFC 7516; ECCG Agreed Mechanisms / HAIP 1.0 encrypted-response profile). Compact serialization. The protected map may carry additional header params (e.g. OID4VP Annex B.2 apu = base64url(mdocGeneratedNonce)); alg/enc/epk are set by the library from policy and must not be supplied by the caller. The pair is never taken from the caller — algorithms are policy-driven, never chosen by callers or tokens.

func GenerateEphemeralKey

func GenerateEphemeralKey(crv string) (*ecdsa.PrivateKey, error)

GenerateEphemeralKey creates a fresh EC keypair for per-session response encryption (HAIP response encryption; OID4VP §8.3 direct_post.jwt). The curve must be ECCG-allowed.

func ParseCertChain

func ParseCertChain(raw []byte) ([]*x509.Certificate, error)

ParseCertChain parses one or more certificates from PEM (CERTIFICATE blocks) or raw DER. Untrusted input — fuzzed (FuzzParseCertChain).

func ParseECPublicKeyJWK

func ParseECPublicKeyJWK(jwkJSON []byte) (stdcrypto.PublicKey, error)

ParseECPublicKeyJWK parses an RFC 7518 EC public-key JWK — as carried in an SD-JWT VC `cnf.jwk` (RFC 7800) — into a *ecdsa.PublicKey. Strict and fail-closed: only kty="EC" on an ECCG-allowed curve is accepted, x/y must be fixed-size big-endian coordinates, and the point is fully validated (on-curve, non-identity) by ecdsa.ParseUncompressedPublicKey. Malformed input is rejected and never panics (fuzzed: FuzzParseECPublicKeyJWK).

func SignCOSESign1

func SignCOSESign1(ctx context.Context, kp KeyProvider, keyID string, protected COSEHeader, payload []byte) ([]byte, error)

SignCOSESign1 signs payload as COSE_Sign1 (RFC 9052 §4.2). The alg label is derived from the key; callers must not set label 1 (algorithms are derived from keys, never chosen by callers or messages).

func SignJWS

func SignJWS(ctx context.Context, kp KeyProvider, keyID string, protected map[string]any, payload []byte) ([]byte, error)

SignJWS signs payload as a compact JWS (RFC 7515). The alg header is derived from the key; callers must not set it (algorithms are derived from keys, never chosen by callers or tokens).

func VerifyChain

func VerifyChain(leaf *x509.Certificate, intermediates []*x509.Certificate, opts ChainOptions) ([][]*x509.Certificate, error)

VerifyChain performs RFC 5280 §6.1 path validation of leaf against the explicit anchor set. Fail closed: empty anchors is an error, never a system-pool fallback.

Types

type COSEHeader

type COSEHeader map[int64]any

COSEHeader carries integer-labeled COSE header parameters (RFC 9052 §3). EUDI profiles (ISO 18013-5 IssuerAuth/DeviceAuth) use integer labels only; string labels are not surfaced by this façade.

func VerifyCOSESign1

func VerifyCOSESign1(raw []byte, key stdcrypto.PublicKey) ([]byte, COSEHeader, error)

VerifyCOSESign1 verifies a COSE_Sign1 message (RFC 9052 §4.2) against an explicitly supplied key. The expected algorithm is derived from the key; a mismatching protected alg is rejected.

type ChainOptions

type ChainOptions struct {
	Anchors []*x509.Certificate
	EKUs    []x509.ExtKeyUsage // empty = any EKU accepted (callers pass profile EKUs)
	At      time.Time          // required; explicitly injected clock, no hidden time.Now
}

ChainOptions configures VerifyChain. Anchors MUST come from go-eudi-trust — never the system pool, never inline PEM in services.

type Decrypter

type Decrypter interface {
	PrivateKey() stdcrypto.PrivateKey
}

Decrypter exposes the private key material needed for JWE ECDH-ES key agreement (RFC 7518 §4.6). In-memory implementations return the key directly; HSM-backed implementations require a native-decrypt extension of this interface — revisited when an HSM-backed provider lands.

type Header map[string]any

Header is a decoded JOSE protected header.

func DecryptJWE

func DecryptJWE(ctx context.Context, kp KeyProvider, keyID string, token []byte) ([]byte, Header, error)

DecryptJWE decrypts a compact JWE (RFC 7516) addressed to keyID. The protected header's alg/enc pair is checked against the ECCG policy BEFORE any decryption is attempted (HAIP: ECDH-ES with AES-GCM only).

func VerifyJWS

func VerifyJWS(token []byte, key stdcrypto.PublicKey) ([]byte, Header, error)

VerifyJWS verifies a compact JWS against an explicitly supplied key. The expected algorithm is derived from the key, never taken from the token (RFC 8725 §3.1 / §3.2); jku/x5u are never dereferenced — key resolution belongs to the trust layer, not this library.

type KeyProvider

type KeyProvider interface {
	Signer(ctx context.Context, keyID string) (stdcrypto.Signer, error)
	Decrypter(ctx context.Context, keyID string) (Decrypter, error)
	Public(ctx context.Context, keyID string) (stdcrypto.PublicKey, error)
}

KeyProvider abstracts access to the operator's private keys. Planned implementations: filekeys (PEM/PKCS#8, dev), k8ssecret, pkcs11 (build tag), kms — only filekeys and the in-memory StaticProvider ship today.

type Policy

type Policy interface {
	AllowedJWSAlg(alg string) bool
	AllowedJWEAlg(alg, enc string) bool
	AllowedCOSEAlg(alg int64) bool
	AllowedCurve(crv string) bool
	HashForAlg(alg string) (stdcrypto.Hash, error)
	AllowedHashName(name string) bool
	HashForName(name string) (stdcrypto.Hash, error)
	HashForMSODigestAlg(alg string) (stdcrypto.Hash, error)
}

Policy is the ECCG-pinned algorithm allow-list. Immutable; no env/config overrides for algorithms — they are derived from keys, never chosen by callers or tokens. Unknown = reject.

func ECCG

func ECCG() Policy

ECCG returns the immutable policy singleton pinned to ECCGVersion.

type StaticProvider

type StaticProvider struct {
	// contains filtered or unexported fields
}

StaticProvider is an in-memory KeyProvider for per-session ephemeral keys (GenerateEphemeralKey) and tests. The map is copied at construction and immutable afterwards, so concurrent use needs no locking.

func NewStaticProvider

func NewStaticProvider(keys map[string]*ecdsa.PrivateKey) *StaticProvider

NewStaticProvider returns a StaticProvider serving the given keys. The map is copied, so callers may safely mutate their own copy afterwards.

func (*StaticProvider) Decrypter

func (p *StaticProvider) Decrypter(_ context.Context, keyID string) (Decrypter, error)

Decrypter returns a Decrypter wrapping the EC private key matching keyID.

func (*StaticProvider) Public

func (p *StaticProvider) Public(_ context.Context, keyID string) (stdcrypto.PublicKey, error)

Public returns the EC public key matching keyID.

func (*StaticProvider) Signer

func (p *StaticProvider) Signer(_ context.Context, keyID string) (stdcrypto.Signer, error)

Signer returns the EC private key matching keyID as a crypto.Signer.

Directories

Path Synopsis
Package filekeys is the file-based (PEM/PKCS#8) KeyProvider for development and tests.
Package filekeys is the file-based (PEM/PKCS#8) KeyProvider for development and tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL