@@ -23,6 +23,7 @@ use std::{
23
23
24
24
use anyhow:: { bail, Context , Result } ;
25
25
use data_encoding:: BASE32_DNSSEC ;
26
+ use ed25519_dalek:: { pkcs8:: DecodePublicKey , VerifyingKey } ;
26
27
use iroh_base:: { NodeAddr , NodeId , RelayUrl , SecretKey } ;
27
28
use iroh_relay:: RelayMap ;
28
29
use n0_future:: { time:: Duration , Stream } ;
@@ -126,6 +127,7 @@ pub struct Builder {
126
127
addr_v6 : Option < SocketAddrV6 > ,
127
128
#[ cfg( any( test, feature = "test-utils" ) ) ]
128
129
path_selection : PathSelection ,
130
+ tls_auth : tls:: Authentication ,
129
131
}
130
132
131
133
impl Default for Builder {
@@ -150,6 +152,7 @@ impl Default for Builder {
150
152
addr_v6 : None ,
151
153
#[ cfg( any( test, feature = "test-utils" ) ) ]
152
154
path_selection : PathSelection :: default ( ) ,
155
+ tls_auth : tls:: Authentication :: RawPublicKey ,
153
156
}
154
157
}
155
158
}
@@ -168,6 +171,7 @@ impl Builder {
168
171
. unwrap_or_else ( || SecretKey :: generate ( rand:: rngs:: OsRng ) ) ;
169
172
let static_config = StaticConfig {
170
173
transport_config : Arc :: new ( self . transport_config ) ,
174
+ tls_auth : self . tls_auth ,
171
175
keylog : self . keylog ,
172
176
secret_key : secret_key. clone ( ) ,
173
177
} ;
@@ -358,6 +362,24 @@ impl Builder {
358
362
self
359
363
}
360
364
365
+ /// Use libp2p based self signed certificates for TLS.
366
+ ///
367
+ /// For details see the libp2p spec at <https://github.com/libp2p/specs/blob/master/tls/tls.md>
368
+ ///
369
+ /// This is the only mechanism available in `[email protected] ` and earlier.
370
+ pub fn tls_x509 ( mut self ) -> Self {
371
+ self . tls_auth = tls:: Authentication :: X509 ;
372
+ self
373
+ }
374
+
375
+ /// Use TLS Raw Public Keys
376
+ ///
377
+ /// This is the default, but is not compatible with older versions of iroh.
378
+ pub fn tls_raw_public_keys ( mut self ) -> Self {
379
+ self . tls_auth = tls:: Authentication :: RawPublicKey ;
380
+ self
381
+ }
382
+
361
383
#[ cfg( feature = "discovery-pkarr-dht" ) ]
362
384
/// Configures the endpoint to also use the mainline DHT with default settings.
363
385
///
@@ -501,6 +523,7 @@ impl Builder {
501
523
/// Configuration for a [`quinn::Endpoint`] that cannot be changed at runtime.
502
524
#[ derive( Debug ) ]
503
525
struct StaticConfig {
526
+ tls_auth : tls:: Authentication ,
504
527
secret_key : SecretKey ,
505
528
transport_config : Arc < quinn:: TransportConfig > ,
506
529
keylog : bool ,
@@ -509,33 +532,16 @@ struct StaticConfig {
509
532
impl StaticConfig {
510
533
/// Create a [`quinn::ServerConfig`] with the specified ALPN protocols.
511
534
fn create_server_config ( & self , alpn_protocols : Vec < Vec < u8 > > ) -> Result < ServerConfig > {
512
- let server_config = make_server_config (
513
- & self . secret_key ,
514
- alpn_protocols,
515
- self . transport_config . clone ( ) ,
516
- self . keylog ,
517
- ) ? ;
535
+ let quic_server_config =
536
+ self . tls_auth
537
+ . make_server_config ( & self . secret_key , alpn_protocols, self . keylog ) ? ;
538
+ let mut server_config = ServerConfig :: with_crypto ( Arc :: new ( quic_server_config ) ) ;
539
+ server_config . transport_config ( self . transport_config . clone ( ) ) ;
540
+
518
541
Ok ( server_config)
519
542
}
520
543
}
521
544
522
- /// Creates a [`ServerConfig`] with the given secret key and limits.
523
- // This return type can not longer be used anywhere in our public API. It is however still
524
- // used by iroh::node::Node (or rather iroh::node::Builder) to create a plain Quinn
525
- // endpoint.
526
- pub fn make_server_config (
527
- secret_key : & SecretKey ,
528
- alpn_protocols : Vec < Vec < u8 > > ,
529
- transport_config : Arc < TransportConfig > ,
530
- keylog : bool ,
531
- ) -> Result < ServerConfig > {
532
- let quic_server_config = tls:: make_server_config ( secret_key, alpn_protocols, keylog) ?;
533
- let mut server_config = ServerConfig :: with_crypto ( Arc :: new ( quic_server_config) ) ;
534
- server_config. transport_config ( transport_config) ;
535
-
536
- Ok ( server_config)
537
- }
538
-
539
545
/// Controls an iroh node, establishing connections with other nodes.
540
546
///
541
547
/// This is the main API interface to create connections to, and accept connections from
@@ -730,9 +736,9 @@ impl Endpoint {
730
736
) ;
731
737
let client_config = {
732
738
let alpn_protocols = vec ! [ alpn. to_vec( ) ] ;
733
- let quic_client_config = tls :: make_client_config (
739
+ let quic_client_config = self . static_config . tls_auth . make_client_config (
734
740
& self . static_config . secret_key ,
735
- Some ( node_id) ,
741
+ node_id,
736
742
alpn_protocols,
737
743
Some ( self . session_store . clone ( ) ) ,
738
744
self . static_config . keylog ,
@@ -1399,7 +1405,10 @@ impl Future for IncomingFuture {
1399
1405
Poll :: Pending => Poll :: Pending ,
1400
1406
Poll :: Ready ( Err ( err) ) => Poll :: Ready ( Err ( err) ) ,
1401
1407
Poll :: Ready ( Ok ( inner) ) => {
1402
- let conn = Connection { inner } ;
1408
+ let conn = Connection {
1409
+ inner,
1410
+ tls_auth : this. ep . static_config . tls_auth ,
1411
+ } ;
1403
1412
try_send_rtt_msg ( & conn, this. ep , None ) ;
1404
1413
Poll :: Ready ( Ok ( conn) )
1405
1414
}
@@ -1469,7 +1478,10 @@ impl Connecting {
1469
1478
pub fn into_0rtt ( self ) -> Result < ( Connection , ZeroRttAccepted ) , Self > {
1470
1479
match self . inner . into_0rtt ( ) {
1471
1480
Ok ( ( inner, zrtt_accepted) ) => {
1472
- let conn = Connection { inner } ;
1481
+ let conn = Connection {
1482
+ inner,
1483
+ tls_auth : self . ep . static_config . tls_auth ,
1484
+ } ;
1473
1485
let zrtt_accepted = ZeroRttAccepted {
1474
1486
inner : zrtt_accepted,
1475
1487
_discovery_drop_guard : self . _discovery_drop_guard ,
@@ -1521,7 +1533,10 @@ impl Future for Connecting {
1521
1533
Poll :: Pending => Poll :: Pending ,
1522
1534
Poll :: Ready ( Err ( err) ) => Poll :: Ready ( Err ( err) ) ,
1523
1535
Poll :: Ready ( Ok ( inner) ) => {
1524
- let conn = Connection { inner } ;
1536
+ let conn = Connection {
1537
+ inner,
1538
+ tls_auth : this. ep . static_config . tls_auth ,
1539
+ } ;
1525
1540
try_send_rtt_msg ( & conn, this. ep , * this. remote_node_id ) ;
1526
1541
Poll :: Ready ( Ok ( conn) )
1527
1542
}
@@ -1567,12 +1582,10 @@ impl Future for ZeroRttAccepted {
1567
1582
/// connection without losing application data.
1568
1583
///
1569
1584
/// May be cloned to obtain another handle to the same connection.
1570
- // This has repr(transparent) as it opens the door to potentially allow casting it to a
1571
- // quinn::Connection in the future. Right now however that'd be iroh_quinn::Connection.
1572
1585
#[ derive( Debug , Clone ) ]
1573
- #[ repr( transparent) ]
1574
1586
pub struct Connection {
1575
1587
inner : quinn:: Connection ,
1588
+ tls_auth : tls:: Authentication ,
1576
1589
}
1577
1590
1578
1591
impl Connection {
@@ -1802,8 +1815,17 @@ impl Connection {
1802
1815
certs. len( )
1803
1816
) ;
1804
1817
}
1805
- let cert = tls:: certificate:: parse ( & certs[ 0 ] ) ?;
1806
- Ok ( cert. peer_id ( ) )
1818
+
1819
+ match self . tls_auth {
1820
+ tls:: Authentication :: X509 => {
1821
+ let cert = tls:: certificate:: parse ( & certs[ 0 ] ) ?;
1822
+ Ok ( cert. peer_id ( ) )
1823
+ }
1824
+ tls:: Authentication :: RawPublicKey => {
1825
+ let peer_id = VerifyingKey :: from_public_key_der ( & certs[ 0 ] ) ?. into ( ) ;
1826
+ Ok ( peer_id)
1827
+ }
1828
+ }
1807
1829
}
1808
1830
Err ( _) => bail ! ( "invalid peer certificate" ) ,
1809
1831
} ,
@@ -2270,19 +2292,36 @@ mod tests {
2270
2292
2271
2293
#[ tokio:: test]
2272
2294
#[ traced_test]
2273
- async fn endpoint_bidi_send_recv ( ) {
2295
+ async fn endpoint_bidi_send_recv_x509 ( ) {
2296
+ endpoint_bidi_send_recv ( tls:: Authentication :: X509 ) . await
2297
+ }
2298
+
2299
+ #[ tokio:: test]
2300
+ #[ traced_test]
2301
+ async fn endpoint_bidi_send_recv_raw_public_key ( ) {
2302
+ endpoint_bidi_send_recv ( tls:: Authentication :: RawPublicKey ) . await
2303
+ }
2304
+
2305
+ async fn endpoint_bidi_send_recv ( auth : tls:: Authentication ) {
2274
2306
let ep1 = Endpoint :: builder ( )
2275
2307
. alpns ( vec ! [ TEST_ALPN . to_vec( ) ] )
2276
- . relay_mode ( RelayMode :: Disabled )
2277
- . bind ( )
2278
- . await
2279
- . unwrap ( ) ;
2308
+ . relay_mode ( RelayMode :: Disabled ) ;
2309
+
2310
+ let ep1 = match auth {
2311
+ tls:: Authentication :: X509 => ep1. tls_x509 ( ) ,
2312
+ tls:: Authentication :: RawPublicKey => ep1. tls_raw_public_keys ( ) ,
2313
+ } ;
2314
+ let ep1 = ep1. bind ( ) . await . unwrap ( ) ;
2280
2315
let ep2 = Endpoint :: builder ( )
2281
2316
. alpns ( vec ! [ TEST_ALPN . to_vec( ) ] )
2282
- . relay_mode ( RelayMode :: Disabled )
2283
- . bind ( )
2284
- . await
2285
- . unwrap ( ) ;
2317
+ . relay_mode ( RelayMode :: Disabled ) ;
2318
+
2319
+ let ep2 = match auth {
2320
+ tls:: Authentication :: X509 => ep2. tls_x509 ( ) ,
2321
+ tls:: Authentication :: RawPublicKey => ep2. tls_raw_public_keys ( ) ,
2322
+ } ;
2323
+ let ep2 = ep2. bind ( ) . await . unwrap ( ) ;
2324
+
2286
2325
let ep1_nodeaddr = ep1. node_addr ( ) . await . unwrap ( ) ;
2287
2326
let ep2_nodeaddr = ep2. node_addr ( ) . await . unwrap ( ) ;
2288
2327
ep1. add_node_addr ( ep2_nodeaddr. clone ( ) ) . unwrap ( ) ;
0 commit comments