cedarcode / cose-ruby

Ruby implementation of RFC 8152 CBOR Object Signing and Encryption (COSE)
https://rubygems.org/gems/cose
MIT License
16 stars 10 forks source link

Handle COSE EC keys encoded without leading 0 bytes in coordinates to avoid "EC_POINT_bn2point: invalid encoding" errors #63

Open waltercacau opened 4 months ago

waltercacau commented 4 months ago

Code sample that demonstrates the issue.

encoded_key='pQECAyYgASFYHynGYDi87vkqpFOep_onzrmNjPdVBthCuIua9pvBCssiWCBZnNAreTzLOVZrLcTrh6eh-v5GrdemuIS-bVvXrk7Wdw=='
sample_key=COSE::Key.deserialize(Base64.urlsafe_decode64(encoded_key))

sample_key.to_pkey
# This fails with:
# OpenSSL::PKey::EC::Point::Error: EC_POINT_bn2point: invalid encoding
# from .../.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/cose-1.3.0/lib/cose/key/ec2.rb:72:in `initialize'

puts "x.length = #{sample_key.x.length} / y.length = #{sample_key.y.length}"
# This prints:
# x.length = 31 / y.length = 32

Apparently some platforms omit leading zeros when encoding coordinates from EC keys. The example key above was generated in an iOS device by Apple's AppAttest.

Ruby-JWT gem also had to handle this issue to avoid the error. https://github.com/jwt/ruby-jwt/pull/585

I believe the fix could be relatively straightforward. Basically we need to patch this line to ensure x/y have the right length and if not add leading zeros. https://github.com/cedarcode/cose-ruby/blob/fcde72f1351d3ba964500d91a19ab0e2d84a5878/lib/cose/key/ec2.rb#L71C27-L71C61

waltercacau commented 4 months ago

Alright, I have a pull request that could address this: https://github.com/cedarcode/cose-ruby/pull/64 . Please take a look when you have a chance