Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix Canonical URI encoding during request signing (#16)
Fix Canonical URI encoding during request signing - resolves #193
- Loading branch information
1 parent
8d52391
commit 5ebdfc8
Showing
6 changed files
with
184 additions
and
25 deletions.
There are no files selected for viewing
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
(ns cognitect.aws.generators | ||
(:require [clojure.string :as str] | ||
[clojure.test.check.generators :as gen] | ||
[cognitect.aws.util :as util])) | ||
|
||
;; see cognitect.aws.protocols.rest/serialize-uri | ||
;; we want to mimic inputs to cognitect.aws.signers/sign-http-request | ||
(defn ^:private serialize-path-part | ||
[part] | ||
(-> part | ||
(util/url-encode) | ||
(str/replace "%2F" "/") | ||
(str/replace "%7E" "~"))) | ||
|
||
(defn gen-service | ||
[sig-ver] | ||
(gen/let [service-name (gen/such-that seq gen/string-alphanumeric)] | ||
{:metadata {:signatureVersion sig-ver | ||
:signingName service-name}})) | ||
|
||
(def gen-request | ||
(gen/let [host (gen/fmap #(str % ".com") (gen/such-that seq gen/string-alphanumeric)) | ||
path-parts (gen/vector (gen/fmap serialize-path-part (gen/such-that (complement str/blank?) gen/string-ascii)) 1 10) | ||
path-separator (gen/elements ["/" "//"]) | ||
query-ks (gen/vector (gen/such-that seq gen/string-alphanumeric)) | ||
query-vs (gen/vector (gen/such-that seq gen/string-alphanumeric) (count query-ks)) | ||
method (gen/elements [:get :post]) | ||
;; https://github.com/aws/aws-sdk-java/blob/d35b018/aws-java-sdk-core/src/main/java/com/amazonaws/auth/internal/SignerKey.java#L30-L34 | ||
;; date must be >1 day past epoch and <= today | ||
;; 1668999574880 == 2022-11-20 | ||
epoch (gen/large-integer* {:min 86400000 :max 1668999574880}) | ||
body gen/string] | ||
{:request-method method | ||
:body (.getBytes ^String body "UTF-8") | ||
:headers {"x-amz-date" (util/format-date util/x-amz-date-format (java.util.Date. epoch)) | ||
"host" host} | ||
:uri (str path-separator | ||
(str/join path-separator path-parts) | ||
(when (seq query-ks) | ||
(str "?" (str/join "&" (map #(str %1 "=" %2) | ||
query-ks | ||
query-vs)))))})) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
(ns cognitect.aws.jdk | ||
(:require [clojure.java.io :as io] | ||
[clojure.string :as str] | ||
[cognitect.aws.util :as util]) | ||
(:import [java.net URI] | ||
[com.amazonaws DefaultRequest] | ||
[com.amazonaws.auth AWS4Signer] | ||
[com.amazonaws.auth BasicAWSCredentials] | ||
[com.amazonaws.http HttpMethodName] | ||
[com.amazonaws.services.s3.internal AWSS3V4Signer] | ||
[com.amazonaws.services.s3.request S3HandlerContextKeys])) | ||
|
||
(defn ^:private ->http-method | ||
[request] | ||
(HttpMethodName/fromValue (name (:request-method request)))) | ||
|
||
(defn ^:private ->x-amz-date | ||
[request] | ||
(->> (get-in request [:headers "x-amz-date"]) | ||
(util/parse-date util/x-amz-date-format))) | ||
|
||
(defn ^:private ->basic-credentials | ||
[credentials] | ||
(BasicAWSCredentials. (:aws/access-key-id credentials) | ||
(:aws/secret-access-key credentials))) | ||
|
||
(defn ^:private ->default-request | ||
[service request] | ||
(let [[path query] (str/split (:uri request) #"\?" 2) | ||
req (doto (DefaultRequest. (get-in service [:metadata :signingName])) | ||
(.setHttpMethod (->http-method request)) | ||
(.setContent (io/input-stream (:body request))) | ||
(.setEndpoint (URI. (str "https://" (get-in request [:headers "host"])))) | ||
(.setResourcePath (str/replace path #"^//+" "/")))] | ||
(when (seq query) | ||
(doseq [[k v] (map #(str/split % #"=") (str/split query #"&"))] | ||
(.addParameter req k v))) | ||
req)) | ||
|
||
(defn v4-jdk-signed-request | ||
[service credentials request] | ||
(let [basic-credentials (->basic-credentials credentials) | ||
req (->default-request service request) | ||
signer (doto (AWS4Signer.) | ||
(.setServiceName (get-in service [:metadata :signingName])) | ||
(.setOverrideDate (->x-amz-date request)))] | ||
(.sign signer req basic-credentials) | ||
req)) | ||
|
||
(defn s3v4-jdk-signed-request | ||
[service credentials request] | ||
(let [basic-credentials (->basic-credentials credentials) | ||
req (doto (->default-request service request) | ||
(.addHandlerContext S3HandlerContextKeys/IS_PAYLOAD_SIGNING_ENABLED true) | ||
(.addHandlerContext S3HandlerContextKeys/IS_CHUNKED_ENCODING_DISABLED true)) | ||
signer (doto (AWSS3V4Signer.) | ||
(.setServiceName (get-in service [:metadata :signingName])) | ||
(.setOverrideDate (->x-amz-date request)))] | ||
(.sign signer req basic-credentials) | ||
req)) |
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