summaryrefslogtreecommitdiff
path: root/vendor/code.superseriousbusiness.org/httpsig
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/code.superseriousbusiness.org/httpsig')
-rw-r--r--vendor/code.superseriousbusiness.org/httpsig/algorithms.gen.go49
-rw-r--r--vendor/code.superseriousbusiness.org/httpsig/algorithms.go97
-rw-r--r--vendor/code.superseriousbusiness.org/httpsig/digest.go52
-rw-r--r--vendor/code.superseriousbusiness.org/httpsig/httpsig.go42
-rw-r--r--vendor/code.superseriousbusiness.org/httpsig/signing.go1
5 files changed, 146 insertions, 95 deletions
diff --git a/vendor/code.superseriousbusiness.org/httpsig/algorithms.gen.go b/vendor/code.superseriousbusiness.org/httpsig/algorithms.gen.go
new file mode 100644
index 000000000..94080f611
--- /dev/null
+++ b/vendor/code.superseriousbusiness.org/httpsig/algorithms.gen.go
@@ -0,0 +1,49 @@
+// generated using: go run ./gen/ algorithms.go algorithms.gen.go
+package httpsig
+
+import "crypto"
+
+func stringToHash(name string) crypto.Hash {
+ switch name {
+ case md4String:
+ return crypto.MD4
+ case md5String:
+ return crypto.MD5
+ case ripemd160String:
+ return crypto.RIPEMD160
+ case md5sha1String:
+ return crypto.MD5SHA1
+ case sha1String:
+ return crypto.SHA1
+ case sha224String:
+ return crypto.SHA224
+ case sha256String:
+ return crypto.SHA256
+ case sha384String:
+ return crypto.SHA384
+ case sha512String:
+ return crypto.SHA512
+ case sha3_224String:
+ return crypto.SHA3_224
+ case sha3_256String:
+ return crypto.SHA3_256
+ case sha3_384String:
+ return crypto.SHA3_384
+ case sha3_512String:
+ return crypto.SHA3_512
+ case sha512_224String:
+ return crypto.SHA512_224
+ case sha512_256String:
+ return crypto.SHA512_256
+ case blake2s_256String:
+ return crypto.BLAKE2s_256
+ case blake2b_256String:
+ return crypto.BLAKE2b_256
+ case blake2b_384String:
+ return crypto.BLAKE2b_384
+ case blake2b_512String:
+ return crypto.BLAKE2b_512
+ default:
+ return 0
+ }
+}
diff --git a/vendor/code.superseriousbusiness.org/httpsig/algorithms.go b/vendor/code.superseriousbusiness.org/httpsig/algorithms.go
index 9595941be..2e3481d73 100644
--- a/vendor/code.superseriousbusiness.org/httpsig/algorithms.go
+++ b/vendor/code.superseriousbusiness.org/httpsig/algorithms.go
@@ -20,7 +20,6 @@ import (
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2s"
"golang.org/x/crypto/ed25519"
- "golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/ssh"
)
@@ -52,14 +51,7 @@ const (
blake2b_512String = "blake2b-512"
)
-var blake2Algorithms = map[crypto.Hash]bool{
- crypto.BLAKE2s_256: true,
- crypto.BLAKE2b_256: true,
- crypto.BLAKE2b_384: true,
- crypto.BLAKE2b_512: true,
-}
-
-var hashToDef = map[crypto.Hash]struct {
+var hashToDef = [...]struct {
name string
new func(key []byte) (hash.Hash, error) // Only MACers will accept a key
}{
@@ -68,40 +60,36 @@ var hashToDef = map[crypto.Hash]struct {
// http://www.iana.org/assignments/signature-algorithms
//
// Note that the forbidden hashes have an invalid 'new' function.
- crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
- crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
+ crypto.MD4: {md4String, nil},
+ crypto.MD5: {md5String, nil},
+ crypto.RIPEMD160: {ripemd160String, nil},
+ crypto.MD5SHA1: {md5sha1String, nil}, // shorthand for crypto/tls, not actually implemented
+
// Temporarily enable SHA1 because of issue https://github.com/golang/go/issues/37278
+ // Still cryptographically secure:
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }},
crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
crypto.SHA384: {sha384String, func(key []byte) (hash.Hash, error) { return sha512.New384(), nil }},
crypto.SHA512: {sha512String, func(key []byte) (hash.Hash, error) { return sha512.New(), nil }},
- crypto.MD5SHA1: {md5sha1String, func(key []byte) (hash.Hash, error) { return nil, nil }},
- crypto.RIPEMD160: {ripemd160String, func(key []byte) (hash.Hash, error) { return ripemd160.New(), nil }},
crypto.SHA3_224: {sha3_224String, func(key []byte) (hash.Hash, error) { return sha3.New224(), nil }},
crypto.SHA3_256: {sha3_256String, func(key []byte) (hash.Hash, error) { return sha3.New256(), nil }},
crypto.SHA3_384: {sha3_384String, func(key []byte) (hash.Hash, error) { return sha3.New384(), nil }},
crypto.SHA3_512: {sha3_512String, func(key []byte) (hash.Hash, error) { return sha3.New512(), nil }},
crypto.SHA512_224: {sha512_224String, func(key []byte) (hash.Hash, error) { return sha512.New512_224(), nil }},
crypto.SHA512_256: {sha512_256String, func(key []byte) (hash.Hash, error) { return sha512.New512_256(), nil }},
- crypto.BLAKE2s_256: {blake2s_256String, func(key []byte) (hash.Hash, error) { return blake2s.New256(key) }},
- crypto.BLAKE2b_256: {blake2b_256String, func(key []byte) (hash.Hash, error) { return blake2b.New256(key) }},
- crypto.BLAKE2b_384: {blake2b_384String, func(key []byte) (hash.Hash, error) { return blake2b.New384(key) }},
- crypto.BLAKE2b_512: {blake2b_512String, func(key []byte) (hash.Hash, error) { return blake2b.New512(key) }},
+ crypto.BLAKE2s_256: {blake2s_256String, blake2s.New256},
+ crypto.BLAKE2b_256: {blake2b_256String, blake2b.New256},
+ crypto.BLAKE2b_384: {blake2b_384String, blake2b.New384},
+ crypto.BLAKE2b_512: {blake2b_512String, blake2b.New512},
}
-var stringToHash map[string]crypto.Hash
-
const (
defaultAlgorithm = RSA_SHA256
defaultAlgorithmHashing = sha256String
)
func init() {
- stringToHash = make(map[string]crypto.Hash, len(hashToDef))
- for k, v := range hashToDef {
- stringToHash[v.name] = k
- }
// This should guarantee that at runtime the defaultAlgorithm will not
// result in errors when fetching a macer or signer (see algorithms.go)
if ok, err := isAvailable(string(defaultAlgorithmHashing)); err != nil {
@@ -112,17 +100,7 @@ func init() {
}
func isForbiddenHash(h crypto.Hash) bool {
- switch h {
- // Not actually cryptographically secure
- case crypto.MD4:
- fallthrough
- case crypto.MD5:
- fallthrough
- case crypto.MD5SHA1: // shorthand for crypto/tls, not actually implemented
- return true
- }
- // Still cryptographically secure
- return false
+ return int(h) >= len(hashToDef) || hashToDef[h].new == nil
}
// signer is an internally public type.
@@ -148,6 +126,9 @@ type hmacAlgorithm struct {
func (h *hmacAlgorithm) Sign(sig, key []byte) ([]byte, error) {
hs, err := h.fn(key)
+ if err != nil {
+ return nil, err
+ }
if err = setSig(hs, sig); err != nil {
return nil, err
}
@@ -169,7 +150,7 @@ func (h *hmacAlgorithm) Equal(sig, actualMAC, key []byte) (bool, error) {
}
func (h *hmacAlgorithm) String() string {
- return fmt.Sprintf("%s-%s", hmacPrefix, hashToDef[h.kind].name)
+ return hmacPrefix + "-" + hashToDef[h.kind].name
}
var _ signer = &rsaAlgorithm{}
@@ -226,7 +207,7 @@ func (r *rsaAlgorithm) Verify(pub crypto.PublicKey, toHash, signature []byte) er
}
func (r *rsaAlgorithm) String() string {
- return fmt.Sprintf("%s-%s", rsaPrefix, hashToDef[r.kind].name)
+ return rsaPrefix + "-" + hashToDef[r.kind].name
}
var _ signer = &ed25519Algorithm{}
@@ -265,7 +246,7 @@ func (r *ed25519Algorithm) Verify(pub crypto.PublicKey, toHash, signature []byte
}
func (r *ed25519Algorithm) String() string {
- return fmt.Sprintf("%s", ed25519Prefix)
+ return ed25519Prefix
}
var _ signer = &ecdsaAlgorithm{}
@@ -335,7 +316,7 @@ func (r *ecdsaAlgorithm) Verify(pub crypto.PublicKey, toHash, signature []byte)
}
func (r *ecdsaAlgorithm) String() string {
- return fmt.Sprintf("%s-%s", ecdsaPrefix, hashToDef[r.kind].name)
+ return ecdsaPrefix + "-" + hashToDef[r.kind].name
}
var _ macer = &blakeMacAlgorithm{}
@@ -371,7 +352,7 @@ func (r *blakeMacAlgorithm) Equal(sig, actualMAC, key []byte) (bool, error) {
}
func (r *blakeMacAlgorithm) String() string {
- return fmt.Sprintf("%s", hashToDef[r.kind].name)
+ return hashToDef[r.kind].name
}
func setSig(a hash.Hash, b []byte) error {
@@ -395,8 +376,8 @@ func IsSupportedHttpSigAlgorithm(algo string) bool {
// isAvailable is an internally public function
func isAvailable(algo string) (bool, error) {
- c, ok := stringToHash[algo]
- if !ok {
+ c := stringToHash(algo)
+ if c == 0 {
return false, fmt.Errorf("no match for %q", algo)
}
if isForbiddenHash(c) {
@@ -406,9 +387,8 @@ func isAvailable(algo string) (bool, error) {
}
func newAlgorithmConstructor(algo string) (fn func(k []byte) (hash.Hash, error), c crypto.Hash, e error) {
- ok := false
- c, ok = stringToHash[algo]
- if !ok {
+ c = stringToHash(algo)
+ if c == 0 {
e = fmt.Errorf("no match for %q", algo)
return
}
@@ -416,18 +396,12 @@ func newAlgorithmConstructor(algo string) (fn func(k []byte) (hash.Hash, error),
e = fmt.Errorf("forbidden hash type in %q", algo)
return
}
- algoDef, ok := hashToDef[c]
- if !ok {
+ if int(c) > len(hashToDef) {
e = fmt.Errorf("have crypto.Hash %v but no definition", c)
return
}
- fn = func(key []byte) (hash.Hash, error) {
- h, err := algoDef.new(key)
- if err != nil {
- return nil, err
- }
- return h, nil
- }
+ algoDef := hashToDef[c]
+ fn = algoDef.new
return
}
@@ -517,7 +491,7 @@ func macerFromString(s string) (macer, error) {
},
kind: cHash,
}, nil
- } else if bl, ok := stringToHash[s]; ok && blake2Algorithms[bl] {
+ } else if bl := stringToHash(s); bl != 0 && isBlake2(bl) {
hashFn, cHash, err := newAlgorithmConstructor(s)
if err != nil {
return nil, err
@@ -530,3 +504,18 @@ func macerFromString(s string) (macer, error) {
return nil, fmt.Errorf("no MACer matching %q", s)
}
}
+
+func isBlake2(h crypto.Hash) bool {
+ switch h {
+ case crypto.BLAKE2s_256:
+ return true
+ case crypto.BLAKE2b_256:
+ return true
+ case crypto.BLAKE2b_384:
+ return true
+ case crypto.BLAKE2b_512:
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/code.superseriousbusiness.org/httpsig/digest.go b/vendor/code.superseriousbusiness.org/httpsig/digest.go
index bf9e3a914..140b10ac5 100644
--- a/vendor/code.superseriousbusiness.org/httpsig/digest.go
+++ b/vendor/code.superseriousbusiness.org/httpsig/digest.go
@@ -14,32 +14,38 @@ type DigestAlgorithm string
const (
DigestSha256 DigestAlgorithm = "SHA-256"
- DigestSha512 = "SHA-512"
+ DigestSha512 DigestAlgorithm = "SHA-512"
)
-var digestToDef = map[DigestAlgorithm]crypto.Hash{
- DigestSha256: crypto.SHA256,
- DigestSha512: crypto.SHA512,
+// hashForDigest returns a hash algorithm for digest algorithm string.
+func hashForDigest(algo DigestAlgorithm) crypto.Hash {
+ switch algo {
+ case DigestSha256:
+ return crypto.SHA256
+ case DigestSha512:
+ return crypto.SHA512
+ default:
+ return 0
+ }
}
// IsSupportedDigestAlgorithm returns true if hte string is supported by this
// library, is not a hash known to be weak, and is supported by the hardware.
func IsSupportedDigestAlgorithm(algo string) bool {
uc := DigestAlgorithm(strings.ToUpper(algo))
- c, ok := digestToDef[uc]
- return ok && c.Available()
+ return hashForDigest(uc).Available()
}
-func getHash(alg DigestAlgorithm) (h hash.Hash, toUse DigestAlgorithm, err error) {
- upper := DigestAlgorithm(strings.ToUpper(string(alg)))
- c, ok := digestToDef[upper]
- if !ok {
- err = fmt.Errorf("unknown or unsupported Digest algorithm: %s", alg)
+func getHash(algo DigestAlgorithm) (h hash.Hash, toUse DigestAlgorithm, err error) {
+ uc := DigestAlgorithm(strings.ToUpper(string(algo)))
+ c := hashForDigest(uc)
+ if c == 0 {
+ err = fmt.Errorf("unknown or unsupported Digest algorithm: %s", algo)
} else if !c.Available() {
- err = fmt.Errorf("unavailable Digest algorithm: %s", alg)
+ err = fmt.Errorf("unavailable Digest algorithm: %s", algo)
} else {
h = c.New()
- toUse = upper
+ toUse = uc
}
return
}
@@ -56,18 +62,16 @@ func addDigest(r *http.Request, algo DigestAlgorithm, b []byte) (err error) {
return
}
var h hash.Hash
- var a DigestAlgorithm
- h, a, err = getHash(algo)
+ h, algo, err = getHash(algo)
if err != nil {
return
}
h.Write(b)
sum := h.Sum(nil)
r.Header.Add(digestHeader,
- fmt.Sprintf("%s%s%s",
- a,
- digestDelim,
- base64.StdEncoding.EncodeToString(sum[:])))
+ string(algo)+
+ digestDelim+
+ base64.StdEncoding.EncodeToString(sum[:]))
return
}
@@ -78,18 +82,16 @@ func addDigestResponse(r http.ResponseWriter, algo DigestAlgorithm, b []byte) (e
return
}
var h hash.Hash
- var a DigestAlgorithm
- h, a, err = getHash(algo)
+ h, algo, err = getHash(algo)
if err != nil {
return
}
h.Write(b)
sum := h.Sum(nil)
r.Header().Add(digestHeader,
- fmt.Sprintf("%s%s%s",
- a,
- digestDelim,
- base64.StdEncoding.EncodeToString(sum[:])))
+ string(algo)+
+ digestDelim+
+ base64.StdEncoding.EncodeToString(sum[:]))
return
}
diff --git a/vendor/code.superseriousbusiness.org/httpsig/httpsig.go b/vendor/code.superseriousbusiness.org/httpsig/httpsig.go
index 8864da055..022b8ff70 100644
--- a/vendor/code.superseriousbusiness.org/httpsig/httpsig.go
+++ b/vendor/code.superseriousbusiness.org/httpsig/httpsig.go
@@ -17,8 +17,8 @@ import (
"golang.org/x/crypto/ssh"
)
-// Algorithm specifies a cryptography secure algorithm for signing HTTP requests
-// and responses.
+// Algorithm specifies a cryptography secure
+// algorithm for signing HTTP requests and responses.
type Algorithm string
const (
@@ -42,20 +42,24 @@ const (
BLAKE2B_256 Algorithm = blake2b_256String
BLAKE2B_384 Algorithm = blake2b_384String
BLAKE2B_512 Algorithm = blake2b_512String
+
// RSA-based algorithms.
RSA_SHA1 Algorithm = rsaPrefix + "-" + sha1String
RSA_SHA224 Algorithm = rsaPrefix + "-" + sha224String
+
// RSA_SHA256 is the default algorithm.
RSA_SHA256 Algorithm = rsaPrefix + "-" + sha256String
RSA_SHA384 Algorithm = rsaPrefix + "-" + sha384String
RSA_SHA512 Algorithm = rsaPrefix + "-" + sha512String
RSA_RIPEMD160 Algorithm = rsaPrefix + "-" + ripemd160String
+
// ECDSA algorithms
ECDSA_SHA224 Algorithm = ecdsaPrefix + "-" + sha224String
ECDSA_SHA256 Algorithm = ecdsaPrefix + "-" + sha256String
ECDSA_SHA384 Algorithm = ecdsaPrefix + "-" + sha384String
ECDSA_SHA512 Algorithm = ecdsaPrefix + "-" + sha512String
ECDSA_RIPEMD160 Algorithm = ecdsaPrefix + "-" + ripemd160String
+
// ED25519 algorithms
// can only be SHA512
ED25519 Algorithm = ed25519Prefix
@@ -74,16 +78,17 @@ const (
rsa_BLAKE2B_512 Algorithm = rsaPrefix + "-" + blake2b_512String
)
-// HTTP Signatures can be applied to different HTTP headers, depending on the
-// expected application behavior.
+// HTTP Signatures can be applied to different HTTP headers,
+// depending on the expected application behavior.
type SignatureScheme string
const (
- // Signature will place the HTTP Signature into the 'Signature' HTTP
- // header.
+ // Signature will place the HTTP Signature
+ // into the 'Signature' HTTP header.
Signature SignatureScheme = "Signature"
- // Authorization will place the HTTP Signature into the 'Authorization'
- // HTTP header.
+
+ // Authorization will place the HTTP Signature
+ // into the 'Authorization' HTTP header.
Authorization SignatureScheme = "Authorization"
)
@@ -123,6 +128,7 @@ type SignatureOption struct {
// Note that signatures do set the deprecated 'algorithm' parameter for
// backwards compatibility.
type Signer interface {
+
// SignRequest signs the request using a private key. The public key id
// is used by the HTTP server to identify which key to use to verify the
// signature.
@@ -139,6 +145,7 @@ type Signer interface {
// HTTP Signature will then ensure both the Digest and body are not both
// modified to maliciously represent different content.
SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http.Request, body []byte) error
+
// SignResponse signs the response using a private key. The public key
// id is used by the HTTP client to identify which key to use to verify
// the signature.
@@ -176,6 +183,7 @@ type SignerWithOptions interface {
// HTTP Signature will then ensure both the Digest and body are not both
// modified to maliciously represent different content.
SignRequestWithOptions(pKey crypto.PrivateKey, pubKeyId string, r *http.Request, body []byte, opts SignatureOption) error
+
// SignResponseWithOptions signs the response using a private key. The public key
// id is used by the HTTP client to identify which key to use to verify
// the signature.
@@ -228,6 +236,7 @@ func NewSigner(prefs []Algorithm, dAlgo DigestAlgorithm, headers []string, schem
// Note that signatures do set the deprecated 'algorithm' parameter for
// backwards compatibility.
type SSHSigner interface {
+
// SignRequest signs the request using ssh.Signer.
// The public key id is used by the HTTP server to identify which key to use
// to verify the signature.
@@ -239,6 +248,7 @@ type SSHSigner interface {
// HTTP Signature will then ensure both the Digest and body are not both
// modified to maliciously represent different content.
SignRequest(pubKeyId string, r *http.Request, body []byte) error
+
// SignResponse signs the response using ssh.Signer. The public key
// id is used by the HTTP client to identify which key to use to verify
// the signature.
@@ -295,11 +305,13 @@ func getSSHAlgorithm(pkType string) Algorithm {
//
// Note that verification ignores the deprecated 'algorithm' parameter.
type Verifier interface {
+
// KeyId gets the public key id that the signature is signed with.
//
// Note that the application is expected to determine the algorithm
// used based on metadata or out-of-band information for this key id.
KeyId() string
+
// Verify accepts the public key specified by KeyId and returns an
// error if verification fails or if the signature is malformed. The
// algorithm must be the one used to create the signature in order to
@@ -360,7 +372,7 @@ func newSSHSigner(sshSigner ssh.Signer, algo Algorithm, dAlgo DigestAlgorithm, h
return nil, fmt.Errorf("no crypto implementation available for ssh algo %q: %s", algo, err)
}
- a := &asymmSSHSigner{
+ return &asymmSSHSigner{
asymmSigner: &asymmSigner{
s: s,
dAlgo: dAlgo,
@@ -370,13 +382,10 @@ func newSSHSigner(sshSigner ssh.Signer, algo Algorithm, dAlgo DigestAlgorithm, h
created: created,
expires: expires,
},
- }
-
- return a, nil
+ }, nil
}
func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme SignatureScheme, expiresIn int64) (SignerWithOptions, error) {
-
var expires, created int64 = 0, 0
if expiresIn != 0 {
created = time.Now().Unix()
@@ -396,11 +405,13 @@ func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme S
}
return a, nil
}
+
m, err := macerFromString(string(algo))
if err != nil {
return nil, fmt.Errorf("no crypto implementation available for %q: %s", algo, err)
}
- c := &macSigner{
+
+ return &macSigner{
m: m,
dAlgo: dAlgo,
headers: headers,
@@ -408,6 +419,5 @@ func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme S
prefix: scheme.authScheme(),
created: created,
expires: expires,
- }
- return c, nil
+ }, nil
}
diff --git a/vendor/code.superseriousbusiness.org/httpsig/signing.go b/vendor/code.superseriousbusiness.org/httpsig/signing.go
index a2fa38c5b..f1c8d2f1b 100644
--- a/vendor/code.superseriousbusiness.org/httpsig/signing.go
+++ b/vendor/code.superseriousbusiness.org/httpsig/signing.go
@@ -23,6 +23,7 @@ const (
parameterValueDelimiter = "\""
parameterSeparater = ","
headerParameterValueDelim = " "
+
// RequestTarget specifies to include the http request method and
// entire URI in the signature. Pass it as a header to NewSigner.
RequestTarget = "(request-target)"