Skip to content

Commit 216d1e0

Browse files
authored
Fix ECDSA DER edge cases (#20)
1 parent 4cae3bd commit 216d1e0

1 file changed

Lines changed: 40 additions & 10 deletions

File tree

src/signer/ec.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,9 @@ fn p1363_to_der(data: &[u8]) -> Vec<u8> {
172172
const SEQUENCE_TAG: u8 = 0x30;
173173
const INTEGER_TAG: u8 = 0x02;
174174

175-
let (mut r, mut s) = data.split_at(data.len() / 2);
176-
177-
while r[0] == 0x0 {
178-
r = &r[1..];
179-
}
180-
181-
while s[0] == 0x0 {
182-
s = &s[1..];
183-
}
175+
let (r, s) = data.split_at(data.len() / 2);
176+
let r = trim_leading_zeroes(r);
177+
let s = trim_leading_zeroes(s);
184178

185179
// Do we need to pad the r and s parts?
186180
let r_sign: &[u8] = if r[0] >= 0x80 { &[0] } else { &[] };
@@ -191,7 +185,7 @@ fn p1363_to_der(data: &[u8]) -> Vec<u8> {
191185
let v_length = 4 + r_sign.len() + s_sign.len() + r.len() + s.len();
192186

193187
// Do we use short or long form for the length?
194-
let (short_form, length_len) = if v_length <= 0x80 {
188+
let (short_form, length_len) = if v_length < 0x80 {
195189
// Short form, one octet
196190
(true, 1)
197191
} else {
@@ -229,3 +223,39 @@ fn p1363_to_der(data: &[u8]) -> Vec<u8> {
229223
der.extend(s);
230224
der
231225
}
226+
227+
fn trim_leading_zeroes(component: &[u8]) -> &[u8] {
228+
match component.iter().position(|&byte| byte != 0) {
229+
Some(first_nonzero) => &component[first_nonzero..],
230+
None => &[0],
231+
}
232+
}
233+
234+
#[cfg(test)]
235+
mod tests {
236+
use super::p1363_to_der;
237+
238+
#[test]
239+
fn p1363_to_der_uses_long_form_sequence_length_at_128() {
240+
let mut signature = vec![0x01; 124];
241+
signature[62] = 0x02;
242+
243+
let der = p1363_to_der(&signature);
244+
245+
assert_eq!(&der[..3], &[0x30, 0x81, 0x80]);
246+
assert_eq!(der.len(), 131);
247+
assert_eq!(der[3], 0x02);
248+
assert_eq!(der[4], 62);
249+
assert_eq!(der[67], 0x02);
250+
assert_eq!(der[68], 62);
251+
}
252+
253+
#[test]
254+
fn p1363_to_der_encodes_all_zero_components_as_zero_integers() {
255+
let signature = vec![0x00; 64];
256+
257+
let der = p1363_to_der(&signature);
258+
259+
assert_eq!(der, vec![0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00]);
260+
}
261+
}

0 commit comments

Comments
 (0)