cose 1.2.0 → 1.3.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/.github/workflows/build.yml +42 -0
- data/Appraisals +2 -6
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/gemfiles/{openssl_2_0.gemfile → openssl_3_0.gemfile} +1 -1
- data/lib/cose/algorithm/eddsa.rb +41 -0
- data/lib/cose/algorithm.rb +2 -0
- data/lib/cose/key/curve.rb +2 -0
- data/lib/cose/key/ec2.rb +27 -4
- data/lib/cose/key/okp.rb +48 -0
- data/lib/cose/key/rsa.rb +23 -22
- data/lib/cose/key.rb +2 -0
- data/lib/cose/version.rb +1 -1
- metadata +10 -10
- data/.travis.yml +0 -25
- data/gemfiles/openssl_head.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a7da6d20b462494510800b95be262f6100a46b0b066c8255de6f1250a41429b
|
4
|
+
data.tar.gz: a758caf5a05445bc36b4c8e2e64f562c181546eb9740d065e48d2c3c5ea22726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47e4e46bb5e633a1e0eccb8fc9081411d1ff09439046f8ead15070aa2a2f3329d3b34e9744aa56a13a1cb0e6ff0490abc3148efe8e87d5d9efcaeb0f86fa514b
|
7
|
+
data.tar.gz: 2bc529d8091353b0a90a7b04b8e33d490371bfc87c43149a977cde769234b69e9645d9ca8c5677088a91faef8630806c24435ad304551fe467dba4d0cd421971
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: build
|
9
|
+
|
10
|
+
on: push
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
runs-on: ubuntu-20.04
|
15
|
+
strategy:
|
16
|
+
fail-fast: false
|
17
|
+
matrix:
|
18
|
+
ruby:
|
19
|
+
- 3.0.0
|
20
|
+
- 2.7.2
|
21
|
+
- 2.6.6
|
22
|
+
- 2.5.8
|
23
|
+
- 2.4.10
|
24
|
+
gemfile:
|
25
|
+
- openssl_3_0
|
26
|
+
- openssl_2_2
|
27
|
+
- openssl_2_1
|
28
|
+
- openssl_default
|
29
|
+
exclude:
|
30
|
+
- ruby: '2.4.10'
|
31
|
+
gemfile: openssl_3_0
|
32
|
+
- ruby: '2.5.8'
|
33
|
+
gemfile: openssl_3_0
|
34
|
+
env:
|
35
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
36
|
+
steps:
|
37
|
+
- uses: actions/checkout@v2
|
38
|
+
- uses: ruby/setup-ruby@v1
|
39
|
+
with:
|
40
|
+
ruby-version: ${{ matrix.ruby }}
|
41
|
+
bundler-cache: true
|
42
|
+
- run: bundle exec rake
|
data/Appraisals
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
appraise "openssl_head" do
|
4
|
-
gem "openssl", git: "https://github.com/ruby/openssl"
|
5
|
-
end
|
6
|
-
|
7
3
|
appraise "openssl_2_2" do
|
8
4
|
gem "openssl", "~> 2.2.0"
|
9
5
|
end
|
@@ -12,8 +8,8 @@ appraise "openssl_2_1" do
|
|
12
8
|
gem "openssl", "~> 2.1.0"
|
13
9
|
end
|
14
10
|
|
15
|
-
appraise "
|
16
|
-
gem "openssl", "~>
|
11
|
+
appraise "openssl_3_0" do
|
12
|
+
gem "openssl", "~> 3.0.0"
|
17
13
|
end
|
18
14
|
|
19
15
|
appraise "openssl_default" do
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.3.0] - 2022-10-28
|
4
|
+
|
5
|
+
- Add support for EdDSA (#55). Credits to @bdewater.
|
6
|
+
|
7
|
+
## [v1.2.1] - 2022-07-03
|
8
|
+
|
9
|
+
- Support OpenSSL ~>3.0.0. Credits to @ClearlyClaire <3
|
10
|
+
|
3
11
|
## [v1.2.0] - 2020-07-10
|
4
12
|
|
5
13
|
### Added
|
@@ -135,6 +143,8 @@ NOTE: No breaking changes. Moving out of `v0.x` to express the intention to keep
|
|
135
143
|
- EC2 key object
|
136
144
|
- Works with ruby 2.5
|
137
145
|
|
146
|
+
[v1.3.0]: https://github.com/cedarcode/cose-ruby/compare/v1.2.1...v1.3.0/
|
147
|
+
[v1.2.1]: https://github.com/cedarcode/cose-ruby/compare/v1.2.0...v1.2.1/
|
138
148
|
[v1.2.0]: https://github.com/cedarcode/cose-ruby/compare/v1.1.0...v1.2.0/
|
139
149
|
[v1.1.0]: https://github.com/cedarcode/cose-ruby/compare/v1.0.0...v1.1.0/
|
140
150
|
[v1.0.0]: https://github.com/cedarcode/cose-ruby/compare/v0.11.0...v1.0.0/
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Ruby implementation of RFC [8152](https://tools.ietf.org/html/rfc8152) CBOR Object Signing and Encryption (COSE)
|
4
4
|
|
5
5
|
[](https://rubygems.org/gems/cose)
|
6
|
-
[](https://github.com/cedarcode/cose-ruby/actions)
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm/signature_algorithm"
|
4
|
+
require "cose/error"
|
5
|
+
require "cose/key/okp"
|
6
|
+
require "openssl"
|
7
|
+
|
8
|
+
module COSE
|
9
|
+
module Algorithm
|
10
|
+
class EdDSA < SignatureAlgorithm
|
11
|
+
private
|
12
|
+
|
13
|
+
def valid_key?(key)
|
14
|
+
cose_key = to_cose_key(key)
|
15
|
+
|
16
|
+
cose_key.is_a?(COSE::Key::OKP) && (!cose_key.alg || cose_key.alg == id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_pkey(key)
|
20
|
+
case key
|
21
|
+
when COSE::Key::OKP
|
22
|
+
key.to_pkey
|
23
|
+
when OpenSSL::PKey::PKey
|
24
|
+
key
|
25
|
+
else
|
26
|
+
raise(COSE::Error, "Incompatible key for algorithm")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid_signature?(key, signature, verification_data)
|
31
|
+
pkey = to_pkey(key)
|
32
|
+
|
33
|
+
begin
|
34
|
+
pkey.verify(nil, signature, verification_data)
|
35
|
+
rescue OpenSSL::PKey::PKeyError
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/cose/algorithm.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "cose/algorithm/ecdsa"
|
4
|
+
require "cose/algorithm/eddsa"
|
4
5
|
require "cose/algorithm/hmac"
|
5
6
|
require "cose/algorithm/rsa_pss"
|
6
7
|
|
@@ -30,6 +31,7 @@ module COSE
|
|
30
31
|
register(ECDSA.new(-35, "ES384", hash_function: "SHA384", curve_name: "P-384"))
|
31
32
|
register(ECDSA.new(-36, "ES512", hash_function: "SHA512", curve_name: "P-521"))
|
32
33
|
register(ECDSA.new(-47, "ES256K", hash_function: "SHA256", curve_name: "secp256k1"))
|
34
|
+
register(EdDSA.new(-8, "EdDSA"))
|
33
35
|
register(RSAPSS.new(-37, "PS256", hash_function: "SHA256", salt_length: 32))
|
34
36
|
register(RSAPSS.new(-38, "PS384", hash_function: "SHA384", salt_length: 48))
|
35
37
|
register(RSAPSS.new(-39, "PS512", hash_function: "SHA512", salt_length: 64))
|
data/lib/cose/key/curve.rb
CHANGED
@@ -32,4 +32,6 @@ end
|
|
32
32
|
COSE::Key::Curve.register(1, "P-256", "prime256v1")
|
33
33
|
COSE::Key::Curve.register(2, "P-384", "secp384r1")
|
34
34
|
COSE::Key::Curve.register(3, "P-521", "secp521r1")
|
35
|
+
COSE::Key::Curve.register(6, "Ed25519", "ED25519")
|
36
|
+
COSE::Key::Curve.register(7, "Ed448", "ED448")
|
35
37
|
COSE::Key::Curve.register(8, "secp256k1", "secp256k1")
|
data/lib/cose/key/ec2.rb
CHANGED
@@ -68,16 +68,39 @@ module COSE
|
|
68
68
|
def to_pkey
|
69
69
|
if curve
|
70
70
|
group = OpenSSL::PKey::EC::Group.new(curve.pkey_name)
|
71
|
-
pkey = OpenSSL::PKey::EC.new(group)
|
72
71
|
public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
|
73
72
|
public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
|
74
|
-
|
73
|
+
|
74
|
+
# RFC5480 SubjectPublicKeyInfo
|
75
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
76
|
+
[
|
77
|
+
OpenSSL::ASN1::Sequence(
|
78
|
+
[
|
79
|
+
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
|
80
|
+
OpenSSL::ASN1::ObjectId(curve.pkey_name),
|
81
|
+
]
|
82
|
+
),
|
83
|
+
OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed))
|
84
|
+
]
|
85
|
+
)
|
75
86
|
|
76
87
|
if d
|
77
|
-
|
88
|
+
# RFC5915 ECPrivateKey
|
89
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
90
|
+
[
|
91
|
+
OpenSSL::ASN1::Integer.new(1),
|
92
|
+
# Not properly padded but OpenSSL doesn't mind
|
93
|
+
OpenSSL::ASN1::OctetString(OpenSSL::BN.new(d, 2).to_s(2)),
|
94
|
+
OpenSSL::ASN1::ObjectId(curve.pkey_name, 0, :EXPLICIT),
|
95
|
+
OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed), 1, :EXPLICIT),
|
96
|
+
]
|
97
|
+
)
|
98
|
+
|
99
|
+
der = asn1.to_der
|
100
|
+
return OpenSSL::PKey::EC.new(der)
|
78
101
|
end
|
79
102
|
|
80
|
-
|
103
|
+
OpenSSL::PKey::EC.new(asn1.to_der)
|
81
104
|
else
|
82
105
|
raise "Unsupported curve #{crv}"
|
83
106
|
end
|
data/lib/cose/key/okp.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "cose/key/curve"
|
3
4
|
require "cose/key/curve_key"
|
4
5
|
require "openssl"
|
5
6
|
|
@@ -14,9 +15,56 @@ module COSE
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
def self.from_pkey(pkey)
|
19
|
+
curve = Curve.by_pkey_name(pkey.oid) || raise("Unsupported edwards curve #{pkey.oid}")
|
20
|
+
attributes = { crv: curve.id }
|
21
|
+
|
22
|
+
asymmetric_key = pkey.public_to_der
|
23
|
+
public_key_bit_string = OpenSSL::ASN1.decode(asymmetric_key).value.last.value
|
24
|
+
attributes[:x] = public_key_bit_string
|
25
|
+
begin
|
26
|
+
asymmetric_key = pkey.private_to_der
|
27
|
+
private_key = OpenSSL::ASN1.decode(asymmetric_key).value.last.value
|
28
|
+
curve_private_key = OpenSSL::ASN1.decode(private_key).value
|
29
|
+
attributes[:d] = curve_private_key
|
30
|
+
rescue OpenSSL::PKey::PKeyError
|
31
|
+
# work around lack of https://github.com/ruby/openssl/pull/527, otherwise raises this error
|
32
|
+
# with message 'i2d_PKCS8PrivateKey_bio: error converting private key' for public keys
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
new(**attributes)
|
37
|
+
end
|
38
|
+
|
17
39
|
def map
|
18
40
|
super.merge(LABEL_KTY => KTY_OKP)
|
19
41
|
end
|
42
|
+
|
43
|
+
def to_pkey
|
44
|
+
if curve
|
45
|
+
private_key_algo = OpenSSL::ASN1::Sequence.new(
|
46
|
+
[OpenSSL::ASN1::ObjectId.new(curve.pkey_name)]
|
47
|
+
)
|
48
|
+
seq = if d
|
49
|
+
version = OpenSSL::ASN1::Integer.new(0)
|
50
|
+
curve_private_key = OpenSSL::ASN1::OctetString.new(d).to_der
|
51
|
+
private_key = OpenSSL::ASN1::OctetString.new(curve_private_key)
|
52
|
+
[version, private_key_algo, private_key]
|
53
|
+
else
|
54
|
+
public_key = OpenSSL::ASN1::BitString.new(x)
|
55
|
+
[private_key_algo, public_key]
|
56
|
+
end
|
57
|
+
|
58
|
+
asymmetric_key = OpenSSL::ASN1::Sequence.new(seq)
|
59
|
+
OpenSSL::PKey.read(asymmetric_key.to_der)
|
60
|
+
else
|
61
|
+
raise "Unsupported curve #{crv}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def curve
|
66
|
+
Curve.find(crv)
|
67
|
+
end
|
20
68
|
end
|
21
69
|
end
|
22
70
|
end
|
data/lib/cose/key/rsa.rb
CHANGED
@@ -88,31 +88,32 @@ module COSE
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def to_pkey
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
91
|
+
# PKCS#1 RSAPublicKey
|
92
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
93
|
+
[
|
94
|
+
OpenSSL::ASN1::Integer.new(bn(n)),
|
95
|
+
OpenSSL::ASN1::Integer.new(bn(e)),
|
96
|
+
]
|
97
|
+
)
|
98
|
+
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
|
100
99
|
|
101
100
|
if private?
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
101
|
+
# PKCS#1 RSAPrivateKey
|
102
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
103
|
+
[
|
104
|
+
OpenSSL::ASN1::Integer.new(0),
|
105
|
+
OpenSSL::ASN1::Integer.new(bn(n)),
|
106
|
+
OpenSSL::ASN1::Integer.new(bn(e)),
|
107
|
+
OpenSSL::ASN1::Integer.new(bn(d)),
|
108
|
+
OpenSSL::ASN1::Integer.new(bn(p)),
|
109
|
+
OpenSSL::ASN1::Integer.new(bn(q)),
|
110
|
+
OpenSSL::ASN1::Integer.new(bn(dp)),
|
111
|
+
OpenSSL::ASN1::Integer.new(bn(dq)),
|
112
|
+
OpenSSL::ASN1::Integer.new(bn(qinv)),
|
113
|
+
]
|
114
|
+
)
|
108
115
|
|
109
|
-
|
110
|
-
pkey.set_crt_params(bn(dp), bn(dq), bn(qinv))
|
111
|
-
else
|
112
|
-
pkey.dmp1 = bn(dp)
|
113
|
-
pkey.dmq1 = bn(dq)
|
114
|
-
pkey.iqmp = bn(qinv)
|
115
|
-
end
|
116
|
+
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
|
116
117
|
end
|
117
118
|
|
118
119
|
pkey
|
data/lib/cose/key.rb
CHANGED
data/lib/cose/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gonzalo Rodriguez
|
8
8
|
- Braulio Martinez
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-10-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cbor
|
@@ -143,7 +143,7 @@ dependencies:
|
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '1.4'
|
146
|
-
description:
|
146
|
+
description:
|
147
147
|
email:
|
148
148
|
- gonzalo@cedarcode.com
|
149
149
|
- braulio@cedarcode.com
|
@@ -151,11 +151,11 @@ executables: []
|
|
151
151
|
extensions: []
|
152
152
|
extra_rdoc_files: []
|
153
153
|
files:
|
154
|
+
- ".github/workflows/build.yml"
|
154
155
|
- ".gitignore"
|
155
156
|
- ".gitmodules"
|
156
157
|
- ".rspec"
|
157
158
|
- ".rubocop.yml"
|
158
|
-
- ".travis.yml"
|
159
159
|
- Appraisals
|
160
160
|
- CHANGELOG.md
|
161
161
|
- Gemfile
|
@@ -166,15 +166,15 @@ files:
|
|
166
166
|
- bin/console
|
167
167
|
- bin/setup
|
168
168
|
- cose.gemspec
|
169
|
-
- gemfiles/openssl_2_0.gemfile
|
170
169
|
- gemfiles/openssl_2_1.gemfile
|
171
170
|
- gemfiles/openssl_2_2.gemfile
|
171
|
+
- gemfiles/openssl_3_0.gemfile
|
172
172
|
- gemfiles/openssl_default.gemfile
|
173
|
-
- gemfiles/openssl_head.gemfile
|
174
173
|
- lib/cose.rb
|
175
174
|
- lib/cose/algorithm.rb
|
176
175
|
- lib/cose/algorithm/base.rb
|
177
176
|
- lib/cose/algorithm/ecdsa.rb
|
177
|
+
- lib/cose/algorithm/eddsa.rb
|
178
178
|
- lib/cose/algorithm/hmac.rb
|
179
179
|
- lib/cose/algorithm/rsa_pss.rb
|
180
180
|
- lib/cose/algorithm/signature_algorithm.rb
|
@@ -205,7 +205,7 @@ metadata:
|
|
205
205
|
bug_tracker_uri: https://github.com/cedarcode/cose-ruby/issues
|
206
206
|
changelog_uri: https://github.com/cedarcode/cose-ruby/blob/master/CHANGELOG.md
|
207
207
|
source_code_uri: https://github.com/cedarcode/cose-ruby
|
208
|
-
post_install_message:
|
208
|
+
post_install_message:
|
209
209
|
rdoc_options: []
|
210
210
|
require_paths:
|
211
211
|
- lib
|
@@ -220,8 +220,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
222
|
requirements: []
|
223
|
-
rubygems_version: 3.
|
224
|
-
signing_key:
|
223
|
+
rubygems_version: 3.2.32
|
224
|
+
signing_key:
|
225
225
|
specification_version: 4
|
226
226
|
summary: Ruby implementation of RFC 8152 CBOR Object Signing and Encryption (COSE)
|
227
227
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
dist: bionic
|
2
|
-
language: ruby
|
3
|
-
cache: bundler
|
4
|
-
|
5
|
-
rvm:
|
6
|
-
- ruby-head
|
7
|
-
- 2.7.1
|
8
|
-
- 2.6.6
|
9
|
-
- 2.5.8
|
10
|
-
- 2.4.10
|
11
|
-
|
12
|
-
gemfile:
|
13
|
-
- gemfiles/openssl_head.gemfile
|
14
|
-
- gemfiles/openssl_2_2.gemfile
|
15
|
-
- gemfiles/openssl_2_1.gemfile
|
16
|
-
- gemfiles/openssl_2_0.gemfile
|
17
|
-
- gemfiles/openssl_default.gemfile
|
18
|
-
|
19
|
-
before_install: gem install bundler -v '~> 2.0'
|
20
|
-
|
21
|
-
matrix:
|
22
|
-
fast_finish: true
|
23
|
-
allow_failures:
|
24
|
-
- rvm: ruby-head
|
25
|
-
- gemfile: gemfiles/openssl_head.gemfile
|