@@ -31,6 +31,7 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
3131 not( feature = "use-openssl" )
3232) ) ]
3333use rustls:: {
34+ crypto:: CryptoProvider ,
3435 pki_types:: ServerName ,
3536 pki_types:: { Der , TrustAnchor } ,
3637 ClientConfig , ClientConnection , RootCertStore , StreamOwned ,
@@ -368,7 +369,13 @@ impl RawClient<ElectrumSslStream> {
368369 socket_addrs : A ,
369370 validate_domain : bool ,
370371 timeout : Option < Duration > ,
372+ crypto_provider : Option < & CryptoProvider > ,
371373 ) -> Result < Self , Error > {
374+ #[ cfg( feature = "use-rustls" ) ]
375+ use rustls:: crypto:: aws_lc_rs:: default_provider;
376+ #[ cfg( feature = "use-rustls-ring" ) ]
377+ use rustls:: crypto:: ring:: default_provider;
378+
372379 debug ! (
373380 "new_ssl socket_addrs.domain():{:?} validate_domain:{} timeout:{:?}" ,
374381 socket_addrs. domain( ) ,
@@ -378,16 +385,28 @@ impl RawClient<ElectrumSslStream> {
378385 if validate_domain {
379386 socket_addrs. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
380387 }
388+
389+ let crypto_provider = match crypto_provider {
390+ Some ( provider) => provider. to_owned ( ) ,
391+
392+ // TODO: (@leonardo) It should use the proper default of each provider.
393+ #[ cfg( feature = "use-rustls" ) ]
394+ None => default_provider ( ) ,
395+
396+ #[ cfg( feature = "use-rustls-ring" ) ]
397+ None => default_provider ( ) ,
398+ } ;
399+
381400 match timeout {
382401 Some ( timeout) => {
383402 let stream = connect_with_total_timeout ( socket_addrs. clone ( ) , timeout) ?;
384403 stream. set_read_timeout ( Some ( timeout) ) ?;
385404 stream. set_write_timeout ( Some ( timeout) ) ?;
386- Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream)
405+ Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream, crypto_provider )
387406 }
388407 None => {
389408 let stream = TcpStream :: connect ( socket_addrs. clone ( ) ) ?;
390- Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream)
409+ Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream, crypto_provider )
391410 }
392411 }
393412 }
@@ -397,10 +416,13 @@ impl RawClient<ElectrumSslStream> {
397416 socket_addr : A ,
398417 validate_domain : bool ,
399418 tcp_stream : TcpStream ,
419+ crypto_provider : CryptoProvider ,
400420 ) -> Result < Self , Error > {
401421 use std:: convert:: TryFrom ;
402422
403- let builder = ClientConfig :: builder ( ) ;
423+ let builder = ClientConfig :: builder_with_provider ( crypto_provider. into ( ) )
424+ . with_safe_default_protocol_versions ( )
425+ . map_err ( |e| Error :: CouldNotBuildWithSafeDefaultVersion ( e) ) ?;
404426
405427 let config = if validate_domain {
406428 socket_addr. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
@@ -467,14 +489,66 @@ impl RawClient<ElectrumProxyStream> {
467489 Ok ( stream. into ( ) )
468490 }
469491
470- #[ cfg( any(
471- feature = "use-openssl" ,
472- feature = "use-rustls" ,
473- feature = "use-rustls-ring"
492+ #[ cfg( all(
493+ any(
494+ feature = "default" ,
495+ feature = "use-rustls" ,
496+ feature = "use-rustls-ring"
497+ ) ,
498+ not( feature = "use-openssl" )
474499 ) ) ]
475500 /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
476501 /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
477502 /// allows to specify, for instance, `.onion` addresses.
503+ pub fn new_proxy_ssl < T : ToTargetAddr > (
504+ target_addr : T ,
505+ validate_domain : bool ,
506+ proxy : & crate :: Socks5Config ,
507+ timeout : Option < Duration > ,
508+ crypto_provider : Option < & CryptoProvider > ,
509+ ) -> Result < RawClient < ElectrumSslStream > , Error > {
510+ #[ cfg( feature = "use-rustls" ) ]
511+ use rustls:: crypto:: aws_lc_rs:: default_provider;
512+ #[ cfg( feature = "use-rustls-ring" ) ]
513+ use rustls:: crypto:: ring:: default_provider;
514+
515+ let target = target_addr. to_target_addr ( ) ?;
516+
517+ let mut stream = match proxy. credentials . as_ref ( ) {
518+ Some ( cred) => Socks5Stream :: connect_with_password (
519+ & proxy. addr ,
520+ target_addr,
521+ & cred. username ,
522+ & cred. password ,
523+ timeout,
524+ ) ?,
525+ None => Socks5Stream :: connect ( & proxy. addr , target. clone ( ) , timeout) ?,
526+ } ;
527+ stream. get_mut ( ) . set_read_timeout ( timeout) ?;
528+ stream. get_mut ( ) . set_write_timeout ( timeout) ?;
529+
530+ let crypto_provider = match crypto_provider {
531+ Some ( provider) => provider. to_owned ( ) ,
532+
533+ #[ cfg( feature = "use-rustls" ) ]
534+ None => default_provider ( ) ,
535+
536+ #[ cfg( feature = "use-rustls-ring" ) ]
537+ None => default_provider ( ) ,
538+ } ;
539+
540+ RawClient :: new_ssl_from_stream (
541+ target,
542+ validate_domain,
543+ stream. into_inner ( ) ,
544+ crypto_provider,
545+ )
546+ }
547+
548+ #[ cfg( feature = "use-openssl" ) ]
549+ /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
550+ /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
551+ /// allows to specify, for instance, `.onion` addresses.
478552 pub fn new_proxy_ssl < T : ToTargetAddr > (
479553 target_addr : T ,
480554 validate_domain : bool ,
0 commit comments