@@ -23,14 +23,11 @@ use bitcoin::{Script, Txid};
2323use openssl:: ssl:: { SslConnector , SslMethod , SslStream , SslVerifyMode } ;
2424
2525#[ cfg( all(
26- any(
27- feature = "default" ,
28- feature = "use-rustls" ,
29- feature = "use-rustls-ring"
30- ) ,
26+ any( feature = "use-rustls" , feature = "use-rustls-ring" ) ,
3127 not( feature = "use-openssl" )
3228) ) ]
3329use rustls:: {
30+ crypto:: CryptoProvider ,
3431 pki_types:: ServerName ,
3532 pki_types:: { Der , TrustAnchor } ,
3633 ClientConfig , ClientConnection , RootCertStore , StreamOwned ,
@@ -368,7 +365,13 @@ impl RawClient<ElectrumSslStream> {
368365 socket_addrs : A ,
369366 validate_domain : bool ,
370367 timeout : Option < Duration > ,
368+ crypto_provider : Option < & CryptoProvider > ,
371369 ) -> Result < Self , Error > {
370+ #[ cfg( feature = "use-rustls" ) ]
371+ use rustls:: crypto:: aws_lc_rs:: default_provider;
372+ #[ cfg( feature = "use-rustls-ring" ) ]
373+ use rustls:: crypto:: ring:: default_provider;
374+
372375 debug ! (
373376 "new_ssl socket_addrs.domain():{:?} validate_domain:{} timeout:{:?}" ,
374377 socket_addrs. domain( ) ,
@@ -378,16 +381,27 @@ impl RawClient<ElectrumSslStream> {
378381 if validate_domain {
379382 socket_addrs. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
380383 }
384+
385+ let crypto_provider = match crypto_provider {
386+ Some ( provider) => provider. to_owned ( ) ,
387+
388+ #[ cfg( feature = "use-rustls" ) ]
389+ None => default_provider ( ) ,
390+
391+ #[ cfg( feature = "use-rustls-ring" ) ]
392+ None => default_provider ( ) ,
393+ } ;
394+
381395 match timeout {
382396 Some ( timeout) => {
383397 let stream = connect_with_total_timeout ( socket_addrs. clone ( ) , timeout) ?;
384398 stream. set_read_timeout ( Some ( timeout) ) ?;
385399 stream. set_write_timeout ( Some ( timeout) ) ?;
386- Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream)
400+ Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream, crypto_provider )
387401 }
388402 None => {
389403 let stream = TcpStream :: connect ( socket_addrs. clone ( ) ) ?;
390- Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream)
404+ Self :: new_ssl_from_stream ( socket_addrs, validate_domain, stream, crypto_provider )
391405 }
392406 }
393407 }
@@ -397,10 +411,13 @@ impl RawClient<ElectrumSslStream> {
397411 socket_addr : A ,
398412 validate_domain : bool ,
399413 tcp_stream : TcpStream ,
414+ crypto_provider : CryptoProvider ,
400415 ) -> Result < Self , Error > {
401416 use std:: convert:: TryFrom ;
402417
403- let builder = ClientConfig :: builder ( ) ;
418+ let builder = ClientConfig :: builder_with_provider ( crypto_provider. into ( ) )
419+ . with_safe_default_protocol_versions ( )
420+ . map_err ( Error :: CouldNotBuildWithSafeDefaultVersion ) ?;
404421
405422 let config = if validate_domain {
406423 socket_addr. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
@@ -441,6 +458,7 @@ impl RawClient<ElectrumSslStream> {
441458#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
442459/// Transport type used to establish a connection to a server through a socks proxy
443460pub type ElectrumProxyStream = Socks5Stream ;
461+
444462#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
445463impl RawClient < ElectrumProxyStream > {
446464 /// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as a
@@ -467,14 +485,66 @@ impl RawClient<ElectrumProxyStream> {
467485 Ok ( stream. into ( ) )
468486 }
469487
470- #[ cfg( any(
471- feature = "use-openssl" ,
472- feature = "use-rustls" ,
473- feature = "use-rustls-ring"
488+ #[ cfg( all(
489+ any(
490+ feature = "default" ,
491+ feature = "use-rustls" ,
492+ feature = "use-rustls-ring"
493+ ) ,
494+ not( feature = "use-openssl" )
474495 ) ) ]
475496 /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
476497 /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
477498 /// allows to specify, for instance, `.onion` addresses.
499+ pub fn new_proxy_ssl < T : ToTargetAddr > (
500+ target_addr : T ,
501+ validate_domain : bool ,
502+ proxy : & crate :: Socks5Config ,
503+ timeout : Option < Duration > ,
504+ crypto_provider : Option < & CryptoProvider > ,
505+ ) -> Result < RawClient < ElectrumSslStream > , Error > {
506+ #[ cfg( feature = "use-rustls" ) ]
507+ use rustls:: crypto:: aws_lc_rs:: default_provider;
508+ #[ cfg( feature = "use-rustls-ring" ) ]
509+ use rustls:: crypto:: ring:: default_provider;
510+
511+ let target = target_addr. to_target_addr ( ) ?;
512+
513+ let mut stream = match proxy. credentials . as_ref ( ) {
514+ Some ( cred) => Socks5Stream :: connect_with_password (
515+ & proxy. addr ,
516+ target_addr,
517+ & cred. username ,
518+ & cred. password ,
519+ timeout,
520+ ) ?,
521+ None => Socks5Stream :: connect ( & proxy. addr , target. clone ( ) , timeout) ?,
522+ } ;
523+ stream. get_mut ( ) . set_read_timeout ( timeout) ?;
524+ stream. get_mut ( ) . set_write_timeout ( timeout) ?;
525+
526+ let crypto_provider = match crypto_provider {
527+ Some ( provider) => provider. to_owned ( ) ,
528+
529+ #[ cfg( feature = "use-rustls" ) ]
530+ None => default_provider ( ) ,
531+
532+ #[ cfg( feature = "use-rustls-ring" ) ]
533+ None => default_provider ( ) ,
534+ } ;
535+
536+ RawClient :: new_ssl_from_stream (
537+ target,
538+ validate_domain,
539+ stream. into_inner ( ) ,
540+ crypto_provider,
541+ )
542+ }
543+
544+ #[ cfg( feature = "use-openssl" ) ]
545+ /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
546+ /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
547+ /// allows to specify, for instance, `.onion` addresses.
478548 pub fn new_proxy_ssl < T : ToTargetAddr > (
479549 target_addr : T ,
480550 validate_domain : bool ,
0 commit comments