aws-sigv4 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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