Skip to content

Commit b997db1

Browse files
authored
Handling COSE EC keys encoded without leading 0 bytes in coordinates (#64)
1 parent fcde72f commit b997db1

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

lib/cose/key/ec2.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class EC2 < CurveKey
1111

1212
KTY_EC2 = 2
1313

14+
ZERO_BYTE = "\0".b
15+
1416
def self.enforce_type(map)
1517
if map[LABEL_KTY] != KTY_EC2
1618
raise "Not an EC2 key"
@@ -68,7 +70,7 @@ def map
6870
def to_pkey
6971
if curve
7072
group = OpenSSL::PKey::EC::Group.new(curve.pkey_name)
71-
public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
73+
public_key_bn = OpenSSL::BN.new("\x04" + pad_coordinate(group, x) + pad_coordinate(group, y), 2)
7274
public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
7375

7476
# RFC5480 SubjectPublicKeyInfo
@@ -113,6 +115,14 @@ def curve
113115
def self.keyword_arguments_for_initialize(map)
114116
super.merge(y: map[LABEL_Y])
115117
end
118+
119+
def pad_coordinate(group, coordinate)
120+
coordinate_length = (group.degree + 7) / 8
121+
padding_required = coordinate_length - coordinate.length
122+
return coordinate if padding_required <= 0
123+
124+
(ZERO_BYTE * padding_required) + coordinate
125+
end
116126
end
117127
end
118128
end

spec/cose/key/ec2_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,29 @@
131131
expect(pkey.public_key).to eq(original_pkey.public_key)
132132
expect(pkey.private_key).to eq(original_pkey.private_key)
133133
end
134+
135+
it "works for an EC key that omits leading zero" do
136+
# x was encoded omitting a leading zero. Before calling OpenSSL we must pad it.
137+
x = ")\xC6`8\xBC\xEE\xF9*\xA4S\x9E\xA7\xFA'\xCE\xB9\x8D\x8C\xF7U\x06\xD8B\xB8\x8B\x9A\xF6\x9B\xC1\n\xCB".b
138+
y = "Y\x9C\xD0+y<\xCB9Vk-\xC4\xEB\x87\xA7\xA1\xFA\xFEF\xAD\xD7\xA6\xB8\x84\xBEm[\xD7\xAEN\xD6w".b
139+
original_key = COSE::Key::EC2.new(
140+
kid: "id".b,
141+
alg: -7,
142+
key_ops: 1,
143+
base_iv: "init-vector".b,
144+
crv: 1,
145+
x: x,
146+
y: y,
147+
)
148+
149+
pkey = original_key.to_pkey
150+
key = COSE::Key::EC2.from_pkey(pkey)
151+
152+
expect(pkey).to be_a(OpenSSL::PKey::EC)
153+
expect(pkey.group.curve_name).to eq("prime256v1")
154+
expect(key.x).to eq("\0".b + x)
155+
expect(key.y).to eq(y)
156+
end
134157
end
135158

136159
describe "#serialize" do

0 commit comments

Comments
 (0)