Created
August 21, 2017 11:39
-
-
Save themarcelor/e09a25c722c390c41a456173c93d9125 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############ User input for AWS Access key and AWS Secret key | |
echo "Please provide your S3 Access Key: " | |
read -s AWSID | |
echo "Please provide your S3 Secret key:" | |
read -s AWSSEC | |
calculate_signature () { | |
AWSSEC=$1 | |
x_amz_date_short=$2 | |
region=$3 | |
service=$4 | |
string_to_sign=$5 | |
hex_secret=$(printf "AWS4$AWSSEC" | xxd -p -c 256) | |
digest=$(printf "$x_amz_date_short" | openssl dgst -sha256 -mac HMAC -macopt hexkey:$hex_secret) | |
digest="${digest#* }" | |
digest=$(printf "$region" | openssl dgst -sha256 -mac HMAC -macopt hexkey:$digest) | |
digest="${digest#* }" | |
digest=$(printf "$service" | openssl dgst -sha256 -mac HMAC -macopt hexkey:$digest) | |
digest="${digest#* }" | |
digest=$(printf "aws4_request" | openssl dgst -sha256 -mac HMAC -macopt hexkey:$digest) | |
signing_key="${digest#* }" | |
signature=$(printf "$string_to_sign" | openssl dgst -binary -hex -sha256 -mac HMAC -macopt hexkey:$signing_key) | |
} | |
create_string_to_sign () { | |
x_amz_date_long=$1 | |
x_amz_date_short=$2 | |
region=$3 | |
service=$4 | |
hashed_canonical_request=$5 | |
string_to_sign="AWS4-HMAC-SHA256 | |
$x_amz_date_long | |
$x_amz_date_short/$region/$service/aws4_request | |
$hashed_canonical_request" | |
} | |
create_canonical_request () { | |
method=$1 | |
uri=$2 | |
query_string=$3 | |
service=$4 | |
payload=$5 | |
host=$6 | |
x_amz_date_long=$7 | |
the_kms_key=$8 | |
http_request_method="$method" | |
canonical_uri="$uri" | |
canonical_query_string="$query_string" | |
################################################ | |
# KMS HEADERS | |
################################################ | |
if [ "$service" == "kms" ]; then | |
hashed_payload=$(echo -n "$payload" | openssl dgst -sha256 | awk -F ' ' '{print $2}') | |
# Identation looks a bit funny here but the aws v4 signature doesnt' like additional white spaces | |
canonical_headers="content-type:application/x-amz-json-1.1 | |
host:$host | |
x-amz-date:$x_amz_date_long | |
x-amz-target:TrentService.ListAliases" | |
signed_headers="content-type;host;x-amz-date;x-amz-target" | |
################################################ | |
# S3 HEADERS | |
################################################ | |
elif [ "$service" == "s3" ]; then | |
################################################ | |
# FILE UPLOAD | |
################################################ | |
if [ -z "$query_string" ]; then | |
# just a normal file upload ( file size < 5GB ) | |
hashed_payload=$(openssl dgst -sha256 $payload | awk -F ' ' '{print $2}') | |
canonical_headers="host:$host | |
x-amz-content-sha256:$hashed_payload | |
x-amz-date:$x_amz_date_long | |
x-amz-server-side-encryption:aws:kms | |
x-amz-server-side-encryption-aws-kms-key-id:$the_kms_key" | |
signed_headers="host;x-amz-content-sha256;x-amz-date;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id" | |
else | |
if [ -z "$payload" ]; then | |
################################################ | |
# MULTIPART UPLOAD - INITIATE | |
################################################ | |
# empty payload means that this request is either initiating or completing a multipart upload | |
# hardcode hash from empty string and provide md5 from the original file | |
hashed_payload="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" | |
amz_meta_md5=$(openssl dgst -binary -md5 "$FILE" | openssl enc -base64) | |
canonical_headers="host:$host | |
x-amz-content-sha256:$hashed_payload | |
x-amz-date:$x_amz_date_long | |
x-amz-meta-md5:$amz_meta_md5 | |
x-amz-server-side-encryption:aws:kms | |
x-amz-server-side-encryption-aws-kms-key-id:$the_kms_key" | |
signed_headers="host;x-amz-content-sha256;x-amz-date;x-amz-meta-md5;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id" | |
else | |
################################################ | |
# MULTIPART UPLOAD - FILE PART | |
################################################ | |
echo "##### FILE PART: $payload" | |
# the presence of a payload means this request is uploading a file part | |
# take sha256 and md5 hashes from the payload (file part) | |
hashed_payload=$(openssl dgst -sha256 $payload | awk -F ' ' '{print $2}') | |
canonical_headers="host:$host | |
x-amz-content-sha256:$hashed_payload | |
x-amz-date:$x_amz_date_long" | |
signed_headers="host;x-amz-content-sha256;x-amz-date" | |
fi | |
fi | |
else | |
echo "S3 file upload failed. This service { $service } is not supported." | |
exit 1 | |
fi | |
canonical_request="$http_request_method | |
$canonical_uri | |
$canonical_query_string | |
$canonical_headers | |
$signed_headers | |
$hashed_payload" | |
hashed_canonical_request=$(echo -n "$canonical_request" | openssl dgst -sha256 | awk -F ' ' '{print $2}') | |
} | |
assemble_aws_v4_signature () { | |
method=$1 | |
service=$2 | |
region=$3 | |
host=$4 | |
uri=$5 | |
query_string=$6 | |
payload=$7 | |
the_kms_key=$8 | |
x_amz_date_long=$(date -u '+%Y%m%dT%H%M%SZ') | |
x_amz_date_short="${x_amz_date_long/T*}" | |
create_canonical_request "${method}" "${uri}" "${query_string}" "${service}" "${payload}" "${host}" "${x_amz_date_long}" "${the_kms_key}" | |
create_string_to_sign "${x_amz_date_long}" "${x_amz_date_short}" "${region}" "${service}" "${hashed_canonical_request}" | |
calculate_signature "${AWSSEC}" "${x_amz_date_short}" "${region}" "${service}" "${string_to_sign}" | |
signature="${signature#* }" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment