signature-v4: stringToSign and signingKey should use Scope's date. (#3688)

fixes #3676
master
Krishna Srinivas 8 years ago committed by Harshavardhana
parent 93fd269329
commit 45d9cfa0c5
  1. 10
      cmd/signature-v4-parser.go
  2. 20
      cmd/signature-v4.go
  3. 11
      cmd/signature-v4_test.go
  4. 4
      cmd/streaming-signature-v4.go
  5. 5
      cmd/test-utils_test.go
  6. 2
      cmd/web-handlers.go

@ -34,6 +34,16 @@ type credentialHeader struct {
} }
} }
// Return scope string.
func (c credentialHeader) getScope() string {
return strings.Join([]string{
c.scope.date.Format(yyyymmdd),
c.scope.region,
c.scope.service,
c.scope.request,
}, "/")
}
// parse credentialHeader string into its structured form. // parse credentialHeader string into its structured form.
func parseCredentialHeader(credElement string) (credentialHeader, APIErrorCode) { func parseCredentialHeader(credElement string) (credentialHeader, APIErrorCode) {
creds := strings.Split(strings.TrimSpace(credElement), "=") creds := strings.Split(strings.TrimSpace(credElement), "=")

@ -124,9 +124,9 @@ func getScope(t time.Time, region string) string {
} }
// getStringToSign a string based on selected query values. // getStringToSign a string based on selected query values.
func getStringToSign(canonicalRequest string, t time.Time, region string) string { func getStringToSign(canonicalRequest string, t time.Time, scope string) string {
stringToSign := signV4Algorithm + "\n" + t.Format(iso8601Format) + "\n" stringToSign := signV4Algorithm + "\n" + t.Format(iso8601Format) + "\n"
stringToSign = stringToSign + getScope(t, region) + "\n" stringToSign = stringToSign + scope + "\n"
canonicalRequestBytes := sha256.Sum256([]byte(canonicalRequest)) canonicalRequestBytes := sha256.Sum256([]byte(canonicalRequest))
stringToSign = stringToSign + hex.EncodeToString(canonicalRequestBytes[:]) stringToSign = stringToSign + hex.EncodeToString(canonicalRequestBytes[:])
return stringToSign return stringToSign
@ -182,14 +182,8 @@ func doesPolicySignatureV4Match(formValues map[string]string) APIErrorCode {
return ErrInvalidRegion return ErrInvalidRegion
} }
// Parse date string.
t, e := time.Parse(iso8601Format, formValues["X-Amz-Date"])
if e != nil {
return ErrMalformedDate
}
// Get signing key. // Get signing key.
signingKey := getSigningKey(cred.SecretKey, t, region) signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, region)
// Get signature. // Get signature.
newSignature := getSignature(signingKey, formValues["Policy"]) newSignature := getSignature(signingKey, formValues["Policy"])
@ -311,10 +305,10 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
presignedCanonicalReq := getCanonicalRequest(extractedSignedHeaders, hashedPayload, encodedQuery, req.URL.Path, req.Method, req.Host) presignedCanonicalReq := getCanonicalRequest(extractedSignedHeaders, hashedPayload, encodedQuery, req.URL.Path, req.Method, req.Host)
// Get string to sign from canonical request. // Get string to sign from canonical request.
presignedStringToSign := getStringToSign(presignedCanonicalReq, t, region) presignedStringToSign := getStringToSign(presignedCanonicalReq, t, pSignValues.Credential.getScope())
// Get hmac presigned signing key. // Get hmac presigned signing key.
presignedSigningKey := getSigningKey(cred.SecretKey, t, region) presignedSigningKey := getSigningKey(cred.SecretKey, pSignValues.Credential.scope.date, region)
// Get new signature. // Get new signature.
newSignature := getSignature(presignedSigningKey, presignedStringToSign) newSignature := getSignature(presignedSigningKey, presignedStringToSign)
@ -408,10 +402,10 @@ func doesSignatureMatch(hashedPayload string, r *http.Request, region string) AP
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, req.URL.Path, req.Method, req.Host) canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, req.URL.Path, req.Method, req.Host)
// Get string to sign from canonical request. // Get string to sign from canonical request.
stringToSign := getStringToSign(canonicalRequest, t, region) stringToSign := getStringToSign(canonicalRequest, t, signV4Values.Credential.getScope())
// Get hmac signing key. // Get hmac signing key.
signingKey := getSigningKey(cred.SecretKey, t, region) signingKey := getSigningKey(cred.SecretKey, signV4Values.Credential.scope.date, region)
// Calculate signature. // Calculate signature.
newSignature := getSignature(signingKey, stringToSign) newSignature := getSignature(signingKey, stringToSign)

@ -61,14 +61,7 @@ func TestDoesPolicySignatureMatch(t *testing.T) {
}, },
expected: ErrInvalidRegion, expected: ErrInvalidRegion,
}, },
// (3) It should fail if the date is invalid (or missing, in this case). // (3) It should fail with a bad signature.
{
form: map[string]string{
"X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion),
},
expected: ErrMalformedDate,
},
// (4) It should fail with a bad signature.
{ {
form: map[string]string{ form: map[string]string{
"X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), "X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion),
@ -78,7 +71,7 @@ func TestDoesPolicySignatureMatch(t *testing.T) {
}, },
expected: ErrSignatureDoesNotMatch, expected: ErrSignatureDoesNotMatch,
}, },
// (5) It should succeed if everything is correct. // (4) It should succeed if everything is correct.
{ {
form: map[string]string{ form: map[string]string{
"X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), "X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion),

@ -135,10 +135,10 @@ func calculateSeedSignature(r *http.Request) (signature string, date time.Time,
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, payload, queryStr, req.URL.Path, req.Method, req.Host) canonicalRequest := getCanonicalRequest(extractedSignedHeaders, payload, queryStr, req.URL.Path, req.Method, req.Host)
// Get string to sign from canonical request. // Get string to sign from canonical request.
stringToSign := getStringToSign(canonicalRequest, date, region) stringToSign := getStringToSign(canonicalRequest, date, signV4Values.Credential.getScope())
// Get hmac signing key. // Get hmac signing key.
signingKey := getSigningKey(cred.SecretKey, date, region) signingKey := getSigningKey(cred.SecretKey, signV4Values.Credential.scope.date, region)
// Calculate signature. // Calculate signature.
newSignature := getSignature(signingKey, stringToSign) newSignature := getSignature(signingKey, stringToSign)

@ -893,7 +893,8 @@ func preSignV4(req *http.Request, accessKeyID, secretAccessKey string, expires i
region := serverConfig.GetRegion() region := serverConfig.GetRegion()
date := time.Now().UTC() date := time.Now().UTC()
credential := fmt.Sprintf("%s/%s", accessKeyID, getScope(date, region)) scope := getScope(date, region)
credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
// Set URL query. // Set URL query.
query := req.URL.Query() query := req.URL.Query()
@ -909,7 +910,7 @@ func preSignV4(req *http.Request, accessKeyID, secretAccessKey string, expires i
queryStr := strings.Replace(query.Encode(), "+", "%20", -1) queryStr := strings.Replace(query.Encode(), "+", "%20", -1)
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, queryStr, req.URL.Path, req.Method, req.Host) canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, queryStr, req.URL.Path, req.Method, req.Host)
stringToSign := getStringToSign(canonicalRequest, date, region) stringToSign := getStringToSign(canonicalRequest, date, scope)
signingKey := getSigningKey(secretAccessKey, date, region) signingKey := getSigningKey(secretAccessKey, date, region)
signature := getSignature(signingKey, stringToSign) signature := getSignature(signingKey, stringToSign)

@ -748,7 +748,7 @@ func presignedGet(host, bucket, object string, expiry int64) string {
var extractedSignedHeaders http.Header var extractedSignedHeaders http.Header
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, query, path, "GET", host) canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, query, path, "GET", host)
stringToSign := getStringToSign(canonicalRequest, date, region) stringToSign := getStringToSign(canonicalRequest, date, getScope(date, region))
signingKey := getSigningKey(secretKey, date, region) signingKey := getSigningKey(secretKey, date, region)
signature := getSignature(signingKey, stringToSign) signature := getSignature(signingKey, stringToSign)

Loading…
Cancel
Save