awssig

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2020 License: Apache-2.0 Imports: 13 Imported by: 0

README

go-aws-sigv4-verifier

Server-side verification of AWS SigV4 signatures (Golang)

Documentation

Overview

Package awssig provides AWS API request signatures verification routines.

This is essentially the server-side complement of github.com/aws/aws-sdk-go/aws/signer/v4 (https://docs.aws.amazon.com/sdk-for-go/api/aws/signer/v4/).

This implements the AWS SigV4 and SigV4S3 algorithms (http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html and https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CanonicalizeURIPath

func CanonicalizeURIPath(uriPath string) (string, error)

CanonicalizeURIPath normalizes a specified URI path, removing redundant slashes and relative path components.

The uriPath must be absolute (start with "/") or empty (assumed to be "/").

If a current-directory relative path component (".") is encountered, it is removed. For example, "/a/b/./c" becomes "/a/b/c".

If a parent-directory relative path component ("..") is encountered, it and the preceding component are removed. For example, "/a/b/../c" becomes "/a/c". Attempts to to above the root (e.g. "/a/../../b") result in an error.

If any component fails to normalize according to the rules of NormalizeURIPathComponent, an error is returned.

func IsRFC3986Unreserved

func IsRFC3986Unreserved(c byte) bool

IsRFC3986Unreserved indicates whether the s2pecified byte falls in the RFC 3986 range of unreserved characters. This is the following characters: %2D ('-'), %2E ('.'), %30-%39 ('0'-'9'), %41-%5A ('A'-'Z'), %5F ('_'), %61-%7A ('a'-'z'), %7E ('~').

func NormalizeQueryParameters

func NormalizeQueryParameters(queryString string) (map[string][]string, error)

NormalizeQueryParameters converts a query string into a map of parameter names to a list of sorted values. This ensurses that the query string follows RFC 3986 percent-encoding rules and checks for duplicate keys.

If a percent encoding is invalid, an error is returned.

func NormalizeURIPathComponent

func NormalizeURIPathComponent(pathComponent string) (string, error)

NormalizeURIPathComponent normalizes a path component according to RFC 3986. This performs the following operations:

* Alpha, digit, and the symbols '-', '.', '_', and '~' (unreserved characters) are left alone.

* Characters outside this range are percent-encoded.

* Percent-encoded values are upper-cased ('%2a' becomes '%2A').

* Plus signs ('+') are interpreted as encoded spaces and converted to '%20'.

* Percent-encoded values in the RFC 3986 unreserved space are converted to normal characters.

If a percent-encoding is invalid, an error is returned.

Types

type Request

type Request struct {
	// The request method (GET, PUT, POST). Client supplied.
	RequestMethod string

	// The URI path being accessed. This must be an absolute path starting
	// with "/".  Client supplied
	URIPath string

	// Query string portion of the URI. Client suppplied
	QueryString string

	// The HTTP headers and their values sent with the request. The header keys
	// must be lower-cased. Client supplied.
	Headers map[string][]string

	// The request body (if any). Client supplied.
	Body string

	// The region the request was sent to. Service supplied.
	Region string

	// The service being accessed. Service supplied.
	Service string
}

Request is a data structure containing the elements of the request (some client-supplied, some service-supplied) involved in the SigV4 verification process.

func (*Request) GetAccessKey

func (r *Request) GetAccessKey() (string, error)

GetAccessKey returns the access key used to sign the request.

If the credential scope does not match our expected credential scope, an error is returned.

func (*Request) GetAuthorizationHeaderParameters

func (r *Request) GetAuthorizationHeaderParameters() (map[string]string, error)

GetAuthorizationHeaderParameters returns the parameters from the authorization header (only). If there is not exactly one authorization header present using the AWS4-HMAC-SHA256 algorithm, an error is returned.

func (*Request) GetBodyDigest

func (r *Request) GetBodyDigest() string

GetBodyDigest returns the SHA-256 hex digest of the request body.

func (*Request) GetCanonicalQueryString

func (r *Request) GetCanonicalQueryString() (string, error)

GetCanonicalQueryString returns the canonical query string from the query parameters.

This takes the query string from the request, ordering multiple values for each key (e.g., "x=foo&x=bar" becomes "x=bar&x=foo"), and orders the keys ("y=a&x=b" becomes "x=a&y=b").

If the body is of type "application/x-www-form-urlencoded", it is included as part of the query string.

An error is returned if the query string contains an invalid percent encoding or the body is of type "application/x-www-form-urlencoded" and not a supported character set encoding.

func (*Request) GetCanonicalRequest

func (r *Request) GetCanonicalRequest() ([]byte, error)

GetCanonicalRequest returns the AWS SigV4 canonical request from the request parameters. The process is outlined here: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

The canonical request is:

request_method + '\n' +
canonical_uri_path + '\n' +
canonical_query_string + '\n' +
signed_headers + '\n' +
sha256(body).hexdigest()

func (*Request) GetCanonicalizedURIPath

func (r *Request) GetCanonicalizedURIPath() (string, error)

GetCanonicalizedURIPath returns the canonicalized URI path from the request.

If the URI path cannot be canonicalized due to invalid relative path components or invalid percent encoding, an error is returned.

func (*Request) GetContentTypeAndCharset

func (r *Request) GetContentTypeAndCharset() (contentType string, charset string, err error)

GetContentTypeAndCharset returns the content type and character set used in the request.

If the content-type header is not included in the request, an empty contentType and charset are returned.

If multiple content-type values were specified, an error is returned.

func (*Request) GetCredentialScope

func (r *Request) GetCredentialScope() (string, error)

GetCredentialScope returns the scope of the credentials to use, as calculated by the service's region and name, but using the timestamp of the request.

func (*Request) GetExpectedSignature

func (r *Request) GetExpectedSignature(secretKeyFn func(string, string) (string, error)) (string, error)

GetExpectedSignature returns the expected signature for the request given the request and a function that returns the secret key given an access key and optional session token.

func (*Request) GetRequestSignature

func (r *Request) GetRequestSignature() (string, error)

GetRequestSignature returns the signature passed into the request, either from the query parameter X-Amz-Signature or the Signature parameter in the AWS4-HMAC-SHA256 authorization header.

func (*Request) GetRequestTimestamp

func (r *Request) GetRequestTimestamp() (time.Time, error)

GetRequestTimestamp returns the timestamp of the request.

func (*Request) GetSessionToken

func (r *Request) GetSessionToken() (string, error)

GetSessionToken returns the session token sent with the access key.

Session tokens are used only for temporary credentials. If a long-term credential was used, the result is "", nil.

func (*Request) GetSignedHeaders

func (r *Request) GetSignedHeaders() ([]SignedHeader, error)

GetSignedHeaders returns a slice containing the signed header names and values.

This is returned as a sorted list of values since the order of the headers is important in the signature calculation.

Either the X-Amz-SignedHeaders query parameter or the SignedHeaders authorization header parameter must be present or an error is returned.

If multiple X-Amz-SignedHeaders query parameters are present, or the X-Amz-SignedHeaders query parameter cannot be decoded, an error is returned.

If the signed headers value is not canonicalized -- that is, all elements are lower-cased and sorted -- an error is returned. For example, "a;b;c;d" is valid, but "a;B;c;d", "a;c;b;d", and "A;C;B;D" are not.

Finally, all headers must be present in the request or an error is returned.

func (*Request) GetStringToSign

func (r *Request) GetStringToSign() (string, error)

GetStringToSign returns the expected string that should be signed for the request.

func (*Request) Verify

func (r *Request) Verify(
	secretKeyFn func(string, string) (string, error),
	allowedMismatch time.Duration) error

Verify verifies that the request timestamp is not beyond the allowed timestamp mismatch and that the request signature matches our expected signature.

To allow any amount of timestamp mismatch, pass time.Duration(-1) for the duration.

func (*Request) VerifyAt

func (r *Request) VerifyAt(
	secretKeyFn func(string, string) (string, error),
	serverTimestamp time.Time,
	allowedMismatch time.Duration) error

VerifyAt verifies that the request timestamp is not beyond the allowed timestamp mismatch and that the request signature matches our expected signature.

This version allows you to specify the server timestamp for testing. For normal use, use Verify.

To allow any amount of timestamp mismatch, pass time.Duration(-1) for the duration.

type SignedHeader

type SignedHeader struct {
	// The name of the header
	Name string

	// The associated value of the header
	Value string
}

SignedHeader incorporates a header name and its associated value.

Directories

Path Synopsis
timeutil module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL