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 +5 -5
- data/lib/aws-sigv4/credentials.rb +10 -3
- data/lib/aws-sigv4/signer.rb +115 -13
- metadata +26 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 20343231e403c71c5f020e97a51d2218cbc392109eeaabb6d2dfc20350251acc
|
4
|
+
data.tar.gz: 0b36d157ccfcd9fc92c307d602bb3b1da6ba910cea99836879b2e618bf57a196
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
data/lib/aws-sigv4/signer.rb
CHANGED
@@ -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 =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
658
|
+
|
659
|
+
def fetch_credentials
|
565
660
|
credentials = @credentials_provider.credentials
|
566
661
|
if credentials_set?(credentials)
|
567
662
|
credentials
|
568
663
|
else
|
569
|
-
|
570
|
-
|
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 &&
|
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.
|
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:
|
12
|
-
dependencies:
|
13
|
-
|
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:
|
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.
|
68
|
+
rubygems_version: 2.7.6.2
|
49
69
|
signing_key:
|
50
70
|
specification_version: 4
|
51
71
|
summary: AWS Signature Version 4 library.
|