github.com/google/osv-scalibr@v0.4.1/veles/secrets/common/awssignerv4/awssignerv4_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package signerv4 provides an implementation of AWS Signature Version 4 signing. 16 // It allows signing HTTP requests using AWS credentials 17 package awssignerv4_test 18 19 import ( 20 "io" 21 "log" 22 "net/http" 23 "strings" 24 "testing" 25 "time" 26 27 "github.com/google/osv-scalibr/veles/secrets/common/awssignerv4" 28 ) 29 30 const ( 31 accessKeyID = "AKIAIOSFODNN7EXAMPLE" 32 secretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" 33 ) 34 35 // TestSign verifies that the signature generated using the signerv4 package corresponds to the one generated by 36 // github.com/aws/aws-sdk-go-v2. 37 // 38 // The signature was extracted using both the s3 and sts client with the `config.WithClientLogMode(aws.LogRequest)` 39 func TestSign(t *testing.T) { 40 time1, err := time.Parse("20060102T150405Z", "20251107T181714Z") 41 if err != nil { 42 log.Fatal(err) 43 } 44 45 time2, err := time.Parse("20060102T150405Z", "20251107T181716Z") 46 if err != nil { 47 log.Fatal(err) 48 } 49 50 testcases := []struct { 51 name string 52 service string 53 req func() *http.Request 54 time time.Time 55 reqID string 56 signedHeaders []string 57 want string 58 }{ 59 { 60 name: "s3 ListBuckets api", 61 service: "s3", 62 req: func() *http.Request { 63 req, _ := http.NewRequestWithContext(t.Context(), http.MethodGet, "https://s3.us-east-1.amazonaws.com/?x-id=ListBuckets", nil) 64 req.Header.Set("Accept-Encoding", "identity") 65 req.Header.Set("Host", "s3.us-east-1.amazonaws.com") 66 req.Header.Set("User-Agent", "aws-sdk-go-v2/1.39.6 ua/2.1 os/macos lang/go#1.25.4 md/GOOS#darwin md/GOARCH#arm64 api/s3#1.90.0 m/E,e") 67 return req 68 }, 69 time: time1, 70 reqID: "6c8a4c0d-23ef-4471-be71-14c80ec8f680", 71 signedHeaders: []string{ 72 "accept-encoding", "amz-sdk-invocation-id", "amz-sdk-request", 73 "host", "x-amz-content-sha256", "x-amz-date", 74 }, 75 want: "Signature=0fe2b0caa3bbe457ebba25c502c6094e640c8ee4308100ce647e4497bad5ce7f", 76 }, 77 { 78 name: "sts GetCallerIdentity action", 79 service: "sts", 80 req: func() *http.Request { 81 req, _ := http.NewRequestWithContext( 82 t.Context(), http.MethodPost, 83 "https://sts.us-east-1.amazonaws.com/", 84 io.NopCloser(strings.NewReader("Action=GetCallerIdentity&Version=2011-06-15")), 85 ) 86 req.Header.Set("Host", "sts.us-east-1.amazonaws.com") 87 req.Header.Set("User-Agent", "aws-sdk-go-v2/1.39.6 ua/2.1 os/macos lang/go#1.25.4 md/GOOS#darwin md/GOARCH#arm64 api/sts#1.39.1 m/E,e") 88 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 89 req.Header.Set("Accept-Encoding", "gzip") 90 return req 91 }, 92 time: time2, 93 signedHeaders: []string{ 94 "amz-sdk-invocation-id", "amz-sdk-request", "content-length", 95 "content-type", "host", "x-amz-date", 96 }, 97 reqID: "2f0054ff-8975-4c0d-8168-f4446fe4d76b", 98 want: "Signature=1789c751a9d360e0ec1f75e38f7768ab05a382cdf34b40d553fa72d53e7a8a08", 99 }, 100 } 101 102 for _, tt := range testcases { 103 t.Run(tt.name, func(t *testing.T) { 104 s := awssignerv4.New(awssignerv4.Config{ 105 Service: tt.service, 106 Region: "us-east-1", 107 Now: func() time.Time { return tt.time }, 108 SignedHeaders: tt.signedHeaders, 109 UUID: func() string { return tt.reqID }, 110 }) 111 112 req := tt.req() 113 err := s.Sign(req, accessKeyID, secretAccessKey) 114 if err != nil { 115 t.Errorf("Sign(%v) error: %v; want error presence = false", req, err) 116 } 117 118 authHeader := req.Header.Get("Authorization") 119 if !strings.Contains(authHeader, tt.want) { 120 t.Errorf("Authorization header: %q; does not contain the correct signature: %q, \n\n%v", authHeader, tt.want, req.Header) 121 } 122 }) 123 } 124 }