Skip to content

Commit 530db2f

Browse files
Merge pull request #61 from ClearlyClaire/openssl-3
Add support for OpenSSL 3.0
2 parents 0dfb889 + 5052909 commit 530db2f

6 files changed

Lines changed: 53 additions & 33 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
- 2.5.8
2323
- 2.4.10
2424
gemfile:
25+
- openssl_3_0
2526
- openssl_2_2
2627
- openssl_2_1
2728
- openssl_2_0

Appraisals

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ appraise "openssl_2_0" do
1212
gem "openssl", "~> 2.0.0"
1313
end
1414

15+
appraise "openssl_3_0" do
16+
gem "openssl", "~> 3.0.0"
17+
end
18+
1519
appraise "openssl_default" do
1620
end

lib/cose/key/ec2.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,31 @@ def to_pkey
7171
pkey = OpenSSL::PKey::EC.new(group)
7272
public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
7373
public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
74-
pkey.public_key = public_key_point
74+
75+
# RFC5480 SubjectPublicKeyInfo
76+
asn1 = OpenSSL::ASN1::Sequence([
77+
OpenSSL::ASN1::Sequence([
78+
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
79+
OpenSSL::ASN1::ObjectId(curve.pkey_name),
80+
]),
81+
OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed))
82+
])
7583

7684
if d
77-
pkey.private_key = OpenSSL::BN.new(d, 2)
85+
# RFC5915 ECPrivateKey
86+
asn1 = OpenSSL::ASN1::Sequence([
87+
OpenSSL::ASN1::Integer.new(1),
88+
# Not properly padded but OpenSSL doesn't mind
89+
OpenSSL::ASN1::OctetString(OpenSSL::BN.new(d, 2).to_s(2)),
90+
OpenSSL::ASN1::ObjectId(curve.pkey_name, 0, :EXPLICIT),
91+
OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed), 1, :EXPLICIT),
92+
])
93+
94+
der = asn1.to_der
95+
return OpenSSL::PKey::EC.new(der)
7896
end
7997

80-
pkey
98+
OpenSSL::PKey::EC.new(asn1.to_der)
8199
else
82100
raise "Unsupported curve #{crv}"
83101
end

lib/cose/key/rsa.rb

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,31 +88,28 @@ def map
8888
end
8989

9090
def to_pkey
91-
pkey = OpenSSL::PKey::RSA.new
92-
93-
if pkey.respond_to?(:set_key)
94-
pkey.set_key(bn(n), bn(e), bn(d))
95-
else
96-
pkey.n = bn(n)
97-
pkey.e = bn(e)
98-
pkey.d = bn(d)
99-
end
91+
# PKCS#1 RSAPublicKey
92+
asn1 = OpenSSL::ASN1::Sequence([
93+
OpenSSL::ASN1::Integer.new(bn(n)),
94+
OpenSSL::ASN1::Integer.new(bn(e)),
95+
])
96+
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
10097

10198
if private?
102-
if pkey.respond_to?(:set_factors)
103-
pkey.set_factors(bn(p), bn(q))
104-
else
105-
pkey.p = bn(p)
106-
pkey.q = bn(q)
107-
end
108-
109-
if pkey.respond_to?(:set_crt_params)
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
99+
# PKCS#1 RSAPrivateKey
100+
asn1 = OpenSSL::ASN1::Sequence([
101+
OpenSSL::ASN1::Integer.new(0),
102+
OpenSSL::ASN1::Integer.new(bn(n)),
103+
OpenSSL::ASN1::Integer.new(bn(e)),
104+
OpenSSL::ASN1::Integer.new(bn(d)),
105+
OpenSSL::ASN1::Integer.new(bn(p)),
106+
OpenSSL::ASN1::Integer.new(bn(q)),
107+
OpenSSL::ASN1::Integer.new(bn(dp)),
108+
OpenSSL::ASN1::Integer.new(bn(dq)),
109+
OpenSSL::ASN1::Integer.new(bn(qinv)),
110+
])
111+
112+
pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
116113
end
117114

118115
pkey

spec/cose/key/ec2_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393

9494
context "#to_pkey" do
9595
it "works for an EC key in the P-256 curve" do
96-
original_pkey = OpenSSL::PKey::EC.new("prime256v1").generate_key
96+
original_pkey = OpenSSL::PKey::EC.generate("prime256v1")
9797
pkey = COSE::Key::EC2.from_pkey(original_pkey).to_pkey
9898

9999
expect(pkey).to be_a(OpenSSL::PKey::EC)
@@ -103,7 +103,7 @@
103103
end
104104

105105
it "works for an EC key in the P-384 curve" do
106-
original_pkey = OpenSSL::PKey::EC.new("secp384r1").generate_key
106+
original_pkey = OpenSSL::PKey::EC.generate("secp384r1")
107107
pkey = COSE::Key::EC2.from_pkey(original_pkey).to_pkey
108108

109109
expect(pkey).to be_a(OpenSSL::PKey::EC)
@@ -113,7 +113,7 @@
113113
end
114114

115115
it "works for an EC key in the P-521 curve" do
116-
original_pkey = OpenSSL::PKey::EC.new("secp521r1").generate_key
116+
original_pkey = OpenSSL::PKey::EC.generate("secp521r1")
117117
pkey = COSE::Key::EC2.from_pkey(original_pkey).to_pkey
118118

119119
expect(pkey).to be_a(OpenSSL::PKey::EC)
@@ -123,7 +123,7 @@
123123
end
124124

125125
it "works for an EC key in the secp256k1 curve" do
126-
original_pkey = OpenSSL::PKey::EC.new("secp256k1").generate_key
126+
original_pkey = OpenSSL::PKey::EC.generate("secp256k1")
127127
pkey = COSE::Key::EC2.from_pkey(original_pkey).to_pkey
128128

129129
expect(pkey).to be_a(OpenSSL::PKey::EC)

spec/cose/key_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
RSpec.describe COSE::Key do
88
describe ".serialize" do
99
it "can serialize EC P-256 key" do
10-
key = OpenSSL::PKey::EC.new("prime256v1").generate_key
10+
key = OpenSSL::PKey::EC.generate("prime256v1")
1111

1212
cbor = COSE::Key.serialize(key)
1313
map = CBOR.decode(cbor)
@@ -21,7 +21,7 @@
2121
end
2222

2323
it "can serialize EC P-384 key" do
24-
key = OpenSSL::PKey::EC.new("secp384r1").generate_key
24+
key = OpenSSL::PKey::EC.generate("secp384r1")
2525

2626
cbor = COSE::Key.serialize(key)
2727
map = CBOR.decode(cbor)
@@ -35,7 +35,7 @@
3535
end
3636

3737
it "can serialize EC P-521 key" do
38-
key = OpenSSL::PKey::EC.new("secp521r1").generate_key
38+
key = OpenSSL::PKey::EC.generate("secp521r1")
3939

4040
cbor = COSE::Key.serialize(key)
4141
map = CBOR.decode(cbor)

0 commit comments

Comments
 (0)