Documentation
¶
Index ¶
- Variables
- func DefaultResolver() (*MultiResolver, *InMemoryResolver)
- func GenerateDIDKey() (*DIDDocument, *KeyMaterial, error)
- func GenerateDIDWeb(domain, path string) (*DIDDocument, *KeyMaterial, error)
- func SafeHTTPClient(allowLoopback bool) *http.Client
- type Client
- type ContentEncryption
- type DIDDocument
- type DIDKeyResolver
- type DIDResolver
- type DIDWebResolver
- type InMemoryResolver
- type KeyMaterial
- type KeyStore
- type Message
- type Metadata
- type Mode
- type MultiResolver
- type PackOption
- type Profile
- type Serialization
- type Service
- type VerificationMethod
Constants ¶
This section is empty.
Variables ¶
var ( // ErrKeyNotFound is returned when a key cannot be found for a kid. ErrKeyNotFound = errors.New("didcomm: key not found") // ErrDIDNotFound is returned when a DID document cannot be resolved. ErrDIDNotFound = errors.New("didcomm: DID not found") // ErrInvalidMessage is returned when a message is malformed or missing // required fields. ErrInvalidMessage = errors.New("didcomm: invalid message") // ErrUnsupportedKeyType is returned for an unsupported key or curve. ErrUnsupportedKeyType = errors.New("didcomm: unsupported key type") // ErrUnsupportedProfile is returned when a profile cannot be packed or a wire // envelope uses an algorithm this library does not implement. ErrUnsupportedProfile = errors.New("didcomm: unsupported profile") // ErrNoRecipients is returned when encryption is requested with no recipients. ErrNoRecipients = errors.New("didcomm: no recipients") // ErrNoSender is returned when an operation requires a sender and none is set. ErrNoSender = errors.New("didcomm: no sender") // ErrNoServiceEndpoint is returned when a DID document exposes no // DIDCommMessaging service endpoint. ErrNoServiceEndpoint = errors.New("didcomm: no service endpoint") // ErrBlockedAddress is returned when did:web resolution is refused because the // target resolves to a non-public (loopback, private, link-local, or // metadata) address. ErrBlockedAddress = errors.New("didcomm: blocked non-public address") // ErrDecryptFailed is the single, opaque failure for any decryption or // signature-verification error. It never reveals which stage failed, so it // cannot be used as a decryption oracle. ErrDecryptFailed = errors.New("didcomm: decryption or verification failed") // ErrUnauthenticated is returned by Unpack for a message with no verifiable // sender (plain or anonymous encryption). Use UnpackUnverified to accept such // messages, understanding that the sender is not authenticated. ErrUnauthenticated = errors.New("didcomm: message has no authenticated sender") // ErrSenderMismatch is returned when the cryptographically verified sender // does not match the message's declared "from". ErrSenderMismatch = errors.New("didcomm: signer does not match message sender") // ErrRecipientMismatch is returned when this recipient is not listed in the // message's "to", which would indicate a forwarded or misdirected message. ErrRecipientMismatch = errors.New("didcomm: recipient not in message addressees") )
Sentinel errors returned across the package boundary. Match with errors.Is.
Functions ¶
func DefaultResolver ¶
func DefaultResolver() (*MultiResolver, *InMemoryResolver)
DefaultResolver creates a MultiResolver pre-configured with did:key and did:web resolvers, and an InMemoryResolver as fallback for manually stored documents. Returns both the MultiResolver (for use with Client) and the InMemoryResolver (for Store calls).
func GenerateDIDKey ¶
func GenerateDIDKey() (*DIDDocument, *KeyMaterial, error)
GenerateDIDKey generates a new did:key with an Ed25519 signing key and its derived X25519 key-agreement key. It returns the public DID document and the private KeyMaterial for the caller to load into a KeyStore.
func GenerateDIDWeb ¶
func GenerateDIDWeb(domain, path string) (*DIDDocument, *KeyMaterial, error)
GenerateDIDWeb generates a did:web with an Ed25519 signing key and its derived X25519 key-agreement key. The caller hosts the returned document at the resolved URL and loads the KeyMaterial into a KeyStore.
func SafeHTTPClient ¶
SafeHTTPClient builds an HTTP client hardened against SSRF: it blocks non-public destinations (loopback, private, link-local, and cloud-metadata addresses) at dial time, times out, and refuses redirects. It is used for did:web resolution and is exported so callers that POST to a resolved serviceEndpoint (e.g. delivering a packed message) can apply the same guard. Set allowLoopback for local development.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client packs and unpacks DIDComm v2 messages. It resolves DIDs through a Resolver and performs every private-key operation through a KeyStore, so it never holds key material itself.
func NewClient ¶
func NewClient(resolver DIDResolver, keys KeyStore) *Client
NewClient creates a Client backed by the given resolver and key store.
func (*Client) Pack ¶
Pack serializes and protects a message according to the chosen profile (default ProfileSignedAnoncrypt). See the Profile constants for the security properties of each.
func (*Client) Unpack ¶
Unpack decrypts and/or verifies an envelope and REQUIRES an authenticated sender. On success Metadata.SenderDID is cryptographically verified and equals Message.From. Plain and anonymously-encrypted messages are rejected with ErrUnauthenticated; use UnpackUnverified to accept them.
func (*Client) UnpackUnverified ¶
func (c *Client) UnpackUnverified(ctx context.Context, envelope []byte) (*Message, *Metadata, error)
UnpackUnverified decrypts where it can but does NOT require an authenticated sender. For a returned message with an empty Metadata.SenderDID, Message.From is attacker-controlled and must not be trusted. Use it only for diagnostics, relaying, or anonymous intake.
type ContentEncryption ¶
type ContentEncryption uint8
ContentEncryption identifies a content-encryption algorithm for WithContentEncryption.
const ( ContentA256GCM ContentEncryption = iota ContentA256CBCHS512 )
Content-encryption choices.
type DIDDocument ¶
type DIDDocument struct {
ID string `json:"id"`
VerificationMethod []VerificationMethod `json:"verificationMethod,omitempty"`
Authentication []VerificationMethod `json:"authentication,omitempty"`
KeyAgreement []VerificationMethod `json:"keyAgreement,omitempty"`
Service []Service `json:"service,omitempty"`
}
DIDDocument is a thin DID document with only DIDComm-relevant fields.
func (*DIDDocument) FindDIDCommEndpoint ¶
func (doc *DIDDocument) FindDIDCommEndpoint() (string, error)
FindDIDCommEndpoint returns the first DIDCommMessaging service endpoint URL from the document.
func (*DIDDocument) FindEncryptionKey ¶
func (doc *DIDDocument) FindEncryptionKey() (*VerificationMethod, error)
FindEncryptionKey returns the first X25519 key agreement key from a DID document, skipping keys of other curves (e.g. a P-256 PII key).
func (*DIDDocument) FindSigningKey ¶
func (doc *DIDDocument) FindSigningKey() (*VerificationMethod, error)
FindSigningKey returns the first authentication key from a DID document.
func (*DIDDocument) UnmarshalJSON ¶
func (doc *DIDDocument) UnmarshalJSON(data []byte) error
UnmarshalJSON handles DID document fields where authentication and keyAgreement can contain either inline verification method objects or string references to entries in the verificationMethod array.
type DIDKeyResolver ¶
type DIDKeyResolver struct{}
DIDKeyResolver resolves did:key DIDs locally by decoding the multicodec-encoded public key.
func (*DIDKeyResolver) Resolve ¶
func (r *DIDKeyResolver) Resolve(_ context.Context, did string) (*DIDDocument, error)
Resolve parses a did:key DID and returns a DIDDocument with authentication and key agreement keys.
type DIDResolver ¶
type DIDResolver interface {
Resolve(ctx context.Context, did string) (*DIDDocument, error)
}
DIDResolver resolves DIDs to DID documents.
type DIDWebResolver ¶
type DIDWebResolver struct {
// HTTPClient overrides the default guarded client. Setting it opts out of the
// built-in SSRF protections, so supply your own guard if you do.
HTTPClient *http.Client
// AllowLoopback permits connections to loopback addresses, for local
// development against a node on 127.0.0.1.
AllowLoopback bool
}
DIDWebResolver resolves did:web DIDs over HTTPS. Because a did:web identifier in an inbound message is attacker-controlled, the default transport refuses to connect to loopback, private, link-local, or cloud-metadata addresses (checked at dial time, which also defeats DNS rebinding), sets a timeout, caps the response size, and does not follow redirects.
func (*DIDWebResolver) Resolve ¶
func (r *DIDWebResolver) Resolve(ctx context.Context, did string) (*DIDDocument, error)
Resolve fetches and parses a did:web DID document.
type InMemoryResolver ¶
type InMemoryResolver struct {
// contains filtered or unexported fields
}
InMemoryResolver is a simple in-memory implementation of DIDResolver.
func NewInMemoryResolver ¶
func NewInMemoryResolver() *InMemoryResolver
NewInMemoryResolver creates a new in-memory DID resolver.
func (*InMemoryResolver) Resolve ¶
func (r *InMemoryResolver) Resolve(_ context.Context, did string) (*DIDDocument, error)
Resolve looks up a DID document by DID.
func (*InMemoryResolver) Store ¶
func (r *InMemoryResolver) Store(doc *DIDDocument)
Store registers a DID document with the resolver.
type KeyMaterial ¶
type KeyMaterial struct {
DID string `json:"did"`
SigningKID string `json:"signingKid"` // Ed25519 signing verification-method id
KeyAgreementKID string `json:"keyAgreementKid"` // X25519 key-agreement verification-method id
Ed25519Seed []byte `json:"ed25519Seed"` // 32-byte Ed25519 private seed
X25519Private []byte `json:"x25519Private"` // 32-byte X25519 private scalar
}
KeyMaterial is the private key material for a generated DID. It is returned to the caller, who loads it into a KeyStore (see the softkey package for a development store, or a KMS/HSM adapter in production). It is never passed back into the library — the library operates only through the sealed KeyStore.
type KeyStore ¶
type KeyStore interface {
// Sign returns the raw EdDSA signature over data for signing key kid.
Sign(ctx context.Context, kid string, data []byte) ([]byte, error)
// DiffieHellman returns the X25519 shared secret between key kid and
// peerPublicKey. The long-term private key is not recoverable from it.
DiffieHellman(ctx context.Context, kid string, peerPublicKey []byte) ([]byte, error)
}
KeyStore is the sole channel for private-key material: implementations hold the keys and return only operation results, so a compromised build of this library cannot exfiltrate a key. Back it with an HSM or KMS. Keys are named by their DID verification-method id (kid, e.g. "did:web:example.com#key-1").
type Message ¶
type Message struct {
ID string `json:"id"`
Type string `json:"type"`
From string `json:"from,omitempty"`
To []string `json:"to,omitempty"`
CreatedAt *time.Time `json:"created_time,omitempty"`
ExpiresAt *time.Time `json:"expires_time,omitempty"`
Body json.RawMessage `json:"body"`
Thid string `json:"thid,omitempty"`
Pthid string `json:"pthid,omitempty"`
Extra map[string]any `json:"-"`
}
Message represents a DIDComm v2 message.
func (*Message) MarshalJSON ¶
MarshalJSON implements custom JSON marshaling that includes Extra fields.
func (*Message) UnmarshalJSON ¶
UnmarshalJSON implements custom JSON unmarshaling that captures extra fields.
type Metadata ¶
type Metadata struct {
// Mode is the wire protection that was applied.
Mode Mode
// SenderDID is the cryptographically verified sender. For messages returned
// by Unpack it always equals Message.From. It is empty only for anonymous or
// plain messages, which Unpack rejects and only UnpackUnverified returns.
SenderDID string
// Encrypted reports whether the message was encrypted on the wire.
Encrypted bool
// Profile is the encrypted profile that was detected, when Encrypted.
Profile Profile
}
Metadata describes how an unpacked message was protected.
type MultiResolver ¶
type MultiResolver struct {
// contains filtered or unexported fields
}
MultiResolver routes DID resolution to method-specific resolvers based on the DID prefix.
func NewMultiResolver ¶
func NewMultiResolver(methods map[string]DIDResolver, fallback DIDResolver) *MultiResolver
NewMultiResolver creates a MultiResolver with the given method resolvers and optional fallback. The methods map keys should be DID method prefixes like "did:key" or "did:web".
func (*MultiResolver) Resolve ¶
func (r *MultiResolver) Resolve(ctx context.Context, did string) (*DIDDocument, error)
Resolve routes the DID to the appropriate method-specific resolver.
type PackOption ¶
type PackOption func(*packConfig)
PackOption configures a Pack call.
func WithContentEncryption ¶
func WithContentEncryption(enc ContentEncryption) PackOption
WithContentEncryption overrides the JWE content-encryption algorithm. Ignored where a profile fixes it (ProfileAuthcrypt1PUv4 requires A256CBC-HS512).
func WithProfile ¶
func WithProfile(p Profile) PackOption
WithProfile selects the envelope profile (default ProfileSignedAnoncrypt).
func WithSerialization ¶
func WithSerialization(s Serialization) PackOption
WithSerialization selects the JWE serialization (default GeneralJSON). Compact supports a single recipient only.
type Profile ¶
type Profile uint8
Profile selects the DIDComm envelope a message is packed into. The choice is a security and interoperability decision; see each constant.
const ( // ProfileSignedAnoncrypt is sign-then-encrypt: an inner EdDSA JWS wrapped in // an ECDH-ES anonymous-sender JWE. Authentication is the inner signature, so // it is NON-repudiable (provable to third parties) — the recommended default // where a message's origin must stand up to later audit. RFC 7515 (JWS) + // RFC 7518 §4.6 (ECDH-ES). ProfileSignedAnoncrypt Profile = iota // ProfileAuthcrypt1PUv3 is authenticated encryption via ECDH-1PU key // agreement, draft-madden-jose-ecdh-1pu-03: the sender's static key enters // the KDF, authenticating the sender at the envelope with no inner signature. // Repudiable. Interoperates with implementations that predate the draft-04 // tag binding. ProfileAuthcrypt1PUv3 // ProfileAuthcrypt1PUv4 is ECDH-1PU authcrypt per draft-madden-jose-ecdh-1pu-04, // which folds the content-encryption tag into the key derivation (§2.3) and // requires the AES-CBC-HMAC content-encryption family. ProfileAuthcrypt1PUv4 // ProfileAnoncrypt is anonymous encryption (ECDH-ES) with no sender // authentication. A message packed this way carries no verifiable sender and // is only readable through Client.UnpackUnverified. ProfileAnoncrypt // ProfileSigned is a signed-only JWS with no encryption. The body is // authenticated and non-repudiable but travels in the clear; use it only for // content that is not confidential (e.g. out-of-band invitations). ProfileSigned )
type Serialization ¶
type Serialization uint8
Serialization selects the JWE serialization for encrypted profiles.
const ( GeneralJSON Serialization = iota Compact )
JWE serialization forms.
type Service ¶
type Service struct {
ID string `json:"id"`
Type string `json:"type"`
ServiceEndpoint string `json:"serviceEndpoint"`
}
Service represents a DID document service entry.
type VerificationMethod ¶
type VerificationMethod struct {
ID string `json:"id"`
Type string `json:"type"`
Controller string `json:"controller"`
PublicKey jwk.Key `json:"-"`
}
VerificationMethod represents a DID document verification method.
func (VerificationMethod) MarshalJSON ¶
func (vm VerificationMethod) MarshalJSON() ([]byte, error)
MarshalJSON serializes a VerificationMethod including publicKeyJwk.
func (*VerificationMethod) UnmarshalJSON ¶
func (vm *VerificationMethod) UnmarshalJSON(data []byte) error
UnmarshalJSON deserializes a VerificationMethod restoring publicKeyJwk into PublicKey.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
didcomm
command
Command didcomm generates DID identities and packs, unpacks, and sends DIDComm v2 messages from the shell.
|
Command didcomm generates DID identities and packs, unpacks, and sends DIDComm v2 messages from the shell. |
|
internal
|
|
|
convert
Package convert provides Ed25519 to X25519 key conversion utilities.
|
Package convert provides Ed25519 to X25519 key conversion utilities. |
|
jose
Package jose implements the JOSE primitives DIDComm v2 needs that are not available from the standard library or the jwx JWS layer: NIST SP 800-56A Concat KDF, RFC 3394 AES key wrap, RFC 7518 content encryption, and the ECDH-ES / ECDH-1PU key-agreement key derivation used to build JWE envelopes.
|
Package jose implements the JOSE primitives DIDComm v2 needs that are not available from the standard library or the jwx JWS layer: NIST SP 800-56A Concat KDF, RFC 3394 AES key wrap, RFC 7518 content encryption, and the ECDH-ES / ECDH-1PU key-agreement key derivation used to build JWE envelopes. |
|
Package softkey provides an in-memory KeyStore for tests and local development.
|
Package softkey provides an in-memory KeyStore for tests and local development. |