diff options
Diffstat (limited to 'vendor/code.superseriousbusiness.org/httpsig')
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)" |
