@@ -100,7 +100,7 @@ impl Identity {
100
100
101
101
pub fn from_pkcs8 ( pem : & [ u8 ] , key : & [ u8 ] ) -> Result < Identity , Error > {
102
102
let mut store = Memory :: new ( ) ?. into_store ( ) ;
103
- let mut cert_iter = crate :: pem:: PemBlock :: new ( pem) . into_iter ( ) ;
103
+ let mut cert_iter = pem:: PemBlock :: new ( pem) . into_iter ( ) ;
104
104
let leaf = cert_iter. next ( ) . expect ( "at least one certificate must be provided to create an identity" ) ;
105
105
let cert = CertContext :: from_pem ( std:: str:: from_utf8 ( leaf) . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: InvalidInput , "leaf cert contains invalid utf8" ) ) ?) ?;
106
106
@@ -378,3 +378,84 @@ impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
378
378
self . 0 . flush ( )
379
379
}
380
380
}
381
+
382
+
383
+ mod pem {
384
+ /// Split data by PEM guard lines
385
+ pub struct PemBlock < ' a > {
386
+ pem_block : & ' a str ,
387
+ cur_end : usize ,
388
+ }
389
+
390
+ impl < ' a > PemBlock < ' a > {
391
+ pub fn new ( data : & ' a [ u8 ] ) -> PemBlock < ' a > {
392
+ let s = :: std:: str:: from_utf8 ( data) . unwrap ( ) ;
393
+ PemBlock {
394
+ pem_block : s,
395
+ cur_end : s. find ( "-----BEGIN" ) . unwrap_or ( s. len ( ) ) ,
396
+ }
397
+ }
398
+ }
399
+
400
+ impl < ' a > Iterator for PemBlock < ' a > {
401
+ type Item = & ' a [ u8 ] ;
402
+ fn next ( & mut self ) -> Option < Self :: Item > {
403
+ let last = self . pem_block . len ( ) ;
404
+ if self . cur_end >= last {
405
+ return None ;
406
+ }
407
+ let begin = self . cur_end ;
408
+ let pos = self . pem_block [ begin + 1 ..] . find ( "-----BEGIN" ) ;
409
+ self . cur_end = match pos {
410
+ Some ( end) => end + begin + 1 ,
411
+ None => last,
412
+ } ;
413
+ return Some ( & self . pem_block [ begin..self . cur_end ] . as_bytes ( ) ) ;
414
+ }
415
+ }
416
+
417
+ #[ test]
418
+ fn test_split ( ) {
419
+ // Split three certs, CRLF line terminators.
420
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\r \n -----END FIRST-----\r \n \
421
+ -----BEGIN SECOND-----\r \n -----END SECOND\r \n \
422
+ -----BEGIN THIRD-----\r \n -----END THIRD\r \n ") . collect:: <Vec <& [ u8 ] >>( ) ,
423
+ vec![ b"-----BEGIN FIRST-----\r \n -----END FIRST-----\r \n " as & [ u8 ] ,
424
+ b"-----BEGIN SECOND-----\r \n -----END SECOND\r \n " ,
425
+ b"-----BEGIN THIRD-----\r \n -----END THIRD\r \n " ] ) ;
426
+ // Split three certs, CRLF line terminators except at EOF.
427
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\r \n -----END FIRST-----\r \n \
428
+ -----BEGIN SECOND-----\r \n -----END SECOND-----\r \n \
429
+ -----BEGIN THIRD-----\r \n -----END THIRD-----") . collect:: <Vec <& [ u8 ] >>( ) ,
430
+ vec![ b"-----BEGIN FIRST-----\r \n -----END FIRST-----\r \n " as & [ u8 ] ,
431
+ b"-----BEGIN SECOND-----\r \n -----END SECOND-----\r \n " ,
432
+ b"-----BEGIN THIRD-----\r \n -----END THIRD-----" ] ) ;
433
+ // Split two certs, LF line terminators.
434
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\n -----END FIRST-----\n \
435
+ -----BEGIN SECOND-----\n -----END SECOND\n ") . collect:: <Vec <& [ u8 ] >>( ) ,
436
+ vec![ b"-----BEGIN FIRST-----\n -----END FIRST-----\n " as & [ u8 ] ,
437
+ b"-----BEGIN SECOND-----\n -----END SECOND\n " ] ) ;
438
+ // Split two certs, CR line terminators.
439
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\r -----END FIRST-----\r \
440
+ -----BEGIN SECOND-----\r -----END SECOND\r ") . collect:: <Vec <& [ u8 ] >>( ) ,
441
+ vec![ b"-----BEGIN FIRST-----\r -----END FIRST-----\r " as & [ u8 ] ,
442
+ b"-----BEGIN SECOND-----\r -----END SECOND\r " ] ) ;
443
+ // Split two certs, LF line terminators except at EOF.
444
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\n -----END FIRST-----\n \
445
+ -----BEGIN SECOND-----\n -----END SECOND") . collect:: <Vec <& [ u8 ] >>( ) ,
446
+ vec![ b"-----BEGIN FIRST-----\n -----END FIRST-----\n " as & [ u8 ] ,
447
+ b"-----BEGIN SECOND-----\n -----END SECOND" ] ) ;
448
+ // Split a single cert, LF line terminators.
449
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\n -----END FIRST-----\n " ) . collect:: <Vec <& [ u8 ] >>( ) ,
450
+ vec![ b"-----BEGIN FIRST-----\n -----END FIRST-----\n " as & [ u8 ] ] ) ;
451
+ // Split a single cert, LF line terminators except at EOF.
452
+ assert_eq ! ( PemBlock :: new( b"-----BEGIN FIRST-----\n -----END FIRST-----" ) . collect:: <Vec <& [ u8 ] >>( ) ,
453
+ vec![ b"-----BEGIN FIRST-----\n -----END FIRST-----" as & [ u8 ] ] ) ;
454
+ // (Don't) split garbage.
455
+ assert_eq ! ( PemBlock :: new( b"junk" ) . collect:: <Vec <& [ u8 ] >>( ) ,
456
+ Vec :: <& [ u8 ] >:: new( ) ) ;
457
+ assert_eq ! ( PemBlock :: new( b"junk-----BEGIN garbage" ) . collect:: <Vec <& [ u8 ] >>( ) ,
458
+ vec![ b"-----BEGIN garbage" as & [ u8 ] ] ) ;
459
+ }
460
+ }
461
+
0 commit comments