github.com/smugmug/godynamo@v0.0.0-20151122084750-7913028f6623/auth_v4/tasks/tasks.go (about) 1 // Manages signing tasks required by AWS Auth v4 requests to DynamoDB. 2 // See http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html 3 // for more information on v4 signed requests. 4 package tasks 5 6 import ( 7 "crypto/hmac" 8 "crypto/sha256" 9 "encoding/hex" 10 "github.com/smugmug/godynamo/aws_const" 11 "hash" 12 "strings" 13 "time" 14 ) 15 16 // MakeSignature returns a auth_v4 signature from the `string to sign` variable. 17 // May be useful for creating v4 requests for services other than DynamoDB. 18 func MakeSignature(string2sign, zone, service, secret string) string { 19 kCredentials, _ := cacheable_hmacs(zone, service, secret) 20 var kSigning_hmac_sha256 hash.Hash = hmac.New(sha256.New, kCredentials) 21 kSigning_hmac_sha256.Write([]byte(string2sign)) 22 kSigning := kSigning_hmac_sha256.Sum(nil) 23 return hex.EncodeToString(kSigning) 24 } 25 26 // Return the byte slice for the cacheable hmac, along with the date string 27 // that describes its time of creation. 28 func cacheable_hmacs(zone, service, secret string) ([]byte, string) { 29 t := time.Now().UTC() 30 gmt_yyyymmdd := t.Format(aws_const.ISODATEFMT) 31 32 init_secret := []byte("AWS4" + secret) 33 var kDate_hmac_sha256 hash.Hash = hmac.New(sha256.New, init_secret) 34 kDate_hmac_sha256.Write([]byte(gmt_yyyymmdd)) 35 kDate := kDate_hmac_sha256.Sum(nil) 36 37 var kRegion_hmac_sha256 hash.Hash = hmac.New(sha256.New, kDate) 38 kRegion_hmac_sha256.Write([]byte(zone)) 39 kRegion := kRegion_hmac_sha256.Sum(nil) 40 41 var kService_hmac_sha256 hash.Hash = hmac.New(sha256.New, kRegion) 42 kService_hmac_sha256.Write([]byte(service)) 43 kService := kService_hmac_sha256.Sum(nil) 44 45 var kCredentials_hmac_sha256 hash.Hash = hmac.New(sha256.New, kService) 46 kCredentials_hmac_sha256.Write([]byte("aws4_request")) 47 return kCredentials_hmac_sha256.Sum(nil), gmt_yyyymmdd 48 } 49 50 // CanonicalRequest will create the aws v4 `canonical request`. 51 // This function is specific to DynamoDB. 52 func CanonicalRequest(host, port, amzDateHdr, amzTargetHdr, hexPayload string) string { 53 // Some AWS services use the x-amz-target header. Some don't. Allow it to 54 // be passed as empty when not used. 55 amzTarget_list_elt := "" 56 amzTarget_val := "" 57 if amzTargetHdr != "" { 58 amzTarget_val = strings.ToLower(aws_const.AMZ_TARGET_HDR) + ":" + 59 amzTargetHdr + "\n" 60 amzTarget_list_elt = ";x-amz-target" 61 } 62 return aws_const.METHOD + "\n" + 63 "/" + "\n" + 64 "" + "\n" + 65 strings.ToLower(aws_const.CONTENT_TYPE_HDR) + ":" + 66 aws_const.CTYPE + "\n" + 67 strings.ToLower("host") + ":" + 68 host + ":" + 69 port + "\n" + 70 strings.ToLower(aws_const.X_AMZ_DATE_HDR) + ":" + 71 amzDateHdr + "\n" + 72 amzTarget_val + 73 "\n" + 74 "content-type;host;x-amz-date" + amzTarget_list_elt + "\n" + 75 hexPayload 76 } 77 78 // String2Sign will create the aws v4 `string to sign` from the `canoncial request`. 79 // May be useful for creating v4 requests for services other than DynamoDB. 80 func String2Sign(t time.Time, canonical_request, zone, service string) string { 81 var h256 hash.Hash = sha256.New() 82 h256.Write([]byte(canonical_request)) 83 hexCanonReq := hex.EncodeToString([]byte(h256.Sum(nil))) 84 return "AWS4-HMAC-SHA256" + "\n" + 85 t.UTC().Format(aws_const.ISO8601FMT_CONDENSED) + "\n" + 86 t.UTC().Format(aws_const.ISODATEFMT) + "/" + 87 zone + 88 "/" + service + "/aws4_request" + "\n" + 89 hexCanonReq 90 }