cose 1.2.1 → 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 +5 -1
- data/Appraisals +0 -4
- data/CHANGELOG.md +6 -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 +20 -15
- data/lib/cose/key/okp.rb +48 -0
- data/lib/cose/key/rsa.rb +19 -15
- data/lib/cose/key.rb +2 -0
- data/lib/cose/version.rb +1 -1
- metadata +4 -3
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
|
data/.github/workflows/build.yml
CHANGED
@@ -25,8 +25,12 @@ jobs:
|
|
25
25
|
- openssl_3_0
|
26
26
|
- openssl_2_2
|
27
27
|
- openssl_2_1
|
28
|
-
- openssl_2_0
|
29
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
|
30
34
|
env:
|
31
35
|
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
32
36
|
steps:
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.3.0] - 2022-10-28
|
4
|
+
|
5
|
+
- Add support for EdDSA (#55). Credits to @bdewater.
|
6
|
+
|
3
7
|
## [v1.2.1] - 2022-07-03
|
4
8
|
|
5
9
|
- Support OpenSSL ~>3.0.0. Credits to @ClearlyClaire <3
|
@@ -139,7 +143,8 @@ NOTE: No breaking changes. Moving out of `v0.x` to express the intention to keep
|
|
139
143
|
- EC2 key object
|
140
144
|
- Works with ruby 2.5
|
141
145
|
|
142
|
-
[v1.
|
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/
|
143
148
|
[v1.2.0]: https://github.com/cedarcode/cose-ruby/compare/v1.1.0...v1.2.0/
|
144
149
|
[v1.1.0]: https://github.com/cedarcode/cose-ruby/compare/v1.0.0...v1.1.0/
|
145
150
|
[v1.0.0]: https://github.com/cedarcode/cose-ruby/compare/v0.11.0...v1.0.0/
|
@@ -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,28 +68,33 @@ 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
|
|
75
74
|
# RFC5480 SubjectPublicKeyInfo
|
76
|
-
asn1 = OpenSSL::ASN1::Sequence(
|
77
|
-
|
78
|
-
OpenSSL::ASN1::
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
+
)
|
83
86
|
|
84
87
|
if d
|
85
88
|
# RFC5915 ECPrivateKey
|
86
|
-
asn1 = OpenSSL::ASN1::Sequence(
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
+
)
|
93
98
|
|
94
99
|
der = asn1.to_der
|
95
100
|
return OpenSSL::PKey::EC.new(der)
|
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
@@ -89,25 +89,29 @@ module COSE
|
|
89
89
|
|
90
90
|
def to_pkey
|
91
91
|
# PKCS#1 RSAPublicKey
|
92
|
-
asn1 = OpenSSL::ASN1::Sequence(
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
93
|
+
[
|
94
|
+
OpenSSL::ASN1::Integer.new(bn(n)),
|
95
|
+
OpenSSL::ASN1::Integer.new(bn(e)),
|
96
|
+
]
|
97
|
+
)
|
96
98
|
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
|
97
99
|
|
98
100
|
if private?
|
99
101
|
# PKCS#1 RSAPrivateKey
|
100
|
-
asn1 = OpenSSL::ASN1::Sequence(
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
+
)
|
111
115
|
|
112
116
|
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
|
113
117
|
end
|
data/lib/cose/key.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: 1.
|
4
|
+
version: 1.3.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: 2022-
|
12
|
+
date: 2022-10-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cbor
|
@@ -166,14 +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
173
|
- lib/cose.rb
|
174
174
|
- lib/cose/algorithm.rb
|
175
175
|
- lib/cose/algorithm/base.rb
|
176
176
|
- lib/cose/algorithm/ecdsa.rb
|
177
|
+
- lib/cose/algorithm/eddsa.rb
|
177
178
|
- lib/cose/algorithm/hmac.rb
|
178
179
|
- lib/cose/algorithm/rsa_pss.rb
|
179
180
|
- lib/cose/algorithm/signature_algorithm.rb
|