aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/auth_signature_v4.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/auth_signature_v4.go')
-rw-r--r--weed/s3api/auth_signature_v4.go78
1 files changed, 55 insertions, 23 deletions
diff --git a/weed/s3api/auth_signature_v4.go b/weed/s3api/auth_signature_v4.go
index 02a6bd4e0..06cdf67e4 100644
--- a/weed/s3api/auth_signature_v4.go
+++ b/weed/s3api/auth_signature_v4.go
@@ -23,6 +23,7 @@ import (
"crypto/sha256"
"crypto/subtle"
"encoding/hex"
+ "hash"
"io"
"net/http"
"net/url"
@@ -30,6 +31,7 @@ import (
"sort"
"strconv"
"strings"
+ "sync"
"time"
"unicode/utf8"
@@ -151,14 +153,14 @@ func (iam *IdentityAccessManagement) doesSignatureMatch(hashedPayload string, r
// Get string to sign from canonical request.
stringToSign := getStringToSign(canonicalRequest, t, signV4Values.Credential.getScope())
- // Get hmac signing key.
- signingKey := getSigningKey(cred.SecretKey,
+ // Calculate signature.
+ newSignature := iam.getSignature(
+ cred.SecretKey,
signV4Values.Credential.scope.date,
signV4Values.Credential.scope.region,
- signV4Values.Credential.scope.service)
-
- // Calculate signature.
- newSignature := getSignature(signingKey, stringToSign)
+ signV4Values.Credential.scope.service,
+ stringToSign,
+ )
// Verify if signature match.
if !compareSignatureV4(newSignature, signV4Values.Signature) {
@@ -325,11 +327,14 @@ func (iam *IdentityAccessManagement) doesPolicySignatureV4Match(formValues http.
return s3err.ErrInvalidAccessKeyID
}
- // Get signing key.
- signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, credHeader.scope.region, credHeader.scope.service)
-
// Get signature.
- newSignature := getSignature(signingKey, formValues.Get("Policy"))
+ newSignature := iam.getSignature(
+ cred.SecretKey,
+ credHeader.scope.date,
+ credHeader.scope.region,
+ credHeader.scope.service,
+ formValues.Get("Policy"),
+ )
// Verify signature.
if !compareSignatureV4(newSignature, formValues.Get("X-Amz-Signature")) {
@@ -442,14 +447,14 @@ func (iam *IdentityAccessManagement) doesPresignedSignatureMatch(hashedPayload s
// Get string to sign from canonical request.
presignedStringToSign := getStringToSign(presignedCanonicalReq, t, pSignValues.Credential.getScope())
- // Get hmac presigned signing key.
- presignedSigningKey := getSigningKey(cred.SecretKey,
+ // Get new signature.
+ newSignature := iam.getSignature(
+ cred.SecretKey,
pSignValues.Credential.scope.date,
pSignValues.Credential.scope.region,
- pSignValues.Credential.scope.service)
-
- // Get new signature.
- newSignature := getSignature(presignedSigningKey, presignedStringToSign)
+ pSignValues.Credential.scope.service,
+ presignedStringToSign,
+ )
// Verify signature.
if !compareSignatureV4(req.URL.Query().Get("X-Amz-Signature"), newSignature) {
@@ -458,6 +463,38 @@ func (iam *IdentityAccessManagement) doesPresignedSignatureMatch(hashedPayload s
return identity, s3err.ErrNone
}
+// getSignature
+func (iam *IdentityAccessManagement) getSignature(secretKey string, t time.Time, region string, service string, stringToSign string) string {
+ date := t.Format(yyyymmdd)
+ hashID := "AWS4" + secretKey + "/" + date + "/" + region + "/" + service + "/" + "aws4_request"
+
+ iam.hashMu.RLock()
+ pool, ok := iam.hashes[hashID]
+ iam.hashMu.RUnlock()
+
+ if !ok {
+ iam.hashMu.Lock()
+ if pool, ok = iam.hashes[hashID]; !ok {
+ pool = &sync.Pool{
+ New: func() any {
+ signingKey := getSigningKey(secretKey, date, region, service)
+ return hmac.New(sha256.New, signingKey)
+ },
+ }
+ iam.hashes[hashID] = pool
+ }
+ iam.hashMu.Unlock()
+ }
+
+ h := pool.Get().(hash.Hash)
+ h.Reset()
+ h.Write([]byte(stringToSign))
+ sig := hex.EncodeToString(h.Sum(nil))
+ pool.Put(h)
+
+ return sig
+}
+
func contains(list []string, elem string) bool {
for _, t := range list {
if t == elem {
@@ -674,19 +711,14 @@ func sumHMAC(key []byte, data []byte) []byte {
}
// getSigningKey hmac seed to calculate final signature.
-func getSigningKey(secretKey string, t time.Time, region string, service string) []byte {
- date := sumHMAC([]byte("AWS4"+secretKey), []byte(t.Format(yyyymmdd)))
+func getSigningKey(secretKey string, time string, region string, service string) []byte {
+ date := sumHMAC([]byte("AWS4"+secretKey), []byte(time))
regionBytes := sumHMAC(date, []byte(region))
serviceBytes := sumHMAC(regionBytes, []byte(service))
signingKey := sumHMAC(serviceBytes, []byte("aws4_request"))
return signingKey
}
-// getSignature final signature in hexadecimal form.
-func getSignature(signingKey []byte, stringToSign string) string {
- return hex.EncodeToString(sumHMAC(signingKey, []byte(stringToSign)))
-}
-
// getCanonicalHeaders generate a list of request headers with their values
func getCanonicalHeaders(signedHeaders http.Header) string {
var headers []string