manifoldco_signature 0.0.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a3ff3aafe5057d737179dba27c7d91b6fdbbd5b
4
- data.tar.gz: 7927ce286d4f39f3a83ebc71d658f32d103d85d5
3
+ metadata.gz: a7bf5031e1176e57479f88d88d776e2d72dd0f2c
4
+ data.tar.gz: 60da3f571ac3c93b442b80693caa651746450988
5
5
  SHA512:
6
- metadata.gz: 62645710aa36c657705573ee46477ac4628c440d167c113e3a22fa7160926830d9a60393f2a442173329843046c2c54ab3a22d6428f990b9632daf70a4d634a0
7
- data.tar.gz: ff52fcf5524d69a37a06e9f75791db423da40311b052be18234a758e75874372cf2b1df1d34b6a430bc6e82e48e4a1f652629ed2f648b74f92799728059792bb
6
+ metadata.gz: 6d60f1a6c0d81953a011bf0735116acbcea9943d9cce53190279a25014c4e36040083b337daf81fdd235ad7945878782bea50019f51dcc3c68d262e68d561b05
7
+ data.tar.gz: 244eade1babf9cdf8fc9e6fea81dd4ff6562a77063a678b7e1213ae7bd708ec70e878ad0840843329fbb7b36e532e2148f2959595af9d78284bded01b990ccf0
data/.gitignore CHANGED
@@ -7,3 +7,6 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+
11
+ coverage
12
+ vendor
data/README.md CHANGED
@@ -18,3 +18,14 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install manifoldco_signature
20
20
 
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'manifoldco_signature'
25
+
26
+ # initialize once per application
27
+ verifier = ManifoldcoSignature::Verifier.new
28
+
29
+ # verify a Rack::Request. returns a boolean.
30
+ verifier.valid? request
31
+ ```
@@ -1,5 +1,6 @@
1
+ require "manifoldco_signature/signature"
2
+ require "manifoldco_signature/verifier"
1
3
  require "manifoldco_signature/version"
2
4
 
3
5
  module ManifoldcoSignature
4
- # Your code goes here...
5
6
  end
@@ -0,0 +1,4 @@
1
+ module ManifoldcoSignature
2
+ MASTER_KEY = "PtISNzqQmQPBxNlUw3CdxsWczXbIwyExxlkRqZ7E690"
3
+ PERMITTED_SKEW_IN_MINUTES = 5
4
+ end
@@ -0,0 +1,69 @@
1
+ require 'base64url'
2
+ require 'date'
3
+ require 'rbnacl/libsodium'
4
+ require 'manifoldco_signature/constants'
5
+
6
+ module ManifoldcoSignature
7
+
8
+ class Signature
9
+
10
+ def initialize(req)
11
+ sig = req.env['HTTP_X_SIGNATURE'].split
12
+ @signature = Base64URL.decode(sig[0])
13
+ @public_key_raw = Base64URL.decode(sig[1])
14
+ @public_key = RbNaCl::VerifyKey.new @public_key_raw
15
+ @endorsement = Base64URL.decode(sig[2])
16
+
17
+ @message = canonize(req)
18
+ @req_time = DateTime.rfc3339(req.env['HTTP_DATE'])
19
+ end
20
+
21
+ def valid?(master_key)
22
+ good_signature?(master_key) && valid_time?
23
+ end
24
+
25
+ def good_signature?(master_key)
26
+ begin
27
+ master_key.verify(@endorsement, @public_key_raw) &&
28
+ @public_key.verify(@signature, @message)
29
+ rescue
30
+ false
31
+ end
32
+ end
33
+
34
+ def valid_time?
35
+ now = DateTime.now()
36
+ ((now - @req_time) * 24 * 60).abs <= PERMITTED_SKEW_IN_MINUTES
37
+ end
38
+
39
+ protected
40
+ def canonize(req)
41
+
42
+ msg = "#{req.request_method.downcase} #{req.path_info}"
43
+
44
+ if !req.query_string.empty?
45
+ msg += '?' + req.query_string.split('&').sort!.join('&')
46
+ end
47
+ msg += "\n"
48
+
49
+ headers = req.env['HTTP_X_SIGNED_HEADERS'].split
50
+ headers << 'x-signed-headers'
51
+ headers.each do |header|
52
+ if header.downcase == 'content-type'
53
+ value = req.content_type
54
+ elsif header.downcase == 'content-length'
55
+ value = req.content_length
56
+ else
57
+ value = req.env["HTTP_#{header.upcase.gsub(/-/, '_')}"]
58
+ end
59
+ msg += "#{header.downcase}: #{value}\n"
60
+ end
61
+
62
+ msg += req.body.read
63
+ req.body.rewind
64
+
65
+ msg
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,25 @@
1
+ require 'base64url'
2
+ require 'rbnacl/libsodium'
3
+ require 'manifoldco_signature/constants'
4
+
5
+ module ManifoldcoSignature
6
+ class Verifier
7
+
8
+ def initialize(master_key=MASTER_KEY)
9
+ dec = Base64URL.decode(master_key)
10
+ @master_key = RbNaCl::VerifyKey.new dec
11
+ end
12
+
13
+ def valid?(req)
14
+ begin
15
+ Signature.new(req).valid?(@master_key)
16
+ rescue
17
+ false
18
+ end
19
+ end
20
+
21
+ def valid_signature?(signature)
22
+ signature.valid?(@master_key)
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module ManifoldcoSignature
2
- VERSION = "0.0.0"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["jbowes@repl.ca"]
11
11
 
12
12
  spec.summary = "Verify signed HTTP requests from Manifold"
13
- spec.homepage = "https://github.com/manifoldco/ruby-manifoldco-signaturek"
13
+ spec.homepage = "https://github.com/manifoldco/ruby-manifoldco-signature"
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
16
  f.match(%r{^(test|spec|features)/})
@@ -19,7 +19,13 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.add_dependency "base64url", "~> 1.0.1"
23
+ spec.add_dependency "rbnacl-libsodium", "~> 1.0.11"
24
+
22
25
  spec.add_development_dependency "bundler", "~> 1.14"
23
26
  spec.add_development_dependency "rake", "~> 10.0"
24
27
  spec.add_development_dependency "minitest", "~> 5.0"
28
+ spec.add_development_dependency "simplecov", "~> 0.13.0"
29
+ spec.add_development_dependency "rack", "~> 1.6.5"
30
+ spec.add_development_dependency "timecop", "~> 0.8.1"
25
31
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manifoldco_signature
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Bowes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-05 00:00:00.000000000 Z
11
+ date: 2017-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64url
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rbnacl-libsodium
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.11
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.11
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +80,48 @@ dependencies:
52
80
  - - ~>
53
81
  - !ruby/object:Gem::Version
54
82
  version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.13.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.13.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 1.6.5
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.6.5
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.8.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 0.8.1
55
125
  description:
56
126
  email:
57
127
  - jbowes@repl.ca
@@ -70,9 +140,12 @@ files:
70
140
  - bin/console
71
141
  - bin/setup
72
142
  - lib/manifoldco_signature.rb
143
+ - lib/manifoldco_signature/constants.rb
144
+ - lib/manifoldco_signature/signature.rb
145
+ - lib/manifoldco_signature/verifier.rb
73
146
  - lib/manifoldco_signature/version.rb
74
147
  - manifoldco_signature.gemspec
75
- homepage: https://github.com/manifoldco/ruby-manifoldco-signaturek
148
+ homepage: https://github.com/manifoldco/ruby-manifoldco-signature
76
149
  licenses: []
77
150
  metadata: {}
78
151
  post_install_message: