aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go')
-rw-r--r--vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go465
1 files changed, 0 insertions, 465 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
deleted file mode 100644
index 4765800..0000000
--- a/vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
+++ /dev/null
@@ -1,465 +0,0 @@
-// Package v4 implements signing for AWS V4 signer
-package v4
-
-import (
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "fmt"
- "io"
- "net/http"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/aws/aws-sdk-go/aws"
- "github.com/aws/aws-sdk-go/aws/credentials"
- "github.com/aws/aws-sdk-go/aws/request"
- "github.com/aws/aws-sdk-go/private/protocol/rest"
-)
-
-const (
- authHeaderPrefix = "AWS4-HMAC-SHA256"
- timeFormat = "20060102T150405Z"
- shortTimeFormat = "20060102"
-)
-
-var ignoredHeaders = rules{
- blacklist{
- mapRule{
- "Authorization": struct{}{},
- "User-Agent": struct{}{},
- },
- },
-}
-
-// requiredSignedHeaders is a whitelist for build canonical headers.
-var requiredSignedHeaders = rules{
- whitelist{
- mapRule{
- "Cache-Control": struct{}{},
- "Content-Disposition": struct{}{},
- "Content-Encoding": struct{}{},
- "Content-Language": struct{}{},
- "Content-Md5": struct{}{},
- "Content-Type": struct{}{},
- "Expires": struct{}{},
- "If-Match": struct{}{},
- "If-Modified-Since": struct{}{},
- "If-None-Match": struct{}{},
- "If-Unmodified-Since": struct{}{},
- "Range": struct{}{},
- "X-Amz-Acl": struct{}{},
- "X-Amz-Copy-Source": struct{}{},
- "X-Amz-Copy-Source-If-Match": struct{}{},
- "X-Amz-Copy-Source-If-Modified-Since": struct{}{},
- "X-Amz-Copy-Source-If-None-Match": struct{}{},
- "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
- "X-Amz-Copy-Source-Range": struct{}{},
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
- "X-Amz-Grant-Full-control": struct{}{},
- "X-Amz-Grant-Read": struct{}{},
- "X-Amz-Grant-Read-Acp": struct{}{},
- "X-Amz-Grant-Write": struct{}{},
- "X-Amz-Grant-Write-Acp": struct{}{},
- "X-Amz-Metadata-Directive": struct{}{},
- "X-Amz-Mfa": struct{}{},
- "X-Amz-Request-Payer": struct{}{},
- "X-Amz-Server-Side-Encryption": struct{}{},
- "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
- "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
- "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
- "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
- "X-Amz-Storage-Class": struct{}{},
- "X-Amz-Website-Redirect-Location": struct{}{},
- },
- },
- patterns{"X-Amz-Meta-"},
-}
-
-// allowedHoisting is a whitelist for build query headers. The boolean value
-// represents whether or not it is a pattern.
-var allowedQueryHoisting = inclusiveRules{
- blacklist{requiredSignedHeaders},
- patterns{"X-Amz-"},
-}
-
-type signer struct {
- Request *http.Request
- Time time.Time
- ExpireTime time.Duration
- ServiceName string
- Region string
- CredValues credentials.Value
- Credentials *credentials.Credentials
- Query url.Values
- Body io.ReadSeeker
- Debug aws.LogLevelType
- Logger aws.Logger
-
- isPresign bool
- formattedTime string
- formattedShortTime string
-
- signedHeaders string
- canonicalHeaders string
- canonicalString string
- credentialString string
- stringToSign string
- signature string
- authorization string
- notHoist bool
- signedHeaderVals http.Header
-}
-
-// Sign requests with signature version 4.
-//
-// Will sign the requests with the service config's Credentials object
-// Signing is skipped if the credentials is the credentials.AnonymousCredentials
-// object.
-func Sign(req *request.Request) {
- // If the request does not need to be signed ignore the signing of the
- // request if the AnonymousCredentials object is used.
- if req.Config.Credentials == credentials.AnonymousCredentials {
- return
- }
-
- region := req.ClientInfo.SigningRegion
- if region == "" {
- region = aws.StringValue(req.Config.Region)
- }
-
- name := req.ClientInfo.SigningName
- if name == "" {
- name = req.ClientInfo.ServiceName
- }
-
- s := signer{
- Request: req.HTTPRequest,
- Time: req.Time,
- ExpireTime: req.ExpireTime,
- Query: req.HTTPRequest.URL.Query(),
- Body: req.Body,
- ServiceName: name,
- Region: region,
- Credentials: req.Config.Credentials,
- Debug: req.Config.LogLevel.Value(),
- Logger: req.Config.Logger,
- notHoist: req.NotHoist,
- }
-
- req.Error = s.sign()
- req.Time = s.Time
- req.SignedHeaderVals = s.signedHeaderVals
-}
-
-func (v4 *signer) sign() error {
- if v4.ExpireTime != 0 {
- v4.isPresign = true
- }
-
- if v4.isRequestSigned() {
- if !v4.Credentials.IsExpired() && time.Now().Before(v4.Time.Add(10*time.Minute)) {
- // If the request is already signed, and the credentials have not
- // expired, and the request is not too old ignore the signing request.
- return nil
- }
- v4.Time = time.Now()
-
- // The credentials have expired for this request. The current signing
- // is invalid, and needs to be request because the request will fail.
- if v4.isPresign {
- v4.removePresign()
- // Update the request's query string to ensure the values stays in
- // sync in the case retrieving the new credentials fails.
- v4.Request.URL.RawQuery = v4.Query.Encode()
- }
- }
-
- var err error
- v4.CredValues, err = v4.Credentials.Get()
- if err != nil {
- return err
- }
-
- if v4.isPresign {
- v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
- if v4.CredValues.SessionToken != "" {
- v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
- } else {
- v4.Query.Del("X-Amz-Security-Token")
- }
- } else if v4.CredValues.SessionToken != "" {
- v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
- }
-
- v4.build()
-
- if v4.Debug.Matches(aws.LogDebugWithSigning) {
- v4.logSigningInfo()
- }
-
- return nil
-}
-
-const logSignInfoMsg = `DEBUG: Request Signiture:
----[ CANONICAL STRING ]-----------------------------
-%s
----[ STRING TO SIGN ]--------------------------------
-%s%s
------------------------------------------------------`
-const logSignedURLMsg = `
----[ SIGNED URL ]------------------------------------
-%s`
-
-func (v4 *signer) logSigningInfo() {
- signedURLMsg := ""
- if v4.isPresign {
- signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String())
- }
- msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg)
- v4.Logger.Log(msg)
-}
-
-func (v4 *signer) build() {
-
- v4.buildTime() // no depends
- v4.buildCredentialString() // no depends
-
- unsignedHeaders := v4.Request.Header
- if v4.isPresign {
- if !v4.notHoist {
- urlValues := url.Values{}
- urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
- for k := range urlValues {
- v4.Query[k] = urlValues[k]
- }
- }
- }
-
- v4.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
- v4.buildCanonicalString() // depends on canon headers / signed headers
- v4.buildStringToSign() // depends on canon string
- v4.buildSignature() // depends on string to sign
-
- if v4.isPresign {
- v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
- } else {
- parts := []string{
- authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
- "SignedHeaders=" + v4.signedHeaders,
- "Signature=" + v4.signature,
- }
- v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
- }
-}
-
-func (v4 *signer) buildTime() {
- v4.formattedTime = v4.Time.UTC().Format(timeFormat)
- v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
-
- if v4.isPresign {
- duration := int64(v4.ExpireTime / time.Second)
- v4.Query.Set("X-Amz-Date", v4.formattedTime)
- v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
- } else {
- v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
- }
-}
-
-func (v4 *signer) buildCredentialString() {
- v4.credentialString = strings.Join([]string{
- v4.formattedShortTime,
- v4.Region,
- v4.ServiceName,
- "aws4_request",
- }, "/")
-
- if v4.isPresign {
- v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
- }
-}
-
-func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
- query := url.Values{}
- unsignedHeaders := http.Header{}
- for k, h := range header {
- if r.IsValid(k) {
- query[k] = h
- } else {
- unsignedHeaders[k] = h
- }
- }
-
- return query, unsignedHeaders
-}
-func (v4 *signer) buildCanonicalHeaders(r rule, header http.Header) {
- var headers []string
- headers = append(headers, "host")
- for k, v := range header {
- canonicalKey := http.CanonicalHeaderKey(k)
- if !r.IsValid(canonicalKey) {
- continue // ignored header
- }
- if v4.signedHeaderVals == nil {
- v4.signedHeaderVals = make(http.Header)
- }
-
- lowerCaseKey := strings.ToLower(k)
- if _, ok := v4.signedHeaderVals[lowerCaseKey]; ok {
- // include additional values
- v4.signedHeaderVals[lowerCaseKey] = append(v4.signedHeaderVals[lowerCaseKey], v...)
- continue
- }
-
- headers = append(headers, lowerCaseKey)
- v4.signedHeaderVals[lowerCaseKey] = v
- }
- sort.Strings(headers)
-
- v4.signedHeaders = strings.Join(headers, ";")
-
- if v4.isPresign {
- v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
- }
-
- headerValues := make([]string, len(headers))
- for i, k := range headers {
- if k == "host" {
- headerValues[i] = "host:" + v4.Request.URL.Host
- } else {
- headerValues[i] = k + ":" +
- strings.Join(v4.signedHeaderVals[k], ",")
- }
- }
-
- v4.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n")
-}
-
-func (v4 *signer) buildCanonicalString() {
- v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
- uri := v4.Request.URL.Opaque
- if uri != "" {
- uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
- } else {
- uri = v4.Request.URL.Path
- }
- if uri == "" {
- uri = "/"
- }
-
- if v4.ServiceName != "s3" {
- uri = rest.EscapePath(uri, false)
- }
-
- v4.canonicalString = strings.Join([]string{
- v4.Request.Method,
- uri,
- v4.Request.URL.RawQuery,
- v4.canonicalHeaders + "\n",
- v4.signedHeaders,
- v4.bodyDigest(),
- }, "\n")
-}
-
-func (v4 *signer) buildStringToSign() {
- v4.stringToSign = strings.Join([]string{
- authHeaderPrefix,
- v4.formattedTime,
- v4.credentialString,
- hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
- }, "\n")
-}
-
-func (v4 *signer) buildSignature() {
- secret := v4.CredValues.SecretAccessKey
- date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
- region := makeHmac(date, []byte(v4.Region))
- service := makeHmac(region, []byte(v4.ServiceName))
- credentials := makeHmac(service, []byte("aws4_request"))
- signature := makeHmac(credentials, []byte(v4.stringToSign))
- v4.signature = hex.EncodeToString(signature)
-}
-
-func (v4 *signer) bodyDigest() string {
- hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
- if hash == "" {
- if v4.isPresign && v4.ServiceName == "s3" {
- hash = "UNSIGNED-PAYLOAD"
- } else if v4.Body == nil {
- hash = hex.EncodeToString(makeSha256([]byte{}))
- } else {
- hash = hex.EncodeToString(makeSha256Reader(v4.Body))
- }
- v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
- }
- return hash
-}
-
-// isRequestSigned returns if the request is currently signed or presigned
-func (v4 *signer) isRequestSigned() bool {
- if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
- return true
- }
- if v4.Request.Header.Get("Authorization") != "" {
- return true
- }
-
- return false
-}
-
-// unsign removes signing flags for both signed and presigned requests.
-func (v4 *signer) removePresign() {
- v4.Query.Del("X-Amz-Algorithm")
- v4.Query.Del("X-Amz-Signature")
- v4.Query.Del("X-Amz-Security-Token")
- v4.Query.Del("X-Amz-Date")
- v4.Query.Del("X-Amz-Expires")
- v4.Query.Del("X-Amz-Credential")
- v4.Query.Del("X-Amz-SignedHeaders")
-}
-
-func makeHmac(key []byte, data []byte) []byte {
- hash := hmac.New(sha256.New, key)
- hash.Write(data)
- return hash.Sum(nil)
-}
-
-func makeSha256(data []byte) []byte {
- hash := sha256.New()
- hash.Write(data)
- return hash.Sum(nil)
-}
-
-func makeSha256Reader(reader io.ReadSeeker) []byte {
- hash := sha256.New()
- start, _ := reader.Seek(0, 1)
- defer reader.Seek(start, 0)
-
- io.Copy(hash, reader)
- return hash.Sum(nil)
-}
-
-func stripExcessSpaces(headerVals []string) []string {
- vals := make([]string, len(headerVals))
- for i, str := range headerVals {
- stripped := ""
- found := false
- str = strings.TrimSpace(str)
- for _, c := range str {
- if !found && c == ' ' {
- stripped += string(c)
- found = true
- } else if c != ' ' {
- stripped += string(c)
- found = false
- }
- }
- vals[i] = stripped
- }
- return vals
-}