barking_iguana-verify 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +2 -0
- data/barking_iguana-verify.gemspec +29 -0
- data/bin/example +45 -0
- data/lib/barking_iguana/verify/exceptions.rb +9 -0
- data/lib/barking_iguana/verify/signable_action.rb +67 -0
- data/lib/barking_iguana/verify/signature.rb +72 -0
- data/lib/barking_iguana/verify/signed_action.rb +32 -0
- data/lib/barking_iguana/verify/version.rb +5 -0
- data/lib/barking_iguana/verify.rb +15 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8331add902d90dcafc8c3b2b6ee724c8e24e01ca
|
4
|
+
data.tar.gz: c557293573bf87c2273fdd0ba9cb1023120a1d48
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8232f3a7356fcc8c3ede1f890cfd0f2d5800e90dbcf9bbf006270deafd12d718f62210744100567d814e304c27ae68d065e6c54481235f309b57b71c9d85a54d
|
7
|
+
data.tar.gz: 4ca2b693eb6c9e284b026f26ef1f481c468a0598506c35344a13afc73b917065cf5b7475ee659b8c5b9b6bcf6aab2764af045df6bfc2b2dc58e2d6431bafe449
|
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/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Craig R Webster
|
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,71 @@
|
|
1
|
+
# BarkingIguana::Verify
|
2
|
+
|
3
|
+
Verify that a remote caller is who they say they are.
|
4
|
+
|
5
|
+
Don't send passwords or API keys over the wire. That's risky.
|
6
|
+
|
7
|
+
Make sure replay attacks have a very limited window in case someone has
|
8
|
+
listened in to the HTTP conversation somehow.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'barking_iguana-verify'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install barking_iguana-verify
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
### Client
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'barking_iguana/verify'
|
30
|
+
|
31
|
+
# Anyone can know your username, this isn't protected data
|
32
|
+
my_username = 'craigw'
|
33
|
+
# Only you and the remote service know the API key, this should NOT be
|
34
|
+
# transmitted in-band.
|
35
|
+
my_api_key = '123456-1234-1234-123456'
|
36
|
+
# Express an intent to send an HTTP DELETE to /resource/123 with a confirm
|
37
|
+
# parameter
|
38
|
+
intent = BarkingIguana::Verify::SignableAction.new 'DELETE', '/resource/123', confirm: true
|
39
|
+
# Sign the action so the remote service can know this request was made by
|
40
|
+
# us. Let the remote service know how long you're going to take to do this.
|
41
|
+
time_i_will_perform_this_delete_by = Time.at 1402665888
|
42
|
+
action = intent.sign my_username, my_api_key, time_i_will_perform_this_delete_by
|
43
|
+
# Perform the delete
|
44
|
+
RestClient.delete "https://example.com#{action.signed_path}"
|
45
|
+
```
|
46
|
+
|
47
|
+
### Server
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
require 'barking_iguana/verify'
|
51
|
+
|
52
|
+
username = params[BarkingIguana::Verify::SignedAction::PARAMETER_PUBLIC_KEY]
|
53
|
+
# It's up to you to implement the ApiKey part.
|
54
|
+
api_key = ApiKey.find_by_username username
|
55
|
+
signature = params[BarkingIguana::Verify::SignedAction::PARAMETER_SIGNATURE]
|
56
|
+
expected_intent = BarkingIguana::Verify::SignableAction.new 'DELETE', "/resource/#{params['id']}", confirm: true
|
57
|
+
|
58
|
+
if expected_intent.verify? signature, api_key.token
|
59
|
+
Resource.delete params['id']
|
60
|
+
else
|
61
|
+
raise NotAuthorized
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it ( https://github.com/[my-github-username]/barking_iguana-verify/fork )
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'barking_iguana/verify/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "barking_iguana-verify"
|
8
|
+
spec.version = BarkingIguana::Verify::VERSION
|
9
|
+
spec.authors = ["Craig R Webster"]
|
10
|
+
spec.email = ["craig@barkingiguana.com"]
|
11
|
+
spec.summary = %q{Verify that a remote caller is who they say they are without sending password or API keys over the wire.}
|
12
|
+
spec.description = %q{Verify that a remote caller is who they say they are.
|
13
|
+
|
14
|
+
Don't send passwords or API keys over the wire. That's risky.
|
15
|
+
|
16
|
+
Make sure replay attacks have a very limited window in case someone has
|
17
|
+
listened in to the HTTP conversation somehow.}
|
18
|
+
spec.homepage = ""
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0")
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency "addressable"
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
end
|
data/bin/example
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require
|
5
|
+
include BarkingIguana::Verify
|
6
|
+
|
7
|
+
my_key = 'dc551120-f2e2-11e3-ac10-0800200c9a66'
|
8
|
+
secrets = { # This would usually be your app database
|
9
|
+
my_key => 'a2ee8c40-f2e2-11e3-ac10-0800200c9a66'
|
10
|
+
}
|
11
|
+
|
12
|
+
signable_action = SignableAction.new 'GET', '/foo/bar', return_to: '/quux'
|
13
|
+
puts "Signable Action: #{signable_action.inspect}"
|
14
|
+
|
15
|
+
signed_at = Time.now
|
16
|
+
signed_for = 7
|
17
|
+
expires_at = signed_at + signed_for
|
18
|
+
signed_action = signable_action.sign my_key, secrets[my_key], expires_at
|
19
|
+
puts "Signed Action : #{signed_action.inspect}"
|
20
|
+
puts "Signed at : #{signed_at.to_i}"
|
21
|
+
puts "Signed for : #{signed_for}"
|
22
|
+
puts "Signed until : #{expires_at.to_i}"
|
23
|
+
# A request would be made from my client to this path
|
24
|
+
puts "Signed path : #{signed_action.signed_path}"
|
25
|
+
|
26
|
+
# This would normally be a param in your application
|
27
|
+
# Note that the secret isn't part of this, even in an encrypted form
|
28
|
+
signature = signed_action.signed_path.query_values[SignedAction::PARAMETER_SIGNATURE]
|
29
|
+
# Need the public key to look up their secret for verification
|
30
|
+
their_key = signed_action.signed_path.query_values[SignedAction::PARAMETER_PUBLIC_KEY]
|
31
|
+
puts "Signature : #{signature}"
|
32
|
+
puts "Their key : #{their_key}"
|
33
|
+
their_secret = secrets[their_key]
|
34
|
+
|
35
|
+
puts "Verification : "
|
36
|
+
14.times do |n|
|
37
|
+
print "#{Time.now.to_i} : "
|
38
|
+
begin
|
39
|
+
signable_action.verify! signature, their_secret
|
40
|
+
puts "Valid"
|
41
|
+
rescue SignatureException => e
|
42
|
+
puts "Invalid: #{e.class.name} - #{e.message}"
|
43
|
+
end
|
44
|
+
sleep 1
|
45
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module BarkingIguana
|
2
|
+
module Verify
|
3
|
+
SignatureException = Class.new(StandardError)
|
4
|
+
WindowTooLarge = Class.new(SignatureException)
|
5
|
+
SignatureExpired = Class.new(SignatureException)
|
6
|
+
FarFutureExpiry = Class.new(SignatureException)
|
7
|
+
TokenMismatch = Class.new(SignatureException)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module BarkingIguana
|
4
|
+
module Verify
|
5
|
+
class SignableAction
|
6
|
+
attr_accessor :verb
|
7
|
+
private :verb=, :verb
|
8
|
+
|
9
|
+
attr_accessor :path
|
10
|
+
private :path=, :path
|
11
|
+
|
12
|
+
attr_accessor :params
|
13
|
+
private :params=, :params
|
14
|
+
|
15
|
+
def initialize verb, path, params = {}
|
16
|
+
self.verb = verb
|
17
|
+
self.path = path
|
18
|
+
self.params = params
|
19
|
+
end
|
20
|
+
|
21
|
+
def add key, value
|
22
|
+
params[key] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def ordered_params
|
26
|
+
# Ruby has ordered hashes, but I want alphabetical order
|
27
|
+
params.keys.sort_by(&:to_s).inject({}) { |a, e|
|
28
|
+
a.merge! e => params[e]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
private :ordered_params
|
32
|
+
|
33
|
+
def query_string
|
34
|
+
return '' unless params.any?
|
35
|
+
'?' + URI.encode_www_form(ordered_params)
|
36
|
+
end
|
37
|
+
|
38
|
+
def unsigned_path
|
39
|
+
Addressable::URI.parse "#{path}#{query_string}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
"#{verb} #{unsigned_path}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def sign public_key, secret, expires_at
|
47
|
+
signature = Signature.new public_key, self, secret, expires_at
|
48
|
+
SignedAction.new self, signature
|
49
|
+
end
|
50
|
+
|
51
|
+
def verify! signature, secret
|
52
|
+
Signature.verify signature, self, secret
|
53
|
+
end
|
54
|
+
|
55
|
+
def verify? signature, secret
|
56
|
+
verify! signature, secret
|
57
|
+
true
|
58
|
+
rescue SignatureException
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def inspect
|
63
|
+
"#<BarkingIguana::Verify::SignableAction #{to_s.inspect}>"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module BarkingIguana
|
5
|
+
module Verify
|
6
|
+
class Signature
|
7
|
+
MAXIMUM_VALIDITY = 3600
|
8
|
+
|
9
|
+
attr_accessor :public_key
|
10
|
+
private :public_key=
|
11
|
+
|
12
|
+
attr_accessor :action
|
13
|
+
private :action=, :action
|
14
|
+
|
15
|
+
attr_accessor :secret
|
16
|
+
private :secret=, :secret
|
17
|
+
|
18
|
+
attr_accessor :expires_at
|
19
|
+
private :expires_at=, :expires_at
|
20
|
+
|
21
|
+
attr_accessor :signed_at
|
22
|
+
private :signed_at=, :signed_at
|
23
|
+
|
24
|
+
def initialize public_key, action, secret, expires_at, signed_at = nil
|
25
|
+
self.public_key = public_key
|
26
|
+
self.action = action
|
27
|
+
self.secret = secret
|
28
|
+
self.expires_at = expires_at
|
29
|
+
self.signed_at = signed_at
|
30
|
+
end
|
31
|
+
|
32
|
+
SEPARATOR = '--'.freeze
|
33
|
+
DIGEST = 'sha256'.freeze
|
34
|
+
|
35
|
+
# Get an ASCII representation of this signature
|
36
|
+
def to_s
|
37
|
+
signed = (signed_at || Time.now).to_i.to_s
|
38
|
+
expires = expires_at.to_i.to_s
|
39
|
+
signature = "#{public_key}#{expires}#{signed}#{action}"
|
40
|
+
token = OpenSSL::HMAC.hexdigest DIGEST, secret, signature
|
41
|
+
encoded_token = Base64.encode64(token)
|
42
|
+
encoded_token.gsub! /\n/, ''
|
43
|
+
params = [ encoded_token, public_key, expires, signed ].join SEPARATOR
|
44
|
+
Base64.encode64(params).gsub(/\n/, '')
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
s = "#<#{self.class.name}: @public_key=#{public_key.inspect}, @action=#{action.inspect}, @secret=(hidden), @expires_at=#{expires_at.inspect}"
|
49
|
+
unless signed_at.nil?
|
50
|
+
s += ", @signed_at=#{signed_at.inspect}"
|
51
|
+
end
|
52
|
+
s + '>'
|
53
|
+
end
|
54
|
+
|
55
|
+
# Verify that a signature is valid, not expired, and not for an insanely
|
56
|
+
# far future date.
|
57
|
+
def self.verify ascii, action, secret, now = Time.now
|
58
|
+
this_second = Time.at now.to_i
|
59
|
+
params = Base64.decode64 ascii
|
60
|
+
_, public_key, expires, signed = params.split /#{SEPARATOR}/, 4
|
61
|
+
expires_at = Time.at expires.to_i
|
62
|
+
signed_at = Time.at signed.to_i
|
63
|
+
raise WindowTooLarge.new "Time between now and expiry is more than #{MAXIMUM_VALIDITY}" if expires_at - signed_at > MAXIMUM_VALIDITY
|
64
|
+
raise SignatureExpired.new "#{expires_at} vs #{this_second}" if this_second > expires_at
|
65
|
+
raise FarFutureExpiry.new "#{expires} vs #{this_second + MAXIMUM_VALIDITY}" if expires_at > this_second + MAXIMUM_VALIDITY
|
66
|
+
expected_signature = Signature.new public_key, action, secret,
|
67
|
+
expires_at, signed_at
|
68
|
+
raise TokenMismatch.new "#{expected_signature.to_s} vs #{ascii}" if expected_signature.to_s != ascii
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module BarkingIguana
|
2
|
+
module Verify
|
3
|
+
class SignedAction
|
4
|
+
PARAMETER_SIGNATURE = 'verify_signature'.freeze
|
5
|
+
PARAMETER_PUBLIC_KEY = 'verify_public_key'.freeze
|
6
|
+
|
7
|
+
attr_accessor :action
|
8
|
+
private :action=, :action
|
9
|
+
|
10
|
+
attr_accessor :signature
|
11
|
+
private :signature=, :signature
|
12
|
+
|
13
|
+
def initialize action, signature
|
14
|
+
self.action = action
|
15
|
+
self.signature = signature
|
16
|
+
end
|
17
|
+
|
18
|
+
def signed_path
|
19
|
+
path = action.unsigned_path
|
20
|
+
q = path.query_values
|
21
|
+
q[PARAMETER_SIGNATURE] = signature.to_s
|
22
|
+
q[PARAMETER_PUBLIC_KEY] = signature.public_key.to_s
|
23
|
+
path.query_values = q
|
24
|
+
path
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
"#<#{self.class.name}: @signed_path=#{signed_path.inspect}, @signature=#{signature.inspect}>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module BarkingIguana
|
2
|
+
module Verify
|
3
|
+
autoload :Signature, 'barking_iguana/verify/signature'
|
4
|
+
autoload :SignedAction, 'barking_iguana/verify/signed_action'
|
5
|
+
autoload :SignableAction, 'barking_iguana/verify/signable_action'
|
6
|
+
|
7
|
+
autoload :SignatureException, 'barking_iguana/verify/exceptions'
|
8
|
+
autoload :WindowTooLarge, 'barking_iguana/verify/exceptions'
|
9
|
+
autoload :SignatureExpired, 'barking_iguana/verify/exceptions'
|
10
|
+
autoload :FarFutureExpiry, 'barking_iguana/verify/exceptions'
|
11
|
+
autoload :TokenMismatch, 'barking_iguana/verify/exceptions'
|
12
|
+
|
13
|
+
autoload :VERSION, 'barking_iguana/verify/version'
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: barking_iguana-verify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Craig R Webster
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |-
|
56
|
+
Verify that a remote caller is who they say they are.
|
57
|
+
|
58
|
+
Don't send passwords or API keys over the wire. That's risky.
|
59
|
+
|
60
|
+
Make sure replay attacks have a very limited window in case someone has
|
61
|
+
listened in to the HTTP conversation somehow.
|
62
|
+
email:
|
63
|
+
- craig@barkingiguana.com
|
64
|
+
executables:
|
65
|
+
- example
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- ".gitignore"
|
70
|
+
- Gemfile
|
71
|
+
- LICENSE.txt
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- barking_iguana-verify.gemspec
|
75
|
+
- bin/example
|
76
|
+
- lib/barking_iguana/verify.rb
|
77
|
+
- lib/barking_iguana/verify/exceptions.rb
|
78
|
+
- lib/barking_iguana/verify/signable_action.rb
|
79
|
+
- lib/barking_iguana/verify/signature.rb
|
80
|
+
- lib/barking_iguana/verify/signed_action.rb
|
81
|
+
- lib/barking_iguana/verify/version.rb
|
82
|
+
homepage: ''
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.2.2
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: Verify that a remote caller is who they say they are without sending password
|
106
|
+
or API keys over the wire.
|
107
|
+
test_files: []
|