cose 0.8.0 → 1.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 +4 -4
- data/.gitmodules +3 -0
- data/.rspec +1 -1
- data/.rubocop.yml +4 -5
- data/.travis.yml +7 -17
- data/Appraisals +6 -0
- data/CHANGELOG.md +48 -0
- data/README.md +30 -33
- data/SECURITY.md +2 -2
- data/bin/setup +2 -0
- data/cose.gemspec +6 -5
- data/gemfiles/openssl_2_2.gemfile +7 -0
- data/lib/cose.rb +1 -0
- data/lib/cose/algorithm.rb +40 -0
- data/lib/cose/algorithm/base.rb +14 -0
- data/lib/cose/algorithm/ecdsa.rb +44 -0
- data/lib/cose/algorithm/hmac.rb +40 -0
- data/lib/cose/algorithm/rsa_pss.rb +43 -0
- data/lib/cose/algorithm/signature_algorithm.rb +57 -0
- data/lib/cose/encrypt.rb +2 -0
- data/lib/cose/encrypt0.rb +2 -0
- data/lib/cose/error.rb +5 -0
- data/lib/cose/key.rb +15 -4
- data/lib/cose/key/base.rb +2 -4
- data/lib/cose/key/curve.rb +2 -0
- data/lib/cose/key/curve_key.rb +3 -5
- data/lib/cose/key/ec2.rb +3 -5
- data/lib/cose/key/rsa.rb +4 -6
- data/lib/cose/key/symmetric.rb +1 -1
- data/lib/cose/mac.rb +29 -12
- data/lib/cose/mac0.rb +24 -1
- data/lib/cose/recipient.rb +2 -0
- data/lib/cose/security_message.rb +49 -4
- data/lib/cose/security_message/headers.rb +31 -0
- data/lib/cose/sign.rb +35 -1
- data/lib/cose/sign1.rb +24 -1
- data/lib/cose/signature.rb +2 -0
- data/lib/cose/version.rb +1 -1
- metadata +38 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef03f2ea3b2f4f4bb8f81fdd777cf3ae3905e1eae953599f0e6b0feca89343f5
|
4
|
+
data.tar.gz: 94db44b9a0a449bdb81ae9274fb193365838ec84f9df3db3540dcf5eb1ca3303
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17492d5ba3f7fce248418a158d29419392f9d849f33421d7b6192e61e021e5d62ca14f6a42721a05e77e31dfc67ef267c18e8be7138360a9146e359e5cb5b740
|
7
|
+
data.tar.gz: 49834d1df018a49669dfc02b8548c30f2aedf99fbad979cd072ee480eff99e9b6076e74654cfff72e6d6a6da96798d1de7902497f19f70e53b6464ac5a7d716a
|
data/.gitmodules
ADDED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
@@ -6,7 +6,7 @@ inherit_mode:
|
|
6
6
|
- Exclude
|
7
7
|
|
8
8
|
AllCops:
|
9
|
-
TargetRubyVersion: 2.
|
9
|
+
TargetRubyVersion: 2.4
|
10
10
|
DisabledByDefault: true
|
11
11
|
Exclude:
|
12
12
|
- "gemfiles/**/*"
|
@@ -20,13 +20,12 @@ Gemspec:
|
|
20
20
|
Layout:
|
21
21
|
Enabled: true
|
22
22
|
|
23
|
+
Layout/LineLength:
|
24
|
+
Max: 120
|
25
|
+
|
23
26
|
Lint:
|
24
27
|
Enabled: true
|
25
28
|
|
26
|
-
Metrics/LineLength:
|
27
|
-
Max: 120
|
28
|
-
IgnoreCopDirectives: true
|
29
|
-
|
30
29
|
Naming:
|
31
30
|
Enabled: true
|
32
31
|
|
data/.travis.yml
CHANGED
@@ -1,35 +1,25 @@
|
|
1
|
-
|
1
|
+
dist: bionic
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
4
|
|
5
5
|
rvm:
|
6
6
|
- ruby-head
|
7
|
-
- 2.7.
|
8
|
-
- 2.6.
|
9
|
-
- 2.5.
|
10
|
-
- 2.4.
|
11
|
-
- 2.3.8
|
12
|
-
- 2.2.10
|
7
|
+
- 2.7.1
|
8
|
+
- 2.6.6
|
9
|
+
- 2.5.8
|
10
|
+
- 2.4.10
|
13
11
|
|
14
12
|
gemfile:
|
15
13
|
- gemfiles/openssl_head.gemfile
|
14
|
+
- gemfiles/openssl_2_2.gemfile
|
16
15
|
- gemfiles/openssl_2_1.gemfile
|
17
16
|
- gemfiles/openssl_2_0.gemfile
|
18
17
|
- gemfiles/openssl_default.gemfile
|
19
18
|
|
20
|
-
before_install: gem install bundler -v '~>
|
19
|
+
before_install: gem install bundler -v '~> 2.0'
|
21
20
|
|
22
21
|
matrix:
|
23
22
|
fast_finish: true
|
24
23
|
allow_failures:
|
25
24
|
- rvm: ruby-head
|
26
|
-
- rvm: 2.7.0-preview1
|
27
|
-
- rvm: 2.2.10
|
28
25
|
- gemfile: gemfiles/openssl_head.gemfile
|
29
|
-
exclude:
|
30
|
-
- rvm: 2.2.10
|
31
|
-
gemfile: gemfiles/openssl_head.gemfile
|
32
|
-
- rvm: 2.2.10
|
33
|
-
gemfile: gemfiles/openssl_2_1.gemfile
|
34
|
-
- rvm: 2.2.10
|
35
|
-
gemfile: gemfiles/openssl_2_0.gemfile
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,48 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.1.0] - 2020-07-09
|
4
|
+
|
5
|
+
### Dependencies
|
6
|
+
|
7
|
+
- Update `openssl-signature_algorithm` runtime dependency from `~> 0.4.0` to `~> 1.0`.
|
8
|
+
|
9
|
+
## [v1.0.0] - 2020-03-29
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Signature verification validates key `alg` is compatible with the signature algorithm
|
14
|
+
|
15
|
+
NOTE: No breaking changes. Moving out of `v0.x` to express the intention to keep the public API stable.
|
16
|
+
|
17
|
+
## [v0.11.0] - 2020-01-30
|
18
|
+
|
19
|
+
### Added
|
20
|
+
|
21
|
+
- Let others easily support more signature algorithms by making `COSE::Algorithm::SignatureAlgorithm` smarter
|
22
|
+
|
23
|
+
## [v0.10.0] - 2019-12-19
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
- Works on ruby 2.7 without throwing any warnings
|
28
|
+
- Simpler way to rescue key deserialization error, now possible to:
|
29
|
+
```rb
|
30
|
+
begin
|
31
|
+
COSE::Key.deserialize(cbor)
|
32
|
+
rescue COSE::KeyDeserializationError
|
33
|
+
# handle error
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
## [v0.9.0] - 2019-08-31
|
38
|
+
|
39
|
+
### Added
|
40
|
+
|
41
|
+
- `COSE::Sign1#verify`
|
42
|
+
- `COSE::Sign#verify`
|
43
|
+
- `COSE::Mac0#verify`
|
44
|
+
- `COSE::Mac#verify`
|
45
|
+
|
3
46
|
## [v0.8.0] - 2019-08-17
|
4
47
|
|
5
48
|
### Added
|
@@ -86,6 +129,11 @@
|
|
86
129
|
- EC2 key object
|
87
130
|
- Works with ruby 2.5
|
88
131
|
|
132
|
+
[v1.1.0]: https://github.com/cedarcode/cose-ruby/compare/v1.0.0...v1.1.0/
|
133
|
+
[v1.0.0]: https://github.com/cedarcode/cose-ruby/compare/v0.11.0...v1.0.0/
|
134
|
+
[v0.11.0]: https://github.com/cedarcode/cose-ruby/compare/v0.10.0...v0.11.0/
|
135
|
+
[v0.10.0]: https://github.com/cedarcode/cose-ruby/compare/v0.9.0...v0.10.0/
|
136
|
+
[v0.9.0]: https://github.com/cedarcode/cose-ruby/compare/v0.8.0...v0.9.0/
|
89
137
|
[v0.8.0]: https://github.com/cedarcode/cose-ruby/compare/v0.7.0...v0.8.0/
|
90
138
|
[v0.7.0]: https://github.com/cedarcode/cose-ruby/compare/v0.6.1...v0.7.0/
|
91
139
|
[v0.6.1]: https://github.com/cedarcode/cose-ruby/compare/v0.6.0...v0.6.1/
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# cose
|
1
|
+
# cose-ruby
|
2
2
|
|
3
|
-
Ruby implementation of RFC 8152 CBOR Object Signing and Encryption (COSE)
|
3
|
+
Ruby implementation of RFC [8152](https://tools.ietf.org/html/rfc8152) CBOR Object Signing and Encryption (COSE)
|
4
4
|
|
5
|
-
[](https://rubygems.org/gems/cose)
|
5
|
+
[](https://rubygems.org/gems/cose)
|
6
6
|
[](https://travis-ci.org/cedarcode/cose-ruby)
|
7
7
|
|
8
8
|
## Installation
|
@@ -145,15 +145,14 @@ cbor_data = "..."
|
|
145
145
|
|
146
146
|
sign = COSE::Sign.deserialize(cbor_data)
|
147
147
|
|
148
|
-
|
149
|
-
sign.
|
150
|
-
sign.payload
|
148
|
+
# Verify by doing (key should be a COSE::Key):
|
149
|
+
sign.verify(key)
|
151
150
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
151
|
+
# or, if externally supplied authenticated data exists:
|
152
|
+
sign.verify(key, external_aad)
|
153
|
+
|
154
|
+
# Then access payload
|
155
|
+
sign.payload
|
157
156
|
```
|
158
157
|
|
159
158
|
#### COSE_Sign1
|
@@ -163,10 +162,14 @@ cbor_data = "..."
|
|
163
162
|
|
164
163
|
sign1 = COSE::Sign1.deserialize(cbor_data)
|
165
164
|
|
166
|
-
|
167
|
-
sign1.
|
165
|
+
# Verify by doing (key should be a COSE::Key):
|
166
|
+
sign1.verify(key)
|
167
|
+
|
168
|
+
# or, if externally supplied authenticated data exists:
|
169
|
+
sign1.verify(key, external_aad)
|
170
|
+
|
171
|
+
# Then access payload
|
168
172
|
sign1.payload
|
169
|
-
sign1.signature
|
170
173
|
```
|
171
174
|
|
172
175
|
### MAC Objects
|
@@ -178,24 +181,14 @@ cbor_data = "..."
|
|
178
181
|
|
179
182
|
mac = COSE::Mac.deserialize(cbor_data)
|
180
183
|
|
181
|
-
|
182
|
-
mac.
|
183
|
-
mac.payload
|
184
|
-
mac.tag
|
184
|
+
# Verify by doing (key should be a COSE::Key::Symmetric):
|
185
|
+
mac.verify(key)
|
185
186
|
|
186
|
-
|
187
|
-
|
188
|
-
recipient.unprotected_headers
|
189
|
-
recipient.ciphertext
|
187
|
+
# or, if externally supplied authenticated data exists:
|
188
|
+
mac.verify(key, external_aad)
|
190
189
|
|
191
|
-
|
192
|
-
|
193
|
-
recipient.protected_headers
|
194
|
-
recipient.unprotected_headers
|
195
|
-
recipient.ciphertext
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
190
|
+
# Then access payload
|
191
|
+
mac.payload
|
199
192
|
```
|
200
193
|
|
201
194
|
#### COSE_Mac0
|
@@ -205,10 +198,14 @@ cbor_data = "..."
|
|
205
198
|
|
206
199
|
mac0 = COSE::Mac0.deserialize(cbor_data)
|
207
200
|
|
208
|
-
|
209
|
-
mac0.
|
201
|
+
# Verify by doing (key should be a COSE::Key::Symmetric):
|
202
|
+
mac0.verify(key)
|
203
|
+
|
204
|
+
# or, if externally supplied authenticated data exists:
|
205
|
+
mac0.verify(key, external_aad)
|
206
|
+
|
207
|
+
# Then access payload
|
210
208
|
mac0.payload
|
211
|
-
mac0.tag
|
212
209
|
```
|
213
210
|
|
214
211
|
### Encryption Objects
|
data/SECURITY.md
CHANGED
data/bin/setup
CHANGED
data/cose.gemspec
CHANGED
@@ -29,15 +29,16 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
|
-
spec.required_ruby_version = ">= 2.
|
32
|
+
spec.required_ruby_version = ">= 2.4"
|
33
33
|
|
34
34
|
spec.add_dependency "cbor", "~> 0.5.9"
|
35
|
+
spec.add_dependency "openssl-signature_algorithm", "~> 1.0"
|
35
36
|
|
36
37
|
spec.add_development_dependency "appraisal", "~> 2.2.0"
|
37
38
|
spec.add_development_dependency "bundler", ">= 1.17", "< 3"
|
38
|
-
spec.add_development_dependency "byebug", "
|
39
|
-
spec.add_development_dependency "rake", "~>
|
39
|
+
spec.add_development_dependency "byebug", "~> 11.0"
|
40
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
40
41
|
spec.add_development_dependency "rspec", "~> 3.8"
|
41
|
-
spec.add_development_dependency "rubocop", "0.
|
42
|
-
spec.add_development_dependency "rubocop-performance", "~> 1.
|
42
|
+
spec.add_development_dependency "rubocop", "0.80.1"
|
43
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.4"
|
43
44
|
end
|
data/lib/cose.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/ecdsa"
|
4
|
+
require "cose/algorithm/hmac"
|
5
|
+
require "cose/algorithm/rsa_pss"
|
6
|
+
|
7
|
+
module COSE
|
8
|
+
module Algorithm
|
9
|
+
@registered_by_id = {}
|
10
|
+
@registered_by_name = {}
|
11
|
+
|
12
|
+
def self.register(algorithm)
|
13
|
+
@registered_by_id[algorithm.id] = algorithm
|
14
|
+
@registered_by_name[algorithm.name] = algorithm
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find(id_or_name)
|
18
|
+
by_id(id_or_name) || by_name(id_or_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.by_id(id)
|
22
|
+
@registered_by_id[id]
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.by_name(name)
|
26
|
+
@registered_by_name[name]
|
27
|
+
end
|
28
|
+
|
29
|
+
register(ECDSA.new(-7, "ES256", hash_function: "SHA256"))
|
30
|
+
register(ECDSA.new(-35, "ES384", hash_function: "SHA384"))
|
31
|
+
register(ECDSA.new(-36, "ES512", hash_function: "SHA512"))
|
32
|
+
register(RSAPSS.new(-37, "PS256", hash_function: "SHA256", salt_length: 32))
|
33
|
+
register(RSAPSS.new(-38, "PS384", hash_function: "SHA384", salt_length: 48))
|
34
|
+
register(RSAPSS.new(-39, "PS512", hash_function: "SHA512", salt_length: 64))
|
35
|
+
register(HMAC.new(4, "HMAC 256/64", hash_function: "SHA256", tag_length: 64))
|
36
|
+
register(HMAC.new(5, "HMAC 256/256", hash_function: "SHA256", tag_length: 256))
|
37
|
+
register(HMAC.new(6, "HMAC 384/384", hash_function: "SHA384", tag_length: 384))
|
38
|
+
register(HMAC.new(7, "HMAC 512/512", hash_function: "SHA512", tag_length: 512))
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/signature_algorithm"
|
4
|
+
require "cose/error"
|
5
|
+
require "cose/key/ec2"
|
6
|
+
require "openssl"
|
7
|
+
require "openssl/signature_algorithm/ecdsa"
|
8
|
+
|
9
|
+
module COSE
|
10
|
+
module Algorithm
|
11
|
+
class ECDSA < SignatureAlgorithm
|
12
|
+
attr_reader :hash_function
|
13
|
+
|
14
|
+
def initialize(*args, hash_function:)
|
15
|
+
super(*args)
|
16
|
+
|
17
|
+
@hash_function = hash_function
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def valid_key?(key)
|
23
|
+
cose_key = to_cose_key(key)
|
24
|
+
|
25
|
+
cose_key.is_a?(COSE::Key::EC2) && (!cose_key.alg || cose_key.alg == id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def signature_algorithm_class
|
29
|
+
OpenSSL::SignatureAlgorithm::ECDSA
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_pkey(key)
|
33
|
+
case key
|
34
|
+
when COSE::Key::EC2
|
35
|
+
key.to_pkey
|
36
|
+
when OpenSSL::PKey::EC
|
37
|
+
key
|
38
|
+
else
|
39
|
+
raise(COSE::Error, "Incompatible key for algorithm")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/base"
|
4
|
+
require "openssl"
|
5
|
+
|
6
|
+
module COSE
|
7
|
+
module Algorithm
|
8
|
+
class HMAC < Base
|
9
|
+
BYTE_LENGTH = 8
|
10
|
+
|
11
|
+
attr_reader :hash_function, :tag_length
|
12
|
+
|
13
|
+
def initialize(*args, hash_function:, tag_length:)
|
14
|
+
super(*args)
|
15
|
+
|
16
|
+
@hash_function = hash_function
|
17
|
+
@tag_length = tag_length
|
18
|
+
end
|
19
|
+
|
20
|
+
def mac(key, to_be_signed)
|
21
|
+
mac = OpenSSL::HMAC.digest(hash_function, key, to_be_signed)
|
22
|
+
|
23
|
+
if tag_bytesize && tag_bytesize < mac.bytesize
|
24
|
+
mac.byteslice(0, tag_bytesize)
|
25
|
+
else
|
26
|
+
mac
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def tag_bytesize
|
33
|
+
@tag_bytesize ||=
|
34
|
+
if tag_length
|
35
|
+
tag_length / BYTE_LENGTH
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/signature_algorithm"
|
4
|
+
require "cose/key/rsa"
|
5
|
+
require "cose/error"
|
6
|
+
require "openssl"
|
7
|
+
require "openssl/signature_algorithm/rsapss"
|
8
|
+
|
9
|
+
module COSE
|
10
|
+
module Algorithm
|
11
|
+
class RSAPSS < SignatureAlgorithm
|
12
|
+
attr_reader :hash_function, :salt_length
|
13
|
+
|
14
|
+
def initialize(*args, hash_function:, salt_length:)
|
15
|
+
super(*args)
|
16
|
+
|
17
|
+
@hash_function = hash_function
|
18
|
+
@salt_length = salt_length
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def valid_key?(key)
|
24
|
+
to_cose_key(key).is_a?(COSE::Key::RSA)
|
25
|
+
end
|
26
|
+
|
27
|
+
def signature_algorithm_class
|
28
|
+
OpenSSL::SignatureAlgorithm::RSAPSS
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_pkey(key)
|
32
|
+
case key
|
33
|
+
when COSE::Key::RSA
|
34
|
+
key.to_pkey
|
35
|
+
when OpenSSL::PKey::RSA
|
36
|
+
key
|
37
|
+
else
|
38
|
+
raise(COSE::Error, "Incompatible key for algorithm")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/base"
|
4
|
+
require "cose/error"
|
5
|
+
|
6
|
+
module COSE
|
7
|
+
module Algorithm
|
8
|
+
class SignatureAlgorithm < Base
|
9
|
+
def verify(key, signature, verification_data)
|
10
|
+
compatible_key?(key) || raise(COSE::Error, "Incompatible key for signature verification")
|
11
|
+
valid_signature?(key, signature, verification_data) || raise(COSE::Error, "Signature verification failed")
|
12
|
+
end
|
13
|
+
|
14
|
+
def compatible_key?(key)
|
15
|
+
valid_key?(key) && to_pkey(key)
|
16
|
+
rescue COSE::Error
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def valid_signature?(key, signature, verification_data)
|
23
|
+
signature_algorithm = signature_algorithm_class.new(hash_function: hash_function)
|
24
|
+
signature_algorithm.verify_key = to_pkey(key)
|
25
|
+
|
26
|
+
begin
|
27
|
+
signature_algorithm.verify(signature, verification_data)
|
28
|
+
rescue OpenSSL::SignatureAlgorithm::Error
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_cose_key(key)
|
34
|
+
case key
|
35
|
+
when COSE::Key::Base
|
36
|
+
key
|
37
|
+
when OpenSSL::PKey::PKey
|
38
|
+
COSE::Key.from_pkey(key)
|
39
|
+
else
|
40
|
+
raise(COSE::Error, "Don't know how to transform #{key.class} to COSE::Key")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def signature_algorithm_class
|
45
|
+
raise NotImplementedError
|
46
|
+
end
|
47
|
+
|
48
|
+
def valid_key?(_key)
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_pkey(_key)
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/cose/encrypt.rb
CHANGED
data/lib/cose/encrypt0.rb
CHANGED
data/lib/cose/error.rb
ADDED
data/lib/cose/key.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cbor"
|
2
4
|
require "cose/key/ec2"
|
3
5
|
require "cose/key/okp"
|
@@ -6,7 +8,10 @@ require "cose/key/symmetric"
|
|
6
8
|
require "openssl"
|
7
9
|
|
8
10
|
module COSE
|
9
|
-
class
|
11
|
+
class Error < StandardError; end
|
12
|
+
class KeyDeserializationError < Error; end
|
13
|
+
class MalformedKeyError < KeyDeserializationError; end
|
14
|
+
class UnknownKeyType < KeyDeserializationError; end
|
10
15
|
|
11
16
|
module Key
|
12
17
|
def self.serialize(pkey)
|
@@ -25,7 +30,7 @@ module COSE
|
|
25
30
|
end
|
26
31
|
|
27
32
|
def self.deserialize(data)
|
28
|
-
map =
|
33
|
+
map = cbor_decode(data)
|
29
34
|
|
30
35
|
case map[Base::LABEL_KTY]
|
31
36
|
when COSE::Key::OKP::KTY_OKP
|
@@ -37,10 +42,16 @@ module COSE
|
|
37
42
|
when COSE::Key::Symmetric::KTY_SYMMETRIC
|
38
43
|
COSE::Key::Symmetric.from_map(map)
|
39
44
|
when nil
|
40
|
-
raise UnknownKeyType, "Missing required key type kty label"
|
45
|
+
raise COSE::UnknownKeyType, "Missing required key type kty label"
|
41
46
|
else
|
42
|
-
raise UnknownKeyType, "Unsupported or unknown key type #{map[Base::LABEL_KTY]}"
|
47
|
+
raise COSE::UnknownKeyType, "Unsupported or unknown key type #{map[Base::LABEL_KTY]}"
|
43
48
|
end
|
44
49
|
end
|
50
|
+
|
51
|
+
def self.cbor_decode(data)
|
52
|
+
CBOR.decode(data)
|
53
|
+
rescue CBOR::MalformedFormatError, EOFError, FloatDomainError, RegexpError, TypeError, URI::InvalidURIError
|
54
|
+
raise COSE::MalformedKeyError, "Malformed CBOR key input"
|
55
|
+
end
|
45
56
|
end
|
46
57
|
end
|
data/lib/cose/key/base.rb
CHANGED
data/lib/cose/key/curve.rb
CHANGED
data/lib/cose/key/curve_key.rb
CHANGED
@@ -20,7 +20,7 @@ module COSE
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
def initialize(crv:, x: nil, d: nil, **keyword_arguments) # rubocop:disable Naming/
|
23
|
+
def initialize(crv:, x: nil, d: nil, **keyword_arguments) # rubocop:disable Naming/MethodParameterName
|
24
24
|
super(**keyword_arguments)
|
25
25
|
|
26
26
|
if !crv
|
@@ -35,13 +35,11 @@ module COSE
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def map
|
38
|
-
|
38
|
+
super.merge(
|
39
39
|
LABEL_CRV => crv,
|
40
40
|
LABEL_X => x,
|
41
41
|
LABEL_D => d
|
42
|
-
)
|
43
|
-
|
44
|
-
map.reject { |_k, v| v.nil? }
|
42
|
+
).compact
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
data/lib/cose/key/ec2.rb
CHANGED
@@ -48,7 +48,7 @@ module COSE
|
|
48
48
|
|
49
49
|
attr_reader :y
|
50
50
|
|
51
|
-
def initialize(y: nil, **keyword_arguments) # rubocop:disable Naming/
|
51
|
+
def initialize(y: nil, **keyword_arguments) # rubocop:disable Naming/MethodParameterName
|
52
52
|
if (!y || !keyword_arguments[:x]) && !keyword_arguments[:d]
|
53
53
|
raise ArgumentError, "Both x and y are required if d is missing"
|
54
54
|
else
|
@@ -59,12 +59,10 @@ module COSE
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def map
|
62
|
-
|
62
|
+
super.merge(
|
63
63
|
Base::LABEL_KTY => KTY_EC2,
|
64
64
|
LABEL_Y => y,
|
65
|
-
)
|
66
|
-
|
67
|
-
map.reject { |_k, v| v.nil? }
|
65
|
+
).compact
|
68
66
|
end
|
69
67
|
|
70
68
|
def to_pkey
|
data/lib/cose/key/rsa.rb
CHANGED
@@ -42,12 +42,12 @@ module COSE
|
|
42
42
|
)
|
43
43
|
end
|
44
44
|
|
45
|
-
new(attributes)
|
45
|
+
new(**attributes)
|
46
46
|
end
|
47
47
|
|
48
48
|
attr_reader :n, :e, :d, :p, :q, :dp, :dq, :qinv
|
49
49
|
|
50
|
-
def initialize(n:, e:, d: nil, p: nil, q: nil, dp: nil, dq: nil, qinv: nil, **keyword_arguments) # rubocop:disable Naming/
|
50
|
+
def initialize(n:, e:, d: nil, p: nil, q: nil, dp: nil, dq: nil, qinv: nil, **keyword_arguments) # rubocop:disable Naming/MethodParameterName
|
51
51
|
super(**keyword_arguments)
|
52
52
|
|
53
53
|
if !n
|
@@ -74,7 +74,7 @@ module COSE
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def map
|
77
|
-
|
77
|
+
super.merge(
|
78
78
|
Base::LABEL_KTY => KTY_RSA,
|
79
79
|
LABEL_N => n,
|
80
80
|
LABEL_E => e,
|
@@ -84,9 +84,7 @@ module COSE
|
|
84
84
|
LABEL_DP => dp,
|
85
85
|
LABEL_DQ => dq,
|
86
86
|
LABEL_QINV => qinv
|
87
|
-
)
|
88
|
-
|
89
|
-
map.reject { |_k, v| v.nil? }
|
87
|
+
).compact
|
90
88
|
end
|
91
89
|
|
92
90
|
def to_pkey
|
data/lib/cose/key/symmetric.rb
CHANGED
data/lib/cose/mac.rb
CHANGED
@@ -1,25 +1,42 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "cose/recipient"
|
3
|
-
require "cose/
|
4
|
+
require "cose/mac0"
|
4
5
|
|
5
6
|
module COSE
|
6
|
-
class Mac <
|
7
|
-
|
7
|
+
class Mac < Mac0
|
8
|
+
CONTEXT = "MAC"
|
9
|
+
|
10
|
+
attr_reader :recipients
|
8
11
|
|
9
12
|
def self.keyword_arguments_for_initialize(decoded)
|
10
|
-
{
|
11
|
-
payload: CBOR.decode(decoded[0]),
|
12
|
-
tag: decoded[1],
|
13
|
-
recipients: decoded[2].map { |s| COSE::Recipient.deserialize(s) }
|
14
|
-
}
|
13
|
+
super.merge(recipients: decoded.last.map { |r| COSE::Recipient.from_array(r) })
|
15
14
|
end
|
16
15
|
|
17
|
-
def
|
16
|
+
def self.tag
|
17
|
+
97
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(recipients:, **keyword_arguments)
|
18
21
|
super(**keyword_arguments)
|
19
22
|
|
20
|
-
@payload = payload
|
21
|
-
@tag = tag
|
22
23
|
@recipients = recipients
|
23
24
|
end
|
25
|
+
|
26
|
+
def verify(key, external_aad = nil)
|
27
|
+
recipient = recipients.detect { |r| r.headers.kid == key.kid }
|
28
|
+
|
29
|
+
if recipient
|
30
|
+
super
|
31
|
+
else
|
32
|
+
raise(COSE::Error, "No recipient match the key")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def context
|
39
|
+
CONTEXT
|
40
|
+
end
|
24
41
|
end
|
25
42
|
end
|
data/lib/cose/mac0.rb
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cbor"
|
2
4
|
require "cose/security_message"
|
5
|
+
require "openssl"
|
3
6
|
|
4
7
|
module COSE
|
5
8
|
class Mac0 < SecurityMessage
|
9
|
+
CONTEXT = "MAC0"
|
10
|
+
|
6
11
|
attr_reader :payload, :tag
|
7
12
|
|
8
13
|
def self.keyword_arguments_for_initialize(decoded)
|
9
|
-
{ payload:
|
14
|
+
{ payload: decoded[0], tag: decoded[1] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.tag
|
18
|
+
17
|
10
19
|
end
|
11
20
|
|
12
21
|
def initialize(payload:, tag:, **keyword_arguments)
|
@@ -15,5 +24,19 @@ module COSE
|
|
15
24
|
@payload = payload
|
16
25
|
@tag = tag
|
17
26
|
end
|
27
|
+
|
28
|
+
def verify(key, external_aad = nil)
|
29
|
+
tag == algorithm.mac(key.k, data(external_aad)) || raise(COSE::Error, "Mac0 verification failed")
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def data(external_aad = nil)
|
35
|
+
CBOR.encode([context, serialized_map(protected_headers), external_aad || zero_length_bin_string, payload])
|
36
|
+
end
|
37
|
+
|
38
|
+
def context
|
39
|
+
CONTEXT
|
40
|
+
end
|
18
41
|
end
|
19
42
|
end
|
data/lib/cose/recipient.rb
CHANGED
@@ -1,26 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cbor"
|
4
|
+
require "cose/algorithm"
|
5
|
+
require "cose/error"
|
6
|
+
require "cose/security_message/headers"
|
2
7
|
|
3
8
|
module COSE
|
4
9
|
class SecurityMessage
|
10
|
+
ZERO_LENGTH_BIN_STRING = "".b
|
11
|
+
|
5
12
|
attr_reader :protected_headers, :unprotected_headers
|
6
13
|
|
7
14
|
def self.deserialize(cbor)
|
8
15
|
decoded = CBOR.decode(cbor)
|
9
16
|
|
10
|
-
if decoded.
|
17
|
+
if decoded.is_a?(CBOR::Tagged)
|
18
|
+
if respond_to?(:tag) && tag != decoded.tag
|
19
|
+
raise(COSE::Error, "Invalid CBOR tag")
|
20
|
+
end
|
21
|
+
|
11
22
|
decoded = decoded.value
|
12
23
|
end
|
13
24
|
|
25
|
+
from_array(decoded)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.from_array(array)
|
14
29
|
new(
|
15
|
-
protected_headers:
|
16
|
-
unprotected_headers:
|
17
|
-
**keyword_arguments_for_initialize(
|
30
|
+
protected_headers: deserialize_headers(array[0]),
|
31
|
+
unprotected_headers: array[1],
|
32
|
+
**keyword_arguments_for_initialize(array[2..-1])
|
18
33
|
)
|
19
34
|
end
|
20
35
|
|
36
|
+
def self.deserialize_headers(data)
|
37
|
+
if data == ZERO_LENGTH_BIN_STRING
|
38
|
+
{}
|
39
|
+
else
|
40
|
+
CBOR.decode(data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
21
44
|
def initialize(protected_headers:, unprotected_headers:)
|
22
45
|
@protected_headers = protected_headers
|
23
46
|
@unprotected_headers = unprotected_headers
|
24
47
|
end
|
48
|
+
|
49
|
+
def algorithm
|
50
|
+
@algorithm ||= COSE::Algorithm.find(headers.alg) || raise(COSE::Error, "Unsupported algorithm '#{headers.alg}'")
|
51
|
+
end
|
52
|
+
|
53
|
+
def headers
|
54
|
+
@headers ||= Headers.new(protected_headers, unprotected_headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def serialized_map(map)
|
60
|
+
if map && !map.empty?
|
61
|
+
map.to_cbor
|
62
|
+
else
|
63
|
+
zero_length_bin_string
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def zero_length_bin_string
|
68
|
+
ZERO_LENGTH_BIN_STRING
|
69
|
+
end
|
25
70
|
end
|
26
71
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module COSE
|
4
|
+
class SecurityMessage
|
5
|
+
class Headers
|
6
|
+
HEADER_LABEL_ALG = 1
|
7
|
+
HEADER_LABEL_KID = 4
|
8
|
+
|
9
|
+
attr_reader :protected_bucket, :unprotected_bucket
|
10
|
+
|
11
|
+
def initialize(protected_bucket, unprotected_bucket)
|
12
|
+
@protected_bucket = protected_bucket
|
13
|
+
@unprotected_bucket = unprotected_bucket
|
14
|
+
end
|
15
|
+
|
16
|
+
def alg
|
17
|
+
header(HEADER_LABEL_ALG)
|
18
|
+
end
|
19
|
+
|
20
|
+
def kid
|
21
|
+
header(HEADER_LABEL_KID)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def header(label)
|
27
|
+
protected_bucket[label] || unprotected_bucket[label]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/cose/sign.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cbor"
|
4
|
+
require "cose/error"
|
2
5
|
require "cose/security_message"
|
3
6
|
require "cose/signature"
|
4
7
|
|
5
8
|
module COSE
|
6
9
|
class Sign < SecurityMessage
|
10
|
+
CONTEXT = "Signature"
|
11
|
+
|
7
12
|
attr_reader :payload, :signatures
|
8
13
|
|
9
14
|
def self.keyword_arguments_for_initialize(decoded)
|
10
|
-
{ payload:
|
15
|
+
{ payload: decoded[0], signatures: decoded[1].map { |s| COSE::Signature.from_array(s) } }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tag
|
19
|
+
98
|
11
20
|
end
|
12
21
|
|
13
22
|
def initialize(payload:, signatures:, **keyword_arguments)
|
@@ -16,5 +25,30 @@ module COSE
|
|
16
25
|
@payload = payload
|
17
26
|
@signatures = signatures
|
18
27
|
end
|
28
|
+
|
29
|
+
def verify(key, external_aad = nil)
|
30
|
+
signature = signatures.detect { |s| s.headers.kid == key.kid }
|
31
|
+
|
32
|
+
if signature
|
33
|
+
signature.algorithm.verify(key, signature.signature, verification_data(signature, external_aad))
|
34
|
+
else
|
35
|
+
raise(COSE::Error, "No signature matches key kid")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def verification_data(signature, external_aad = nil)
|
42
|
+
@verification_data ||=
|
43
|
+
CBOR.encode(
|
44
|
+
[
|
45
|
+
CONTEXT,
|
46
|
+
serialized_map(protected_headers),
|
47
|
+
serialized_map(signature.protected_headers),
|
48
|
+
external_aad || ZERO_LENGTH_BIN_STRING,
|
49
|
+
payload
|
50
|
+
]
|
51
|
+
)
|
52
|
+
end
|
19
53
|
end
|
20
54
|
end
|
data/lib/cose/sign1.rb
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cbor"
|
4
|
+
require "cose/error"
|
2
5
|
require "cose/security_message"
|
3
6
|
|
4
7
|
module COSE
|
5
8
|
class Sign1 < SecurityMessage
|
9
|
+
CONTEXT = "Signature1"
|
10
|
+
|
6
11
|
attr_reader :payload, :signature
|
7
12
|
|
8
13
|
def self.keyword_arguments_for_initialize(decoded)
|
9
|
-
{ payload:
|
14
|
+
{ payload: decoded[0], signature: decoded[1] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.tag
|
18
|
+
18
|
10
19
|
end
|
11
20
|
|
12
21
|
def initialize(payload:, signature:, **keyword_arguments)
|
@@ -15,5 +24,19 @@ module COSE
|
|
15
24
|
@payload = payload
|
16
25
|
@signature = signature
|
17
26
|
end
|
27
|
+
|
28
|
+
def verify(key, external_aad = nil)
|
29
|
+
if key.kid == headers.kid
|
30
|
+
algorithm.verify(key, signature, verification_data(external_aad))
|
31
|
+
else
|
32
|
+
raise(COSE::Error, "Non matching kid")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def verification_data(external_aad = nil)
|
39
|
+
CBOR.encode([CONTEXT, serialized_map(protected_headers), external_aad || ZERO_LENGTH_BIN_STRING, payload])
|
40
|
+
end
|
18
41
|
end
|
19
42
|
end
|
data/lib/cose/signature.rb
CHANGED
data/lib/cose/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gonzalo Rodriguez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cbor
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 0.5.9
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: openssl-signature_algorithm
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: appraisal
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,30 +77,30 @@ dependencies:
|
|
63
77
|
name: byebug
|
64
78
|
requirement: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - "
|
80
|
+
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '11.0'
|
69
83
|
type: :development
|
70
84
|
prerelease: false
|
71
85
|
version_requirements: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - "
|
87
|
+
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
89
|
+
version: '11.0'
|
76
90
|
- !ruby/object:Gem::Dependency
|
77
91
|
name: rake
|
78
92
|
requirement: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '13.0'
|
83
97
|
type: :development
|
84
98
|
prerelease: false
|
85
99
|
version_requirements: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
103
|
+
version: '13.0'
|
90
104
|
- !ruby/object:Gem::Dependency
|
91
105
|
name: rspec
|
92
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,28 +121,28 @@ dependencies:
|
|
107
121
|
requirements:
|
108
122
|
- - '='
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
124
|
+
version: 0.80.1
|
111
125
|
type: :development
|
112
126
|
prerelease: false
|
113
127
|
version_requirements: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - '='
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
131
|
+
version: 0.80.1
|
118
132
|
- !ruby/object:Gem::Dependency
|
119
133
|
name: rubocop-performance
|
120
134
|
requirement: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '1.
|
138
|
+
version: '1.4'
|
125
139
|
type: :development
|
126
140
|
prerelease: false
|
127
141
|
version_requirements: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - "~>"
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '1.
|
145
|
+
version: '1.4'
|
132
146
|
description:
|
133
147
|
email:
|
134
148
|
- gonzalo@cedarcode.com
|
@@ -138,6 +152,7 @@ extensions: []
|
|
138
152
|
extra_rdoc_files: []
|
139
153
|
files:
|
140
154
|
- ".gitignore"
|
155
|
+
- ".gitmodules"
|
141
156
|
- ".rspec"
|
142
157
|
- ".rubocop.yml"
|
143
158
|
- ".travis.yml"
|
@@ -153,11 +168,19 @@ files:
|
|
153
168
|
- cose.gemspec
|
154
169
|
- gemfiles/openssl_2_0.gemfile
|
155
170
|
- gemfiles/openssl_2_1.gemfile
|
171
|
+
- gemfiles/openssl_2_2.gemfile
|
156
172
|
- gemfiles/openssl_default.gemfile
|
157
173
|
- gemfiles/openssl_head.gemfile
|
158
174
|
- lib/cose.rb
|
175
|
+
- lib/cose/algorithm.rb
|
176
|
+
- lib/cose/algorithm/base.rb
|
177
|
+
- lib/cose/algorithm/ecdsa.rb
|
178
|
+
- lib/cose/algorithm/hmac.rb
|
179
|
+
- lib/cose/algorithm/rsa_pss.rb
|
180
|
+
- lib/cose/algorithm/signature_algorithm.rb
|
159
181
|
- lib/cose/encrypt.rb
|
160
182
|
- lib/cose/encrypt0.rb
|
183
|
+
- lib/cose/error.rb
|
161
184
|
- lib/cose/key.rb
|
162
185
|
- lib/cose/key/base.rb
|
163
186
|
- lib/cose/key/curve.rb
|
@@ -170,6 +193,7 @@ files:
|
|
170
193
|
- lib/cose/mac0.rb
|
171
194
|
- lib/cose/recipient.rb
|
172
195
|
- lib/cose/security_message.rb
|
196
|
+
- lib/cose/security_message/headers.rb
|
173
197
|
- lib/cose/sign.rb
|
174
198
|
- lib/cose/sign1.rb
|
175
199
|
- lib/cose/signature.rb
|
@@ -189,14 +213,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
189
213
|
requirements:
|
190
214
|
- - ">="
|
191
215
|
- !ruby/object:Gem::Version
|
192
|
-
version: '2.
|
216
|
+
version: '2.4'
|
193
217
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
218
|
requirements:
|
195
219
|
- - ">="
|
196
220
|
- !ruby/object:Gem::Version
|
197
221
|
version: '0'
|
198
222
|
requirements: []
|
199
|
-
rubygems_version: 3.
|
223
|
+
rubygems_version: 3.1.4
|
200
224
|
signing_key:
|
201
225
|
specification_version: 4
|
202
226
|
summary: Ruby implementation of RFC 8152 CBOR Object Signing and Encryption (COSE)
|