Documentation ¶
Overview ¶
Package httpsign signs HTTP requests and responses as defined in RFC 9421, formerly draft-ietf-httpbis-message-signatures.
For client-side message signing and verification, use the Client wrapper. Alternatively you can use SignRequest, VerifyResponse etc. directly, but this is more complicated. For server-side operation, WrapHandler installs a wrapper around a normal HTTP message handler. Digest functionality (creation and validation of the Content-Digest header) is available automatically through the Client and WrapHandler interfaces, otherwise it is available separately.
Index ¶
- Constants
- func GenerateContentDigestHeader(body *io.ReadCloser, schemes []string) (string, error)
- func QueryEscapeForSignature(s string) string
- func RequestSignatureNames(req *http.Request, withTrailers bool) ([]string, error)
- func ResponseSignatureNames(res *http.Response, withTrailers bool) ([]string, error)
- func SignRequest(signatureName string, signer Signer, req *http.Request) (signatureInput, signature string, err error)
- func SignResponse(signatureName string, signer Signer, res *http.Response, req *http.Request) (signatureInput, signature string, err error)
- func ValidateContentDigestHeader(received []string, body *io.ReadCloser, accepted []string) error
- func VerifyRequest(signatureName string, verifier Verifier, req *http.Request) error
- func VerifyResponse(signatureName string, verifier Verifier, res *http.Response, req *http.Request) error
- func WrapHandler(h http.Handler, config HandlerConfig) http.Handler
- type Client
- func (c *Client) Do(req *http.Request) (*http.Response, error)
- func (c *Client) Get(url string) (res *http.Response, err error)
- func (c *Client) Head(url string) (res *http.Response, err error)
- func (c *Client) Post(url, contentType string, body io.Reader) (res *http.Response, err error)
- func (c *Client) PostForm(url string, data url.Values) (resp *http.Response, err error)
- type ClientConfig
- func (c *ClientConfig) SetComputeDigest(b bool) *ClientConfig
- func (c *ClientConfig) SetDigestSchemesRecv(s []string) *ClientConfig
- func (c *ClientConfig) SetDigestSchemesSend(s []string) *ClientConfig
- func (c *ClientConfig) SetFetchVerifier(...) *ClientConfig
- func (c *ClientConfig) SetSignatureName(s string) *ClientConfig
- func (c *ClientConfig) SetSigner(s *Signer) *ClientConfig
- func (c *ClientConfig) SetVerifier(v *Verifier) *ClientConfig
- type EscapeError
- type Fields
- func (fs *Fields) AddDictHeader(hdr, key string) *Fields
- func (fs *Fields) AddDictHeaderExt(hdr, key string, optional, associatedRequest, trailer bool) *Fields
- func (fs *Fields) AddHeader(hdr string) *Fields
- func (fs *Fields) AddHeaderExt(hdr string, optional bool, binarySequence bool, associatedRequest bool, ...) *Fields
- func (fs *Fields) AddHeaders(hs ...string) *Fields
- func (fs *Fields) AddQueryParam(qp string) *Fields
- func (fs *Fields) AddQueryParamExt(qp string, optional, associatedRequest, trailer bool) *Fields
- func (fs *Fields) AddStructuredField(hdr string) *Fields
- func (fs *Fields) AddStructuredFieldExt(hdr string, optional, associatedRequest, trailer bool) *Fields
- type HandlerConfig
- func (h *HandlerConfig) SetComputeDigest(b bool) *HandlerConfig
- func (h *HandlerConfig) SetDigestSchemesRecv(s []string) *HandlerConfig
- func (h *HandlerConfig) SetDigestSchemesSend(s []string) *HandlerConfig
- func (h *HandlerConfig) SetFetchSigner(f func(res http.Response, r *http.Request) (sigName string, signer *Signer)) *HandlerConfig
- func (h *HandlerConfig) SetFetchVerifier(f func(r *http.Request) (sigName string, verifier *Verifier)) *HandlerConfig
- func (h *HandlerConfig) SetLogger(l *log.Logger) *HandlerConfig
- func (h *HandlerConfig) SetReqNotVerified(f func(w http.ResponseWriter, r *http.Request, l *log.Logger, err error)) *HandlerConfig
- type InvalidHostError
- type MessageDetails
- type SignConfig
- func (c *SignConfig) SetExpires(expires int64) *SignConfig
- func (c *SignConfig) SetKeyID(keyID string) *SignConfig
- func (c *SignConfig) SetNonce(nonce string) *SignConfig
- func (c *SignConfig) SetTag(tag string) *SignConfig
- func (c *SignConfig) SignAlg(b bool) *SignConfig
- func (c *SignConfig) SignCreated(b bool) *SignConfig
- type Signer
- func NewEd25519Signer(key ed25519.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
- func NewEd25519SignerFromSeed(seed []byte, config *SignConfig, fields Fields) (*Signer, error)
- func NewHMACSHA256Signer(key []byte, config *SignConfig, fields Fields) (*Signer, error)
- func NewJWSSigner(alg jwa.SignatureAlgorithm, key interface{}, config *SignConfig, fields Fields) (*Signer, error)
- func NewP256Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
- func NewP384Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
- func NewRSAPSSSigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
- func NewRSASigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
- type Verifier
- func NewEd25519Verifier(key ed25519.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
- func NewHMACSHA256Verifier(key []byte, config *VerifyConfig, fields Fields) (*Verifier, error)
- func NewJWSVerifier(alg jwa.SignatureAlgorithm, key interface{}, config *VerifyConfig, ...) (*Verifier, error)
- func NewP256Verifier(key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
- func NewP384Verifier(key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
- func NewRSAPSSVerifier(key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
- func NewRSAVerifier(key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
- type VerifyConfig
- func (v *VerifyConfig) SetAllowedAlgs(allowedAlgs []string) *VerifyConfig
- func (v *VerifyConfig) SetAllowedTags(allowedTags []string) *VerifyConfig
- func (v *VerifyConfig) SetKeyID(keyID string) *VerifyConfig
- func (v *VerifyConfig) SetNotNewerThan(notNewerThan time.Duration) *VerifyConfig
- func (v *VerifyConfig) SetNotOlderThan(notOlderThan time.Duration) *VerifyConfig
- func (v *VerifyConfig) SetRejectExpired(rejectExpired bool) *VerifyConfig
- func (v *VerifyConfig) SetVerifyCreated(verifyCreated bool) *VerifyConfig
- func (v *VerifyConfig) SetVerifyDateWithin(d time.Duration) *VerifyConfig
Examples ¶
Constants ¶
const ( DigestSha256 = "sha-256" DigestSha512 = "sha-512" )
Constants define the hash algorithm to be used for the digest
Variables ¶
This section is empty.
Functions ¶
func GenerateContentDigestHeader ¶ added in v0.1.11
func GenerateContentDigestHeader(body *io.ReadCloser, schemes []string) (string, error)
GenerateContentDigestHeader generates a digest of the message body according to the given scheme(s) (currently supporting DigestSha256 and DigestSha512). Side effect: the message body is fully read, and replaced by a static buffer containing the body contents.
func QueryEscapeForSignature ¶ added in v0.1.16
QueryEscapeForSignature escapes the string, so it can be safely placed inside a URL query. Specifically this is "Percent-encode after encoding" in the WhatWG URL standard
func RequestSignatureNames ¶ added in v0.1.16
RequestSignatureNames returns the list of signature names present in a request (empty list if none found). This is useful if signature names are not known in advance. Set withTrailers only if the entire message needs to be read because signature headers appear in trailers. Trailers are very uncommon and come at a performance cost.
func ResponseSignatureNames ¶ added in v0.1.16
ResponseSignatureNames returns the list of signature names present in a response (empty list if none found). This is useful if signature names are not known in advance. Set withTrailers only if the entire message needs to be read because signature headers appear in trailers. Trailers are very uncommon and come at a performance cost.
func SignRequest ¶
func SignRequest(signatureName string, signer Signer, req *http.Request) (signatureInput, signature string, err error)
SignRequest signs an HTTP request. Returns the Signature-Input and the Signature header values.
Example ¶
package main import ( "bufio" "bytes" "fmt" "github.com/yaronf/httpsign" "net/http" "strings" ) func main() { config := httpsign.NewSignConfig().SignCreated(false).SetNonce("BADCAB").SetKeyID("my-shared-secret") // SignCreated should be "true" to protect against replay attacks fields := httpsign.Headers("@authority", "Date", "@method") signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0x77}, 64), config, fields) reqStr := `GET /foo HTTP/1.1 Host: example.org Date: Tue, 20 Apr 2021 02:07:55 GMT Cache-Control: max-age=60 ` req, _ := http.ReadRequest(bufio.NewReader(strings.NewReader(reqStr))) signatureInput, signature, _ := httpsign.SignRequest("sig77", *signer, req) fmt.Printf("Signature-Input: %s\n", signatureInput) fmt.Printf("Signature: %s", signature) }
Output: Signature-Input: sig77=("@authority" "date" "@method");nonce="BADCAB";alg="hmac-sha256";keyid="my-shared-secret" Signature: sig77=:BBxhfE6GoDVcohZvc+pT448u7GAK7EjJYTu+i26YZW0=:
func SignResponse ¶
func SignResponse(signatureName string, signer Signer, res *http.Response, req *http.Request) (signatureInput, signature string, err error)
SignResponse signs an HTTP response. Returns the Signature-Input and the Signature header values. The req parameter (optional) is the associated request.
func ValidateContentDigestHeader ¶ added in v0.1.11
func ValidateContentDigestHeader(received []string, body *io.ReadCloser, accepted []string) error
ValidateContentDigestHeader validates that the Content-Digest header complies to policy: at least one of the "accepted" schemes is used, and all known schemes are associated with a correct digest of the message body. Schemes are constants defined in this file, e.g. DigestSha256. Note that "received" is a string array, typically retrieved through the "Values" method of the header. Returns nil if validation is successful.
func VerifyRequest ¶
VerifyRequest verifies a signed HTTP request. Returns an error if verification failed for any reason, otherwise nil.
Example ¶
package main import ( "bufio" "bytes" "fmt" "github.com/yaronf/httpsign" "net/http" "strings" ) func main() { config := httpsign.NewVerifyConfig().SetKeyID("my-shared-secret").SetVerifyCreated(false) // for testing only verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0x77}, 64), config, httpsign.Headers("@authority", "Date", "@method")) reqStr := `GET /foo HTTP/1.1 Host: example.org Date: Tue, 20 Apr 2021 02:07:55 GMT Cache-Control: max-age=60 Signature-Input: sig77=("@authority" "date" "@method");alg="hmac-sha256";keyid="my-shared-secret" Signature: sig77=:3e9KqLP62NHfHY5OMG4036+U6tvBowZF35ALzTjpsf0=: ` req, _ := http.ReadRequest(bufio.NewReader(strings.NewReader(reqStr))) err := httpsign.VerifyRequest("sig77", *verifier, req) fmt.Printf("verified: %t", err == nil) }
Output: verified: true
func VerifyResponse ¶
func VerifyResponse(signatureName string, verifier Verifier, res *http.Response, req *http.Request) error
VerifyResponse verifies a signed HTTP response. Returns an error if verification failed for any reason, otherwise nil.
func WrapHandler ¶
func WrapHandler(h http.Handler, config HandlerConfig) http.Handler
WrapHandler wraps a server's HTTP request handler so that the incoming request is verified and the response is signed. Both operations are optional. Side effects: when signing, the wrapped handler adds a Signature and a Signature-input header. If the Content-Digest header is included in the list of signed components, it is generated and added to the response. Note: unlike the standard net.http behavior, for the "Content-Type" header to be signed, it should be created explicitly.
Example (ClientSigns) ¶
package main import ( "bufio" "bytes" "fmt" "github.com/yaronf/httpsign" "io" "net/http" "net/http/httptest" "strings" ) func main() { // Note: client/server examples may fail in the Go Playground, https://github.com/golang/go/issues/45855 // Callback to let the server locate its verifying key and configuration fetchVerifier := func(r *http.Request) (string, *httpsign.Verifier) { sigName := "sig1" verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0x99}, 64), httpsign.NewVerifyConfig().SetKeyID("key1"), httpsign.Headers("@method")) return sigName, verifier } // The basic handler (HTTP server) that gets wrapped simpleHandler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("bar", "baz") fmt.Fprintln(w, "Hey client, your message verified just fine") } // Configure the wrapper and set it up config := httpsign.NewHandlerConfig().SetFetchVerifier(fetchVerifier) ts := httptest.NewServer(httpsign.WrapHandler(http.HandlerFunc(simpleHandler), *config)) defer ts.Close() // HTTP client code, with a signer signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0x99}, 64), httpsign.NewSignConfig().SetKeyID("key1"), *httpsign.NewFields().AddHeader("content-type").AddQueryParam("pet").AddHeader("@method")) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetSigner(signer)) body := `{"hello": "world"}` host := ts.URL // test server path := "/foo?param=value&pet=dog" res, _ := client.Post(host+path, "application/json", bufio.NewReader(strings.NewReader(body))) serverText, _ := io.ReadAll(res.Body) res.Body.Close() fmt.Println("Status: ", res.Status) fmt.Println("Server sent: ", string(serverText)) }
Output: Status: 200 OK Server sent: Hey client, your message verified just fine
Example (ServerSigns) ¶
package main import ( "bytes" "fmt" "github.com/yaronf/httpsign" "io" "log" "net/http" "net/http/httptest" ) func main() { // Note: client/server examples may fail in the Go Playground, https://github.com/golang/go/issues/45855 // Callback to let the server locate its signing key and configuration fetchSigner := func(res http.Response, r *http.Request) (string, *httpsign.Signer) { sigName := "sig1" signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0}, 64), httpsign.NewSignConfig().SetKeyID("key"), httpsign.Headers("@status", "bar", "date", "content-type")) return sigName, signer } simpleHandler := func(w http.ResponseWriter, r *http.Request) { // this handler gets wrapped w.WriteHeader(200) w.Header().Set("bar", "some text here") // note: a single word in the header value would be interpreted is a trivial dictionary! w.Header().Set("Content-Type", "text/plain") fmt.Fprintln(w, "Hello, client") } // Configure the wrapper and set it up config := httpsign.NewHandlerConfig().SetFetchSigner(fetchSigner) ts := httptest.NewServer(httpsign.WrapHandler(http.HandlerFunc(simpleHandler), *config)) defer ts.Close() // HTTP client code verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0}, 64), httpsign.NewVerifyConfig().SetKeyID("key"), *httpsign.NewFields()) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetVerifier(verifier)) res, err := client.Get(ts.URL) if err != nil { log.Fatal(err) } serverText, err := io.ReadAll(res.Body) if err != nil { log.Fatal(err) } res.Body.Close() fmt.Println("Server sent: ", string(serverText)) }
Output: Server sent: Hello, client
Types ¶
type Client ¶ added in v0.1.1
type Client struct {
// contains filtered or unexported fields
}
Client represents an HTTP client that optionally signs requests and optionally verifies responses. The Signer may be nil to avoid signing. Similarly, if both Verifier and fetchVerifier are nil, no verification takes place. The fetchVerifier callback allows to generate a Verifier based on the particular response. Either Verifier or fetchVerifier may be specified, but not both. The client embeds an http.Client, which in most cases can be http.DefaultClient. Side effects: when signing, the Client adds a Signature and a Signature-input header. If the Content-Digest header is included in the list of signed components, it is generated and added to the request.
func NewClient ¶ added in v0.1.1
func NewClient(client http.Client, config *ClientConfig) *Client
NewClient constructs a new client, with the flexibility of including a custom http.Client.
func NewDefaultClient ¶ added in v0.1.1
func NewDefaultClient(config *ClientConfig) *Client
NewDefaultClient constructs a new client, based on the http.DefaultClient.
func (*Client) Do ¶ added in v0.1.1
Do sends an http.Request, with optional signing and/or verification. Errors may be produced by any of these operations.
func (*Client) Get ¶ added in v0.1.1
Get sends an HTTP GET, a wrapper for Do.
Example ¶
package main import ( "bytes" "fmt" "github.com/yaronf/httpsign" "io" "net/http" "net/http/httptest" ) func main() { // Note: client/server examples may fail in the Go Playground, https://github.com/golang/go/issues/45855 // Set up a test server simpleHandler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "text/plain") _, _ = fmt.Fprintf(w, "Hey client, you sent a signature with these parameters: %s\n", r.Header.Get("Signature-Input")) } ts := httptest.NewServer(http.HandlerFunc(simpleHandler)) defer ts.Close() // Client code starts here // Create a signer and a wrapped HTTP client (we set SignCreated to false to make the response deterministic, // don't do that in production.) signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), httpsign.NewSignConfig().SignCreated(false).SetKeyID("key1"), httpsign.Headers("@method")) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig22").SetSigner(signer)) // sign, don't verify // Send an HTTP GET, get response -- signing and verification happen behind the scenes res, _ := client.Get(ts.URL) // Read the response serverText, _ := io.ReadAll(res.Body) _ = res.Body.Close() fmt.Println("Server sent: ", string(serverText)) }
Output: Server sent: Hey client, you sent a signature with these parameters: sig22=("@method");alg="hmac-sha256";keyid="key1"
type ClientConfig ¶ added in v0.1.10
type ClientConfig struct {
// contains filtered or unexported fields
}
ClientConfig contains additional configuration for the HTTP client-side wrapper. Signing and verification may either be skipped, independently.
func NewClientConfig ¶ added in v0.1.10
func NewClientConfig() *ClientConfig
NewClientConfig creates a new, default ClientConfig.
func (*ClientConfig) SetComputeDigest ¶ added in v0.1.10
func (c *ClientConfig) SetComputeDigest(b bool) *ClientConfig
SetComputeDigest when set to its default value (true), this flag indicates that if the Content-Digest header is in the set of covered components but the header itself is missing, the header value will be computed and added to the message before sending it; conversely in received messages, if Content-Digest is covered, the digest will be computed and validated. Setting the flag to false inhibits this behavior.
func (*ClientConfig) SetDigestSchemesRecv ¶ added in v0.1.11
func (c *ClientConfig) SetDigestSchemesRecv(s []string) *ClientConfig
SetDigestSchemesRecv defines the cryptographic algorithms to accept when receiving the Content-Digest header. Any recognized algorithm's digest must be correct, but the overall header is valid if at least one accepted digest is included. Default: DigestSha256, DigestSha512.
func (*ClientConfig) SetDigestSchemesSend ¶ added in v0.1.11
func (c *ClientConfig) SetDigestSchemesSend(s []string) *ClientConfig
SetDigestSchemesSend defines the cryptographic algorithms to use when generating the Content-Digest header. Default: DigestSha256.
func (*ClientConfig) SetFetchVerifier ¶ added in v0.1.10
func (c *ClientConfig) SetFetchVerifier(fv func(res *http.Response, req *http.Request) (sigName string, verifier *Verifier)) *ClientConfig
SetFetchVerifier defines a function that fetches a verifier which may be customized for the incoming response.
func (*ClientConfig) SetSignatureName ¶ added in v0.1.10
func (c *ClientConfig) SetSignatureName(s string) *ClientConfig
SetSignatureName sets the signature name to be used for signing or verification.
func (*ClientConfig) SetSigner ¶ added in v0.1.10
func (c *ClientConfig) SetSigner(s *Signer) *ClientConfig
SetSigner defines a signer for outgoing requests.
func (*ClientConfig) SetVerifier ¶ added in v0.1.10
func (c *ClientConfig) SetVerifier(v *Verifier) *ClientConfig
SetVerifier defines a verifier for incoming responses.
type EscapeError ¶ added in v0.1.16
type EscapeError string
func (EscapeError) Error ¶ added in v0.1.16
func (e EscapeError) Error() string
type Fields ¶
type Fields struct {
// contains filtered or unexported fields
}
Fields is a list of fields to be signed or verified. To initialize, use Headers or for more complex cases, NewFields followed by a chain of Add... methods.
Several component types may be marked as optional. When signing a message, an optional component (e.g., header) is signed if it exists in the message to be signed, otherwise it is not included in the signature input. Upon verification, a field marked optional must be included in the signed components if it appears at all. This allows for intuitive handling of application components (headers, query parameters) whose presence in the message depends on application logic. Please do NOT use this functionality for headers that may legitimately be added by a proxy, such as X-Forwarded-For.
func Headers ¶ added in v0.1.5
Headers is a simple way to generate a Fields list, where only simple header names and derived headers are needed.
func (*Fields) AddDictHeader ¶
AddDictHeader indicates that out of a header structured as a dictionary, a specific key value is signed/verified.
func (*Fields) AddDictHeaderExt ¶ added in v0.1.13
func (fs *Fields) AddDictHeaderExt(hdr, key string, optional, associatedRequest, trailer bool) *Fields
AddDictHeaderExt indicates that out of a header structured as a dictionary, a specific key value is signed/verified. See type documentation for details on optional parameters. The component can be marked as coming from an associated request.
func (*Fields) AddHeaderExt ¶ added in v0.1.13
func (fs *Fields) AddHeaderExt(hdr string, optional bool, binarySequence bool, associatedRequest bool, trailer bool) *Fields
AddHeaderExt appends a bare header name, e.g. "cache-control". See type documentation for details on optional parameters. The component can be marked as coming from an associated request.
func (*Fields) AddHeaders ¶ added in v0.1.5
AddHeaders adds a list of simple or derived header names.
func (*Fields) AddQueryParam ¶
AddQueryParam indicates a request for a specific query parameter to be signed.
func (*Fields) AddQueryParamExt ¶ added in v0.1.13
AddQueryParamExt indicates a request for a specific query parameter to be signed. See type documentation for details on optional parameters. The component can be marked as coming from an associated request.
func (*Fields) AddStructuredField ¶ added in v0.1.5
AddStructuredField indicates that a header should be interpreted as a structured field, per RFC 8941.
func (*Fields) AddStructuredFieldExt ¶ added in v0.1.13
func (fs *Fields) AddStructuredFieldExt(hdr string, optional, associatedRequest, trailer bool) *Fields
AddStructuredFieldExt indicates that a header should be interpreted as a structured field, per RFC 8941. See type documentation for details on optional parameters. The component can be marked as coming from an associated request.
type HandlerConfig ¶
type HandlerConfig struct {
// contains filtered or unexported fields
}
HandlerConfig contains additional configuration for the HTTP message handler wrapper. Either or both of fetchVerifier and fetchSigner may be nil for the corresponding operation to be skipped.
func NewHandlerConfig ¶
func NewHandlerConfig() *HandlerConfig
NewHandlerConfig generates a default configuration. When verification or respectively, signing is required, the respective "fetch" callback must be supplied.
func (*HandlerConfig) SetComputeDigest ¶ added in v0.1.10
func (h *HandlerConfig) SetComputeDigest(b bool) *HandlerConfig
SetComputeDigest when set to its default value (true), this flag indicates that if the Content-Digest header is in the set of covered components but the header itself is missing, the header value will be computed and added to the message before sending it; conversely in received messages, if Content-Digest is covered, the digest will be computed and validated. Setting the flag to false inhibits this behavior.
func (*HandlerConfig) SetDigestSchemesRecv ¶ added in v0.1.11
func (h *HandlerConfig) SetDigestSchemesRecv(s []string) *HandlerConfig
SetDigestSchemesRecv defines the cryptographic algorithms to accept when receiving the Content-Digest header. Any recognized algorithm's digest must be correct, but the overall header is valid if at least one accepted digest is included. Default: DigestSha256, DigestSha512.
func (*HandlerConfig) SetDigestSchemesSend ¶ added in v0.1.11
func (h *HandlerConfig) SetDigestSchemesSend(s []string) *HandlerConfig
SetDigestSchemesSend defines the scheme(s) (cryptographic hash algorithms) to be used to generate the message digest. It only needs to be set if a Content-Digest header is signed. Default: DigestSha256
func (*HandlerConfig) SetFetchSigner ¶
func (h *HandlerConfig) SetFetchSigner(f func(res http.Response, r *http.Request) (sigName string, signer *Signer)) *HandlerConfig
SetFetchSigner defines a callback that looks at the incoming request and the response, just before it is sent, and provides a Signer structure. In the simplest case, the signature name is a constant, and the key ID and key value are fetched based on the sender's identity. To simplify this logic, it is recommended to use the request's ctx (Context) member to store this information. If a Signer cannot be determined, the function should return Signer as nil.
func (*HandlerConfig) SetFetchVerifier ¶
func (h *HandlerConfig) SetFetchVerifier(f func(r *http.Request) (sigName string, verifier *Verifier)) *HandlerConfig
SetFetchVerifier defines a callback that looks at the incoming request and provides a Verifier structure. In the simplest case, the signature name is a constant, and the key ID and key value are fetched based on the sender's identity, which in turn is gleaned from a header or query parameter. If a Verifier cannot be determined, the function should return Verifier as nil.
func (*HandlerConfig) SetLogger ¶ added in v0.1.10
func (h *HandlerConfig) SetLogger(l *log.Logger) *HandlerConfig
SetLogger defines a logger for cases where an error cannot be returned. The default logger prints to stderr. Set to nil to prevent logging.
func (*HandlerConfig) SetReqNotVerified ¶
func (h *HandlerConfig) SetReqNotVerified(f func(w http.ResponseWriter, r *http.Request, l *log.Logger, err error)) *HandlerConfig
SetReqNotVerified defines a callback to be called when a request fails to verify. The default callback sends an unsigned 401 status code with a generic error message. For production, you probably need to sign it.
type InvalidHostError ¶ added in v0.1.16
type InvalidHostError string
func (InvalidHostError) Error ¶ added in v0.1.16
func (e InvalidHostError) Error() string
type MessageDetails ¶ added in v0.1.10
MessageDetails aggregates the details of a signed message, for a given signature
func RequestDetails ¶ added in v0.1.1
func RequestDetails(signatureName string, req *http.Request) (details *MessageDetails, err error)
RequestDetails parses a signed request and returns the key ID and optionally the algorithm used in the given signature.
func ResponseDetails ¶ added in v0.1.1
func ResponseDetails(signatureName string, res *http.Response) (details *MessageDetails, err error)
ResponseDetails parses a signed response and returns the key ID and optionally the algorithm used in the given signature.
type SignConfig ¶
type SignConfig struct {
// contains filtered or unexported fields
}
SignConfig contains additional configuration for the signer.
func NewSignConfig ¶
func NewSignConfig() *SignConfig
NewSignConfig generates a default configuration.
func (*SignConfig) SetExpires ¶ added in v0.1.1
func (c *SignConfig) SetExpires(expires int64) *SignConfig
SetExpires adds an "expires" parameter containing an expiration deadline, as Unix time. Default: 0 (do not add the parameter).
func (*SignConfig) SetKeyID ¶ added in v0.3.0
func (c *SignConfig) SetKeyID(keyID string) *SignConfig
SetKeyID configures a keyid value that will be included as a signature parameter.
func (*SignConfig) SetNonce ¶ added in v0.1.1
func (c *SignConfig) SetNonce(nonce string) *SignConfig
SetNonce adds a "nonce" string parameter whose content should be unique per signed message. Default: empty string (do not add the parameter).
func (*SignConfig) SetTag ¶ added in v0.1.15
func (c *SignConfig) SetTag(tag string) *SignConfig
SetTag adds a "tag" string parameter that defines a per-application or per-protocol signature tag, to mitigate cross-protocol attacks.
func (*SignConfig) SignAlg ¶
func (c *SignConfig) SignAlg(b bool) *SignConfig
SignAlg indicates that an "alg" signature parameters must be generated and signed (default: true).
func (*SignConfig) SignCreated ¶
func (c *SignConfig) SignCreated(b bool) *SignConfig
SignCreated indicates that a "created" signature parameters must be generated and signed (default: true).
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer includes a cryptographic key (typically a private key) and configuration of what needs to be signed.
func NewEd25519Signer ¶ added in v0.1.5
func NewEd25519Signer(key ed25519.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
NewEd25519Signer returns a new Signer structure. Key is an EdDSA Curve 25519 private key. Config may be nil for a default configuration.
func NewEd25519SignerFromSeed ¶ added in v0.1.5
func NewEd25519SignerFromSeed(seed []byte, config *SignConfig, fields Fields) (*Signer, error)
NewEd25519SignerFromSeed returns a new Signer structure. Key is an EdDSA Curve 25519 private key, a 32 byte buffer according to RFC 8032. Config may be nil for a default configuration.
func NewHMACSHA256Signer ¶
func NewHMACSHA256Signer(key []byte, config *SignConfig, fields Fields) (*Signer, error)
NewHMACSHA256Signer returns a new Signer structure. Key must be at least 64 bytes long. Config may be nil for a default configuration.
func NewJWSSigner ¶ added in v0.1.4
func NewJWSSigner(alg jwa.SignatureAlgorithm, key interface{}, config *SignConfig, fields Fields) (*Signer, error)
NewJWSSigner creates a generic signer for JWS algorithms, using the go-jwx package. The particular key type for each algorithm is documented in that package. Config may be nil for a default configuration.
func NewP256Signer ¶
func NewP256Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
NewP256Signer returns a new Signer structure. Key is an elliptic curve P-256 private key. Config may be nil for a default configuration.
func NewP384Signer ¶ added in v0.1.14
func NewP384Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
NewP384Signer returns a new Signer structure. Key is an elliptic curve P-384 private key. Config may be nil for a default configuration.
func NewRSAPSSSigner ¶
func NewRSAPSSSigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
NewRSAPSSSigner returns a new Signer structure. Key is an RSA private key. Config may be nil for a default configuration.
func NewRSASigner ¶
func NewRSASigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error)
NewRSASigner returns a new Signer structure. Key is an RSA private key. Config may be nil for a default configuration.
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier includes a cryptographic key (typically a public key) and configuration of what needs to be verified.
func NewEd25519Verifier ¶ added in v0.1.5
func NewEd25519Verifier(key ed25519.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error)
NewEd25519Verifier generates a new Verifier for EdDSA Curve 25519 signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewHMACSHA256Verifier ¶
func NewHMACSHA256Verifier(key []byte, config *VerifyConfig, fields Fields) (*Verifier, error)
NewHMACSHA256Verifier generates a new Verifier for HMAC-SHA256 signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewJWSVerifier ¶ added in v0.1.4
func NewJWSVerifier(alg jwa.SignatureAlgorithm, key interface{}, config *VerifyConfig, fields Fields) (*Verifier, error)
NewJWSVerifier creates a generic verifier for JWS algorithms, using the go-jwx package. The particular key type for each algorithm is documented in that package. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewP256Verifier ¶
NewP256Verifier generates a new Verifier for ECDSA (P-256) signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewP384Verifier ¶ added in v0.1.14
NewP384Verifier generates a new Verifier for ECDSA (P-384) signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewRSAPSSVerifier ¶
NewRSAPSSVerifier generates a new Verifier for RSA-PSS signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
func NewRSAVerifier ¶
NewRSAVerifier generates a new Verifier for RSA signatures. Set config to nil for a default configuration. Fields is the list of required headers and fields, which may be empty (but this is typically insecure).
type VerifyConfig ¶
type VerifyConfig struct {
// contains filtered or unexported fields
}
VerifyConfig contains additional configuration for the verifier.
func NewVerifyConfig ¶
func NewVerifyConfig() *VerifyConfig
NewVerifyConfig generates a default configuration.
func (*VerifyConfig) SetAllowedAlgs ¶
func (v *VerifyConfig) SetAllowedAlgs(allowedAlgs []string) *VerifyConfig
SetAllowedAlgs defines the allowed values of the "alg" parameter. This is useful if the actual algorithm used in verification is taken from the message - not a recommended practice. Default: an empty list, signifying all values are accepted.
func (*VerifyConfig) SetAllowedTags ¶ added in v0.1.15
func (v *VerifyConfig) SetAllowedTags(allowedTags []string) *VerifyConfig
SetAllowedTags defines the allowed values of the "tag" parameter. Default: an empty list, signifying all values are accepted.
func (*VerifyConfig) SetKeyID ¶ added in v0.3.0
func (v *VerifyConfig) SetKeyID(keyID string) *VerifyConfig
SetKeyID defines how to verify the keyid parameter, if one exists. If this value is a non-nil string, the signature verifies only if the value is the same as was specified here. Default: nil.
func (*VerifyConfig) SetNotNewerThan ¶
func (v *VerifyConfig) SetNotNewerThan(notNewerThan time.Duration) *VerifyConfig
SetNotNewerThan sets the window for messages that appear to be newer than the current time, which can only happen if clocks are out of sync. Default: 1,000 ms.
func (*VerifyConfig) SetNotOlderThan ¶
func (v *VerifyConfig) SetNotOlderThan(notOlderThan time.Duration) *VerifyConfig
SetNotOlderThan sets the window for messages that are older than the current time, because of network latency. Default: 10,000 ms.
func (*VerifyConfig) SetRejectExpired ¶ added in v0.1.1
func (v *VerifyConfig) SetRejectExpired(rejectExpired bool) *VerifyConfig
SetRejectExpired indicates that expired messages (according to the "expires" parameter) must fail verification. Default: true.
func (*VerifyConfig) SetVerifyCreated ¶
func (v *VerifyConfig) SetVerifyCreated(verifyCreated bool) *VerifyConfig
SetVerifyCreated indicates that the "created" parameter must be within some time window, defined by NotNewerThan and NotOlderThan. Default: true.
func (*VerifyConfig) SetVerifyDateWithin ¶ added in v0.1.8
func (v *VerifyConfig) SetVerifyDateWithin(d time.Duration) *VerifyConfig
SetVerifyDateWithin indicates that the Date header should be verified if it exists, and its value must be within a certain time duration (positive or negative) of the Created signature parameter. This verification is only available if the Created field itself is verified. Default: 0, meaning no verification of the Date header.