Skip to content

Commit a82812d

Browse files
committed
Bugfix for der conversion + more and stricter unit tests
1 parent a974a48 commit a82812d

File tree

3 files changed

+71
-21
lines changed

3 files changed

+71
-21
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_Securit
2626
clap = { version = "4", default-features = false, features = ["std", "derive", "help"] }
2727
rustls-aws-lc-rs = { git = "https://github.com/rustls/rustls.git" }
2828
rustls-native-certs = "0.8"
29+
der = { version = "0.7", features = ["alloc"] }
2930

3031
[features]
3132
default = ["rustls-log", "rustls-std"]

src/signer.rs

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use windows_sys::Win32::Security::Cryptography::{
1414
use crate::key::{AlgorithmGroup, NCryptKey, SignaturePadding};
1515

1616
// Convert IEEE-P1363 signature format to DER encoding.
17-
// Some modifications are taken from https://github.com/tofay/rustls-cng-crypto/blob/main/src/signer/ec.rs
17+
// The maximum signature size we support is 132 bytes of the NIST P-521 curve.
1818
fn p1363_to_der(data: &[u8]) -> Vec<u8> {
1919
const SEQUENCE_TAG: u8 = 0x30;
2020
const INTEGER_TAG: u8 = 0x02;
@@ -34,24 +34,14 @@ fn p1363_to_der(data: &[u8]) -> Vec<u8> {
3434

3535
let v_length = 4 + r_sign.len() + s_sign.len() + r.len() + s.len();
3636

37-
let (short_form, length_len) = if v_length <= 0x80 {
38-
(true, 1)
39-
} else {
40-
let mut v_length = v_length;
41-
let mut length_len = 0;
42-
while v_length > 0 {
43-
v_length >>= 8;
44-
length_len += 1;
45-
}
46-
(false, length_len)
47-
};
37+
let length_len = (usize::BITS - v_length.leading_zeros()).div_ceil(8) as usize;
4838

49-
let length = length_len + v_length + 1;
50-
let mut der = Vec::with_capacity(length);
39+
let mut der = Vec::with_capacity(1 + length_len + v_length);
5140

5241
der.push(SEQUENCE_TAG);
53-
if short_form {
54-
der.push(v_length as u8); // LENGTH - short form
42+
43+
if v_length < 128 {
44+
der.push(v_length as u8);
5545
} else {
5646
der.push(0x80 | length_len as u8);
5747
for i in (0..length_len).rev() {
@@ -219,20 +209,69 @@ impl SigningKey for CngSigningKey {
219209

220210
#[cfg(test)]
221211
mod tests {
212+
use der::{Decode, Reader, asn1::Int};
213+
214+
fn validate_der(data: &[u8], r: &Int, s: &Int) {
215+
let (decoded_r, decoded_s) = der::SliceReader::new(&data)
216+
.unwrap()
217+
.sequence(|reader| Ok((Int::decode(reader)?, Int::decode(reader)?)))
218+
.unwrap();
219+
220+
assert_eq!(decoded_r, *r);
221+
assert_eq!(decoded_s, *s);
222+
}
223+
222224
#[test]
223225
fn test_p1363_to_der() {
224226
let p1363 = [1, 2, 3, 4, 5, 6, 7, 8];
225227
let der = super::p1363_to_der(&p1363);
226-
assert_eq!(der, [0x30, 0x0c, 0x02, 0x04, 1, 2, 3, 4, 0x02, 0x04, 5, 6, 7, 8])
228+
validate_der(
229+
&der,
230+
&Int::new(&[1, 2, 3, 4]).unwrap(),
231+
&Int::new(&[5, 6, 7, 8]).unwrap(),
232+
);
227233
}
228234

229235
#[test]
230236
fn test_p1363_to_der_signed() {
231237
let p1363 = [0x81, 2, 3, 4, 0x85, 6, 7, 8];
232238
let der = super::p1363_to_der(&p1363);
233-
assert_eq!(
234-
der,
235-
[0x30, 0x0e, 0x02, 0x05, 0, 0x81, 2, 3, 4, 0x02, 0x05, 0, 0x85, 6, 7, 8]
236-
)
239+
validate_der(
240+
&der,
241+
&Int::new(&[0, 0x81, 2, 3, 4]).unwrap(),
242+
&Int::new(&[0, 0x85, 6, 7, 8]).unwrap(),
243+
);
244+
}
245+
246+
#[test]
247+
fn test_p1363_to_der_zeroes_stripped() {
248+
let p1363 = [0, 1, 2, 3, 4, 0, 5, 6, 7, 8];
249+
let der = super::p1363_to_der(&p1363);
250+
validate_der(
251+
&der,
252+
&Int::new(&[1, 2, 3, 4]).unwrap(),
253+
&Int::new(&[5, 6, 7, 8]).unwrap(),
254+
);
255+
}
256+
257+
#[test]
258+
fn test_p1363_to_der_signed_zeroes_stripped() {
259+
let p1363 = [0, 0x81, 2, 3, 4, 0, 0x85, 6, 7, 8];
260+
let der = super::p1363_to_der(&p1363);
261+
validate_der(
262+
&der,
263+
&Int::new(&[0, 0x81, 2, 3, 4]).unwrap(),
264+
&Int::new(&[0, 0x85, 6, 7, 8]).unwrap(),
265+
);
266+
}
267+
268+
#[test]
269+
fn test_p1363_to_der_long() {
270+
let r = (1..128).collect::<Vec<u8>>();
271+
let s = (1..128).rev().collect::<Vec<u8>>();
272+
273+
let p1363 = r.clone().into_iter().chain(s.clone()).collect::<Vec<u8>>();
274+
let der = super::p1363_to_der(&p1363);
275+
validate_der(&der, &Int::new(&r).unwrap(), &Int::new(&s).unwrap());
237276
}
238277
}

0 commit comments

Comments
 (0)