Documentation
¶
Overview ¶
Package httpsignature implements HTTP Message Signatures and digest fields.
Package httpsignature implements RFC 9421 HTTP Message Signatures and RFC 9530 digest fields for net/http.
Parsing and cryptographic validity do not authenticate or authorize an operation by themselves. Applications must construct explicit signing and verification profiles, resolve algorithm-bound keys, enforce replay policy, supply trusted external request context behind proxies, and map safe typed failures to their own protocol.
Example (ClientAndServerMiddleware) ¶
package main
import (
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"time"
httpsignature "github.com/faustbrian/go-http-signature"
)
type exampleProvider struct {
key httpsignature.SigningKey
}
func (provider exampleProvider) SigningKey(context.Context) (httpsignature.SigningKey, error) {
return provider.key, nil
}
type exampleResolver struct {
key httpsignature.ResolvedKey
}
func (resolver exampleResolver) Resolve(context.Context, string) (httpsignature.ResolvedKey, error) {
return resolver.key, nil
}
func main() {
now := time.Unix(1_700_000_000, 0)
key, _ := httpsignature.NewHMACKey([]byte("0123456789abcdef0123456789abcdef"))
components := []httpsignature.ComponentIdentifier{
{Name: "@method"}, {Name: "@authority"}, {Name: "content-digest"},
}
signingProfile, _ := httpsignature.NewSigningProfile(httpsignature.SigningProfileConfig{
AllowedAlgorithms: []httpsignature.Algorithm{httpsignature.HMACSHA256}, CoveredComponents: components,
Expires: httpsignature.ParameterForbidden, AlgorithmParameter: httpsignature.ParameterRequired,
Nonce: httpsignature.ParameterForbidden, Tag: httpsignature.ParameterForbidden,
ResolveTimeout: time.Second, Now: func() time.Time { return now },
Provider: exampleProvider{key: httpsignature.SigningKey{
KeyID: "key-2026", Algorithm: httpsignature.HMACSHA256, Key: key,
NotBefore: now.Add(-time.Hour), NotAfter: now.Add(time.Hour),
}},
})
verificationProfile, _ := httpsignature.NewVerificationProfile(httpsignature.VerificationProfileConfig{
AllowedAlgorithms: []httpsignature.Algorithm{httpsignature.HMACSHA256}, RequiredComponents: components,
Created: httpsignature.ParameterRequired, Expires: httpsignature.ParameterForbidden,
AlgorithmParameter: httpsignature.ParameterRequired, Nonce: httpsignature.ParameterForbidden,
Tag: httpsignature.ParameterForbidden, MaxAge: time.Minute, ClockSkew: time.Second,
ResolveTimeout: time.Second, Now: func() time.Time { return now },
Resolver: exampleResolver{key: httpsignature.ResolvedKey{
Algorithm: httpsignature.HMACSHA256, Key: key,
NotBefore: now.Add(-time.Hour), NotAfter: now.Add(time.Hour), FreshUntil: now.Add(time.Minute),
}},
})
mapError := func(writer http.ResponseWriter, _ *http.Request, _ error) {
http.Error(writer, "invalid signed request", http.StatusUnauthorized)
}
verifySignature, _ := httpsignature.NewRequestVerificationMiddleware(
httpsignature.RequestVerificationMiddlewareConfig{
Verifier: httpsignature.NewVerifier(verificationProfile),
SelectLabel: func(*http.Request, httpsignature.SignatureInputs, httpsignature.Signatures) (string, error) {
return "sig", nil
},
MapError: mapError,
},
)
verifyDigest, _ := httpsignature.NewBufferedContentDigestVerificationMiddleware(
httpsignature.BufferedContentDigestVerificationMiddlewareConfig{
RequiredAlgorithms: []httpsignature.DigestAlgorithm{httpsignature.SHA256},
MaxBytes: 1024, MapError: mapError,
},
)
server := httptest.NewServer(verifyDigest(verifySignature(http.HandlerFunc(
func(writer http.ResponseWriter, request *http.Request) {
body, _ := io.ReadAll(request.Body)
_, verified := httpsignature.VerifiedSignatureFromContext(request.Context())
_, _ = fmt.Fprintln(writer, verified, string(body))
},
))))
defer server.Close()
signingTransport, _ := httpsignature.NewSigningRoundTripper(httpsignature.SigningRoundTripperConfig{
Transport: server.Client().Transport, Signer: httpsignature.NewSigner(signingProfile), Label: "sig",
Existing: httpsignature.ExistingSignaturesReject,
Options: func(context.Context, *http.Request) (httpsignature.SigningOptions, error) {
return httpsignature.SigningOptions{}, nil
},
})
digestTransport, _ := httpsignature.NewBufferedContentDigestRoundTripper(
httpsignature.BufferedContentDigestRoundTripperConfig{
Transport: signingTransport, Algorithms: []httpsignature.DigestAlgorithm{httpsignature.SHA256}, MaxBytes: 1024,
},
)
client := &http.Client{Transport: digestTransport}
response, _ := client.Post(server.URL+"/messages", "text/plain", strings.NewReader("signed payload"))
responseBody, _ := io.ReadAll(response.Body)
_ = response.Body.Close()
fmt.Print(response.StatusCode, " ", string(responseBody))
}
Output: 200 true signed payload
Example (RequestSignAndVerify) ¶
package main
import (
"context"
"fmt"
"net/http"
"time"
httpsignature "github.com/faustbrian/go-http-signature"
)
type exampleProvider struct {
key httpsignature.SigningKey
}
func (provider exampleProvider) SigningKey(context.Context) (httpsignature.SigningKey, error) {
return provider.key, nil
}
type exampleResolver struct {
key httpsignature.ResolvedKey
}
func (resolver exampleResolver) Resolve(context.Context, string) (httpsignature.ResolvedKey, error) {
return resolver.key, nil
}
func main() {
now := time.Unix(1_700_000_000, 0)
key, _ := httpsignature.NewHMACKey([]byte("0123456789abcdef0123456789abcdef"))
signingProfile, _ := httpsignature.NewSigningProfile(httpsignature.SigningProfileConfig{
AllowedAlgorithms: []httpsignature.Algorithm{httpsignature.HMACSHA256},
CoveredComponents: []httpsignature.ComponentIdentifier{{Name: "@method"}, {Name: "@authority"}},
Expires: httpsignature.ParameterForbidden,
AlgorithmParameter: httpsignature.ParameterRequired,
Nonce: httpsignature.ParameterForbidden,
Tag: httpsignature.ParameterForbidden,
ResolveTimeout: time.Second,
Now: func() time.Time { return now },
Provider: exampleProvider{key: httpsignature.SigningKey{
KeyID: "key-2026", Algorithm: httpsignature.HMACSHA256, Key: key,
NotBefore: now.Add(-time.Hour), NotAfter: now.Add(time.Hour),
}},
})
request, _ := http.NewRequest(http.MethodPost, "https://api.example/pay", nil)
signed, _ := httpsignature.NewSigner(signingProfile).Sign(
context.Background(), httpsignature.MessageContext{Request: request}, "sig", httpsignature.SigningOptions{},
)
inputs, _ := httpsignature.ParseSignatureInputs([]string{signed.SignatureInputField()})
signatures, _ := httpsignature.ParseSignatures([]string{signed.SignatureField()})
verificationProfile, _ := httpsignature.NewVerificationProfile(httpsignature.VerificationProfileConfig{
AllowedAlgorithms: []httpsignature.Algorithm{httpsignature.HMACSHA256},
RequiredComponents: []httpsignature.ComponentIdentifier{{Name: "@method"}, {Name: "@authority"}},
Created: httpsignature.ParameterRequired,
Expires: httpsignature.ParameterForbidden,
AlgorithmParameter: httpsignature.ParameterRequired,
Nonce: httpsignature.ParameterForbidden,
Tag: httpsignature.ParameterForbidden,
MaxAge: time.Minute,
ClockSkew: time.Second,
ResolveTimeout: time.Second,
Now: func() time.Time { return now },
Resolver: exampleResolver{key: httpsignature.ResolvedKey{
Algorithm: httpsignature.HMACSHA256, Key: key,
NotBefore: now.Add(-time.Hour), NotAfter: now.Add(time.Hour), FreshUntil: now.Add(time.Minute),
}},
})
verified, err := httpsignature.NewVerifier(verificationProfile).Verify(
context.Background(), httpsignature.MessageContext{Request: request}, "sig", inputs, signatures,
)
fmt.Println(err == nil, verified.Label, verified.Algorithm)
}
Output: true sig hmac-sha256
Index ¶
- Constants
- Variables
- func CombineSignedFields(fields ...SignedFields) (SignatureInputs, Signatures, error)
- func CreateSignatureBase(context MessageContext, input SignatureInput) (string, error)
- func Sign(ctx context.Context, algorithm Algorithm, key any, signatureBase []byte, ...) ([]byte, error)
- func Verify(ctx context.Context, algorithm Algorithm, key any, ...) error
- type AcceptSignatures
- type Algorithm
- type BufferedContentDigestRoundTripper
- type BufferedContentDigestRoundTripperConfig
- type BufferedContentDigestVerificationMiddleware
- type BufferedContentDigestVerificationMiddlewareConfig
- type BufferedTrailerVerificationMiddleware
- type BufferedTrailerVerificationMiddlewareConfig
- type BufferedTrailerVerifyingRoundTripper
- type BufferedTrailerVerifyingRoundTripperConfig
- type ComponentIdentifier
- type Digest
- type DigestAlgorithm
- type DigestField
- type DigestPreference
- type DigestPreferences
- type ExistingSignaturesPolicy
- type ExternalRequestContext
- type HMACKey
- type KeyResolver
- type MemoryReplayConfig
- type MemoryReplayStore
- type MessageContext
- type Parameter
- type ParameterPolicy
- type ReplayRecord
- type ReplayStore
- type RequestVerificationMiddleware
- type RequestVerificationMiddlewareConfig
- type ResolvedKey
- type ResponseSigningMiddleware
- type ResponseSigningMiddlewareConfig
- type ResponseTransportMode
- type SFToken
- type SignatureInput
- type SignatureInputs
- type SignatureRequest
- type SignatureValue
- type Signatures
- type SignedFields
- type Signer
- type SigningKey
- type SigningKeyProvider
- type SigningOptions
- type SigningProfile
- type SigningProfileConfig
- type SigningRoundTripper
- type SigningRoundTripperConfig
- type StructuredFieldType
- type SyntaxLimits
- type TrailerResponseSigningMiddleware
- type TrailerResponseSigningMiddlewareConfig
- type TrailerSigningRoundTripper
- type TrailerSigningRoundTripperConfig
- type VerificationError
- type VerificationFailure
- type VerificationProfile
- type VerificationProfileConfig
- type VerifiedSignature
- type Verifier
- type VerifyingRoundTripper
- type VerifyingRoundTripperConfig
Examples ¶
Constants ¶
const DefaultMaxSignatureBaseBytes = 1 << 20
DefaultMaxSignatureBaseBytes is the bounded default for direct callers that do not select a stricter per-message limit.
Variables ¶
var ( // ErrUnsupportedSignatureAlgorithm reports an unavailable or unregistered algorithm. ErrUnsupportedSignatureAlgorithm = errors.New("http signature: unsupported signature algorithm") // ErrIncompatibleKey reports a wrong, malformed, or out-of-policy key type. ErrIncompatibleKey = errors.New("http signature: incompatible key") // ErrInvalidSignatureValue reports cryptographic verification failure. ErrInvalidSignatureValue = errors.New("http signature: invalid signature value") // ErrSignatureRandomness reports unavailable signing randomness. ErrSignatureRandomness = errors.New("http signature: signing randomness unavailable") )
var ( // ErrInvalidBodyIntegration reports incomplete buffered digest policy. ErrInvalidBodyIntegration = errors.New("http signature: invalid body digest integration") // ErrBodyTooLarge reports that content exceeded its explicit buffering limit. ErrBodyTooLarge = errors.New("http signature: body exceeds digest buffer") // ErrBodyRead reports a body read or closure failure without retaining // potentially sensitive backend details. ErrBodyRead = errors.New("http signature: body unavailable for digest") // ErrExistingDigest reports a caller-supplied Content-Digest field that this // fail-closed adapter refuses to replace. ErrExistingDigest = errors.New("http signature: existing Content-Digest rejected") )
var ( // ErrInvalidDigestField reports malformed, empty, or ambiguous digest data. ErrInvalidDigestField = errors.New("http signature: invalid digest field") // ErrUnsupportedDigestAlgorithm reports an algorithm unavailable for local computation. ErrUnsupportedDigestAlgorithm = errors.New("http signature: unsupported digest algorithm") // ErrMissingDigest reports that policy selected an algorithm absent from the field. ErrMissingDigest = errors.New("http signature: required digest is missing") // ErrDigestMismatch reports that content does not match a selected digest. ErrDigestMismatch = errors.New("http signature: digest mismatch") )
var ( // ErrInvalidHTTPIntegration reports incomplete adapter configuration. ErrInvalidHTTPIntegration = errors.New("http signature: invalid HTTP integration") // ErrHTTPIntegrationSigning reports request-signing failure without exposing // message or key material. ErrHTTPIntegrationSigning = errors.New("http signature: HTTP request signing failed") // ErrExistingSignatures reports fields forbidden by adapter policy. ErrExistingSignatures = errors.New("http signature: existing signature fields rejected") // ErrHTTPIntegrationVerification reports response-verification failure // without exposing message or key material. ErrHTTPIntegrationVerification = errors.New("http signature: HTTP response verification failed") // ErrResponseBodyTooLarge reports that buffered response signing reached its // explicit resource limit before any response bytes were emitted. ErrResponseBodyTooLarge = errors.New("http signature: response body exceeds signing buffer") // ErrAmbiguousProtectedField reports case-colliding map keys for a protected // HTTP field whose values cannot be interpreted unambiguously. ErrAmbiguousProtectedField = errors.New("http signature: ambiguous protected HTTP field") )
var ( // ErrSignatureBase reports that a covered component cannot be resolved safely. ErrSignatureBase = errors.New("http signature: cannot create signature base") // ErrSignatureBaseLimit reports that canonicalization exceeded its explicit // output bound. It wraps ErrSignatureBase so existing classification remains // fail closed. ErrSignatureBaseLimit = fmt.Errorf("%w: resource limit exceeded", ErrSignatureBase) )
var ( // ErrReplayDetected reports that the same key and nonce pair was already // consumed within its validity window. ErrReplayDetected = errors.New("http signature: replay detected") // ErrReplayCapacity reports that a bounded replay backend cannot accept a // new record. Callers must fail verification closed. ErrReplayCapacity = errors.New("http signature: replay store capacity exceeded") // ErrInvalidReplayRecord reports an incomplete or out-of-policy record. ErrInvalidReplayRecord = errors.New("http signature: invalid replay record") // ErrInvalidReplayConfig reports missing or non-positive resource bounds. ErrInvalidReplayConfig = errors.New("http signature: invalid replay store configuration") )
var ( // ErrInvalidSignatureInput reports a malformed or semantically invalid // Signature-Input field. ErrInvalidSignatureInput = errors.New("http signature: invalid Signature-Input field") // ErrInvalidSignature reports a malformed or semantically invalid Signature // field. ErrInvalidSignature = errors.New("http signature: invalid Signature field") // ErrInvalidAcceptSignature reports a malformed or semantically invalid // Accept-Signature field. ErrInvalidAcceptSignature = errors.New("http signature: invalid Accept-Signature field") )
var ( // ErrInvalidSigningProfile reports an incomplete or contradictory signing // policy. ErrInvalidSigningProfile = errors.New("http signature: invalid signing profile") // ErrSigningPolicy reports that a signing request violates its profile. ErrSigningPolicy = errors.New("http signature: signing policy rejected request") // ErrSigningKey reports unavailable, expired, revoked, mismatched, or // incompatible signing material. ErrSigningKey = errors.New("http signature: signing key unavailable") // ErrSigningProvider reports a provider failure without retaining backend // details in the public error chain. ErrSigningProvider = errors.New("http signature: signing key provider failed") // ErrSigningBase reports signature-base construction failure. ErrSigningBase = errors.New("http signature: signing base unavailable") // ErrSigningCryptographic reports failure of the selected signing primitive. ErrSigningCryptographic = errors.New("http signature: cryptographic signing failed") // ErrInvalidSignedFields reports an empty, malformed, mismatched, or // duplicate set supplied for deterministic field combination. ErrInvalidSignedFields = errors.New("http signature: invalid signed fields") )
var ( // ErrInvalidSyntaxLimits reports missing or contradictory parser bounds. ErrInvalidSyntaxLimits = errors.New("http signature: invalid syntax limits") // ErrSyntaxLimit reports input rejected by an explicit parser bound. ErrSyntaxLimit = errors.New("http signature: syntax resource limit exceeded") )
var ( // ErrInvalidVerificationProfile reports an incomplete or contradictory // application policy. ErrInvalidVerificationProfile = errors.New("http signature: invalid verification profile") // ErrKeyNotFound allows resolvers to distinguish an unknown identifier from // transient backend failure without disclosing the identifier. ErrKeyNotFound = errors.New("http signature: verification key not found") // ErrKeyResolutionFailure reports a resolver failure whose backend details // are deliberately not retained in the public error chain. ErrKeyResolutionFailure = errors.New("http signature: verification key resolution failed") // ErrReplayBackendFailure reports an unknown replay-backend outcome whose // details are deliberately not retained in the public error chain. ErrReplayBackendFailure = errors.New("http signature: replay backend failed") )
var ErrInvalidDigestPreferences = errors.New("http signature: invalid digest preferences")
ErrInvalidDigestPreferences reports a malformed RFC 9530 integrity preference dictionary.
Functions ¶
func CombineSignedFields ¶
func CombineSignedFields(fields ...SignedFields) (SignatureInputs, Signatures, error)
CombineSignedFields combines validated label pairs in caller order. It rejects duplicate labels and never uses map iteration to choose wire order.
func CreateSignatureBase ¶
func CreateSignatureBase(context MessageContext, input SignatureInput) (string, error)
CreateSignatureBase resolves the ordered covered components and produces the exact RFC 9421 signature base. It returns no partial base on error.
func Sign ¶
func Sign(ctx context.Context, algorithm Algorithm, key any, signatureBase []byte, random io.Reader) ([]byte, error)
Sign applies the exact RFC 9421 algorithm to signatureBase. RSA moduli must contain 2048 through 8192 bits. Randomized algorithms use Go-managed cryptographically secure randomness. random is retained for source compatibility and ignored.
func Verify ¶
func Verify(ctx context.Context, algorithm Algorithm, key any, signatureBase, signature []byte) error
Verify applies the exact RFC 9421 algorithm and returns only typed, secret-safe errors. RSA moduli must contain 2048 through 8192 bits. Verification keys must be public key types; RSA or ECDSA private keys are deliberately rejected.
Types ¶
type AcceptSignatures ¶
type AcceptSignatures struct {
// contains filtered or unexported fields
}
AcceptSignatures is an immutable ordered Accept-Signature field.
func ParseAcceptSignatures ¶
func ParseAcceptSignatures(values []string) (AcceptSignatures, error)
ParseAcceptSignatures parses requested covered components and metadata. The created and expires parameters are Boolean requests rather than timestamps.
func ParseAcceptSignaturesWithLimits ¶
func ParseAcceptSignaturesWithLimits(values []string, limits SyntaxLimits) (AcceptSignatures, error)
ParseAcceptSignaturesWithLimits parses Accept-Signature under explicit resource bounds.
func (AcceptSignatures) Entries ¶
func (requests AcceptSignatures) Entries() []SignatureRequest
Entries returns a deep copy in combined-field wire order.
func (AcceptSignatures) String ¶
func (requests AcceptSignatures) String() string
String returns the canonical Structured Fields serialization.
type Algorithm ¶
type Algorithm string
Algorithm is an active IANA HTTP Signature Algorithms registry key.
const ( // RSAPSSSHA512 is RSASSA-PSS with SHA-512, MGF1-SHA-512, and 64-byte salt. RSAPSSSHA512 Algorithm = "rsa-pss-sha512" // RSAV15SHA256 is RSASSA-PKCS1-v1_5 with SHA-256. RSAV15SHA256 Algorithm = "rsa-v1_5-sha256" // HMACSHA256 is HMAC with SHA-256. HMACSHA256 Algorithm = "hmac-sha256" // ECDSAP256SHA256 is P-256 ECDSA with SHA-256 and IEEE P1363 encoding. ECDSAP256SHA256 Algorithm = "ecdsa-p256-sha256" // ECDSAP384SHA384 is P-384 ECDSA with SHA-384 and IEEE P1363 encoding. ECDSAP384SHA384 Algorithm = "ecdsa-p384-sha384" // Ed25519 is pure Ed25519 with no prehash. Ed25519 Algorithm = "ed25519" )
type BufferedContentDigestRoundTripper ¶
type BufferedContentDigestRoundTripper struct {
// contains filtered or unexported fields
}
BufferedContentDigestRoundTripper consumes and closes the caller request body, then delegates a cloned request with a replayable buffered body. It is intended to wrap a SigningRoundTripper when Content-Digest must be covered: digest transport outside, signing transport inside, network transport last.
func NewBufferedContentDigestRoundTripper ¶
func NewBufferedContentDigestRoundTripper(config BufferedContentDigestRoundTripperConfig) (*BufferedContentDigestRoundTripper, error)
NewBufferedContentDigestRoundTripper validates explicit algorithms and a positive resource limit.
type BufferedContentDigestRoundTripperConfig ¶
type BufferedContentDigestRoundTripperConfig struct {
Transport http.RoundTripper
Algorithms []DigestAlgorithm
MaxBytes int64
}
BufferedContentDigestRoundTripperConfig defines eager Content-Digest generation. It hashes the HTTP content bytes presented to the transport, after any application-managed content coding.
type BufferedContentDigestVerificationMiddleware ¶
BufferedContentDigestVerificationMiddleware wraps an http.Handler.
func NewBufferedContentDigestVerificationMiddleware ¶
func NewBufferedContentDigestVerificationMiddleware(config BufferedContentDigestVerificationMiddlewareConfig) (BufferedContentDigestVerificationMiddleware, error)
NewBufferedContentDigestVerificationMiddleware validates an explicit, bounded inbound digest policy.
type BufferedContentDigestVerificationMiddlewareConfig ¶
type BufferedContentDigestVerificationMiddlewareConfig struct {
RequiredAlgorithms []DigestAlgorithm
MaxBytes int64
MapError func(http.ResponseWriter, *http.Request, error)
}
BufferedContentDigestVerificationMiddlewareConfig defines eager inbound Content-Digest verification. MapError owns application-specific HTTP status and disclosure behavior.
type BufferedTrailerVerificationMiddleware ¶
BufferedTrailerVerificationMiddleware wraps an http.Handler.
func NewBufferedTrailerVerificationMiddleware ¶
func NewBufferedTrailerVerificationMiddleware(config BufferedTrailerVerificationMiddlewareConfig) (BufferedTrailerVerificationMiddleware, error)
NewBufferedTrailerVerificationMiddleware validates a bounded trailer policy. It requires the verification profile to cover content-digest with tr so a successful result authenticates the digest that was checked.
type BufferedTrailerVerificationMiddlewareConfig ¶
type BufferedTrailerVerificationMiddlewareConfig struct {
Verifier *Verifier
SelectLabel func(*http.Request, SignatureInputs, Signatures) (string, error)
RequiredAlgorithms []DigestAlgorithm
MaxBytes int64
ExternalContext func(context.Context, *http.Request) (*ExternalRequestContext, error)
MapError func(http.ResponseWriter, *http.Request, error)
}
BufferedTrailerVerificationMiddlewareConfig defines eager processing for a request whose Content-Digest and message signature arrive in trailers.
type BufferedTrailerVerifyingRoundTripper ¶
type BufferedTrailerVerifyingRoundTripper struct {
// contains filtered or unexported fields
}
BufferedTrailerVerifyingRoundTripper verifies response trailers after EOF and replaces the consumed body with a replayable in-memory copy. It closes the received response body on every success and failure path.
func NewBufferedTrailerVerifyingRoundTripper ¶
func NewBufferedTrailerVerifyingRoundTripper(config BufferedTrailerVerifyingRoundTripperConfig) (*BufferedTrailerVerifyingRoundTripper, error)
NewBufferedTrailerVerifyingRoundTripper validates an explicit bounded response-trailer policy. The profile must authenticate Content-Digest with the tr parameter.
func (*BufferedTrailerVerifyingRoundTripper) RoundTrip ¶
func (transport *BufferedTrailerVerifyingRoundTripper) RoundTrip(request *http.Request) (*http.Response, error)
RoundTrip implements http.RoundTripper. Trailer loss, digest mismatch, and signature failure close the response body and return no response.
type BufferedTrailerVerifyingRoundTripperConfig ¶
type BufferedTrailerVerifyingRoundTripperConfig struct {
Transport http.RoundTripper
Verifier *Verifier
SelectLabel func(*http.Request, *http.Response, SignatureInputs, Signatures) (string, error)
RequiredAlgorithms []DigestAlgorithm
MaxBytes int64
ExternalContext func(context.Context, *http.Request, *http.Response) (*ExternalRequestContext, error)
}
BufferedTrailerVerifyingRoundTripperConfig defines eager response processing when Content-Digest and the message signature arrive in trailers. The body is not returned to the caller until its bounded digest and signature verify.
type ComponentIdentifier ¶
ComponentIdentifier identifies one ordered covered message component.
type Digest ¶
type Digest struct {
Algorithm DigestAlgorithm
Value []byte
Parameters []Parameter
}
Digest is one algorithm and checksum member of an RFC 9530 integrity field.
type DigestAlgorithm ¶
type DigestAlgorithm string
DigestAlgorithm is an RFC 9530 Hash Algorithms for HTTP Digest Fields key.
const ( // SHA256 identifies the active sha-256 digest algorithm. SHA256 DigestAlgorithm = "sha-256" // SHA512 identifies the active sha-512 digest algorithm. SHA512 DigestAlgorithm = "sha-512" )
type DigestField ¶
type DigestField struct {
// contains filtered or unexported fields
}
DigestField is an ordered, immutable RFC 9530 integrity-field dictionary. Parsed fields preserve wire order; locally computed fields use algorithm-key order so output does not depend on caller or map iteration order.
func ComputeDigests ¶
func ComputeDigests(algorithms []DigestAlgorithm, content []byte) (DigestField, error)
ComputeDigests calculates an integrity field over content using active algorithms from the RFC 9530 registry. At least one unique algorithm is required.
func ParseDigestField ¶
func ParseDigestField(value string) (DigestField, error)
ParseDigestField parses the RFC 9530 Dictionary form used by Content-Digest and Repr-Digest. It rejects duplicate keys and values other than Structured Fields Byte Sequences.
func ParseDigestFields ¶
func ParseDigestFields(values []string) (DigestField, error)
ParseDigestFields combines and parses all field lines for one Content-Digest or Repr-Digest field. Duplicate algorithm keys are rejected across lines.
func ParseDigestFieldsWithLimits ¶
func ParseDigestFieldsWithLimits(values []string, limits SyntaxLimits) (DigestField, error)
ParseDigestFieldsWithLimits combines and parses integrity field lines under explicit resource bounds.
func (DigestField) Entries ¶
func (field DigestField) Entries() []Digest
Entries returns a deep copy of the ordered digest members.
func (DigestField) String ¶
func (field DigestField) String() string
String serializes the digest dictionary using canonical Byte Sequence encoding and the field's stable member order.
func (DigestField) Verify ¶
func (field DigestField) Verify(content []byte, required []DigestAlgorithm) error
Verify computes and constant-time compares every policy-selected digest. Unknown, unselected field members are retained but ignored as RFC 9530 permits recipients to ignore any digest.
type DigestPreference ¶
type DigestPreference struct {
Algorithm DigestAlgorithm
Weight int64
}
DigestPreference is one algorithm and relative weight from a Want-Content-Digest or Want-Repr-Digest field. Weight is in the inclusive range 0 through 10; zero means not acceptable.
type DigestPreferences ¶
type DigestPreferences struct {
// contains filtered or unexported fields
}
DigestPreferences is an immutable ordered RFC 9530 integrity preference dictionary. Order is preserved because equal weights have no protocol-level tie-breaking semantics.
func NewDigestPreferences ¶
func NewDigestPreferences(entries []DigestPreference) (DigestPreferences, error)
NewDigestPreferences validates and copies an ordered preference dictionary.
func ParseDigestPreferences ¶
func ParseDigestPreferences(values []string) (DigestPreferences, error)
ParseDigestPreferences parses combined Want-Content-Digest or Want-Repr-Digest field lines. Unknown algorithm keys are retained for application policy and interoperability.
func ParseDigestPreferencesWithLimits ¶
func ParseDigestPreferencesWithLimits(values []string, limits SyntaxLimits) (DigestPreferences, error)
ParseDigestPreferencesWithLimits parses integrity preferences under explicit resource bounds.
func (DigestPreferences) Entries ¶
func (preferences DigestPreferences) Entries() []DigestPreference
Entries returns a copy in combined-field wire order.
func (DigestPreferences) String ¶
func (preferences DigestPreferences) String() string
String returns the canonical Structured Fields serialization.
type ExistingSignaturesPolicy ¶
type ExistingSignaturesPolicy uint8
ExistingSignaturesPolicy controls how a signing transport handles fields already present on a caller request. The zero value is invalid.
const ( // ExistingSignaturesReject prevents accidental overwrite or signature // confusion. ExistingSignaturesReject ExistingSignaturesPolicy = iota + 1 // ExistingSignaturesAppend parses, validates, and preserves existing label // order before appending the new signature. ExistingSignaturesAppend )
type ExternalRequestContext ¶
ExternalRequestContext is trusted request-target information supplied by an application that terminates HTTP behind an intermediary. Values are never inferred from Forwarded or X-Forwarded-* fields.
type HMACKey ¶
type HMACKey struct {
// contains filtered or unexported fields
}
HMACKey owns copied HMAC key bytes. Keys contain between 256 and 512 bits. The lower bound matches the HMAC-SHA-256 output size; the upper bound matches its block size, beyond which HMAC hashes the key before use.
func NewHMACKey ¶
NewHMACKey copies caller key material and enforces the HMACKey size bounds.
type KeyResolver ¶
type KeyResolver interface {
Resolve(context.Context, string) (ResolvedKey, error)
}
KeyResolver resolves an opaque key identifier under the supplied bounded context. Implementations must return only context-aware, bounded operations.
type MemoryReplayConfig ¶
type MemoryReplayConfig struct {
// Capacity is the maximum number of retained key and nonce identities.
Capacity int
// MaxTTL is the longest accepted interval from Now to ExpiresAt.
MaxTTL time.Duration
// MaxKeyIDBytes and MaxNonceBytes bound caller-controlled identity storage.
MaxKeyIDBytes int
MaxNonceBytes int
// Now must be safe for concurrent use and must return promptly. The store
// never invokes it while holding replay state.
Now func() time.Time
}
MemoryReplayConfig defines mandatory resource bounds and the caller-owned clock for a process-local replay store. String limits count bytes, not Unicode code points. It is not a distributed replay guarantee.
type MemoryReplayStore ¶
type MemoryReplayStore struct {
// contains filtered or unexported fields
}
MemoryReplayStore is a bounded process-local ReplayStore. It starts no goroutines. Consume removes at most one unrelated expired identity and uses an expiration heap, so cleanup work is bounded and never scans all records. Concurrent clock observations are clamped so store time never moves backward. Copies refer to the same synchronized replay state.
func NewMemoryReplayStore ¶
func NewMemoryReplayStore(config MemoryReplayConfig) (*MemoryReplayStore, error)
NewMemoryReplayStore constructs a process-local store only when all resource bounds and the clock are explicitly supplied.
func (*MemoryReplayStore) Consume ¶
func (store *MemoryReplayStore) Consume(ctx context.Context, record ReplayRecord) error
Consume atomically reserves record until its expiration. It performs a constant number of O(log Capacity) heap operations and never scans every retained identity. Caller-owned clock and context methods run without the replay lock held. Cancellation observed while waiting for replay state returns the context error without consuming the record; cancellation racing after lock acquisition may lose to a successful reservation.
type MessageContext ¶
type MessageContext struct {
Request *http.Request
Response *http.Response
RelatedRequest *http.Request
ExternalRequest *ExternalRequestContext
StructuredFields map[string]StructuredFieldType
ResponseTransport ResponseTransportMode
// MaxSignatureBaseBytes bounds the complete canonical base. Zero selects
// DefaultMaxSignatureBaseBytes; negative values are invalid.
MaxSignatureBaseBytes int
}
MessageContext supplies the target message and optional related request. Exactly one of Request and Response must be set. RelatedRequest is required when a response signature covers a component carrying the req parameter.
type Parameter ¶
Parameter is an ordered Structured Fields parameter. Value is one of bool, string, int64, float64, []byte, or SFToken. Byte values are always copied at API boundaries.
type ParameterPolicy ¶
type ParameterPolicy uint8
ParameterPolicy specifies whether one registered signature parameter is prohibited, accepted, or mandatory. The zero value is invalid so profiles cannot accidentally inherit a permissive default.
const ( ParameterForbidden ParameterPolicy = iota + 1 ParameterOptional ParameterRequired )
type ReplayRecord ¶
ReplayRecord identifies one verification attempt until ExpiresAt. KeyID and Nonce are treated as opaque values and are never included in errors.
type ReplayStore ¶
type ReplayStore interface {
Consume(context.Context, ReplayRecord) error
}
ReplayStore atomically consumes a signature nonce. A durable implementation must make concurrent Consume calls for the same key and nonce linearizable: exactly one call succeeds before expiration and all others return ErrReplayDetected. Unknown backend outcomes must return an error, never nil.
type RequestVerificationMiddleware ¶
RequestVerificationMiddleware wraps an http.Handler.
func NewRequestVerificationMiddleware ¶
func NewRequestVerificationMiddleware(config RequestVerificationMiddlewareConfig) (RequestVerificationMiddleware, error)
NewRequestVerificationMiddleware validates an inbound adapter. It supplies no status-code or disclosure defaults; MapError owns application mapping.
type RequestVerificationMiddlewareConfig ¶
type RequestVerificationMiddlewareConfig struct {
Verifier *Verifier
SelectLabel func(*http.Request, SignatureInputs, Signatures) (string, error)
ExternalContext func(context.Context, *http.Request) (*ExternalRequestContext, error)
MapError func(http.ResponseWriter, *http.Request, error)
}
RequestVerificationMiddlewareConfig defines inbound selection, trusted external-origin reconstruction, and application-specific failure mapping.
type ResolvedKey ¶
type ResolvedKey struct {
Algorithm Algorithm
Key any
NotBefore time.Time
NotAfter time.Time
FreshUntil time.Time
Revoked bool
}
ResolvedKey binds verification material to exactly one algorithm and an explicit validity and cache-freshness interval. Resolver implementations own storage, rotation, revocation lookup, caching, and remote IO.
type ResponseSigningMiddleware ¶
ResponseSigningMiddleware wraps an http.Handler.
func NewResponseSigningMiddleware ¶
func NewResponseSigningMiddleware(config ResponseSigningMiddlewareConfig) (ResponseSigningMiddleware, error)
NewResponseSigningMiddleware validates an explicit response-signing policy. Configuration, mapping, and reporting callbacks and the signing profile must be safe for concurrent handler calls.
type ResponseSigningMiddlewareConfig ¶
type ResponseSigningMiddlewareConfig struct {
Signer *Signer
Label string
Existing ExistingSignaturesPolicy
MaxBufferedBytes int64
ContentDigestAlgorithms []DigestAlgorithm
Options func(context.Context, *http.Request, *http.Response) (SigningOptions, error)
ExternalContext func(context.Context, *http.Request, *http.Response) (*ExternalRequestContext, error)
MapError func(http.ResponseWriter, *http.Request, error)
ReportError func(*http.Request, error)
}
ResponseSigningMiddlewareConfig defines a fail-closed buffered response signing boundary. MaxBufferedBytes and ReportError are mandatory; the latter records redacted output failures after signed headers have committed. Handlers requiring streaming, flushing, hijacking, or full-duplex operation need a trailer-aware adapter instead.
type ResponseTransportMode ¶
type ResponseTransportMode uint8
ResponseTransportMode selects the net/http response representation whose transport-managed fields are covered by a signature.
const ( // ResponseTransportUnspecified accepts a managed response field only when // the received and Response.Write representations are provably identical. ResponseTransportUnspecified ResponseTransportMode = iota // ResponseTransportReceived covers a response parsed by net/http or returned // by a RoundTripper. Preserved Header values carry received field identity. ResponseTransportReceived // ResponseTransportWrite covers the deterministic output of Response.Write. ResponseTransportWrite )
type SignatureInput ¶
type SignatureInput struct {
Label string
Components []ComponentIdentifier
Parameters []Parameter
}
SignatureInput is one labeled Signature-Input dictionary member.
type SignatureInputs ¶
type SignatureInputs struct {
// contains filtered or unexported fields
}
SignatureInputs is an immutable ordered Signature-Input field.
func ParseSignatureInputs ¶
func ParseSignatureInputs(values []string) (SignatureInputs, error)
ParseSignatureInputs parses and semantically validates combined Signature-Input field lines. It preserves dictionary, component, and parameter order and rejects duplicate labels before Structured Fields dictionary replacement semantics could hide them.
func ParseSignatureInputsWithLimits ¶
func ParseSignatureInputsWithLimits(values []string, limits SyntaxLimits) (SignatureInputs, error)
ParseSignatureInputsWithLimits parses Signature-Input under explicit resource bounds.
func (SignatureInputs) Entries ¶
func (inputs SignatureInputs) Entries() []SignatureInput
Entries returns a deep copy in combined-field wire order.
func (SignatureInputs) String ¶
func (inputs SignatureInputs) String() string
String returns the canonical Structured Fields serialization.
type SignatureRequest ¶
type SignatureRequest = SignatureInput
SignatureRequest is one requested signature from an Accept-Signature field.
type SignatureValue ¶
SignatureValue is one labeled Signature dictionary member.
type Signatures ¶
type Signatures struct {
// contains filtered or unexported fields
}
Signatures is an immutable ordered Signature field.
func ParseSignatures ¶
func ParseSignatures(values []string) (Signatures, error)
ParseSignatures parses and semantically validates combined Signature field lines, preserving label order and rejecting duplicate labels.
func ParseSignaturesWithLimits ¶
func ParseSignaturesWithLimits(values []string, limits SyntaxLimits) (Signatures, error)
ParseSignaturesWithLimits parses Signature under explicit resource bounds.
func (Signatures) Entries ¶
func (signatures Signatures) Entries() []SignatureValue
Entries returns a deep copy in combined-field wire order.
func (Signatures) String ¶
func (signatures Signatures) String() string
String returns the canonical Structured Fields serialization.
type SignedFields ¶
type SignedFields struct {
// contains filtered or unexported fields
}
SignedFields owns one matching Signature-Input and Signature label pair.
func (SignedFields) SignatureField ¶
func (signed SignedFields) SignatureField() string
SignatureField returns a complete canonical field value for this label.
func (SignedFields) SignatureInputField ¶
func (signed SignedFields) SignatureInputField() string
SignatureInputField returns a complete canonical field value for this label.
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer applies one immutable application signing profile.
func NewSigner ¶
func NewSigner(profile *SigningProfile) *Signer
NewSigner creates a signer with no hidden defaults or network access.
func (*Signer) Sign ¶
func (signer *Signer) Sign(ctx context.Context, message MessageContext, label string, options SigningOptions) (SignedFields, error)
Sign creates one matching signature field pair without mutating the HTTP message or consuming its body.
type SigningKey ¶
type SigningKey struct {
KeyID string
Algorithm Algorithm
Key any
NotBefore time.Time
NotAfter time.Time
Revoked bool
}
SigningKey binds private or shared signing material to an identifier, algorithm, validity interval, and revocation decision.
type SigningKeyProvider ¶
type SigningKeyProvider interface {
SigningKey(context.Context) (SigningKey, error)
}
SigningKeyProvider selects current signing material under a bounded context. Implementations own key storage and rotation; the core performs no IO.
type SigningOptions ¶
type SigningOptions struct {
Nonce string
}
SigningOptions supplies per-message values that cannot be safely defaulted.
type SigningProfile ¶
type SigningProfile struct {
// contains filtered or unexported fields
}
SigningProfile is an immutable application signing policy.
func NewSigningProfile ¶
func NewSigningProfile(config SigningProfileConfig) (*SigningProfile, error)
NewSigningProfile validates and copies an explicit signing policy.
type SigningProfileConfig ¶
type SigningProfileConfig struct {
AllowedAlgorithms []Algorithm
CoveredComponents []ComponentIdentifier
AllowEmptyCoverage bool
Expires ParameterPolicy
AlgorithmParameter ParameterPolicy
Nonce ParameterPolicy
Tag ParameterPolicy
TagValue string
Lifetime time.Duration
ResolveTimeout time.Duration
Now func() time.Time
Provider SigningKeyProvider
// Random is retained for source compatibility.
//
// Deprecated: Random is ignored. Randomized algorithms use Go-managed
// cryptographically secure randomness.
Random io.Reader
RequireExternalRequestContext bool
}
SigningProfileConfig defines all signing decisions. Creation time and keyid are always included as required by this signing API. Other registered parameters must be explicitly required or forbidden.
type SigningRoundTripper ¶
type SigningRoundTripper struct {
// contains filtered or unexported fields
}
SigningRoundTripper signs a cloned request immediately before delegation. It does not read or replace Body; the wrapped transport retains normal body consumption and closure ownership.
func NewSigningRoundTripper ¶
func NewSigningRoundTripper(config SigningRoundTripperConfig) (*SigningRoundTripper, error)
NewSigningRoundTripper validates an explicit outbound adapter configuration.
type SigningRoundTripperConfig ¶
type SigningRoundTripperConfig struct {
Transport http.RoundTripper
Signer *Signer
Label string
Existing ExistingSignaturesPolicy
Options func(context.Context, *http.Request) (SigningOptions, error)
ExternalContext func(context.Context, *http.Request) (*ExternalRequestContext, error)
}
SigningRoundTripperConfig defines an outbound request-signing boundary. Transport, options, label, and existing-field policy are all explicit.
type StructuredFieldType ¶
type StructuredFieldType uint8
StructuredFieldType describes the application-known RFC 8941 field shape required by the sf component parameter.
const ( // StructuredFieldDictionary identifies an RFC 8941 Dictionary field. StructuredFieldDictionary StructuredFieldType = iota + 1 // StructuredFieldList identifies an RFC 8941 List field. StructuredFieldList // StructuredFieldItem identifies an RFC 8941 Item field. StructuredFieldItem )
type SyntaxLimits ¶
type SyntaxLimits struct {
MaxFieldBytes int
MaxFieldLines int
MaxDictionaryMembers int
MaxComponentsPerSignature int
MaxParametersPerItem int
MaxBinaryBytes int
}
SyntaxLimits bounds untrusted Structured Fields before and after parsing. Limits are per logical combined field.
func DefaultSyntaxLimits ¶
func DefaultSyntaxLimits() SyntaxLimits
DefaultSyntaxLimits returns the restrictive bound used by convenience parsers. A fresh value prevents mutable package-global parser policy.
func (SyntaxLimits) Validate ¶
func (limits SyntaxLimits) Validate() error
Validate checks that every resource dimension has a positive bound.
type TrailerResponseSigningMiddleware ¶
TrailerResponseSigningMiddleware wraps an http.Handler. Recipients must wait for EOF and reject a response whose declared digest or signature trailers are absent. Configuration callbacks and ReportError must be concurrency-safe.
func NewTrailerResponseSigningMiddleware ¶
func NewTrailerResponseSigningMiddleware(config TrailerResponseSigningMiddlewareConfig) (TrailerResponseSigningMiddleware, error)
NewTrailerResponseSigningMiddleware validates an explicit streaming policy. The signing profile must cover Content-Digest with the tr parameter.
type TrailerResponseSigningMiddlewareConfig ¶
type TrailerResponseSigningMiddlewareConfig struct {
Signer *Signer
Label string
Algorithms []DigestAlgorithm
MaxBytes int64
Options func(context.Context, *http.Request) (SigningOptions, error)
ExternalContext func(context.Context, *http.Request) (*ExternalRequestContext, error)
ReportError func(*http.Request, error)
}
TrailerResponseSigningMiddlewareConfig defines streaming response signing. ReportError is required because a size, handler-write, key, randomness, or signing failure can occur after response bytes have already been emitted.
type TrailerSigningRoundTripper ¶
type TrailerSigningRoundTripper struct {
// contains filtered or unexported fields
}
TrailerSigningRoundTripper streams one non-replayable request attempt. It does not pre-read the body. Size, hash, key, or signing failure during Read aborts the attempt; bytes returned by earlier reads may already be on wire. A response is released only after EOF finalization succeeds.
func NewTrailerSigningRoundTripper ¶
func NewTrailerSigningRoundTripper(config TrailerSigningRoundTripperConfig) (*TrailerSigningRoundTripper, error)
NewTrailerSigningRoundTripper validates a streaming trailer policy.
func (*TrailerSigningRoundTripper) RoundTrip ¶
func (transport *TrailerSigningRoundTripper) RoundTrip(request *http.Request) (*http.Response, error)
RoundTrip implements http.RoundTripper. The wrapped transport owns the body while active; an early successful response is closed and rejected, and the adapter closes the unfinished request body.
type TrailerSigningRoundTripperConfig ¶
type TrailerSigningRoundTripperConfig struct {
Transport http.RoundTripper
Signer *Signer
Label string
Algorithms []DigestAlgorithm
MaxBytes int64
Options func(context.Context, *http.Request) (SigningOptions, error)
ExternalContext func(context.Context, *http.Request) (*ExternalRequestContext, error)
}
TrailerSigningRoundTripperConfig defines a streaming request adapter that emits Content-Digest, Signature-Input, and Signature in trailers after EOF. The signing profile must cover content-digest with the tr parameter.
type VerificationError ¶
type VerificationError struct {
Failure VerificationFailure
// contains filtered or unexported fields
}
VerificationError is safe for classification and logging. Error omits key identifiers, nonces, signature bases, signature bytes, and message content.
func (*VerificationError) Error ¶
func (err *VerificationError) Error() string
func (*VerificationError) Unwrap ¶
func (err *VerificationError) Unwrap() error
Unwrap supports errors.Is and errors.As without including the cause in the rendered error string.
type VerificationFailure ¶
type VerificationFailure string
VerificationFailure is a stable, application-mappable failure category.
const ( VerificationSelection VerificationFailure = "selection" VerificationPolicy VerificationFailure = "policy" VerificationTime VerificationFailure = "time" VerificationKeyResolution VerificationFailure = "key-resolution" VerificationKey VerificationFailure = "key" VerificationAlgorithm VerificationFailure = "algorithm" VerificationBase VerificationFailure = "signature-base" VerificationCryptographic VerificationFailure = "cryptographic" VerificationReplay VerificationFailure = "replay" )
type VerificationProfile ¶
type VerificationProfile struct {
// contains filtered or unexported fields
}
VerificationProfile is an immutable application verification policy.
func NewVerificationProfile ¶
func NewVerificationProfile(config VerificationProfileConfig) (*VerificationProfile, error)
NewVerificationProfile validates and copies an explicit application policy.
type VerificationProfileConfig ¶
type VerificationProfileConfig struct {
AllowedAlgorithms []Algorithm
RequiredComponents []ComponentIdentifier
AllowEmptyCoverage bool
Created ParameterPolicy
Expires ParameterPolicy
AlgorithmParameter ParameterPolicy
Nonce ParameterPolicy
Tag ParameterPolicy
AllowedTags []string
MaxAge time.Duration
ClockSkew time.Duration
ResolveTimeout time.Duration
ReplayTimeout time.Duration
Now func() time.Time
Resolver KeyResolver
Replay ReplayStore
RequireExternalRequestContext bool
}
VerificationProfileConfig defines the application decisions RFC 9421 leaves to a profile. Key identifiers are mandatory in this profile implementation; static keys can be exposed by a resolver that recognizes a fixed identifier.
type VerifiedSignature ¶
type VerifiedSignature struct {
Label string
KeyID string
Algorithm Algorithm
Created time.Time
Expires time.Time
}
VerifiedSignature reports the selected label and resolved public metadata. A successful result proves cryptographic validity and profile conformance; it does not grant authentication or authorization.
func VerifiedSignatureFromContext ¶
func VerifiedSignatureFromContext(ctx context.Context) (VerifiedSignature, bool)
VerifiedSignatureFromContext returns profile-conformant verification metadata stored by RequestVerificationMiddleware. It is not an authorization result.
func VerifiedSignatureFromResponse ¶
func VerifiedSignatureFromResponse(response *http.Response) (VerifiedSignature, bool)
VerifiedSignatureFromResponse returns profile-conformant verification metadata stored by VerifyingRoundTripper.
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier applies one immutable application profile.
func NewVerifier ¶
func NewVerifier(profile *VerificationProfile) *Verifier
NewVerifier creates a verifier with no hidden defaults or network access.
func (*Verifier) Verify ¶
func (verifier *Verifier) Verify( ctx context.Context, message MessageContext, label string, inputs SignatureInputs, signatures Signatures, ) (VerifiedSignature, error)
Verify selects one explicit label, enforces application policy, resolves an algorithm-bound key, verifies the reconstructed signature base, and only then atomically consumes the nonce.
type VerifyingRoundTripper ¶
type VerifyingRoundTripper struct {
// contains filtered or unexported fields
}
VerifyingRoundTripper verifies response signatures. A selected signature that covers a response Content-Digest is accepted only when an explicit bounded digest policy verifies and replaces the consumed body.
func NewVerifyingRoundTripper ¶
func NewVerifyingRoundTripper(config VerifyingRoundTripperConfig) (*VerifyingRoundTripper, error)
NewVerifyingRoundTripper validates an explicit response-verification adapter.
type VerifyingRoundTripperConfig ¶
type VerifyingRoundTripperConfig struct {
Transport http.RoundTripper
Verifier *Verifier
SelectLabel func(*http.Request, *http.Response, SignatureInputs, Signatures) (string, error)
ContentDigestAlgorithms []DigestAlgorithm
MaxBufferedBytes int64
ExternalContext func(context.Context, *http.Request, *http.Response) (*ExternalRequestContext, error)
}
VerifyingRoundTripperConfig defines response signature selection and trusted external request context. The wrapped transport retains request-body ownership; this adapter closes a response body when verification fails.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package compatibility isolates non-RFC 9421 HTTP authentication schemes behind caller-supplied protocol implementations.
|
Package compatibility isolates non-RFC 9421 HTTP authentication schemes behind caller-supplied protocol implementations. |