aws-sigv4 1.0.3 → 1.1.4

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
- 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.