bitjwt 0.0.2
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 +2 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +49 -0
- data/README.md +80 -0
- data/bitjwt.gemspec +26 -0
- data/lib/bitjwt.rb +8 -0
- data/lib/bitjwt/crypto.rb +24 -0
- data/lib/bitjwt/protocol.rb +93 -0
- data/lib/bitjwt/protocol_error.rb +10 -0
- data/lib/bitjwt/util.rb +17 -0
- data/lib/bitjwt/version.rb +3 -0
- data/spec/lib/crypto_spec.rb +26 -0
- data/spec/lib/protocol_spec.rb +79 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/stubs/jwt_stub.rb +42 -0
- metadata +146 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 03c5f720f7f4793aa960a681c94d591b741df0b0
|
4
|
+
data.tar.gz: 41b4999bae9bc4b134b1fab2133ce52010239612
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bdf041a9d5b60a6f0fc006a4fe07bc1aee9c5acedf47c21c3a8d7c5087d9f92aadb569f8a5efb4553bdc3f39f96d015cc75f28174e7a373e66eb2068fe3dc515
|
7
|
+
data.tar.gz: e7a02f1391dd54e6a2ff1775aa040664404a213f75f5d0b4214a4f8401a1ad1ed57c350c058a23a8e8de3dfcb2220578221f7b294c43ca404012e5049b5bae27
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bitjwt (0.0.1)
|
5
|
+
bitcoin-ruby (= 0.0.8)
|
6
|
+
excon (~> 0.49)
|
7
|
+
ffi (~> 1.9)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.4.0)
|
13
|
+
bitcoin-ruby (0.0.8)
|
14
|
+
crack (0.4.3)
|
15
|
+
safe_yaml (~> 1.0.0)
|
16
|
+
diff-lcs (1.2.5)
|
17
|
+
excon (0.49.0)
|
18
|
+
ffi (1.9.10)
|
19
|
+
hashdiff (0.3.0)
|
20
|
+
rspec (3.4.0)
|
21
|
+
rspec-core (~> 3.4.0)
|
22
|
+
rspec-expectations (~> 3.4.0)
|
23
|
+
rspec-mocks (~> 3.4.0)
|
24
|
+
rspec-core (3.4.4)
|
25
|
+
rspec-support (~> 3.4.0)
|
26
|
+
rspec-expectations (3.4.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.4.0)
|
29
|
+
rspec-mocks (3.4.1)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.4.0)
|
32
|
+
rspec-support (3.4.1)
|
33
|
+
safe_yaml (1.0.4)
|
34
|
+
webmock (2.1.0)
|
35
|
+
addressable (>= 2.3.6)
|
36
|
+
crack (>= 0.3.2)
|
37
|
+
hashdiff
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
bitjwt!
|
44
|
+
rspec (~> 3.4)
|
45
|
+
rspec-mocks (~> 3.4)
|
46
|
+
webmock (~> 2.1)
|
47
|
+
|
48
|
+
BUNDLED WITH
|
49
|
+
1.12.5
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# BitJWT
|
2
|
+
|
3
|
+
Simple JWT Ruby implementation based on Bitcoin secp256k1
|
4
|
+
inspired by bitjws (https://github.com/deginner/bitjws).
|
5
|
+
|
6
|
+
JWT protocol header built on a custom bitcoin algorithm:
|
7
|
+
```ruby
|
8
|
+
header = {
|
9
|
+
'alg' => 'CUSTOM-BITCOIN-SIGN',
|
10
|
+
'kid' => '<bitcoin public address>',
|
11
|
+
'typ' => 'JWT'
|
12
|
+
}
|
13
|
+
```
|
14
|
+
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
gem 'bitjwt'
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install bitjwt
|
29
|
+
|
30
|
+
## Install bitcoin library
|
31
|
+
|
32
|
+
Compile and install libsecp256k1 required by bitcoin-ruby:
|
33
|
+
(https://github.com/bitcoin/bitcoin/tree/v0.11.0/src/secp256k1)
|
34
|
+
|
35
|
+
tag: v0.11.0
|
36
|
+
|
37
|
+
commit: d26f951802c762de04fb68e1a112d611929920ba
|
38
|
+
|
39
|
+
and place it under your vendor/bitcoin/src/secp256k1/.libs local path
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# import your WIF private key
|
45
|
+
wif_key = 'L2mvkaTyiZMVZ8kPjBkov6FHbp2AVo8DeuXEZVvH7P19KrtpsJtj'
|
46
|
+
|
47
|
+
# or generate a new one using Bitcoin library
|
48
|
+
wif_key = Bitcoin::Key.generate.to_base58
|
49
|
+
|
50
|
+
# instantiate BitJWT crypto object with your private key
|
51
|
+
crypto = BitJWT::Crypto.new(wif_key)
|
52
|
+
|
53
|
+
# define your payload to send
|
54
|
+
payload =
|
55
|
+
{
|
56
|
+
'aud' => '/api/audience',
|
57
|
+
'data' => {
|
58
|
+
'key1' => 'value1',
|
59
|
+
'key2' => 0
|
60
|
+
}
|
61
|
+
}
|
62
|
+
# 'aud' relative URL path of your request
|
63
|
+
# 'data' data to send
|
64
|
+
|
65
|
+
#build BitJWT protocol request
|
66
|
+
request = BitJWT::Protocol.build_request(crypto, payload)
|
67
|
+
|
68
|
+
# send request to base URL
|
69
|
+
begin
|
70
|
+
response = request.send('http://service_base_url', 'POST')
|
71
|
+
# check returned data contains a valid signature
|
72
|
+
if response.verify
|
73
|
+
# get your decoded response
|
74
|
+
payload = response.payload_to_h
|
75
|
+
end
|
76
|
+
rescue BitJWT::ProtocolError => e
|
77
|
+
# e.status http error status code
|
78
|
+
# e.body application returned error
|
79
|
+
end
|
80
|
+
```
|
data/bitjwt.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'bitjwt/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'bitjwt'
|
6
|
+
s.version = BitJWT::VERSION
|
7
|
+
s.date = '2016-06-16'
|
8
|
+
s.summary = 'Bitcoin JWT implementation'
|
9
|
+
s.description = 'JWT protocol implementation using Bitcoin secp256k1'
|
10
|
+
s.authors = ['Federico Barbazza']
|
11
|
+
s.email = 'federico.barbazza@gmail.com'
|
12
|
+
s.files = ['lib/bitjwt.rb']
|
13
|
+
s.homepage =
|
14
|
+
'http://rubygems.org/gems/bitjwt'
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.files = `git ls-files -z`.split("\x0")
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.add_dependency 'ffi', '~> 1.9'
|
21
|
+
s.add_dependency 'bitcoin-ruby', '0.0.8'
|
22
|
+
s.add_dependency 'excon', '~> 0.49'
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.4'
|
24
|
+
s.add_development_dependency 'rspec-mocks', '~> 3.4'
|
25
|
+
s.add_development_dependency 'webmock', '~> 2.1'
|
26
|
+
end
|
data/lib/bitjwt.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bitcoin'
|
2
|
+
|
3
|
+
module BitJWT
|
4
|
+
class Crypto
|
5
|
+
def initialize(private_key)
|
6
|
+
@key = Bitcoin::Key.from_base58(private_key)
|
7
|
+
end
|
8
|
+
|
9
|
+
def bitcoin_address
|
10
|
+
@key.addr
|
11
|
+
end
|
12
|
+
|
13
|
+
def sign(data)
|
14
|
+
bsm = Bitcoin.bitcoin_signed_message_hash(data)
|
15
|
+
signature = Bitcoin::Secp256k1.sign_compact(bsm, Util.hex_to_bin(@key.priv))
|
16
|
+
Base64.strict_encode64(signature)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.verify(data, signature_base64, pub_address)
|
20
|
+
pubkey = Bitcoin::Key.recover_compact_signature_to_key(data, signature_base64)
|
21
|
+
pubkey.addr == pub_address
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module BitJWT
|
2
|
+
class Protocol
|
3
|
+
attr_reader :header, :payload, :signature
|
4
|
+
|
5
|
+
def initialize(header, payload, signature = nil)
|
6
|
+
@header = header
|
7
|
+
@payload = payload
|
8
|
+
@signature = signature
|
9
|
+
end
|
10
|
+
|
11
|
+
def header_to_h
|
12
|
+
JSON.parse(header)
|
13
|
+
end
|
14
|
+
|
15
|
+
def payload_to_h
|
16
|
+
JSON.parse(payload)
|
17
|
+
end
|
18
|
+
|
19
|
+
def header_encoded
|
20
|
+
Util.base64url_encode(header)
|
21
|
+
end
|
22
|
+
|
23
|
+
def payload_encoded
|
24
|
+
Util.base64url_encode(payload)
|
25
|
+
end
|
26
|
+
|
27
|
+
def header_payload_encoded
|
28
|
+
"#{header_encoded}.#{payload_encoded}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def signature_encoded
|
32
|
+
Util.base64url_encode(signature)
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_signature(crypto)
|
36
|
+
@signature ||= crypto.sign(header_payload_encoded)
|
37
|
+
end
|
38
|
+
|
39
|
+
def send(url, method)
|
40
|
+
connection = Excon.new(url, omit_default_port: true)
|
41
|
+
response = connection.request(path: payload_to_h['aud'],
|
42
|
+
method: method,
|
43
|
+
headers: {
|
44
|
+
'Content-Type' => 'application/jose',
|
45
|
+
'User-Agent' => 'bitjwt_client'
|
46
|
+
},
|
47
|
+
body: "#{header_payload_encoded}.#{signature_encoded}")
|
48
|
+
raise ProtocolError.new(response.status, response.body) unless (200..299).cover?(response.status)
|
49
|
+
build_response(response.body)
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_response(response)
|
53
|
+
header, payload, signature = response.split('.')
|
54
|
+
header_decoded = Base64.decode64(header)
|
55
|
+
payload_decoded = Base64.decode64(payload)
|
56
|
+
signature_decoded = Base64.decode64(signature)
|
57
|
+
self.class.new(header_decoded, payload_decoded, signature_decoded)
|
58
|
+
end
|
59
|
+
|
60
|
+
def verify
|
61
|
+
Crypto.verify(header_payload_encoded, signature, header_to_h['kid'])
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.build_request(crypto, payload = {})
|
65
|
+
header = default_header.merge({ 'kid' => crypto.bitcoin_address })
|
66
|
+
payload = default_payload.merge(payload)
|
67
|
+
bitjws = new(header.to_json, payload.to_json)
|
68
|
+
bitjws.build_signature(crypto)
|
69
|
+
bitjws
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
class << self
|
75
|
+
def default_header
|
76
|
+
{
|
77
|
+
'alg' => 'CUSTOM-BITCOIN-SIGN',
|
78
|
+
'kid' => '',
|
79
|
+
'typ' => 'JWT'
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def default_payload
|
84
|
+
{
|
85
|
+
'aud' => '',
|
86
|
+
'data' => {},
|
87
|
+
'exp' => Time.now.to_f + 3600,
|
88
|
+
'iat' => Time.now.to_f
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/bitjwt/util.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module BitJWT
|
2
|
+
class Util
|
3
|
+
class << self
|
4
|
+
def hex_to_bin(hex)
|
5
|
+
[hex].pack('H*')
|
6
|
+
end
|
7
|
+
|
8
|
+
def bin_to_hex(bin)
|
9
|
+
bin.unpack('H*')[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
def base64url_encode(str)
|
13
|
+
Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module BitJWT
|
6
|
+
describe BitJWT::Crypto do
|
7
|
+
let(:wif_key) { 'L2mvkaTyiZMVZ8kPjBkov6FHbp2AVo8DeuXEZVvH7P19KrtpsJtj' }
|
8
|
+
let(:public_key) { '1AyG7DLm14sWEAK1By4seHP33KUQakP3Tc' }
|
9
|
+
let(:crypto) { Crypto.new(wif_key) }
|
10
|
+
let(:data) { JSON.generate(data: 'test') }
|
11
|
+
|
12
|
+
it 'import a valid WIF key' do
|
13
|
+
expect(crypto.bitcoin_address).to eql public_key
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'generate a valid Base64 strict signature' do
|
17
|
+
signature = crypto.sign(data)
|
18
|
+
expect(signature).not_to include('\n')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'verify signature to recover right public key' do
|
22
|
+
signature = crypto.sign(data)
|
23
|
+
expect(Crypto.verify(data, signature, public_key)).to be_truthy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'excon'
|
3
|
+
|
4
|
+
module BitJWT
|
5
|
+
describe BitJWT::Protocol do
|
6
|
+
let(:wif_key) { 'L2mvkaTyiZMVZ8kPjBkov6FHbp2AVo8DeuXEZVvH7P19KrtpsJtj' }
|
7
|
+
let(:public_key) { '1AyG7DLm14sWEAK1By4seHP33KUQakP3Tc' }
|
8
|
+
let(:crypto) { Crypto.new(wif_key) }
|
9
|
+
let(:user_payload) {
|
10
|
+
{
|
11
|
+
'aud' => '/endpoint',
|
12
|
+
'data' => 'test'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
context 'initialization' do
|
17
|
+
it 'build a valid JWT request' do
|
18
|
+
request = Protocol.build_request(crypto, user_payload)
|
19
|
+
expect(request.verify).to be_truthy
|
20
|
+
header = request.header_to_h
|
21
|
+
payload = request.payload_to_h
|
22
|
+
# check JWT header
|
23
|
+
expect(header).to have_key('alg')
|
24
|
+
expect(header).to have_key('kid')
|
25
|
+
expect(header).to have_key('typ')
|
26
|
+
expect(header['alg']).to eql 'CUSTOM-BITCOIN-SIGN'
|
27
|
+
expect(header['kid']).to eql public_key
|
28
|
+
expect(header['typ']).to eql 'JWT'
|
29
|
+
# check JWT payload
|
30
|
+
expect(payload).to have_key('aud')
|
31
|
+
expect(payload).to have_key('data')
|
32
|
+
expect(payload).to have_key('exp')
|
33
|
+
expect(payload).to have_key('iat')
|
34
|
+
expect(payload['aud']).to eql user_payload['aud']
|
35
|
+
expect(payload['data']).to eql user_payload['data']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'send request' do
|
40
|
+
let(:url) { 'http://localhost' }
|
41
|
+
let(:request) { Protocol.build_request(crypto, user_payload) }
|
42
|
+
let(:peer_wif_key) { 'L13zZXQnhgAHuQ8n5GkSasMitEoHFWxV3MC3xJ4U66NJWt2uyNA2' }
|
43
|
+
let(:peer_public_key) { '1CAnfBknvhbrpoRmGjRtZ8WsXjMg22wgLf' }
|
44
|
+
let(:jwt_stub) { JWTStub.new(peer_wif_key, url, user_payload['aud']) }
|
45
|
+
|
46
|
+
it 'receive a valid response' do
|
47
|
+
jwt_stub.valid_response
|
48
|
+
response = request.send(url, 'POST')
|
49
|
+
header = response.header_to_h
|
50
|
+
payload = response.payload_to_h
|
51
|
+
expect(response.verify).to be_truthy
|
52
|
+
expect(header['kid']).to eql peer_public_key
|
53
|
+
expect(payload['aud']).to eql JWTStub::PAYLOAD['aud']
|
54
|
+
expect(payload['data']).to eql JWTStub::PAYLOAD['data']
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'receive an invalid response (tampered payload)' do
|
58
|
+
jwt_stub.invalid_response
|
59
|
+
response = request.send(url, 'POST')
|
60
|
+
expect(response.verify).to be_falsey
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'receive a protocol error' do
|
64
|
+
jwt_stub.protocol_error
|
65
|
+
expect{request.send(url, 'POST')}.to raise_error(BitJWT::ProtocolError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'get explict error from exception' do
|
69
|
+
jwt_stub.protocol_error
|
70
|
+
begin
|
71
|
+
request.send(url, 'POST')
|
72
|
+
rescue BitJWT::ProtocolError => e
|
73
|
+
expect(e.status).to eql JWTStub::STATUS_ERROR
|
74
|
+
expect(e.body).to eql JWTStub::PAYLOAD_ERROR.to_json
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
require File.expand_path('../lib/bitjwt.rb', File.dirname(__FILE__))
|
3
|
+
require 'stubs/jwt_stub'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.order = 'random'
|
7
|
+
config.filter_run focus: true
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.mock_with :rspec do |mocks|
|
10
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
11
|
+
# a real object. This is generally recommended, and will default to
|
12
|
+
# `true` in RSpec 4.
|
13
|
+
mocks.verify_partial_doubles = true
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module BitJWT
|
2
|
+
class JWTStub
|
3
|
+
attr_reader :crypto, :base_url
|
4
|
+
|
5
|
+
PAYLOAD = {
|
6
|
+
'aud' => '/response',
|
7
|
+
'data' => {
|
8
|
+
'field1' => 'text1',
|
9
|
+
'field2' => 'text2'
|
10
|
+
}
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
STATUS_ERROR = 400.freeze
|
14
|
+
PAYLOAD_ERROR = {
|
15
|
+
'error' => 'data invalid'
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def initialize(private_key, url, endpoint)
|
19
|
+
@crypto = BitJWT::Crypto.new(private_key)
|
20
|
+
@base_url = url + endpoint
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_response
|
24
|
+
protocol = BitJWT::Protocol.build_request(crypto, JWTStub::PAYLOAD)
|
25
|
+
returned_payload = "#{protocol.header_payload_encoded}.#{protocol.signature_encoded}"
|
26
|
+
WebMock.stub_request(:post, base_url)
|
27
|
+
.to_return(status: 200, body: returned_payload, headers: {})
|
28
|
+
end
|
29
|
+
|
30
|
+
def invalid_response
|
31
|
+
protocol = BitJWT::Protocol.build_request(crypto, JWTStub::PAYLOAD)
|
32
|
+
returned_payload = "#{protocol.header_payload_encoded}X11111.#{protocol.signature_encoded}"
|
33
|
+
WebMock.stub_request(:post, base_url)
|
34
|
+
.to_return(status: 200, body: returned_payload, headers: {})
|
35
|
+
end
|
36
|
+
|
37
|
+
def protocol_error
|
38
|
+
WebMock.stub_request(:post, base_url)
|
39
|
+
.to_return(status: STATUS_ERROR, body: PAYLOAD_ERROR.to_json, headers: {})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitjwt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Federico Barbazza
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bitcoin-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.8
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.8
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: excon
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.49'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.49'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-mocks
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.1'
|
97
|
+
description: JWT protocol implementation using Bitcoin secp256k1
|
98
|
+
email: federico.barbazza@gmail.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- ".gitignore"
|
104
|
+
- Gemfile
|
105
|
+
- Gemfile.lock
|
106
|
+
- README.md
|
107
|
+
- bitjwt.gemspec
|
108
|
+
- lib/bitjwt.rb
|
109
|
+
- lib/bitjwt/crypto.rb
|
110
|
+
- lib/bitjwt/protocol.rb
|
111
|
+
- lib/bitjwt/protocol_error.rb
|
112
|
+
- lib/bitjwt/util.rb
|
113
|
+
- lib/bitjwt/version.rb
|
114
|
+
- spec/lib/crypto_spec.rb
|
115
|
+
- spec/lib/protocol_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
- spec/stubs/jwt_stub.rb
|
118
|
+
homepage: http://rubygems.org/gems/bitjwt
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.4.5.1
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Bitcoin JWT implementation
|
142
|
+
test_files:
|
143
|
+
- spec/lib/crypto_spec.rb
|
144
|
+
- spec/lib/protocol_spec.rb
|
145
|
+
- spec/spec_helper.rb
|
146
|
+
- spec/stubs/jwt_stub.rb
|