@@ -24,7 +24,13 @@ mod macos;
2424use macos as platform;
2525
2626use rustls:: RootCertStore ;
27- use std:: io:: Error ;
27+ use std:: io:: { Error , ErrorKind } ;
28+ use std:: io:: BufRead ;
29+
30+ pub trait RootStoreBuilder {
31+ fn load_der ( & mut self , der : Vec < u8 > ) -> Result < ( ) , Error > ;
32+ fn load_pem_file ( & mut self , rd : & mut dyn BufRead ) -> Result < ( ) , Error > ;
33+ }
2834
2935/// Loads root certificates found in the platform's native certificate
3036/// store.
@@ -37,5 +43,38 @@ use std::io::Error;
3743/// and parsing a ~300KB disk file. It's therefore prudent to call
3844/// this sparingly.
3945pub fn load_native_certs ( ) -> PartialResult < RootCertStore , Error > {
40- platform:: load_native_certs ( )
46+ struct RootCertStoreLoader {
47+ store : RootCertStore ,
48+ } ;
49+ impl RootStoreBuilder for RootCertStoreLoader {
50+ fn load_der ( & mut self , der : Vec < u8 > ) -> Result < ( ) , Error > {
51+ self . store . add ( & rustls:: Certificate ( der) )
52+ . map_err ( |err| Error :: new ( ErrorKind :: InvalidData , err) )
53+ }
54+ fn load_pem_file ( & mut self , rd : & mut dyn BufRead ) -> Result < ( ) , Error > {
55+ self . store . add_pem_file ( rd)
56+ . map ( |_| ( ) )
57+ . map_err ( |( ) | Error :: new ( ErrorKind :: InvalidData , format ! ( "could not load PEM file" ) ) )
58+ }
59+ }
60+ let mut loader = RootCertStoreLoader {
61+ store : RootCertStore :: empty ( ) ,
62+ } ;
63+ match build_native_certs ( & mut loader) {
64+ Err ( err) if loader. store . is_empty ( ) => Err ( ( None , err) ) ,
65+ Err ( err) => Err ( ( Some ( loader. store ) , err) ) ,
66+ Ok ( ( ) ) => Ok ( loader. store ) ,
67+ }
68+ }
69+
70+ /// Loads root certificates found in the platform's native certificate
71+ /// store, executing callbacks on the provided builder.
72+ ///
73+ /// This function fails in a platform-specific way, expressed in a `std::io::Error`.
74+ ///
75+ /// This function can be expensive: on some platforms it involves loading
76+ /// and parsing a ~300KB disk file. It's therefore prudent to call
77+ /// this sparingly.
78+ pub fn build_native_certs < B : RootStoreBuilder > ( builder : & mut B ) -> Result < ( ) , Error > {
79+ platform:: build_native_certs ( builder)
4180}
0 commit comments