Skip to content

Commit 1d7d230

Browse files
committed
Updated dependencies
1 parent 533ca36 commit 1d7d230

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

Cargo.lock

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

src/signer.rs

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
use std::sync::Arc;
44

55
use rustls::{
6-
crypto::{Signer, SigningKey},
7-
enums::SignatureScheme,
6+
crypto::{SignatureScheme, Signer, SigningKey},
87
error::{Error, OtherError},
98
};
109
use rustls_pki_types::SubjectPublicKeyInfoDer;
@@ -15,31 +14,67 @@ use windows_sys::Win32::Security::Cryptography::{
1514
use crate::key::{AlgorithmGroup, NCryptKey, SignaturePadding};
1615

1716
// Convert IEEE-P1363 signature format to DER encoding.
18-
// We assume the length of the r and s parts is less than 256 bytes.
17+
// Some modifications are taken from https://github.com/tofay/rustls-cng-crypto/blob/main/src/signer/ec.rs
1918
fn p1363_to_der(data: &[u8]) -> Vec<u8> {
20-
let (r, s) = data.split_at(data.len() / 2);
19+
const SEQUENCE_TAG: u8 = 0x30;
20+
const INTEGER_TAG: u8 = 0x02;
2121

22+
let (mut r, mut s) = data.split_at(data.len() / 2);
23+
24+
while r[0] == 0x0 {
25+
r = &r[1..];
26+
}
27+
28+
while s[0] == 0x0 {
29+
s = &s[1..];
30+
}
31+
32+
// Do we need to pad the r and s parts?
2233
let r_sign: &[u8] = if r[0] >= 0x80 { &[0] } else { &[] };
2334
let s_sign: &[u8] = if s[0] >= 0x80 { &[0] } else { &[] };
2435

25-
let length = data.len() + 2 + 4 + r_sign.len() + s_sign.len();
36+
// Length of the value, i.e excluding the tag and length bytes
37+
// For longer signatures the 4 Tag-LENGTH bytes are not enough, but we assume that the signature is less than 252 bytes.
38+
let v_length = 4 + r_sign.len() + s_sign.len() + r.len() + s.len();
2639

27-
let mut buf = Vec::with_capacity(length);
40+
// Do we use short or long form for the length?
41+
let (short_form, length_len) = if v_length <= 0x80 {
42+
// Short form, one octet
43+
(true, 1)
44+
} else {
45+
// Long form, first octet is the number of length octets
46+
let mut v_length = v_length;
47+
let mut length_len = 0;
48+
while v_length > 0 {
49+
v_length >>= 8;
50+
length_len += 1;
51+
}
52+
(false, length_len)
53+
};
2854

29-
buf.push(0x30); // SEQUENCE
30-
buf.push((length - 2) as u8);
55+
let length = length_len + v_length + 1;
56+
let mut der = Vec::with_capacity(length);
3157

32-
buf.push(0x02); // INTEGER
33-
buf.push((r.len() + r_sign.len()) as u8);
34-
buf.extend(r_sign);
35-
buf.extend(r);
58+
der.push(SEQUENCE_TAG);
59+
if short_form {
60+
der.push(v_length as u8); // LENGTH - short form
61+
} else {
62+
der.push(0x80 | length_len as u8); // LENGTH - initial octet of long form
63+
for i in (0..length_len).rev() {
64+
der.push((v_length >> (i * 8)) as u8); // LENGTH - long form octets
65+
}
66+
}
3667

37-
buf.push(0x02); // INTEGER
38-
buf.push((s.len() + s_sign.len()) as u8);
39-
buf.extend(s_sign);
40-
buf.extend(s);
68+
der.push(INTEGER_TAG);
69+
der.push((r.len() + r_sign.len()) as u8);
70+
der.extend(r_sign);
71+
der.extend(r);
4172

42-
buf
73+
der.push(INTEGER_TAG);
74+
der.push((s.len() + s_sign.len()) as u8);
75+
der.extend(s_sign);
76+
der.extend(s);
77+
der
4378
}
4479

4580
/// Custom implementation of `rustls` SigningKey trait

tests/test_sign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustls::{crypto::SigningKey, enums::SignatureScheme};
1+
use rustls::crypto::{SignatureScheme, SigningKey};
22
use rustls_cng::{signer::CngSigningKey, store::CertStore};
33

44
const PFX: &[u8] = include_bytes!("assets/rustls-ec.p12");

0 commit comments

Comments
 (0)