aws-sigv4 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46dbb72f9e31ff1022703f91ae7e1d2cfe78c78629e682fe99468933704aff62
4
- data.tar.gz: 963db4a8f39031b64398dea0d2ebc7167af20e79446e23bfd270c6cb85d4738f
3
+ metadata.gz: 709cebb0799ad1e75e1f1e69413798d4da1d523332abc0ac59899e9686aa2e07
4
+ data.tar.gz: a4751a6a7c2356bf76b2ac550f8320e3f8b24951415eaddf1328271c1835f2d3
5
5
  SHA512:
6
- metadata.gz: '0142942e58db9971d8ceaa2aeb7c97d1cd58bdba463366fd06831b1769a3c124f6e1f1b082c4d1b5917f794ab70556f6bd78dbb67824a35e74ccbfc5bdaafa25'
7
- data.tar.gz: aca23ad7a8a98f24abdbbaa2afe9cde1430a7a10f627b63d7da56939665056ccc7a04226dc14e3793e3848032291aba990fc10576369f3974911593566ea9262
6
+ metadata.gz: 07ebb364959ed8bf62c39192707a30caef1127fcf0ab078dab30ecaf695b2a9e22caa017a773987dac297615dfc824eeb8cc04a60a604837024ee850f6812dd2
7
+ data.tar.gz: f9e93932e59b1d43b92aa2c74d33d7553490ecf84ff61b491321c0b031896f30b5375c8a5f2c81d8514691917096e7c3dd5cc298c3a3fa5e6876cabb1f458c8e
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 1.5.0 (2022-04-20)
5
+ ------------------
6
+
7
+ * Feature - Use CRT based signers if `aws-crt` is available - provides support for `sigv4a`.
8
+
4
9
  1.4.0 (2021-09-02)
5
10
  ------------------
6
11
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.0
@@ -32,6 +32,8 @@ module Aws
32
32
  # @return [String] For debugging purposes.
33
33
  attr_accessor :content_sha256
34
34
 
35
+ # @return [Hash] Internal data for debugging purposes.
36
+ attr_accessor :extra
35
37
  end
36
38
  end
37
39
  end
@@ -118,6 +118,18 @@ module Aws
118
118
  # headers. This is required for AWS Glacier, and optional for
119
119
  # every other AWS service as of late 2016.
120
120
  #
121
+ # @option options [Symbol] :signing_algorithm (:sigv4) The
122
+ # algorithm to use for signing. :sigv4a is only supported when
123
+ # `aws-crt` is available.
124
+ #
125
+ # @option options [Boolean] :omit_session_token (false)
126
+ # (Supported only when `aws-crt` is available) If `true`,
127
+ # then security token is added to the final signing result,
128
+ # but is treated as "unsigned" and does not contribute
129
+ # to the authorization signature.
130
+ #
131
+ # @option options [Boolean] :normalize_path (true) (Supported only when `aws-crt` is available)
132
+ # When `true`, the uri paths will be normalized when building the canonical request
121
133
  def initialize(options = {})
122
134
  @service = extract_service(options)
123
135
  @region = extract_region(options)
@@ -126,13 +138,15 @@ module Aws
126
138
  @unsigned_headers << 'authorization'
127
139
  @unsigned_headers << 'x-amzn-trace-id'
128
140
  @unsigned_headers << 'expect'
129
- [:uri_escape_path, :apply_checksum_header].each do |opt|
130
- instance_variable_set("@#{opt}", options.key?(opt) ? !!options[opt] : true)
131
- end
141
+ @uri_escape_path = options.fetch(:uri_escape_path, true)
142
+ @apply_checksum_header = options.fetch(:apply_checksum_header, true)
143
+ @signing_algorithm = options.fetch(:signing_algorithm, :sigv4)
144
+ @normalize_path = options.fetch(:normalize_path, true)
145
+ @omit_session_token = options.fetch(:omit_session_token, false)
132
146
 
133
- if options[:signing_algorithm] == :sigv4a
147
+ if @signing_algorithm == :sigv4a && !Signer.use_crt?
134
148
  raise ArgumentError, 'You are attempting to sign a' \
135
- ' request with sigv4a which requires aws-crt and version 1.4.0.crt or later of the aws-sigv4 gem.'\
149
+ ' request with sigv4a which requires the `aws-crt` gem.'\
136
150
  ' Please install the gem or add it to your gemfile.'
137
151
  end
138
152
  end
@@ -211,6 +225,8 @@ module Aws
211
225
  #
212
226
  def sign_request(request)
213
227
 
228
+ return crt_sign_request(request) if Signer.use_crt?
229
+
214
230
  creds = fetch_credentials
215
231
 
216
232
  http_method = extract_http_method(request)
@@ -289,6 +305,7 @@ module Aws
289
305
  # signature value (a binary string) used at ':chunk-signature' needs to converted to
290
306
  # hex-encoded string using #unpack
291
307
  def sign_event(prior_signature, payload, encoder)
308
+ # Note: CRT does not currently provide event stream signing, so we always use the ruby implementation.
292
309
  creds = fetch_credentials
293
310
  time = Time.now
294
311
  headers = {}
@@ -376,6 +393,8 @@ module Aws
376
393
  #
377
394
  def presign_url(options)
378
395
 
396
+ return crt_presign_url(options) if Signer.use_crt?
397
+
379
398
  creds = fetch_credentials
380
399
 
381
400
  http_method = extract_http_method(options)
@@ -693,8 +712,135 @@ module Aws
693
712
  !credentials.secret_access_key.empty?
694
713
  end
695
714
 
715
+ ### CRT Code
716
+
717
+ # the credentials used by CRT must be a
718
+ # CRT StaticCredentialsProvider object
719
+ def crt_fetch_credentials
720
+ creds = fetch_credentials
721
+ Aws::Crt::Auth::StaticCredentialsProvider.new(
722
+ creds.access_key_id,
723
+ creds.secret_access_key,
724
+ creds.session_token
725
+ )
726
+ end
727
+
728
+ def crt_sign_request(request)
729
+ creds = crt_fetch_credentials
730
+ http_method = extract_http_method(request)
731
+ url = extract_url(request)
732
+ headers = downcase_headers(request[:headers])
733
+
734
+ datetime =
735
+ if headers.include? 'x-amz-date'
736
+ Time.parse(headers.delete('x-amz-date'))
737
+ end
738
+
739
+ content_sha256 = headers.delete('x-amz-content-sha256')
740
+ content_sha256 ||= sha256_hexdigest(request[:body] || '')
741
+
742
+ sigv4_headers = {}
743
+ sigv4_headers['host'] = headers['host'] || host(url)
744
+
745
+ # Modify the user-agent to add usage of crt-signer
746
+ # This should be temporary during developer preview only
747
+ if headers.include? 'user-agent'
748
+ headers['user-agent'] = "#{headers['user-agent']} crt-signer/#{@signing_algorithm}/#{Aws::Sigv4::VERSION}"
749
+ sigv4_headers['user-agent'] = headers['user-agent']
750
+ end
751
+
752
+ headers = headers.merge(sigv4_headers) # merge so we do not modify given headers hash
753
+
754
+ config = Aws::Crt::Auth::SigningConfig.new(
755
+ algorithm: @signing_algorithm,
756
+ signature_type: :http_request_headers,
757
+ region: @region,
758
+ service: @service,
759
+ date: datetime,
760
+ signed_body_value: content_sha256,
761
+ signed_body_header_type: @apply_checksum_header ?
762
+ :sbht_content_sha256 : :sbht_none,
763
+ credentials: creds,
764
+ unsigned_headers: @unsigned_headers,
765
+ use_double_uri_encode: @uri_escape_path,
766
+ should_normalize_uri_path: @normalize_path,
767
+ omit_session_token: @omit_session_token
768
+ )
769
+ http_request = Aws::Crt::Http::Message.new(
770
+ http_method, url.to_s, headers
771
+ )
772
+ signable = Aws::Crt::Auth::Signable.new(http_request)
773
+
774
+ signing_result = Aws::Crt::Auth::Signer.sign_request(config, signable)
775
+
776
+ Signature.new(
777
+ headers: sigv4_headers.merge(
778
+ downcase_headers(signing_result[:headers])
779
+ ),
780
+ string_to_sign: 'CRT_INTERNAL',
781
+ canonical_request: 'CRT_INTERNAL',
782
+ content_sha256: content_sha256,
783
+ extra: {config: config, signable: signable}
784
+ )
785
+ end
786
+
787
+ def crt_presign_url(options)
788
+ creds = crt_fetch_credentials
789
+
790
+ http_method = extract_http_method(options)
791
+ url = extract_url(options)
792
+ headers = downcase_headers(options[:headers])
793
+ headers['host'] ||= host(url)
794
+
795
+ datetime = headers.delete('x-amz-date')
796
+ datetime ||= (options[:time] || Time.now)
797
+
798
+ content_sha256 = headers.delete('x-amz-content-sha256')
799
+ content_sha256 ||= options[:body_digest]
800
+ content_sha256 ||= sha256_hexdigest(options[:body] || '')
801
+
802
+ config = Aws::Crt::Auth::SigningConfig.new(
803
+ algorithm: @signing_algorithm,
804
+ signature_type: :http_request_query_params,
805
+ region: @region,
806
+ service: @service,
807
+ date: datetime,
808
+ signed_body_value: content_sha256,
809
+ signed_body_header_type: @apply_checksum_header ?
810
+ :sbht_content_sha256 : :sbht_none,
811
+ credentials: creds,
812
+ unsigned_headers: @unsigned_headers,
813
+ use_double_uri_encode: @uri_escape_path,
814
+ should_normalize_uri_path: @normalize_path,
815
+ omit_session_token: @omit_session_token,
816
+ expiration_in_seconds: options.fetch(:expires_in, 900)
817
+ )
818
+ http_request = Aws::Crt::Http::Message.new(
819
+ http_method, url.to_s, headers
820
+ )
821
+ signable = Aws::Crt::Auth::Signable.new(http_request)
822
+
823
+ signing_result = Aws::Crt::Auth::Signer.sign_request(config, signable, http_method, url.to_s)
824
+ url = URI.parse(signing_result[:path])
825
+
826
+ if options[:extra] && options[:extra].is_a?(Hash)
827
+ options[:extra][:config] = config
828
+ options[:extra][:signable] = signable
829
+ end
830
+ url
831
+ end
832
+
696
833
  class << self
697
834
 
835
+ def use_crt?
836
+ begin
837
+ require 'aws-crt'
838
+ return true
839
+ rescue LoadError
840
+ return false
841
+ end
842
+ end
843
+
698
844
  # @api private
699
845
  def uri_escape_path(path)
700
846
  path.gsub(/[^\/]+/) { |part| uri_escape(part) }
data/lib/aws-sigv4.rb CHANGED
@@ -4,3 +4,9 @@ require_relative 'aws-sigv4/credentials'
4
4
  require_relative 'aws-sigv4/errors'
5
5
  require_relative 'aws-sigv4/signature'
6
6
  require_relative 'aws-sigv4/signer'
7
+
8
+ module Aws
9
+ module Sigv4
10
+ VERSION = File.read(File.expand_path('../VERSION', __dir__)).strip
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-sigv4
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-02 00:00:00.000000000 Z
11
+ date: 2022-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-eventstream