aws-general-0.1.1: Bindings for AWS General API Version 0.1

Stabilityexperimental
MaintainerLars Kuhtz <lars@alephcloud.com>
Safe HaskellNone

Aws.SignatureV4

Contents

Description

Synopsis

AWS General API Version

Signature Version

AWS Credentials

data SignatureV4Credentials Source

AWS access credentials.

This type is compatible with the Credential type from the aws package. You may use the following function to get a SignatureV4Credential from a Credential:

 cred2credv4 :: Credential -> SignatureV4Credential
 #if MIN_VERSION_aws(0,9,2)
 cred2credv4 (Credential a b c _) = SignatureV4Credential a b c
 #else
 cred2credv4 (Credential a b c) = SignatureV4Credential a b c
 #endif

Constructors

SignatureV4Credentials 

Fields

sigV4AccessKeyId :: ByteString
 
sigV4SecretAccessKey :: ByteString
 
sigV4SigningKeys :: IORef [SigV4Key]

used internally for caching the singing key

newCredentialsSource

Arguments

:: (Functor m, MonadIO m) 
=> ByteString

Access Key ID

-> ByteString

Secret Access Key

-> m SignatureV4Credentials 

= AWS Signature 4 Request Types

There are two types of version 4 signed requests for GET and for POST requests

http://docs.aws.amazon.com/general/1.0/gr/sigv4-signed-request-examples.html

== Common Parameters

Both request types must include the following information in some way

http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

  • Host * Action * Date * Authorization parameters:
  • Algorithm * Credential * Signed headers * signature

== POST Request

Computed by signPostRequest or signPostRequestIO.

Headers:

  • host, * x-amz-date (or date), * authorization (containing all authorization parameters), and * content-type: application/x-www-form-urlencoded. charset=utf-8.

The query parameters (including Action and Version) are placed in the body.

== GET Request

Computed with signGetRequest or signGetRequestIO.

Headers:

  • host

TODO why is this content-type required?

Query:

  • Action, * Version, * X-Amz-Algorithm, * X-Amz-Credential, * Authorization parameters:
  • X-Amz-Date, * X-Amz-SignedHeaders, * X-Amz-Signature, * SignedHeaders, * Signature.

(NOTE that the AWS specification considers X-Amz-Date an authorization parameter only for URI requests. So for URI requests there are five authorization parameters whereas otherwise there are just four.)

Somewhat surprisingly (and covered neither by the AWS Signature V4 test suite nor by the AWS API reference) the canonical request includes all authorization parameters except for the signature.

TODO: is it possible to do a POST with this style and place the query in the body?

Pure signing

signPostRequestSource

Arguments

:: SignatureV4Credentials

AWS credentials

-> Region

request region

-> ServiceNamespace

service of the request

-> UTCTime

request time

-> Method

HTTP method of request

-> UriPath

URI Path of request

-> UriQuery

URI Query of request

-> RequestHeaders

request headers

-> ByteString

request payload

-> Either String RequestHeaders 

Compute an AWS Signature Version 4

This version computes the derivied signing key each time it is invoked

The request headers must include the host header. The query must include the Action parameter.

The x-amz-date header is generated by the code. A possibly existing x-amz-date header or date header is replaced.

signGetRequestSource

Arguments

:: SignatureV4Credentials

AWS credentials

-> Region

request region

-> ServiceNamespace

service of the request

-> UTCTime

request time

-> Method

HTTP method of request

-> UriPath

URI Path of request

-> UriQuery

URI Query of request

-> RequestHeaders

request headers

-> ByteString

request payload

-> Either String UriQuery 

Compute an AWS Signature Version 4

This version computes the derivied signing key each time it is invoked

The request headers must include the host header. The query must include the Action parameter.

Signing With Cached Key

signPostRequestIOSource

Arguments

:: SignatureV4Credentials

AWS credentials

-> Region 
-> ServiceNamespace 
-> UTCTime 
-> Method

HTTP method of request

-> UriPath

URI Path of request

-> UriQuery

URI Query of request

-> RequestHeaders

request headers

-> ByteString

request payload

-> IO (Either String RequestHeaders) 

The request headers must include the host header. The query must include the Action parameter.

The x-amz-date header is generated by the code. A possibly existing x-amz-date header or date header is replaced.

signGetRequestIOSource

Arguments

:: SignatureV4Credentials

AWS credentials

-> Region 
-> ServiceNamespace 
-> UTCTime 
-> Method

HTTP method of request

-> UriPath

URI Path of request

-> UriQuery

URI Query of request

-> RequestHeaders

request headers

-> ByteString

request payload

-> IO (Either String UriQuery) 

The request headers must include the host header. The query must include the Action parameter.

Authorization Info

Internal

dateNormalizationEnabled :: BoolSource

Normalization of the date header breaks the AWS test suite, since the tests in that test suite use an invalid date.

Date normalization is enabled by default but can be turned of via the cabal (compiletime) flag normalize-signature-v4-date.

Constants

signingAlgorithm :: IsString a => aSource

We only support SHA256 since SHA1 has been deprecated

Canoncial URI

normalizeUriPath :: UriPath -> UriPathSource

Normalize URI Path according to RFC 3986 (6.2.2)

normalizeUriQuery :: UriQuery -> UriQuerySource

Normalize URI Query according to RFC 3986 (6.2.2)

canonicalUri :: UriPath -> UriQuery -> CanonicalUriSource

Compute canonical URI

http://docs.aws.amazon.com/general/1.0/gr/sigv4-create-canonical-request.html

The input is assumed to be an absolute URI. If the first segment is .. it is kept as is. Most likely such an URI is invalid.

Canonical Headers

canonicalHeaders :: RequestHeaders -> CanonicalHeadersSource

Compute canonical HTTP headers

http://docs.aws.amazon.com/general/1.0/gr/sigv4-create-canonical-request.html

It is assumed (and not checked) that the header values comform with the definitions in RFC 2661. In particular non-comformant usage of quotation characters may lead to invalid results.

SignedHeaders

Canonical Request

canonicalRequestSource

Arguments

:: Method

HTTP method of request

-> UriPath

canonical URI Path of request

-> UriQuery

canonical URI Query of request

-> RequestHeaders

canonical request headers

-> ByteString

Request payload

-> CanonicalRequest 

Create Canonical Request for AWS Signature Version 4

http://docs.aws.amazon.com/general/1.0/gr/sigv4-create-canonical-request.html

This functions performs normalization of the URI and the Headers which is expensive. We should consider providing an alternate version of this function that bypasses these steps and simply assumes that the input is already canonical.

Credenital Scope

String to Sign

stringToSignSource

Arguments

:: UTCTime

request date

-> CredentialScope

credential scope for the request

-> CanonicalRequest

canonical request

-> StringToSign 

Create the String to Sign for AWS Signature Version 4

http://docs.aws.amazon.com/general/1.0/gr/sigv4-create-string-to-sign.html

Signing Key

newtype SigningKey Source

This key can be computed once and cached. It is valid for all requests to the same service and the region till 00:00:00 UTC time.

Constructors

SigningKey ByteString 

Signature

Low level signing function