@@ -23,14 +23,11 @@ use bitcoin::{Script, Txid};
23
23
use openssl:: ssl:: { SslConnector , SslMethod , SslStream , SslVerifyMode } ;
24
24
25
25
#[ 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" ) ,
31
27
not( feature = "use-openssl" )
32
28
) ) ]
33
29
use rustls:: {
30
+ crypto:: CryptoProvider ,
34
31
pki_types:: ServerName ,
35
32
pki_types:: { Der , TrustAnchor } ,
36
33
ClientConfig , ClientConnection , RootCertStore , StreamOwned ,
@@ -368,7 +365,13 @@ impl RawClient<ElectrumSslStream> {
368
365
socket_addrs : A ,
369
366
validate_domain : bool ,
370
367
timeout : Option < Duration > ,
368
+ crypto_provider : Option < & CryptoProvider > ,
371
369
) -> 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
+
372
375
debug ! (
373
376
"new_ssl socket_addrs.domain():{:?} validate_domain:{} timeout:{:?}" ,
374
377
socket_addrs. domain( ) ,
@@ -378,16 +381,27 @@ impl RawClient<ElectrumSslStream> {
378
381
if validate_domain {
379
382
socket_addrs. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
380
383
}
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
+
381
395
match timeout {
382
396
Some ( timeout) => {
383
397
let stream = connect_with_total_timeout ( socket_addrs. clone ( ) , timeout) ?;
384
398
stream. set_read_timeout ( Some ( timeout) ) ?;
385
399
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 )
387
401
}
388
402
None => {
389
403
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 )
391
405
}
392
406
}
393
407
}
@@ -397,10 +411,13 @@ impl RawClient<ElectrumSslStream> {
397
411
socket_addr : A ,
398
412
validate_domain : bool ,
399
413
tcp_stream : TcpStream ,
414
+ crypto_provider : CryptoProvider ,
400
415
) -> Result < Self , Error > {
401
416
use std:: convert:: TryFrom ;
402
417
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 ) ?;
404
421
405
422
let config = if validate_domain {
406
423
socket_addr. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
@@ -441,6 +458,7 @@ impl RawClient<ElectrumSslStream> {
441
458
#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
442
459
/// Transport type used to establish a connection to a server through a socks proxy
443
460
pub type ElectrumProxyStream = Socks5Stream ;
461
+
444
462
#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
445
463
impl RawClient < ElectrumProxyStream > {
446
464
/// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as a
@@ -467,14 +485,66 @@ impl RawClient<ElectrumProxyStream> {
467
485
Ok ( stream. into ( ) )
468
486
}
469
487
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" )
474
495
) ) ]
475
496
/// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
476
497
/// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
477
498
/// 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.
478
548
pub fn new_proxy_ssl < T : ToTargetAddr > (
479
549
target_addr : T ,
480
550
validate_domain : bool ,
0 commit comments