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