-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correct padding when extracting r and s components of the DER encoded EC signature #56
Conversation
…e from a DER encoded sequence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The results of this code are not wrong, but they give a false impression of possible states. I think that the dstPos
is the only value that needs to be adjusted for the array copy.
System.arraycopy(r, r.length > len ? 1 : 0, result, r.length < len ? 1 : 0, r.length > len ? len : r.length); | ||
//noinspection ManualMinMaxCalculation | ||
System.arraycopy(s, s.length > len ? 1 : 0, result, s.length < len ? (len + 1) : len, s.length > len ? len : s.length); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment for these after they are cleaned up about offsetting the destination position for left padding when r
or s
is shorter than 66
bytes in the ES512
case.
Do we know whether it only happens with that algorithm? Or just that we have never seen it with another?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can occur in any algorithm in theory. In my testing, I could get r
and s
src and dst positions to be greater than 0
for all three algorithms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. The updated code seems good then. I still think there should be a comment about how these changes account for left padding with 0s in both the source and destination byte arrays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
Other things I thought of after I submitted the review.
|
re: these comments - #56 (comment) let's discuss further if you are concerned. I believe the This is all part of the DER spec, but you can review the JDK impl for comparision if you want. The length portion of the encoding can only be 4 bytes at most, this allows us to represent a value up to The DER length encoding is kind of complicated, and I would not want to change any of it unless we can come up with a test that proves it is broken. If you do think we have a bug, see if you can recreate it in |
… extracting the r and s components, and how the result must be padded to correctly fill the result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Issue
ES512
algorithm may have an invalid signature fusionauth-issues#2661r
ands
from the DER encoded value #57Description
Correct padding when extracting r and s components of the DER encoded EC signature
There was a bug in how we were extracting the
r
ands
components into a byte array from the DER encoded version.For the
ES512
algorithm, we build a132
byte array to fill up with ther
ands
components. The array has to be split evenly so it can be parsed using a0
and64
byte offset. But within each of those segments, ther
ands
component need to be left padded correctly.The code was previously assume we would at most have a single
0
to pad, but in some cases we would have a64
byte value forr
ors
and then our value was left shifted by one byte.So for example:
So in practice because the code assumed the maximum padding of
1
byte we ended up with012340
instead of001234
for one or both of these components.So when the
r
value is only64
bytes, we need to pad it correctly so that when we need to DER encode it again and we simply split the132
byte array down the middle we have the correct components with the correct padding.Your classic elliptic signature DER decoding mistake. 😎