1
1
use futures_util:: future;
2
- use std:: io;
3
- use std:: io:: { Cursor , Read , Write } ;
2
+ use std:: io:: { self , BufReader , Cursor , Read , Write } ;
4
3
use std:: sync:: Arc ;
5
4
use std:: task:: { Context , Poll } ;
6
5
use std:: time:: SystemTime ;
@@ -48,7 +47,7 @@ impl<S: Socket> Socket for RustlsSocket<S> {
48
47
match self . state . writer ( ) . write ( buf) {
49
48
// Returns a zero-length write when the buffer is full.
50
49
Ok ( 0 ) => Err ( io:: ErrorKind :: WouldBlock . into ( ) ) ,
51
- other => return other,
50
+ other => other,
52
51
}
53
52
}
54
53
@@ -81,10 +80,32 @@ where
81
80
{
82
81
let config = ClientConfig :: builder ( ) . with_safe_defaults ( ) ;
83
82
83
+ // authentication using user's key and its associated certificate
84
+ let user_auth = match ( tls_config. client_cert_path , tls_config. client_key_path ) {
85
+ ( Some ( cert_path) , Some ( key_path) ) => {
86
+ let cert_chain = certs_from_pem ( cert_path. data ( ) . await ?) ?;
87
+ let key_der = private_key_from_pem ( key_path. data ( ) . await ?) ?;
88
+ Some ( ( cert_chain, key_der) )
89
+ }
90
+ ( None , None ) => None ,
91
+ ( _, _) => {
92
+ return Err ( Error :: Configuration (
93
+ "user auth key and certs must be given together" . into ( ) ,
94
+ ) )
95
+ }
96
+ } ;
97
+
84
98
let config = if tls_config. accept_invalid_certs {
85
- config
86
- . with_custom_certificate_verifier ( Arc :: new ( DummyTlsVerifier ) )
87
- . with_no_client_auth ( )
99
+ if let Some ( user_auth) = user_auth {
100
+ config
101
+ . with_custom_certificate_verifier ( Arc :: new ( DummyTlsVerifier ) )
102
+ . with_single_cert ( user_auth. 0 , user_auth. 1 )
103
+ . map_err ( Error :: tls) ?
104
+ } else {
105
+ config
106
+ . with_custom_certificate_verifier ( Arc :: new ( DummyTlsVerifier ) )
107
+ . with_no_client_auth ( )
108
+ }
88
109
} else {
89
110
let mut cert_store = RootCertStore :: empty ( ) ;
90
111
cert_store. add_server_trust_anchors ( webpki_roots:: TLS_SERVER_ROOTS . 0 . iter ( ) . map ( |ta| {
@@ -100,37 +121,22 @@ where
100
121
let mut cursor = Cursor :: new ( data) ;
101
122
102
123
for cert in rustls_pemfile:: certs ( & mut cursor)
103
- . map_err ( |_| Error :: Tls ( format ! ( "Invalid certificate {}" , ca ) . into ( ) ) ) ?
124
+ . map_err ( |_| Error :: Tls ( format ! ( "Invalid certificate {ca}" ) . into ( ) ) ) ?
104
125
{
105
126
cert_store
106
127
. add ( & rustls:: Certificate ( cert) )
107
128
. map_err ( |err| Error :: Tls ( err. into ( ) ) ) ?;
108
129
}
109
130
}
110
131
111
- // authentication using user's key and its associated certificate
112
- let user_auth = match ( tls_config. client_cert_path , tls_config. client_key_path ) {
113
- ( Some ( cert_path) , Some ( key_path) ) => {
114
- let cert_chain = certs_from_pem ( cert_path. data ( ) . await ?) ?;
115
- let key_der = private_key_from_pem ( key_path. data ( ) . await ?) ?;
116
- Some ( ( cert_chain, key_der) )
117
- }
118
- ( None , None ) => None ,
119
- ( _, _) => {
120
- return Err ( Error :: Configuration (
121
- "user auth key and certs must be given together" . into ( ) ,
122
- ) )
123
- }
124
- } ;
125
-
126
132
if tls_config. accept_invalid_hostnames {
127
133
let verifier = WebPkiVerifier :: new ( cert_store, None ) ;
128
134
129
135
if let Some ( user_auth) = user_auth {
130
136
config
131
137
. with_custom_certificate_verifier ( Arc :: new ( NoHostnameTlsVerifier { verifier } ) )
132
138
. with_single_cert ( user_auth. 0 , user_auth. 1 )
133
- . map_err ( |err| Error :: Tls ( err . into ( ) ) ) ?
139
+ . map_err ( Error :: tls ) ?
134
140
} else {
135
141
config
136
142
. with_custom_certificate_verifier ( Arc :: new ( NoHostnameTlsVerifier { verifier } ) )
@@ -140,7 +146,7 @@ where
140
146
config
141
147
. with_root_certificates ( cert_store)
142
148
. with_single_cert ( user_auth. 0 , user_auth. 1 )
143
- . map_err ( |err| Error :: Tls ( err . into ( ) ) ) ?
149
+ . map_err ( Error :: tls ) ?
144
150
} else {
145
151
config
146
152
. with_root_certificates ( cert_store)
@@ -162,6 +168,31 @@ where
162
168
Ok ( socket)
163
169
}
164
170
171
+ fn certs_from_pem ( pem : Vec < u8 > ) -> Result < Vec < rustls:: Certificate > , Error > {
172
+ let cur = Cursor :: new ( pem) ;
173
+ let mut reader = BufReader :: new ( cur) ;
174
+ rustls_pemfile:: certs ( & mut reader) ?
175
+ . into_iter ( )
176
+ . map ( |v| Ok ( rustls:: Certificate ( v) ) )
177
+ . collect ( )
178
+ }
179
+
180
+ fn private_key_from_pem ( pem : Vec < u8 > ) -> Result < rustls:: PrivateKey , Error > {
181
+ let cur = Cursor :: new ( pem) ;
182
+ let mut reader = BufReader :: new ( cur) ;
183
+
184
+ loop {
185
+ match rustls_pemfile:: read_one ( & mut reader) ? {
186
+ Some ( rustls_pemfile:: Item :: RSAKey ( key) ) => return Ok ( rustls:: PrivateKey ( key) ) ,
187
+ Some ( rustls_pemfile:: Item :: PKCS8Key ( key) ) => return Ok ( rustls:: PrivateKey ( key) ) ,
188
+ None => break ,
189
+ _ => { }
190
+ }
191
+ }
192
+
193
+ Err ( Error :: Configuration ( "no keys found pem file" . into ( ) ) )
194
+ }
195
+
165
196
struct DummyTlsVerifier ;
166
197
167
198
impl ServerCertVerifier for DummyTlsVerifier {
0 commit comments