Do not reply on ignoredHeaders for server, rely on SignedHeaders sent as part of Authorization header

This commit is contained in:
Harshavardhana
2015-07-10 17:21:53 -07:00
parent 538572ca91
commit 97d4a27c7e
3 changed files with 29 additions and 18 deletions

View File

@@ -102,13 +102,10 @@ func urlEncodeName(name string) (string, error) {
}
// getCanonicalHeaders generate a list of request headers with their values
func (r *Signature) getCanonicalHeaders() string {
func (r *Signature) getCanonicalHeaders(signedHeaders map[string][]string) string {
var headers []string
vals := make(map[string][]string)
for k, vv := range r.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header
}
for k, vv := range signedHeaders {
headers = append(headers, strings.ToLower(k))
vals[strings.ToLower(k)] = vv
}
@@ -137,12 +134,9 @@ func (r *Signature) getCanonicalHeaders() string {
}
// getSignedHeaders generate a string i.e alphabetically sorted, semicolon-separated list of lowercase request header names
func (r *Signature) getSignedHeaders() string {
func (r *Signature) getSignedHeaders(signedHeaders map[string][]string) string {
var headers []string
for k := range r.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header
}
for k := range signedHeaders {
headers = append(headers, strings.ToLower(k))
}
headers = append(headers, "host")
@@ -150,6 +144,22 @@ func (r *Signature) getSignedHeaders() string {
return strings.Join(headers, ";")
}
// extractSignedHeaders extract signed headers from Authorization header
func (r *Signature) extractSignedHeaders() map[string][]string {
authFields := strings.Split(strings.TrimSpace(r.AuthHeader), ",")
extractedHeaders := strings.Split(strings.Split(strings.TrimSpace(authFields[1]), "=")[1], ";")
extractedSignedHeadersMap := make(map[string][]string)
for _, header := range extractedHeaders {
val, ok := r.Request.Header[http.CanonicalHeaderKey(header)]
if !ok {
// if not found continue, we will fail later
continue
}
extractedSignedHeadersMap[header] = val
}
return extractedSignedHeadersMap
}
// getCanonicalRequest generate a canonical request of style
//
// canonicalRequest =
@@ -169,9 +179,9 @@ func (r *Signature) getCanonicalRequest() string {
r.Request.Method,
encodedPath,
r.Request.URL.RawQuery,
r.getCanonicalHeaders(),
r.getSignedHeaders(),
r.Request.Header.Get("x-amz-content-sha256"),
r.getCanonicalHeaders(r.extractSignedHeaders()),
r.getSignedHeaders(r.extractSignedHeaders()),
r.Request.Header.Get(http.CanonicalHeaderKey("x-amz-content-sha256")),
}, "\n")
return canonicalRequest
}
@@ -214,11 +224,11 @@ func (r *Signature) getSignature(signingKey []byte, stringToSign string) string
// returns true if matches, false other wise if error is not nil then it is always false
func (r *Signature) DoesSignatureMatch(hashedPayload string) (bool, error) {
// set new calulated payload
r.Request.Header.Set("x-amz-content-sha256", hashedPayload)
r.Request.Header.Set("X-Amz-Content-Sha256", hashedPayload)
// Add date if not present
var date string
if date = r.Request.Header.Get("x-amz-date"); date == "" {
if date = r.Request.Header.Get(http.CanonicalHeaderKey("x-amz-date")); date == "" {
if date = r.Request.Header.Get("Date"); date == "" {
return false, iodine.New(MissingDateHeader{}, nil)
}