@@ -1037,6 +1037,7 @@ pub async fn default_send_request_handler(
1037
1037
first_byte_timeout,
1038
1038
between_bytes_timeout,
1039
1039
} : wasmtime_wasi_http:: types:: OutgoingRequestConfig ,
1040
+ client_tls_opts : Option < HashMap < String , ParsedClientTlsOpts > > ,
1040
1041
) -> Result < wasmtime_wasi_http:: types:: IncomingResponse , types:: ErrorCode > {
1041
1042
let authority = if let Some ( authority) = request. uri ( ) . authority ( ) {
1042
1043
if authority. port ( ) . is_some ( ) {
@@ -1078,7 +1079,7 @@ pub async fn default_send_request_handler(
1078
1079
#[ cfg( not( any( target_arch = "riscv64" , target_arch = "s390x" ) ) ) ]
1079
1080
{
1080
1081
use rustls:: pki_types:: ServerName ;
1081
- let config = get_client_tls_config_for_authority ( & authority) ;
1082
+ let config = get_client_tls_config_for_authority ( & authority, client_tls_opts ) ;
1082
1083
let connector = tokio_rustls:: TlsConnector :: from ( std:: sync:: Arc :: new ( config) ) ;
1083
1084
let mut parts = authority. split ( ":" ) ;
1084
1085
let host = parts. next ( ) . unwrap_or ( & authority) ;
@@ -1162,13 +1163,54 @@ pub async fn default_send_request_handler(
1162
1163
} )
1163
1164
}
1164
1165
1165
- fn get_client_tls_config_for_authority ( _authority : & String ) -> rustls:: ClientConfig {
1166
+ fn get_client_tls_config_for_authority (
1167
+ authority : & String ,
1168
+ client_tls_opts : Option < HashMap < String , ParsedClientTlsOpts > > ,
1169
+ ) -> rustls:: ClientConfig {
1166
1170
// derived from https://github.com/tokio-rs/tls/blob/master/tokio-rustls/examples/client/src/main.rs
1167
- let root_cert_store = rustls:: RootCertStore {
1171
+ let mut root_cert_store = rustls:: RootCertStore {
1168
1172
roots : webpki_roots:: TLS_SERVER_ROOTS . into ( ) ,
1169
1173
} ;
1170
1174
1171
- return rustls:: ClientConfig :: builder ( )
1172
- . with_root_certificates ( root_cert_store)
1173
- . with_no_client_auth ( ) ;
1175
+ let client_tls_opts = match client_tls_opts {
1176
+ Some ( opts) => opts,
1177
+ _ => {
1178
+ return rustls:: ClientConfig :: builder ( )
1179
+ . with_root_certificates ( root_cert_store)
1180
+ . with_no_client_auth ( ) ;
1181
+ }
1182
+ } ;
1183
+
1184
+ let client_tls_opts_for_host = match client_tls_opts. get ( authority) {
1185
+ Some ( opts) => opts,
1186
+ _ => {
1187
+ return rustls:: ClientConfig :: builder ( )
1188
+ . with_root_certificates ( root_cert_store)
1189
+ . with_no_client_auth ( ) ;
1190
+ }
1191
+ } ;
1192
+
1193
+ if let Some ( custom_root_ca) = & client_tls_opts_for_host. custom_root_ca {
1194
+ for cer in custom_root_ca {
1195
+ match root_cert_store. add ( cer. to_owned ( ) ) {
1196
+ Ok ( _) => { }
1197
+ Err ( e) => {
1198
+ tracing:: warn!( "failed to add custom cert to root_cert_store. error: {}" , e)
1199
+ }
1200
+ }
1201
+ }
1202
+ }
1203
+
1204
+ match (
1205
+ & client_tls_opts_for_host. cert_chain ,
1206
+ & client_tls_opts_for_host. private_key ,
1207
+ ) {
1208
+ ( Some ( cert_chain) , Some ( private_key) ) => rustls:: ClientConfig :: builder ( )
1209
+ . with_root_certificates ( root_cert_store)
1210
+ . with_client_auth_cert ( cert_chain. to_owned ( ) , private_key. clone_key ( ) )
1211
+ . unwrap ( ) ,
1212
+ _ => rustls:: ClientConfig :: builder ( )
1213
+ . with_root_certificates ( root_cert_store)
1214
+ . with_no_client_auth ( ) ,
1215
+ }
1174
1216
}
0 commit comments