aws-sigv4 1.0.3 → 1.1.4

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
- SHA1:
3
- metadata.gz: 230c5aa7c49bded384ea0cc96ecbc3cdc6d3bec7
4
- data.tar.gz: b1b194fa0740e2588a94dd9a0c66f7c5f4198f70
2
+ SHA256:
3
+ metadata.gz: 20343231e403c71c5f020e97a51d2218cbc392109eeaabb6d2dfc20350251acc
4
+ data.tar.gz: 0b36d157ccfcd9fc92c307d602bb3b1da6ba910cea99836879b2e618bf57a196
5
5
  SHA512:
6
- metadata.gz: 53016c5f240e3154815b4f172158a5a29c84ef7e912e756f8f5b53e619854bbc30a041358b5be4a8fc82708cbbb12c549f31c843421cbf5a0e6c3f2e0537ab23
7
- data.tar.gz: 4ff775b31b1603a3eaf5206cb0c59bdac3599a95973626d746d81ec21b8e51db46cdc9fd8cb6a7008afaeaec5bb6ac6af6a12b5317ba60e2c64303424235a63d
6
+ metadata.gz: 1422ecb16c75a15b94c521b14a62502a8ed1e53756119c914bf91f720dc0edee45d566ea909e7a0617ecc3bc560ef7f840d0d4745a6b4a401e16199630727d5e
7
+ data.tar.gz: f0488cd4c6d30ee2f61f1fb2b7f803eea8a638efc432346a5416659cca33d0d4aebe372f8187a40e3637ad6ce5ab5ae98ea5d9af79c3c778dc7c795b08f9b065
@@ -28,11 +28,14 @@ module Aws
28
28
  # @return [String, nil]
29
29
  attr_reader :session_token
30
30
 
31
- # @return [Boolean]
31
+ # @return [Boolean] Returns `true` if the access key id and secret
32
+ # access key are both set.
32
33
  def set?
33
- !!(access_key_id && secret_access_key)
34
+ !access_key_id.nil? &&
35
+ !access_key_id.empty? &&
36
+ !secret_access_key.nil? &&
37
+ !secret_access_key.empty?
34
38
  end
35
-
36
39
  end
37
40
 
38
41
  # Users that wish to configure static credentials can use the
@@ -53,6 +56,10 @@ module Aws
53
56
  # @return [Credentials]
54
57
  attr_reader :credentials
55
58
 
59
+ # @return [Boolean]
60
+ def set?
61
+ !!credentials && credentials.set?
62
+ end
56
63
  end
57
64
 
58
65
  end
@@ -4,6 +4,7 @@ require 'time'
4
4
  require 'uri'
5
5
  require 'set'
6
6
  require 'cgi'
7
+ require 'aws-eventstream'
7
8
 
8
9
  module Aws
9
10
  module Sigv4
@@ -122,6 +123,7 @@ module Aws
122
123
  @unsigned_headers = Set.new((options.fetch(:unsigned_headers, [])).map(&:downcase))
123
124
  @unsigned_headers << 'authorization'
124
125
  @unsigned_headers << 'x-amzn-trace-id'
126
+ @unsigned_headers << 'expect'
125
127
  [:uri_escape_path, :apply_checksum_header].each do |opt|
126
128
  instance_variable_set("@#{opt}", options.key?(opt) ? !!options[:opt] : true)
127
129
  end
@@ -201,7 +203,7 @@ module Aws
201
203
  #
202
204
  def sign_request(request)
203
205
 
204
- creds = get_credentials
206
+ creds = fetch_credentials
205
207
 
206
208
  http_method = extract_http_method(request)
207
209
  url = extract_url(request)
@@ -243,6 +245,59 @@ module Aws
243
245
  )
244
246
  end
245
247
 
248
+ # Signs a event and returns signature headers and prior signature
249
+ # used for next event signing.
250
+ #
251
+ # Headers of a sigv4 signed event message only contains 2 headers
252
+ # * ':chunk-signature'
253
+ # * computed signature of the event, binary string, 'bytes' type
254
+ # * ':date'
255
+ # * millisecond since epoch, 'timestamp' type
256
+ #
257
+ # Payload of the sigv4 signed event message contains eventstream encoded message
258
+ # which is serialized based on input and protocol
259
+ #
260
+ # To sign events
261
+ #
262
+ # headers_0, signature_0 = signer.sign_event(
263
+ # prior_signature, # hex-encoded string
264
+ # payload_0, # binary string (eventstream encoded event 0)
265
+ # encoder, # Aws::EventStreamEncoder
266
+ # )
267
+ #
268
+ # headers_1, signature_1 = signer.sign_event(
269
+ # signature_0,
270
+ # payload_1, # binary string (eventstream encoded event 1)
271
+ # encoder
272
+ # )
273
+ #
274
+ # The initial prior_signature should be using the signature computed at initial request
275
+ #
276
+ # Note:
277
+ #
278
+ # Since ':chunk-signature' header value has bytes type, the signature value provided
279
+ # needs to be a binary string instead of a hex-encoded string (like original signature
280
+ # V4 algorithm). Thus, when returning signature value used for next event siging, the
281
+ # signature value (a binary string) used at ':chunk-signature' needs to converted to
282
+ # hex-encoded string using #unpack
283
+ def sign_event(prior_signature, payload, encoder)
284
+ creds = fetch_credentials
285
+ time = Time.now
286
+ headers = {}
287
+
288
+ datetime = time.utc.strftime("%Y%m%dT%H%M%SZ")
289
+ date = datetime[0,8]
290
+ headers[':date'] = Aws::EventStream::HeaderValue.new(value: time.to_i * 1000, type: 'timestamp')
291
+
292
+ sts = event_string_to_sign(datetime, headers, payload, prior_signature, encoder)
293
+ sig = event_signature(creds.secret_access_key, date, sts)
294
+
295
+ headers[':chunk-signature'] = Aws::EventStream::HeaderValue.new(value: sig, type: 'bytes')
296
+
297
+ # Returning signed headers and signature value in hex-encoded string
298
+ [headers, sig.unpack('H*').first]
299
+ end
300
+
246
301
  # Signs a URL with query authentication. Using query parameters
247
302
  # to authenticate requests is useful when you want to express a
248
303
  # request entirely in a URL. This method is also referred as
@@ -313,7 +368,7 @@ module Aws
313
368
  #
314
369
  def presign_url(options)
315
370
 
316
- creds = get_credentials
371
+ creds = fetch_credentials
317
372
 
318
373
  http_method = extract_http_method(options)
319
374
  url = extract_url(options)
@@ -375,6 +430,29 @@ module Aws
375
430
  ].join("\n")
376
431
  end
377
432
 
433
+ # Compared to original #string_to_sign at signature v4 algorithm
434
+ # there is no canonical_request concept for an eventstream event,
435
+ # instead, an event contains headers and payload two parts, and
436
+ # they will be used for computing digest in #event_string_to_sign
437
+ #
438
+ # Note:
439
+ # While headers need to be encoded under eventstream format,
440
+ # payload used is already eventstream encoded (event without signature),
441
+ # thus no extra encoding is needed.
442
+ def event_string_to_sign(datetime, headers, payload, prior_signature, encoder)
443
+ encoded_headers = encoder.encode_headers(
444
+ Aws::EventStream::Message.new(headers: headers, payload: payload)
445
+ )
446
+ [
447
+ "AWS4-HMAC-SHA256-PAYLOAD",
448
+ datetime,
449
+ credential_scope(datetime[0,8]),
450
+ prior_signature,
451
+ sha256_hexdigest(encoded_headers),
452
+ sha256_hexdigest(payload)
453
+ ].join("\n")
454
+ end
455
+
378
456
  def credential_scope(date)
379
457
  [
380
458
  date,
@@ -396,6 +474,24 @@ module Aws
396
474
  hexhmac(k_credentials, string_to_sign)
397
475
  end
398
476
 
477
+ # Comparing to original signature v4 algorithm,
478
+ # returned signature is a binary string instread of
479
+ # hex-encoded string. (Since ':chunk-signature' requires
480
+ # 'bytes' type)
481
+ #
482
+ # Note:
483
+ # converting signature from binary string to hex-encoded
484
+ # string is handled at #sign_event instead. (Will be used
485
+ # as next prior signature for event signing)
486
+ def event_signature(secret_access_key, date, string_to_sign)
487
+ k_date = hmac("AWS4" + secret_access_key, date)
488
+ k_region = hmac(k_date, @region)
489
+ k_service = hmac(k_region, @service)
490
+ k_credentials = hmac(k_service, 'aws4_request')
491
+ hmac(k_credentials, string_to_sign)
492
+ end
493
+
494
+
399
495
  def path(url)
400
496
  path = url.path
401
497
  path = '/' if path == ''
@@ -454,18 +550,14 @@ module Aws
454
550
  end
455
551
 
456
552
  def host(uri)
457
- if standard_port?(uri)
553
+ # Handles known and unknown URI schemes; default_port nil when unknown.
554
+ if uri.default_port == uri.port
458
555
  uri.host
459
556
  else
460
557
  "#{uri.host}:#{uri.port}"
461
558
  end
462
559
  end
463
560
 
464
- def standard_port?(uri)
465
- (uri.scheme == 'http' && uri.port == 80) ||
466
- (uri.scheme == 'https' && uri.port == 443)
467
- end
468
-
469
561
  # @param [File, Tempfile, IO#read, String] value
470
562
  # @return [String<SHA256 Hexdigest>]
471
563
  def sha256_hexdigest(value)
@@ -473,7 +565,9 @@ module Aws
473
565
  OpenSSL::Digest::SHA256.file(value).hexdigest
474
566
  elsif value.respond_to?(:read)
475
567
  sha256 = OpenSSL::Digest::SHA256.new
476
- while chunk = value.read(1024 * 1024, buffer ||= "") # 1MB
568
+ loop do
569
+ chunk = value.read(1024 * 1024) # 1MB
570
+ break unless chunk
477
571
  sha256.update(chunk)
478
572
  end
479
573
  value.rewind
@@ -561,18 +655,26 @@ module Aws
561
655
  self.class.uri_escape_path(string)
562
656
  end
563
657
 
564
- def get_credentials
658
+
659
+ def fetch_credentials
565
660
  credentials = @credentials_provider.credentials
566
661
  if credentials_set?(credentials)
567
662
  credentials
568
663
  else
569
- msg = 'unable to sign request without credentials set'
570
- raise Errors::MissingCredentialsError.new(msg)
664
+ raise Errors::MissingCredentialsError,
665
+ 'unable to sign request without credentials set'
571
666
  end
572
667
  end
573
668
 
669
+ # Returns true if credentials are set (not nil or empty)
670
+ # Credentials may not implement the Credentials interface
671
+ # and may just be credential like Client response objects
672
+ # (eg those returned by sts#assume_role)
574
673
  def credentials_set?(credentials)
575
- credentials.access_key_id && credentials.secret_access_key
674
+ !credentials.access_key_id.nil? &&
675
+ !credentials.access_key_id.empty? &&
676
+ !credentials.secret_access_key.nil? &&
677
+ !credentials.secret_access_key.empty?
576
678
  end
577
679
 
578
680
  class << self
metadata CHANGED
@@ -1,16 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-sigv4
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.4
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: 2018-06-28 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Amazon Web Services Signature Version 4 signing ligrary. Generates sigv4
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-eventstream
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.2
33
+ description: Amazon Web Services Signature Version 4 signing library. Generates sigv4
14
34
  signature for HTTP requests.
15
35
  email:
16
36
  executables: []
@@ -23,7 +43,7 @@ files:
23
43
  - lib/aws-sigv4/request.rb
24
44
  - lib/aws-sigv4/signature.rb
25
45
  - lib/aws-sigv4/signer.rb
26
- homepage: http://github.com/aws/aws-sdk-ruby
46
+ homepage: https://github.com/aws/aws-sdk-ruby
27
47
  licenses:
28
48
  - Apache-2.0
29
49
  metadata:
@@ -45,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
65
  version: '0'
46
66
  requirements: []
47
67
  rubyforge_project:
48
- rubygems_version: 2.5.2.3
68
+ rubygems_version: 2.7.6.2
49
69
  signing_key:
50
70
  specification_version: 4
51
71
  summary: AWS Signature Version 4 library.