このコミットが含まれているのは:
Cory Slep 2020-05-28 17:47:39 +02:00
コミット d7a8424b0c
4個のファイルの変更122行の追加123行の削除

ファイルの表示

@ -2,13 +2,13 @@ package httpsig
import (
"crypto"
"crypto/ecdsa"
"crypto/hmac"
"crypto/rsa"
"crypto/sha256"
"crypto/sha512"
"crypto/ecdsa"
"crypto/subtle" // Use should trigger great care
"encoding/asn1"
"encoding/asn1"
"errors"
"fmt"
"golang.org/x/crypto/blake2b"
@ -17,14 +17,14 @@ import (
"golang.org/x/crypto/sha3"
"hash"
"io"
"math/big"
"strings"
"math/big"
)
const (
hmacPrefix = "hmac"
rsaPrefix = "rsa"
ecdsaPrefix = "ecdsa"
ecdsaPrefix = "ecdsa"
md4String = "md4"
md5String = "md5"
sha1String = "sha1"
@ -234,7 +234,7 @@ func (r *ecdsaAlgorithm) setSig(b []byte) error {
}
type ECDSASignature struct {
R, S *big.Int
R, S *big.Int
}
func (r *ecdsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) ([]byte, error) {
@ -246,13 +246,13 @@ func (r *ecdsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) (
if !ok {
return nil, errors.New("crypto.PrivateKey is not *ecdsa.PrivateKey")
}
R, S, err := ecdsa.Sign(rand, ecdsaK, r.Sum(nil))
if err != nil {
return nil, err
}
R, S, err := ecdsa.Sign(rand, ecdsaK, r.Sum(nil))
if err != nil {
return nil, err
}
signature := ECDSASignature {R: R, S: S}
bytes, err := asn1.Marshal(signature)
signature := ECDSASignature{R: R, S: S}
bytes, err := asn1.Marshal(signature)
return bytes, err
}
@ -267,17 +267,17 @@ func (r *ecdsaAlgorithm) Verify(pub crypto.PublicKey, toHash, signature []byte)
return err
}
sig := new(ECDSASignature)
_, err := asn1.Unmarshal(signature, sig)
if err != nil {
return err
}
sig := new(ECDSASignature)
_, err := asn1.Unmarshal(signature, sig)
if err != nil {
return err
}
if ecdsa.Verify(ecdsaK, r.Sum(nil), sig.R, sig.S) {
return nil
} else {
return errors.New("Invalid signature")
}
if ecdsa.Verify(ecdsaK, r.Sum(nil), sig.R, sig.S) {
return nil
} else {
return errors.New("Invalid signature")
}
}
func (r *ecdsaAlgorithm) String() string {
@ -389,26 +389,26 @@ func newAlgorithm(algo string, key []byte) (hash.Hash, crypto.Hash, error) {
// signerFromString is an internally public method constructor
func signerFromString(s string) (signer, error) {
s = strings.ToLower(s)
isEcdsa := false
var algo string = ""
if strings.HasPrefix(s, ecdsaPrefix) {
algo = strings.TrimPrefix(s, ecdsaPrefix + "-")
isEcdsa = true
} else if strings.HasPrefix(s, rsaPrefix) {
algo = strings.TrimPrefix(s, rsaPrefix+"-")
isEcdsa := false
var algo string = ""
if strings.HasPrefix(s, ecdsaPrefix) {
algo = strings.TrimPrefix(s, ecdsaPrefix+"-")
isEcdsa = true
} else if strings.HasPrefix(s, rsaPrefix) {
algo = strings.TrimPrefix(s, rsaPrefix+"-")
} else {
return nil, fmt.Errorf("no signer matching %q", s)
}
}
hash, cHash, err := newAlgorithm(algo, nil)
if err != nil {
return nil, err
}
if isEcdsa {
return &ecdsaAlgorithm {
Hash: hash,
kind: cHash,
}, nil
}
if isEcdsa {
return &ecdsaAlgorithm{
Hash: hash,
kind: cHash,
}, nil
}
return &rsaAlgorithm{
Hash: hash,
kind: cHash,

ファイルの表示

@ -8,10 +8,10 @@
package httpsig
import (
"time"
"crypto"
"fmt"
"net/http"
"time"
)
// Algorithm specifies a cryptography secure algorithm for signing HTTP requests
@ -46,8 +46,8 @@ const (
RSA_SHA384 Algorithm = rsaPrefix + "-" + sha384String
RSA_SHA512 Algorithm = rsaPrefix + "-" + sha512String
RSA_RIPEMD160 Algorithm = rsaPrefix + "-" + ripemd160String
// ECDSA algorithms
ECDSA_SHA224 Algorithm = ecdsaPrefix + "-" + sha224String
// ECDSA algorithms
ECDSA_SHA224 Algorithm = ecdsaPrefix + "-" + sha224String
ECDSA_SHA256 Algorithm = ecdsaPrefix + "-" + sha256String
ECDSA_SHA384 Algorithm = ecdsaPrefix + "-" + sha384String
ECDSA_SHA512 Algorithm = ecdsaPrefix + "-" + sha512String
@ -224,11 +224,11 @@ func NewResponseVerifier(r *http.Response) (Verifier, error) {
func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme SignatureScheme, expiresIn int64) (Signer, error) {
var expires, created int64 = 0, 0
if expiresIn != 0 {
created = time.Now().Unix()
expires = created + expiresIn
}
var expires, created int64 = 0, 0
if expiresIn != 0 {
created = time.Now().Unix()
expires = created + expiresIn
}
s, err := signerFromString(string(algo))
if err == nil {
@ -238,8 +238,8 @@ func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme S
headers: headers,
targetHeader: scheme,
prefix: scheme.authScheme(),
created: created,
expires: expires,
created: created,
expires: expires,
}
return a, nil
}
@ -253,9 +253,8 @@ func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme S
headers: headers,
targetHeader: scheme,
prefix: scheme.authScheme(),
created: created,
expires: expires,
created: created,
expires: expires,
}
return c, nil
}

ファイルの表示

@ -1,7 +1,6 @@
package httpsig
import (
"strconv"
"bytes"
"crypto"
"crypto/rand"
@ -9,6 +8,7 @@ import (
"fmt"
"net/http"
"net/textproto"
"strconv"
"strings"
)
@ -26,8 +26,8 @@ const (
// RequestTarget specifies to include the http request method and
// entire URI in the signature. Pass it as a header to NewSigner.
RequestTarget = "(request-target)"
createdKey = "created"
expiresKey = "expires"
createdKey = "created"
expiresKey = "expires"
dateHeader = "date"
// Signature String Construction
@ -48,8 +48,8 @@ type macSigner struct {
headers []string
targetHeader SignatureScheme
prefix string
created int64
expires int64
created int64
expires int64
}
func (m *macSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http.Request, body []byte) error {
@ -120,8 +120,8 @@ type asymmSigner struct {
headers []string
targetHeader SignatureScheme
prefix string
created int64
expires int64
created int64
expires int64
}
func (a *asymmSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http.Request, body []byte) error {
@ -203,32 +203,32 @@ func setSignatureHeader(h http.Header, targetHeader, prefix, pubKeyId, algo, enc
b.WriteString(parameterValueDelimiter)
b.WriteString(parameterSeparater)
hasCreated := false
hasExpires := false
for _, h := range headers {
val := strings.ToLower(h)
if val == "(" + createdKey + ")" {
hasCreated = true
} else if val == "(" + expiresKey + ")" {
hasExpires = true
}
hasCreated := false
hasExpires := false
for _, h := range headers {
val := strings.ToLower(h)
if val == "("+createdKey+")" {
hasCreated = true
} else if val == "("+expiresKey+")" {
hasExpires = true
}
}
// Created
if hasCreated == true {
b.WriteString(createdKey)
b.WriteString(parameterKVSeparater)
b.WriteString(strconv.FormatInt(created, 10))
b.WriteString(parameterSeparater)
}
// Created
if hasCreated == true {
b.WriteString(createdKey)
b.WriteString(parameterKVSeparater)
b.WriteString(strconv.FormatInt(created, 10))
b.WriteString(parameterSeparater)
}
// Expires
if hasExpires == true {
b.WriteString(expiresKey)
b.WriteString(parameterKVSeparater)
b.WriteString(strconv.FormatInt(expires, 10))
b.WriteString(parameterSeparater)
}
// Expires
if hasExpires == true {
b.WriteString(expiresKey)
b.WriteString(parameterKVSeparater)
b.WriteString(strconv.FormatInt(expires, 10))
b.WriteString(parameterSeparater)
}
// Headers
b.WriteString(headersParameter)
@ -284,20 +284,20 @@ func signatureString(values http.Header, include []string, requestTargetFn func(
if err != nil {
return "", err
}
} else if i == "(" + expiresKey + ")" {
if expires == 0 {
return "", fmt.Errorf("mssing expires value")
}
b.WriteString(i)
b.WriteString(headerFieldDelimiter)
b.WriteString(strconv.FormatInt(expires, 10))
} else if i == "(" + createdKey + ")" {
if created == 0 {
return "", fmt.Errorf("mssing created value")
}
b.WriteString(i)
b.WriteString(headerFieldDelimiter)
b.WriteString(strconv.FormatInt(created, 10))
} else if i == "("+expiresKey+")" {
if expires == 0 {
return "", fmt.Errorf("mssing expires value")
}
b.WriteString(i)
b.WriteString(headerFieldDelimiter)
b.WriteString(strconv.FormatInt(expires, 10))
} else if i == "("+createdKey+")" {
if created == 0 {
return "", fmt.Errorf("mssing created value")
}
b.WriteString(i)
b.WriteString(headerFieldDelimiter)
b.WriteString(strconv.FormatInt(created, 10))
} else {
hv, ok := values[textproto.CanonicalMIMEHeaderKey(i)]
if !ok {

ファイルの表示

@ -1,14 +1,14 @@
package httpsig
import (
"strconv"
"crypto"
"encoding/base64"
"errors"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"errors"
"time"
)
var _ Verifier = &verifier{}
@ -17,8 +17,8 @@ type verifier struct {
header http.Header
kId string
signature string
created int64
expires int64
created int64
expires int64
headers []string
sigStringFn func(http.Header, []string, int64, int64) (string, error)
}
@ -29,20 +29,20 @@ func newVerifier(h http.Header, sigStringFn func(http.Header, []string, int64, i
return nil, err
}
kId, sig, headers, created, expires, err := getSignatureComponents(scheme, s)
if created != 0 {
//check if created is not in the future, we assume a maximum clock offset of 10 seconds
now := time.Now().Unix()
if created - now > 10 {
return nil, errors.New("created is in the future")
}
}
if expires != 0 {
//check if expires is in the past, we assume a maximum clock offset of 10 seconds
now := time.Now().Unix()
if now - expires > 10 {
return nil, errors.New("signature expired")
}
}
if created != 0 {
//check if created is not in the future, we assume a maximum clock offset of 10 seconds
now := time.Now().Unix()
if created-now > 10 {
return nil, errors.New("created is in the future")
}
}
if expires != 0 {
//check if expires is in the past, we assume a maximum clock offset of 10 seconds
now := time.Now().Unix()
if now-expires > 10 {
return nil, errors.New("signature expired")
}
}
if err != nil {
return nil, err
}
@ -50,8 +50,8 @@ func newVerifier(h http.Header, sigStringFn func(http.Header, []string, int64, i
header: h,
kId: kId,
signature: sig,
created: created,
expires: expires,
created: created,
expires: expires,
headers: headers,
sigStringFn: sigStringFn,
}, nil
@ -153,16 +153,16 @@ func getSignatureComponents(scheme SignatureScheme, s string) (kId, sig string,
switch k {
case keyIdParameter:
kId = v
case createdKey:
created, err = strconv.ParseInt(v, 10, 64)
if err != nil {
return
}
case expiresKey:
expires, err = strconv.ParseInt(v, 10, 64)
if err != nil {
return
}
case createdKey:
created, err = strconv.ParseInt(v, 10, 64)
if err != nil {
return
}
case expiresKey:
expires, err = strconv.ParseInt(v, 10, 64)
if err != nil {
return
}
case algorithmParameter:
// Deprecated, ignore
case headersParameter: