nkeys 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 +7 -0
- data/lib/nkeys.rb +116 -0
- data/lib/nkeys/crc16.rb +64 -0
- data/lib/nkeys/keypair.rb +91 -0
- data/lib/nkeys/version.rb +16 -0
- data/nkeys.gemspec +40 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 14f5eb34b132d8bbe6d8e058766d82e6f3eb4579aa14abb2327932e4ec53a343
|
4
|
+
data.tar.gz: 660dfbc5cf39956ef0e7f0d37bf5ad7699b7eedba2527ef6ab2fbe407dbd97bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce9433466b8f6d734b4291ccc899fe951632dc171bddc7c04d95c2787440650eb2a0662e6d0659f9260225862c248ed91c9c8e15abeeae77f6c386beab653188
|
7
|
+
data.tar.gz: a812e1099ded76d6e66155670ae12c9cf2dbd70254909bd2e8d73b811bd3f35032cc87ab237dedfc88768aa5c41f056c68c5262ecdbbc78c900925954cd7a93e
|
data/lib/nkeys.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Copyright 2018 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
require 'base32'
|
15
|
+
require_relative 'nkeys/keypair'
|
16
|
+
|
17
|
+
module NKEYS
|
18
|
+
|
19
|
+
# PREFIX_BYTE_SEED is the version byte used for encoded NATS Seeds
|
20
|
+
PREFIX_BYTE_SEED = 18 << 3 # Base32-encodes to 'S...'
|
21
|
+
|
22
|
+
# PREFIX_BYTE_PRIVATE is the version byte used for encoded NATS Private keys
|
23
|
+
PREFIX_BYTE_PRIVATE = 15 << 3 # Base32-encodes to 'P...'
|
24
|
+
|
25
|
+
# PREFIX_BYTE_SERVER is the version byte used for encoded NATS Servers
|
26
|
+
PREFIX_BYTE_SERVER = 13 << 3 # Base32-encodes to 'N...'
|
27
|
+
|
28
|
+
# PREFIX_BYTE_CLUSTER is the version byte used for encoded NATS Clusters
|
29
|
+
PREFIX_BYTE_CLUSTER = 2 << 3 # Base32-encodes to 'C...'
|
30
|
+
|
31
|
+
# PREFIX_BYTE_OPERATOR is the version byte used for encoded NATS Operators
|
32
|
+
PREFIX_BYTE_OPERATOR = 14 << 3 # Base32-encodes to 'O...'
|
33
|
+
|
34
|
+
# PREFIX_BYTE_ACCOUNT is the version byte used for encoded NATS Accounts
|
35
|
+
PREFIX_BYTE_ACCOUNT = 0 # Base32-encodes to 'A...'
|
36
|
+
|
37
|
+
# PREFIX_BYTE_USER is the version byte used for encoded NATS Users
|
38
|
+
PREFIX_BYTE_USER = 20 << 3 # Base32-encodes to 'U...'
|
39
|
+
|
40
|
+
class << self
|
41
|
+
|
42
|
+
# Create a keypair to use for signing from a seed.
|
43
|
+
# @param [String] seed The seed from which can create a public/private KeyPair.
|
44
|
+
def from_seed(seed)
|
45
|
+
_, raw_seed = decode_seed(seed)
|
46
|
+
keys = Ed25519::SigningKey.new(raw_seed)
|
47
|
+
|
48
|
+
KeyPair.new(seed: seed, keys: keys)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create a keypair capable of verifying signatures.
|
52
|
+
# @param [String] public_key The public key to create the KeyPair.
|
53
|
+
def from_public_key(public_key)
|
54
|
+
KeyPair.new(public_key: public_key)
|
55
|
+
end
|
56
|
+
|
57
|
+
def decode_seed(src)
|
58
|
+
if src.nil? || src.empty?
|
59
|
+
raise NKEYS::InvalidSeed, "nkeys: Invalid Seed"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Take the encoded seed if provided and generate the private and public keys,
|
63
|
+
# since both are needed to be able to sign things.
|
64
|
+
raw = nil
|
65
|
+
begin
|
66
|
+
base32_decoded = Base32.decode(src).bytes
|
67
|
+
raw = base32_decoded[0...(base32_decoded.size-2)]
|
68
|
+
rescue
|
69
|
+
raise NKEYS::InvalidSeed, "nkeys: Invalid Seed"
|
70
|
+
end
|
71
|
+
|
72
|
+
# 248 = 11111000
|
73
|
+
b1 = raw[0] & 248
|
74
|
+
|
75
|
+
# 7 = 00000111
|
76
|
+
b2 = (raw[0] & 7) << 5 | ((raw[1] & 248) >> 3)
|
77
|
+
|
78
|
+
if b1 != PREFIX_BYTE_SEED
|
79
|
+
raise NKEYS::InvalidSeed, "nkeys: Invalid Seed"
|
80
|
+
elsif !valid_public_prefix_byte(b2)
|
81
|
+
raise NKEYS::InvalidPrefixByte, "nkeys: Invalid Prefix Byte"
|
82
|
+
end
|
83
|
+
|
84
|
+
prefix = b2
|
85
|
+
result = raw[2..(raw.size)].pack('c*')
|
86
|
+
|
87
|
+
[prefix, result]
|
88
|
+
end
|
89
|
+
|
90
|
+
def valid_public_prefix_byte(prefix)
|
91
|
+
case
|
92
|
+
when prefix == PREFIX_BYTE_OPERATOR; true
|
93
|
+
when prefix == PREFIX_BYTE_SERVER; true
|
94
|
+
when prefix == PREFIX_BYTE_CLUSTER; true
|
95
|
+
when prefix == PREFIX_BYTE_ACCOUNT; true
|
96
|
+
when prefix == PREFIX_BYTE_USER; true
|
97
|
+
else
|
98
|
+
false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def valid_prefix_byte(prefix)
|
103
|
+
case
|
104
|
+
when prefix == PREFIX_BYTE_OPERATOR; true
|
105
|
+
when prefix == PREFIX_BYTE_SERVER; true
|
106
|
+
when prefix == PREFIX_BYTE_CLUSTER; true
|
107
|
+
when prefix == PREFIX_BYTE_ACCOUNT; true
|
108
|
+
when prefix == PREFIX_BYTE_USER; true
|
109
|
+
when prefix == PREFIX_BYTE_SEED; true
|
110
|
+
when prefix == PREFIX_BYTE_PRIVATE; true
|
111
|
+
else
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/nkeys/crc16.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright 2018 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module NKEYS
|
16
|
+
class << self
|
17
|
+
|
18
|
+
def crc16(data)
|
19
|
+
crc = 0
|
20
|
+
data.each do |b|
|
21
|
+
crc = ((crc << 8) & 0xffff) ^ CRC16TAB[((crc>>8)^b)&0x00FF]
|
22
|
+
end
|
23
|
+
|
24
|
+
crc
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
CRC16TAB = [
|
30
|
+
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
31
|
+
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
32
|
+
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
33
|
+
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
34
|
+
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
35
|
+
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
36
|
+
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
37
|
+
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
38
|
+
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
39
|
+
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
40
|
+
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
41
|
+
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
42
|
+
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
43
|
+
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
44
|
+
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
45
|
+
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
46
|
+
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
47
|
+
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
48
|
+
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
49
|
+
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
50
|
+
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
51
|
+
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
52
|
+
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
53
|
+
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
54
|
+
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
55
|
+
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
56
|
+
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
57
|
+
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
58
|
+
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
59
|
+
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
60
|
+
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
61
|
+
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
62
|
+
]
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
# Copyright 2018 The NATS Authors
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
#
|
15
|
+
require 'ed25519'
|
16
|
+
require 'base32'
|
17
|
+
require 'nkeys/version'
|
18
|
+
require 'nkeys/crc16'
|
19
|
+
|
20
|
+
module NKEYS
|
21
|
+
|
22
|
+
class Error < StandardError; end #:nodoc:
|
23
|
+
|
24
|
+
class InvalidSeed < Error; end #:nodoc:
|
25
|
+
|
26
|
+
class InvalidPrefixByte < Error; end #:nodoc:
|
27
|
+
|
28
|
+
class KeyPair
|
29
|
+
attr_reader :seed, :public_key, :private_key
|
30
|
+
|
31
|
+
def initialize(opts={})
|
32
|
+
@seed = opts[:seed]
|
33
|
+
@public_key = opts[:public_key]
|
34
|
+
@private_key = opts[:private_key]
|
35
|
+
@keys = opts[:keys]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sign will sign the input with KeyPair's private key.
|
39
|
+
# @param [String] input
|
40
|
+
# @return [String] signed raw data
|
41
|
+
def sign(input)
|
42
|
+
raise ::NKEYS::Error, "nkeys: Missing keys for signing" if @keys.nil?
|
43
|
+
|
44
|
+
@keys.sign(input)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Verify the input againt a signature utilizing the public key.
|
48
|
+
# @param [String] input
|
49
|
+
# @param [String] sig
|
50
|
+
# @return [Bool] the result of verifying the signed input.
|
51
|
+
def verify(input, sig)
|
52
|
+
# TODO
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
def public_key
|
57
|
+
return @public_key unless @public_key.nil?
|
58
|
+
# TODO: If no keys present then try to generate from seed.
|
59
|
+
# prefix, public_raw = ::NATS::NKEYS::decode_seed(@seed)
|
60
|
+
|
61
|
+
pk = @keys.verify_key.to_bytes.unpack("C*")
|
62
|
+
pk.prepend(PREFIX_BYTE_USER)
|
63
|
+
|
64
|
+
# Include crc16 checksum.
|
65
|
+
crc16 = NKEYS::crc16(pk)
|
66
|
+
crc16_suffix = [crc16].pack("s<*")
|
67
|
+
crc16_suffix.each_byte do |b|
|
68
|
+
pk << b
|
69
|
+
end
|
70
|
+
res = pk.pack("c*")
|
71
|
+
|
72
|
+
# Remove padding since Base32 library always uses padding...
|
73
|
+
@public_key = Base32.encode(res).gsub("=", '')
|
74
|
+
|
75
|
+
@public_key
|
76
|
+
end
|
77
|
+
|
78
|
+
def private_key
|
79
|
+
return @private_key unless @private_key.nil?
|
80
|
+
# TODO
|
81
|
+
end
|
82
|
+
|
83
|
+
def wipe
|
84
|
+
@seed.clear if @seed
|
85
|
+
@public_key.clear if @public_key
|
86
|
+
@private_key.clear if @private_key
|
87
|
+
@keys = nil
|
88
|
+
end
|
89
|
+
alias_method :wipe!, :wipe
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright 2018 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
module NKEYS
|
15
|
+
VERSION = "0.1.0"
|
16
|
+
end
|
data/nkeys.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright 2010-2018 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
lib = File.expand_path('../lib/', __FILE__)
|
16
|
+
$:.unshift lib unless $:.include?(lib)
|
17
|
+
|
18
|
+
require File.expand_path('../lib/nkeys/version', __FILE__)
|
19
|
+
|
20
|
+
spec = Gem::Specification.new do |s|
|
21
|
+
s.name = 'nkeys'
|
22
|
+
s.version = NKEYS::VERSION
|
23
|
+
s.summary = 'NKEYS for Ruby'
|
24
|
+
s.homepage = 'https://nats.io'
|
25
|
+
s.description = 'NATS Keys for Ruby'
|
26
|
+
s.licenses = ['MIT']
|
27
|
+
s.authors = ['Waldemar Quevedo']
|
28
|
+
s.email = ['wally@synadia.com']
|
29
|
+
s.add_dependency('ed25519', '~> 1.2')
|
30
|
+
s.add_dependency('base32', '~> 0.3')
|
31
|
+
s.require_paths = ['lib']
|
32
|
+
|
33
|
+
s.files = %w[
|
34
|
+
nkeys.gemspec
|
35
|
+
lib/nkeys.rb
|
36
|
+
lib/nkeys/crc16.rb
|
37
|
+
lib/nkeys/keypair.rb
|
38
|
+
lib/nkeys/version.rb
|
39
|
+
]
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nkeys
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Waldemar Quevedo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-06-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ed25519
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: base32
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.3'
|
41
|
+
description: NATS Keys for Ruby
|
42
|
+
email:
|
43
|
+
- wally@synadia.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/nkeys.rb
|
49
|
+
- lib/nkeys/crc16.rb
|
50
|
+
- lib/nkeys/keypair.rb
|
51
|
+
- lib/nkeys/version.rb
|
52
|
+
- nkeys.gemspec
|
53
|
+
homepage: https://nats.io
|
54
|
+
licenses:
|
55
|
+
- MIT
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubygems_version: 3.0.2
|
73
|
+
signing_key:
|
74
|
+
specification_version: 4
|
75
|
+
summary: NKEYS for Ruby
|
76
|
+
test_files: []
|