aws-sigv4 1.4.0 → 1.5.1

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: '024807372644472d420e52bd415e36b47d1ceb4eabad0d76c505e9a5b8c1bf4a'
4
+ data.tar.gz: a1f7102b525847893157a95988b2252fa560443d461fd568744599563a060a10
5
5
  SHA512:
6
- metadata.gz: '0142942e58db9971d8ceaa2aeb7c97d1cd58bdba463366fd06831b1769a3c124f6e1f1b082c4d1b5917f794ab70556f6bd78dbb67824a35e74ccbfc5bdaafa25'
7
- data.tar.gz: aca23ad7a8a98f24abdbbaa2afe9cde1430a7a10f627b63d7da56939665056ccc7a04226dc14e3793e3848032291aba990fc10576369f3974911593566ea9262
6
+ metadata.gz: 1e2d0ad4e485957c009ced92febe1df4105c557a224ac9a6a93c960f46503cb8f8fde5e695afec58bcd02b8866fb5705c96e085863479115ceb193a490a55e51
7
+ data.tar.gz: 7cc4b490fd35ceb5a7af7904b8f353cdb08f76da8c286a4358071136f3491bf49e4adbbe24599193da2a5dc59a0daa3ad382aa0609a8060a5f13d0ed52a48d63
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 1.5.1 (2022-07-19)
5
+ ------------------
6
+
7
+ * Issue - Fix performance regression when checking if `aws-crt` is available. (#2729)
8
+
9
+ 1.5.0 (2022-04-20)
10
+ ------------------
11
+
12
+ * Feature - Use CRT based signers if `aws-crt` is available - provides support for `sigv4a`.
13
+
4
14
  1.4.0 (2021-09-02)
5
15
  ------------------
6
16
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.1
@@ -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
@@ -74,6 +74,14 @@ module Aws
74
74
  #
75
75
  class Signer
76
76
 
77
+ @@use_crt =
78
+ begin
79
+ require 'aws-crt'
80
+ true
81
+ rescue LoadError
82
+ false
83
+ end
84
+
77
85
  # @overload initialize(service:, region:, access_key_id:, secret_access_key:, session_token:nil, **options)
78
86
  # @param [String] :service The service signing name, e.g. 's3'.
79
87
  # @param [String] :region The region name, e.g. 'us-east-1'.
@@ -118,6 +126,18 @@ module Aws
118
126
  # headers. This is required for AWS Glacier, and optional for
119
127
  # every other AWS service as of late 2016.
120
128
  #
129
+ # @option options [Symbol] :signing_algorithm (:sigv4) The
130
+ # algorithm to use for signing. :sigv4a is only supported when
131
+ # `aws-crt` is available.
132
+ #
133
+ # @option options [Boolean] :omit_session_token (false)
134
+ # (Supported only when `aws-crt` is available) If `true`,
135
+ # then security token is added to the final signing result,
136
+ # but is treated as "unsigned" and does not contribute
137
+ # to the authorization signature.
138
+ #
139
+ # @option options [Boolean] :normalize_path (true) (Supported only when `aws-crt` is available)
140
+ # When `true`, the uri paths will be normalized when building the canonical request
121
141
  def initialize(options = {})
122
142
  @service = extract_service(options)
123
143
  @region = extract_region(options)
@@ -126,13 +146,15 @@ module Aws
126
146
  @unsigned_headers << 'authorization'
127
147
  @unsigned_headers << 'x-amzn-trace-id'
128
148
  @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
149
+ @uri_escape_path = options.fetch(:uri_escape_path, true)
150
+ @apply_checksum_header = options.fetch(:apply_checksum_header, true)
151
+ @signing_algorithm = options.fetch(:signing_algorithm, :sigv4)
152
+ @normalize_path = options.fetch(:normalize_path, true)
153
+ @omit_session_token = options.fetch(:omit_session_token, false)
132
154
 
133
- if options[:signing_algorithm] == :sigv4a
155
+ if @signing_algorithm == :sigv4a && !Signer.use_crt?
134
156
  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.'\
157
+ ' request with sigv4a which requires the `aws-crt` gem.'\
136
158
  ' Please install the gem or add it to your gemfile.'
137
159
  end
138
160
  end
@@ -211,6 +233,8 @@ module Aws
211
233
  #
212
234
  def sign_request(request)
213
235
 
236
+ return crt_sign_request(request) if Signer.use_crt?
237
+
214
238
  creds = fetch_credentials
215
239
 
216
240
  http_method = extract_http_method(request)
@@ -289,6 +313,7 @@ module Aws
289
313
  # signature value (a binary string) used at ':chunk-signature' needs to converted to
290
314
  # hex-encoded string using #unpack
291
315
  def sign_event(prior_signature, payload, encoder)
316
+ # Note: CRT does not currently provide event stream signing, so we always use the ruby implementation.
292
317
  creds = fetch_credentials
293
318
  time = Time.now
294
319
  headers = {}
@@ -376,6 +401,8 @@ module Aws
376
401
  #
377
402
  def presign_url(options)
378
403
 
404
+ return crt_presign_url(options) if Signer.use_crt?
405
+
379
406
  creds = fetch_credentials
380
407
 
381
408
  http_method = extract_http_method(options)
@@ -693,8 +720,130 @@ module Aws
693
720
  !credentials.secret_access_key.empty?
694
721
  end
695
722
 
723
+ ### CRT Code
724
+
725
+ # the credentials used by CRT must be a
726
+ # CRT StaticCredentialsProvider object
727
+ def crt_fetch_credentials
728
+ creds = fetch_credentials
729
+ Aws::Crt::Auth::StaticCredentialsProvider.new(
730
+ creds.access_key_id,
731
+ creds.secret_access_key,
732
+ creds.session_token
733
+ )
734
+ end
735
+
736
+ def crt_sign_request(request)
737
+ creds = crt_fetch_credentials
738
+ http_method = extract_http_method(request)
739
+ url = extract_url(request)
740
+ headers = downcase_headers(request[:headers])
741
+
742
+ datetime =
743
+ if headers.include? 'x-amz-date'
744
+ Time.parse(headers.delete('x-amz-date'))
745
+ end
746
+
747
+ content_sha256 = headers.delete('x-amz-content-sha256')
748
+ content_sha256 ||= sha256_hexdigest(request[:body] || '')
749
+
750
+ sigv4_headers = {}
751
+ sigv4_headers['host'] = headers['host'] || host(url)
752
+
753
+ # Modify the user-agent to add usage of crt-signer
754
+ # This should be temporary during developer preview only
755
+ if headers.include? 'user-agent'
756
+ headers['user-agent'] = "#{headers['user-agent']} crt-signer/#{@signing_algorithm}/#{Aws::Sigv4::VERSION}"
757
+ sigv4_headers['user-agent'] = headers['user-agent']
758
+ end
759
+
760
+ headers = headers.merge(sigv4_headers) # merge so we do not modify given headers hash
761
+
762
+ config = Aws::Crt::Auth::SigningConfig.new(
763
+ algorithm: @signing_algorithm,
764
+ signature_type: :http_request_headers,
765
+ region: @region,
766
+ service: @service,
767
+ date: datetime,
768
+ signed_body_value: content_sha256,
769
+ signed_body_header_type: @apply_checksum_header ?
770
+ :sbht_content_sha256 : :sbht_none,
771
+ credentials: creds,
772
+ unsigned_headers: @unsigned_headers,
773
+ use_double_uri_encode: @uri_escape_path,
774
+ should_normalize_uri_path: @normalize_path,
775
+ omit_session_token: @omit_session_token
776
+ )
777
+ http_request = Aws::Crt::Http::Message.new(
778
+ http_method, url.to_s, headers
779
+ )
780
+ signable = Aws::Crt::Auth::Signable.new(http_request)
781
+
782
+ signing_result = Aws::Crt::Auth::Signer.sign_request(config, signable)
783
+
784
+ Signature.new(
785
+ headers: sigv4_headers.merge(
786
+ downcase_headers(signing_result[:headers])
787
+ ),
788
+ string_to_sign: 'CRT_INTERNAL',
789
+ canonical_request: 'CRT_INTERNAL',
790
+ content_sha256: content_sha256,
791
+ extra: {config: config, signable: signable}
792
+ )
793
+ end
794
+
795
+ def crt_presign_url(options)
796
+ creds = crt_fetch_credentials
797
+
798
+ http_method = extract_http_method(options)
799
+ url = extract_url(options)
800
+ headers = downcase_headers(options[:headers])
801
+ headers['host'] ||= host(url)
802
+
803
+ datetime = headers.delete('x-amz-date')
804
+ datetime ||= (options[:time] || Time.now)
805
+
806
+ content_sha256 = headers.delete('x-amz-content-sha256')
807
+ content_sha256 ||= options[:body_digest]
808
+ content_sha256 ||= sha256_hexdigest(options[:body] || '')
809
+
810
+ config = Aws::Crt::Auth::SigningConfig.new(
811
+ algorithm: @signing_algorithm,
812
+ signature_type: :http_request_query_params,
813
+ region: @region,
814
+ service: @service,
815
+ date: datetime,
816
+ signed_body_value: content_sha256,
817
+ signed_body_header_type: @apply_checksum_header ?
818
+ :sbht_content_sha256 : :sbht_none,
819
+ credentials: creds,
820
+ unsigned_headers: @unsigned_headers,
821
+ use_double_uri_encode: @uri_escape_path,
822
+ should_normalize_uri_path: @normalize_path,
823
+ omit_session_token: @omit_session_token,
824
+ expiration_in_seconds: options.fetch(:expires_in, 900)
825
+ )
826
+ http_request = Aws::Crt::Http::Message.new(
827
+ http_method, url.to_s, headers
828
+ )
829
+ signable = Aws::Crt::Auth::Signable.new(http_request)
830
+
831
+ signing_result = Aws::Crt::Auth::Signer.sign_request(config, signable, http_method, url.to_s)
832
+ url = URI.parse(signing_result[:path])
833
+
834
+ if options[:extra] && options[:extra].is_a?(Hash)
835
+ options[:extra][:config] = config
836
+ options[:extra][:signable] = signable
837
+ end
838
+ url
839
+ end
840
+
696
841
  class << self
697
842
 
843
+ def use_crt?
844
+ @@use_crt
845
+ end
846
+
698
847
  # @api private
699
848
  def uri_escape_path(path)
700
849
  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.1
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-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-eventstream