aws4_signer 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40d14a60591fbacc5974d2146d052a90d6c82e8d
4
+ data.tar.gz: ac94c5b92bf12e4617387070a7616d3f6066365a
5
+ SHA512:
6
+ metadata.gz: a975872efa7da0c5c1bd42f25a132c5213a0c10e7f54196158fb9df615a1a2351645942e697bfeb47dd8a8b0b39279acba2a7bb4078ab994668e1627f3e27f18
7
+ data.tar.gz: 995dbc0117c08c1d96165eb138637164e3422733d80a0f3ad2f56bc80681bff606f4556fb60786118fcf628cc8cf86ad327f0ab034b77a52fca57267238853a3
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - "2.1.1"
5
+ - "2.0.0"
6
+ - "ruby-head"
7
+ matrix:
8
+ allow_failures:
9
+ - rvm:
10
+ - "ruby-head"
11
+ fast_finish: true
12
+ notifications:
13
+ email:
14
+ - travis-ci@sorah.jp
15
+ script: bundle exec rake test
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aws4_signer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Shota Fukumori (sora_h)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Aws4Signer - Simple signer module implements AWS4 signature
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ gem 'aws4_signer'
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install aws4_signer
16
+
17
+ ## Usage
18
+
19
+ ```
20
+ bucket, key = 'foo', 'path/to/file'
21
+ signer = Aws4Signer.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], 'ap-northeast-1', 's3')
22
+ uri = URI("https://s3-ap-northeast-1.amazonaws.com/#{bucket}/#{key}")
23
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
24
+ req = Net::HTTP::Get.new(uri)
25
+ signer.sign_http_request(req)
26
+
27
+ response = http.request(req)
28
+ p response.body
29
+ end
30
+ ```
31
+
32
+ ## Reference
33
+
34
+ - [Authenticating Requests (AWS Signature Version 4) - Amazon Simple Storage Service](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)
35
+ - [Authenticating Requests by Using the Authorization Header (Compute Checksum of the Entire Payload Prior to Transmission) - Signature Version 4 - Amazon Simple Storage Service](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html)
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it ( https://github.com/sorah/aws4_signer/fork )
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.pattern= "test/*_spec.rb"
6
+ end
7
+
8
+ task default: :test
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aws4_signer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aws4_signer"
8
+ spec.version = Aws4Signer::VERSION
9
+ spec.authors = ["Shota Fukumori (sora_h)"]
10
+ spec.email = ["her@sorah.jp"]
11
+ spec.summary = %q{Simple signer module implements AWS4 signature}
12
+ spec.description = nil
13
+ spec.homepage = "https://github.com/sorah/aws4_signer"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "minitest", '~> 5.4.0'
24
+ spec.add_development_dependency 'minitest-reporters', '~> 1.0.5'
25
+ end
@@ -0,0 +1,22 @@
1
+ require 'aws4_signer'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'net/https'
5
+
6
+ bucket, key = ARGV
7
+
8
+ unless bucket && key && ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"] && ENV["AWS_REGION"]
9
+ puts "Usage: #{$0} bucket key"
10
+ puts "Specify AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION via environment variable"
11
+ exit 2
12
+ end
13
+
14
+ signer = Aws4Signer.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], ENV["AWS_REGION"], 's3')
15
+ uri = URI("https://s3-#{ENV["AWS_REGION"]}.amazonaws.com/#{bucket}/#{key}")
16
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
17
+ req = Net::HTTP::Get.new(uri)
18
+ signer.sign_http_request(req)
19
+
20
+ response = http.request(req)
21
+ puts response.body
22
+ end
@@ -0,0 +1,142 @@
1
+ class Aws4Signer
2
+ class Signature
3
+ def initialize(access_key_id, secret_access_key, region, service, verb, uri, headers, body)
4
+ @access_key_id = access_key_id
5
+ @secret_access_key = secret_access_key
6
+ @region = region
7
+ @service = service
8
+ @verb = verb
9
+ @uri = uri
10
+ @headers = headers.dup
11
+ @body = body
12
+
13
+ @headers.each do |name, value|
14
+ if value.kind_of?(Array)
15
+ @headers[name] = value.first
16
+ end
17
+ end
18
+
19
+ @headers["x-amz-date"] ||= @headers.delete("X-Amz-Date")
20
+ unless @headers["x-amz-date"]
21
+ @date = Time.now.utc
22
+ @headers["x-amz-date"] = @date.strftime("%Y%m%dT%H%M%SZ")
23
+ end
24
+ @headers["Host"] ||= @headers.delete("host") || uri.host
25
+ end
26
+
27
+ attr_reader :region, :service, :verb, :uri, :headers, :body, :access_key_id, :secret_access_key
28
+
29
+ def attach_to_http_request(req)
30
+ headers.each do |name, value|
31
+ req[name.downcase] = value
32
+ end
33
+
34
+ req["x-amz-content-sha256"] = Digest::SHA2.hexdigest(req.body || '', 256)
35
+ req["authorization"] = authorization_header
36
+
37
+ req
38
+ end
39
+
40
+ def authorization_header
41
+ "AWS4-HMAC-SHA256 " \
42
+ "Credential=#{@access_key_id}/#{scope}," \
43
+ "SignedHeaders=#{signed_headers}," \
44
+ "Signature=#{signature}"
45
+ end
46
+
47
+ def date
48
+ @date ||= begin
49
+ time = Time.strptime(headers["x-amz-date"],"%Y%m%dT%H%M%SZ")
50
+ time += time.utc_offset
51
+ time.utc
52
+ end
53
+ end
54
+
55
+ def canonical_headers
56
+ @canonical_headers ||= begin
57
+ signed = []
58
+ hs = headers.sort_by { |name, _| name.downcase }.flat_map { |name, value|
59
+ next if name == "Authorization"
60
+
61
+ signed << name.downcase
62
+ case value
63
+ when Array
64
+ value.each do |v|
65
+ "#{name.downcase}:#{v.to_s.strip}\n"
66
+ end
67
+ else
68
+ "#{name.downcase}:#{value.to_s.strip}\n"
69
+ end
70
+ }.compact.join.freeze
71
+
72
+ @signed_headers = signed.join(";").freeze
73
+ hs
74
+ end
75
+ end
76
+
77
+ def signed_headers
78
+ canonical_headers; @signed_headers
79
+ end
80
+
81
+ def hashed_payload
82
+ @hashed_payload ||= Digest::SHA2.hexdigest(body, 256)
83
+ end
84
+
85
+ def canonical_request
86
+ @canonical_request ||= [
87
+ @verb.upcase,
88
+ @uri.path,
89
+ @uri.query,
90
+ canonical_headers,
91
+ signed_headers,
92
+ hashed_payload,
93
+ ].join("\n")
94
+ end
95
+
96
+ def scope
97
+ "#{date.strftime("%Y%m%d")}/#{@region}/#{service}/aws4_request"
98
+ end
99
+
100
+ def string_to_sign
101
+ @string_to_sign ||= [
102
+ "AWS4-HMAC-SHA256",
103
+ headers["x-amz-date"],
104
+ scope,
105
+ Digest::SHA2.hexdigest(canonical_request, 256),
106
+ ].join("\n")
107
+ end
108
+
109
+ def date_key
110
+ @date_key ||= hmac("AWS4#{@secret_access_key}", date.strftime("%Y%m%d"))
111
+ end
112
+
113
+ def date_region_key
114
+ @date_region_key ||= hmac(date_key, region)
115
+ end
116
+
117
+ def date_region_service_key
118
+ @date_region_service_key ||= hmac(date_region_key, service)
119
+ end
120
+
121
+ def signing_key
122
+ @signing_key ||= hmac(date_region_service_key, 'aws4_request')
123
+ end
124
+
125
+ def signature
126
+ @signature ||= hmac(signing_key, string_to_sign, :hex)
127
+ end
128
+
129
+ private
130
+
131
+ def hmac(key, data, hex = false)
132
+ hm = OpenSSL::HMAC.new(key, OpenSSL::Digest.new('sha256'))
133
+ hm.update(data)
134
+
135
+ if hex
136
+ hm.hexdigest
137
+ else
138
+ hm.digest
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,3 @@
1
+ class Aws4Signer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,48 @@
1
+ require 'uri'
2
+ require 'time'
3
+ require 'digest/sha2'
4
+ require 'openssl'
5
+
6
+ require 'net/http'
7
+ require 'net/https'
8
+
9
+ require "aws4_signer/version"
10
+ require 'aws4_signer/signature'
11
+
12
+ class Aws4Signer
13
+ # to be exactly follow the AWS documentation, implement by ourselves
14
+ def self.uri_encode(str)
15
+ str.bytes.map do |c|
16
+ if %w[- . _ ~].include?(c) || (?A .. ?Z).cover?(c) || (?a .. ?z).cover?(c) || (?0 .. ?9).cover?(c)
17
+ c
18
+ else
19
+ "%#{c.ord.to_s(16)}"
20
+ end
21
+ end.join
22
+ end
23
+
24
+ def initialize(access_key_id, secret_access_key, region, service)
25
+ @access_key_id = access_key_id
26
+ @secret_access_key = secret_access_key
27
+ @region = region
28
+ @service = service
29
+ end
30
+
31
+ def sign(verb, uri, headers: {}, body: '')
32
+ raise ArgumentError, 'URI must provided' unless uri
33
+ Signature.new(@access_key_id, @secret_access_key, @region, @service, verb, uri, headers, body)
34
+ end
35
+
36
+ def sign_http_request(req, uri = nil)
37
+ sign(
38
+ req.method,
39
+ uri || req.uri,
40
+ headers: req.to_hash,
41
+ body: req.body || '',
42
+ ).tap do |signature|
43
+ signature.attach_to_http_request(req)
44
+ end
45
+ end
46
+ end
47
+
48
+
@@ -0,0 +1,27 @@
1
+ require_relative './test_helper'
2
+ require 'minitest/autorun'
3
+ require 'aws4_signer'
4
+
5
+ require 'uri'
6
+ require 'net/http'
7
+
8
+ describe Aws4Signer do
9
+ let(:signer) { Aws4Signer.new('KEYKEYKEY','THISISSECRET', 'xx-region-1', 'svc') }
10
+ let(:uri) { URI('https://example.org/foo/bar?baz=blah') }
11
+
12
+ describe "#sign" do
13
+ it "returns Signature" do
14
+ signature = signer.sign('PUT', uri, headers: {'foo' => 'bar'}, body: 'hello')
15
+
16
+ assert signature.is_a?(Aws4Signer::Signature)
17
+ assert_equal 'KEYKEYKEY', signature.access_key_id
18
+ assert_equal 'THISISSECRET', signature.secret_access_key
19
+ assert_equal 'xx-region-1', signature.region
20
+ assert_equal 'svc', signature.service
21
+ assert_equal 'PUT', signature.verb
22
+ assert_equal uri, signature.uri
23
+ assert_equal 'hello', signature.body
24
+ assert_equal 'bar', signature.headers['foo']
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,197 @@
1
+ require_relative './test_helper'
2
+ require 'minitest/autorun'
3
+ require 'aws4_signer/signature'
4
+
5
+ require 'uri'
6
+ require 'digest/sha2'
7
+
8
+ describe Aws4Signer::Signature do
9
+ let(:uri) { URI('https://example.org/foo/bar?baz=blah') }
10
+ let(:verb) { 'PUT' }
11
+ let(:headers) do
12
+ {'x-foo' => 'bar'}
13
+ end
14
+ let(:body) { 'hello' }
15
+
16
+ let(:signature) do
17
+ Aws4Signer::Signature.new(
18
+ 'AKID',
19
+ 'SECRET',
20
+ 'xx-region-1',
21
+ 'svc',
22
+ verb,
23
+ uri,
24
+ headers,
25
+ body,
26
+ )
27
+ end
28
+
29
+ describe "headers" do
30
+ describe "without x-amz-date" do
31
+ it "assigns" do
32
+ assert signature.headers['x-amz-date'].is_a?(String)
33
+ end
34
+ end
35
+
36
+ describe "with x-amz-date" do
37
+ before do
38
+ headers['x-amz-date'] = '20140222T070605Z'
39
+ end
40
+
41
+ it "doesn't assign" do
42
+ assert signature.headers['x-amz-date'].is_a?(String)
43
+ assert_equal Time.utc(2014,02,22,07,06,05), signature.date
44
+ end
45
+ end
46
+
47
+ describe "without host" do
48
+ it "assigns" do
49
+ assert_equal 'example.org', signature.headers['Host']
50
+ end
51
+ end
52
+
53
+ describe "with host" do
54
+ before do
55
+ headers['host'] = 'example.com'
56
+ end
57
+
58
+ it "doesn't assign" do
59
+ assert_equal 'example.com', signature.headers['Host']
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#attach_to_http_request" do
65
+ before do
66
+ headers['x-amz-date'] = '20140222T070605Z'
67
+ end
68
+
69
+ it "assigns headers" do
70
+ headers = {}
71
+ class << headers
72
+ def body
73
+ 'hello'
74
+ end
75
+ end
76
+ signature.attach_to_http_request(headers)
77
+
78
+ assert_equal 'example.org', headers['host']
79
+ assert_equal '20140222T070605Z', headers['x-amz-date']
80
+ assert_equal 'bar', headers['x-foo']
81
+ assert_equal signature.authorization_header, headers['authorization']
82
+ assert_equal Digest::SHA2.hexdigest('hello', 256), headers['x-amz-content-sha256']
83
+ end
84
+ end
85
+
86
+ describe "#authorization_header" do
87
+ before do
88
+ headers['x-amz-date'] = '20140222T070605Z'
89
+ end
90
+
91
+ it "returns" do
92
+ assert_equal 'AWS4-HMAC-SHA256 '\
93
+ 'Credential=AKID/20140222/xx-region-1/svc/aws4_request,' \
94
+ 'SignedHeaders=host;x-amz-date;x-foo,' \
95
+ 'Signature=2845eebf2510f52010a9d9e228d4b60d4dd33fb7e9f349fb21bd6a533bfc37b6',
96
+ signature.authorization_header
97
+ end
98
+ end
99
+
100
+ describe "#signature" do
101
+ before do
102
+ headers['x-amz-date'] = '20140222T070605Z'
103
+ end
104
+
105
+ it "return the sign" do
106
+ assert_equal '2845eebf2510f52010a9d9e228d4b60d4dd33fb7e9f349fb21bd6a533bfc37b6', signature.signature
107
+ end
108
+ end
109
+
110
+ describe "#canonical_headers,signed_headers" do
111
+ let(:headers) do
112
+ {
113
+ 'x-test-b' => '2',
114
+ 'X-Test-A' => '1',
115
+ 'x-test-c' => '3',
116
+ 'Authorization' => 'skip',
117
+ }
118
+ end
119
+
120
+ it "ends with return" do
121
+ assert_equal "\n", signature.canonical_headers[-1]
122
+ end
123
+
124
+ it "contains headers" do
125
+ assert signature.canonical_headers.lines.include?("x-test-b:2\n")
126
+ assert signature.canonical_headers.lines.include?("x-test-a:1\n") # downcase
127
+ assert signature.canonical_headers.lines.include?("x-test-c:3\n")
128
+ assert !signature.canonical_headers.lines.include?("Authorization:skip\n")
129
+
130
+ %w(x-test-a x-test-b x-test-c).each do |name|
131
+ assert signature.signed_headers.split(/;/).include?(name)
132
+ end
133
+ end
134
+
135
+ it "sorts headers" do
136
+ assert %w(host x-amz-date x-test-a x-test-b x-test-c),
137
+ signature.canonical_headers.lines.map { |_| _.split(/:/,2).first }
138
+
139
+ assert_equal 'host;x-amz-date;x-test-a;x-test-b;x-test-c', signature.signed_headers
140
+ end
141
+ end
142
+
143
+ describe "#hashed_payload" do
144
+ let(:body) { 'body' }
145
+
146
+ it "returns hashed payloed" do
147
+ assert_equal Digest::SHA2.hexdigest('body', 256), signature.hashed_payload
148
+ end
149
+ end
150
+
151
+ describe "#canonical_request" do
152
+ before do
153
+ headers['x-amz-date'] = '20140222T070605Z'
154
+ end
155
+
156
+ it "returns canonical request" do
157
+ canonical_request = signature.canonical_request
158
+
159
+ assert_equal <<-EXPECTED.chomp, canonical_request
160
+ PUT
161
+ /foo/bar
162
+ baz=blah
163
+ host:example.org
164
+ x-amz-date:20140222T070605Z
165
+ x-foo:bar
166
+
167
+ host;x-amz-date;x-foo
168
+ #{Digest::SHA2.hexdigest('hello', 256)}
169
+ EXPECTED
170
+ end
171
+ end
172
+
173
+ describe "#scope" do
174
+ before do
175
+ headers['x-amz-date'] = '20140222T070605Z'
176
+ end
177
+
178
+ it "returns scope" do
179
+ assert_equal '20140222/xx-region-1/svc/aws4_request', signature.scope
180
+ end
181
+ end
182
+
183
+ describe "#string_to_sign" do
184
+ before do
185
+ headers['x-amz-date'] = '20140222T070605Z'
186
+ end
187
+
188
+ it "returns string to sign" do
189
+ assert_equal <<-EXPECTED.chomp, signature.string_to_sign
190
+ AWS4-HMAC-SHA256
191
+ 20140222T070605Z
192
+ 20140222/xx-region-1/svc/aws4_request
193
+ #{Digest::SHA2.hexdigest(signature.canonical_request, 256)}
194
+ EXPECTED
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,3 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/reporters'
3
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws4_signer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shota Fukumori (sora_h)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.4.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.5
69
+ description: ''
70
+ email:
71
+ - her@sorah.jp
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - aws4_signer.gemspec
83
+ - examples/s3_get.rb
84
+ - lib/aws4_signer.rb
85
+ - lib/aws4_signer/signature.rb
86
+ - lib/aws4_signer/version.rb
87
+ - test/aws4_signer_spec.rb
88
+ - test/signature_spec.rb
89
+ - test/test_helper.rb
90
+ homepage: https://github.com/sorah/aws4_signer
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.2.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Simple signer module implements AWS4 signature
114
+ test_files:
115
+ - test/aws4_signer_spec.rb
116
+ - test/signature_spec.rb
117
+ - test/test_helper.rb