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

fixes #3676
This commit is contained in:
Krishna Srinivas 2017-02-06 13:09:09 -08:00 committed by Harshavardhana
parent 93fd269329
commit 45d9cfa0c5
6 changed files with 25 additions and 27 deletions

View file

@ -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.
func parseCredentialHeader(credElement string) (credentialHeader, APIErrorCode) {
creds := strings.Split(strings.TrimSpace(credElement), "=")

View file

@ -124,9 +124,9 @@ func getScope(t time.Time, region string) string {
}
// 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 = stringToSign + getScope(t, region) + "\n"
stringToSign = stringToSign + scope + "\n"
canonicalRequestBytes := sha256.Sum256([]byte(canonicalRequest))
stringToSign = stringToSign + hex.EncodeToString(canonicalRequestBytes[:])
return stringToSign
@ -182,14 +182,8 @@ func doesPolicySignatureV4Match(formValues map[string]string) APIErrorCode {
return ErrInvalidRegion
}
// Parse date string.
t, e := time.Parse(iso8601Format, formValues["X-Amz-Date"])
if e != nil {
return ErrMalformedDate
}
// Get signing key.
signingKey := getSigningKey(cred.SecretKey, t, region)
signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, region)
// Get signature.
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)
// Get string to sign from canonical request.
presignedStringToSign := getStringToSign(presignedCanonicalReq, t, region)
presignedStringToSign := getStringToSign(presignedCanonicalReq, t, pSignValues.Credential.getScope())
// Get hmac presigned signing key.
presignedSigningKey := getSigningKey(cred.SecretKey, t, region)
presignedSigningKey := getSigningKey(cred.SecretKey, pSignValues.Credential.scope.date, region)
// Get new signature.
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)
// Get string to sign from canonical request.
stringToSign := getStringToSign(canonicalRequest, t, region)
stringToSign := getStringToSign(canonicalRequest, t, signV4Values.Credential.getScope())
// Get hmac signing key.
signingKey := getSigningKey(cred.SecretKey, t, region)
signingKey := getSigningKey(cred.SecretKey, signV4Values.Credential.scope.date, region)
// Calculate signature.
newSignature := getSignature(signingKey, stringToSign)

View file

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

View file

@ -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)
// Get string to sign from canonical request.
stringToSign := getStringToSign(canonicalRequest, date, region)
stringToSign := getStringToSign(canonicalRequest, date, signV4Values.Credential.getScope())
// Get hmac signing key.
signingKey := getSigningKey(cred.SecretKey, date, region)
signingKey := getSigningKey(cred.SecretKey, signV4Values.Credential.scope.date, region)
// Calculate signature.
newSignature := getSignature(signingKey, stringToSign)

View file

@ -893,7 +893,8 @@ func preSignV4(req *http.Request, accessKeyID, secretAccessKey string, expires i
region := serverConfig.GetRegion()
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.
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)
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)
signature := getSignature(signingKey, stringToSign)

View file

@ -748,7 +748,7 @@ func presignedGet(host, bucket, object string, expiry int64) string {
var extractedSignedHeaders http.Header
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)
signature := getSignature(signingKey, stringToSign)