Browse Source

test(iam): refactor STS tests to use AWS SDK signer

pull/8003/head
Chris Lu 3 weeks ago
parent
commit
4b8dc318b0
  1. 99
      test/s3/iam/s3_sts_assume_role_test.go

99
test/s3/iam/s3_sts_assume_role_test.go

@ -1,19 +1,17 @@
package iam
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/xml"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strings"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws/credentials"
v4 "github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -334,88 +332,19 @@ func callSTSAPIWithSigV4(t *testing.T, params url.Values, accessKey, secretKey s
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Host", req.URL.Host)
// Sign request with AWS Signature V4
signRequestV4(req, body, accessKey, secretKey, "us-east-1", "sts")
// Sign request with AWS Signature V4 using official SDK
creds := credentials.NewStaticCredentials(accessKey, secretKey, "")
signer := v4.NewSigner(creds)
// Read body for signing
// Note: We need a ReadSeeker for the signer, or we can pass the body string/bytes to ComputeBodyHash if needed,
// but standard Sign method takes an io.ReadSeeker for the body.
bodyReader := strings.NewReader(body)
_, err = signer.Sign(req, bodyReader, "sts", "us-east-1", time.Now())
if err != nil {
return nil, fmt.Errorf("failed to sign request: %w", err)
}
client := &http.Client{Timeout: 30 * time.Second}
return client.Do(req)
}
// signRequestV4 signs an HTTP request using AWS Signature Version 4
func signRequestV4(req *http.Request, payload, accessKey, secretKey, region, service string) {
// AWS SigV4 signing implementation
now := time.Now().UTC()
amzDate := now.Format("20060102T150405Z")
dateStamp := now.Format("20060102")
// Set required headers
req.Header.Set("X-Amz-Date", amzDate)
// Create canonical request
canonicalURI := "/"
canonicalQueryString := ""
// Sort and format headers
signedHeaders := []string{"content-type", "host", "x-amz-date"}
sort.Strings(signedHeaders)
canonicalHeaders := fmt.Sprintf("content-type:%s\nhost:%s\nx-amz-date:%s\n",
req.Header.Get("Content-Type"),
req.Host,
amzDate)
signedHeadersStr := strings.Join(signedHeaders, ";")
// Hash payload
payloadHash := sha256Hex(payload)
canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s",
req.Method,
canonicalURI,
canonicalQueryString,
canonicalHeaders,
signedHeadersStr,
payloadHash)
// Create string to sign
algorithm := "AWS4-HMAC-SHA256"
credentialScope := fmt.Sprintf("%s/%s/%s/aws4_request", dateStamp, region, service)
stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s",
algorithm,
amzDate,
credentialScope,
sha256Hex(canonicalRequest))
// Calculate signature
signingKey := getSignatureKey(secretKey, dateStamp, region, service)
signature := hex.EncodeToString(hmacSHA256(signingKey, stringToSign))
// Create authorization header
authHeader := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s",
algorithm,
accessKey,
credentialScope,
signedHeadersStr,
signature)
req.Header.Set("Authorization", authHeader)
}
func sha256Hex(data string) string {
hash := sha256.Sum256([]byte(data))
return hex.EncodeToString(hash[:])
}
func hmacSHA256(key []byte, data string) []byte {
h := hmac.New(sha256.New, key)
h.Write([]byte(data))
return h.Sum(nil)
}
func getSignatureKey(secretKey, dateStamp, region, service string) []byte {
kDate := hmacSHA256([]byte("AWS4"+secretKey), dateStamp)
kRegion := hmacSHA256(kDate, region)
kService := hmacSHA256(kRegion, service)
kSigning := hmacSHA256(kService, "aws4_request")
return kSigning
}
Loading…
Cancel
Save