@@ -31,6 +31,7 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
31
31
not( feature = "use-openssl" )
32
32
) ) ]
33
33
use rustls:: {
34
+ crypto:: CryptoProvider ,
34
35
pki_types:: ServerName ,
35
36
pki_types:: { Der , TrustAnchor } ,
36
37
ClientConfig , ClientConnection , RootCertStore , StreamOwned ,
@@ -368,7 +369,13 @@ impl RawClient<ElectrumSslStream> {
368
369
socket_addrs : A ,
369
370
validate_domain : bool ,
370
371
timeout : Option < Duration > ,
372
+ crypto_provider : Option < & CryptoProvider > ,
371
373
) -> 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
+
372
379
debug ! (
373
380
"new_ssl socket_addrs.domain():{:?} validate_domain:{} timeout:{:?}" ,
374
381
socket_addrs. domain( ) ,
@@ -378,16 +385,28 @@ impl RawClient<ElectrumSslStream> {
378
385
if validate_domain {
379
386
socket_addrs. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
380
387
}
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
+
381
400
match timeout {
382
401
Some ( timeout) => {
383
402
let stream = connect_with_total_timeout ( socket_addrs. clone ( ) , timeout) ?;
384
403
stream. set_read_timeout ( Some ( timeout) ) ?;
385
404
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 )
387
406
}
388
407
None => {
389
408
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 )
391
410
}
392
411
}
393
412
}
@@ -397,10 +416,13 @@ impl RawClient<ElectrumSslStream> {
397
416
socket_addr : A ,
398
417
validate_domain : bool ,
399
418
tcp_stream : TcpStream ,
419
+ crypto_provider : CryptoProvider ,
400
420
) -> Result < Self , Error > {
401
421
use std:: convert:: TryFrom ;
402
422
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) ) ?;
404
426
405
427
let config = if validate_domain {
406
428
socket_addr. domain ( ) . ok_or ( Error :: MissingDomain ) ?;
@@ -467,14 +489,66 @@ impl RawClient<ElectrumProxyStream> {
467
489
Ok ( stream. into ( ) )
468
490
}
469
491
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" )
474
499
) ) ]
475
500
/// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
476
501
/// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
477
502
/// 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.
478
552
pub fn new_proxy_ssl < T : ToTargetAddr > (
479
553
target_addr : T ,
480
554
validate_domain : bool ,
0 commit comments