aws-sigv4 1.4.0 → 1.5.2

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: 33cb09610570a5aefa4e83ab34277756201d8f1e50197bfe343fc49cce668672
4
+ data.tar.gz: 4d070f7cf41c0a77b69e7ca6cc80c2fb7a8111eb3640819fb01ee6602027b5d9
5
5
  SHA512:
6
- metadata.gz: '0142942e58db9971d8ceaa2aeb7c97d1cd58bdba463366fd06831b1769a3c124f6e1f1b082c4d1b5917f794ab70556f6bd78dbb67824a35e74ccbfc5bdaafa25'
7
- data.tar.gz: aca23ad7a8a98f24abdbbaa2afe9cde1430a7a10f627b63d7da56939665056ccc7a04226dc14e3793e3848032291aba990fc10576369f3974911593566ea9262
6
+ metadata.gz: ddb8c5fc04288a396501afb0cd74907232ac78a2ca5e3bbb4c0879c27c15d72c19e30b9ddcaf5b8fe536e8b04d4ccc3c98eee74f27f92b594058a54b29edf704
7
+ data.tar.gz: 283afcb61ae4b06a68b5a644a529b560864b82f0e69c107a8c059c04b9b6448421ac93015c483aae1bdf77bed41cb3088942c1e18dc26fc4b569aa7fde65f563
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 1.5.2 (2022-09-30)
5
+ ------------------
6
+
7
+ * Issue - Fix an issue where quoted strings with multiple spaces are not trimmed. (#2758)
8
+
9
+ 1.5.1 (2022-07-19)
10
+ ------------------
11
+
12
+ * Issue - Fix performance regression when checking if `aws-crt` is available. (#2729)
13
+
14
+ 1.5.0 (2022-04-20)
15
+ ------------------
16
+
17
+ * Feature - Use CRT based signers if `aws-crt` is available - provides support for `sigv4a`.
18
+
4
19
  1.4.0 (2021-09-02)
5
20
  ------------------
6
21
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.2
@@ -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)
@@ -562,7 +589,7 @@ module Aws
562
589
  end
563
590
 
564
591
  def canonical_header_value(value)
565
- value.match(/^".*"$/) ? value : value.gsub(/\s+/, ' ').strip
592
+ value.gsub(/\s+/, ' ').strip
566
593
  end
567
594
 
568
595
  def host(uri)
@@ -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.2
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-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-eventstream