@@ -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