33use std:: sync:: Arc ;
44
55use rustls:: {
6- crypto:: { Signer , SigningKey } ,
7- enums:: SignatureScheme ,
6+ crypto:: { SignatureScheme , Signer , SigningKey } ,
87 error:: { Error , OtherError } ,
98} ;
109use rustls_pki_types:: SubjectPublicKeyInfoDer ;
@@ -15,31 +14,67 @@ use windows_sys::Win32::Security::Cryptography::{
1514use 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
1918fn 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
0 commit comments