@@ -31,7 +31,8 @@ use crate::util::errors::APIError;
31
31
32
32
use bitcoin:: hash_types:: BlockHash ;
33
33
34
- use bitcoin:: hashes:: Hash ;
34
+ use bitcoin:: hashes:: { Hash , HashEngine } ;
35
+ use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
35
36
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
36
37
37
38
use bitcoin:: secp256k1;
@@ -57,7 +58,12 @@ fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>,
57
58
// 3: final node fails backward (but tamper onion payloads from node0)
58
59
// 100: trigger error in the intermediate node and tamper returning fail_htlc
59
60
// 200: trigger error in the final node and tamper returning fail_htlc
60
- fn run_onion_failure_test_with_fail_intercept < F1 , F2 , F3 > ( _name : & str , test_case : u8 , nodes : & Vec < Node > , route : & Route , payment_hash : & PaymentHash , payment_secret : & PaymentSecret , mut callback_msg : F1 , mut callback_fail : F2 , mut callback_node : F3 , expected_retryable : bool , expected_error_code : Option < u16 > , expected_channel_update : Option < NetworkUpdate > , expected_short_channel_id : Option < u64 > )
61
+ fn run_onion_failure_test_with_fail_intercept < F1 , F2 , F3 > (
62
+ _name : & str , test_case : u8 , nodes : & Vec < Node > , route : & Route , payment_hash : & PaymentHash ,
63
+ payment_secret : & PaymentSecret , mut callback_msg : F1 , mut callback_fail : F2 ,
64
+ mut callback_node : F3 , expected_retryable : bool , expected_error_code : Option < u16 > ,
65
+ expected_channel_update : Option < NetworkUpdate > , expected_short_channel_id : Option < u64 >
66
+ )
61
67
where F1 : for < ' a > FnMut ( & ' a mut msgs:: UpdateAddHTLC ) ,
62
68
F2 : for < ' a > FnMut ( & ' a mut msgs:: UpdateFailHTLC ) ,
63
69
F3 : FnMut ( ) ,
@@ -620,6 +626,49 @@ fn test_onion_failure() {
620
626
} , ||{
621
627
nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash) ;
622
628
} , true , Some ( 23 ) , None , None ) ;
629
+
630
+ run_onion_failure_test_with_fail_intercept ( "bogus err packet with valid hmac" , 200 , & nodes,
631
+ & route, & payment_hash, & payment_secret, |_msg| { } , |msg| {
632
+ let session_priv = SecretKey :: from_slice ( & [ 3 ; 32 ] ) . unwrap ( ) ;
633
+ let onion_keys = onion_utils:: construct_onion_keys ( & Secp256k1 :: new ( ) , & route. paths [ 0 ] , & session_priv) . unwrap ( ) ;
634
+ let mut decoded_err_packet = msgs:: DecodedOnionErrorPacket {
635
+ failuremsg : vec ! [ 0 ] ,
636
+ pad : vec ! [ 0 ; 255 ] ,
637
+ hmac : [ 0 ; 32 ] ,
638
+ } ;
639
+ let um = onion_utils:: gen_um_from_shared_secret ( & onion_keys[ 1 ] . shared_secret . as_ref ( ) ) ;
640
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
641
+ hmac. input ( & decoded_err_packet. encode ( ) [ 32 ..] ) ;
642
+ decoded_err_packet. hmac = Hmac :: from_engine ( hmac) . into_inner ( ) ;
643
+ msg. reason = onion_utils:: encrypt_failure_packet (
644
+ & onion_keys[ 1 ] . shared_secret . as_ref ( ) , & decoded_err_packet. encode ( ) [ ..] )
645
+ } , || nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash) , false , None ,
646
+ Some ( NetworkUpdate :: NodeFailure { node_id : route. paths [ 0 ] . hops [ 1 ] . pubkey , is_permanent : true } ) ,
647
+ Some ( channels[ 1 ] . 0 . contents . short_channel_id ) ) ;
648
+ run_onion_failure_test_with_fail_intercept ( "0-length channel update in UPDATE onion failure" , 200 , & nodes,
649
+ & route, & payment_hash, & payment_secret, |_msg| { } , |msg| {
650
+ let session_priv = SecretKey :: from_slice ( & [ 3 ; 32 ] ) . unwrap ( ) ;
651
+ let onion_keys = onion_utils:: construct_onion_keys ( & Secp256k1 :: new ( ) , & route. paths [ 0 ] , & session_priv) . unwrap ( ) ;
652
+ let mut decoded_err_packet = msgs:: DecodedOnionErrorPacket {
653
+ failuremsg : vec ! [
654
+ 0x10 , 0x7 , // UPDATE|7
655
+ 0x0 , 0x0 // 0-len channel update
656
+ ] ,
657
+ pad : vec ! [ 0 ; 255 - 4 /* 4-byte error message */ ] ,
658
+ hmac : [ 0 ; 32 ] ,
659
+ } ;
660
+ let um = onion_utils:: gen_um_from_shared_secret ( & onion_keys[ 1 ] . shared_secret . as_ref ( ) ) ;
661
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
662
+ hmac. input ( & decoded_err_packet. encode ( ) [ 32 ..] ) ;
663
+ decoded_err_packet. hmac = Hmac :: from_engine ( hmac) . into_inner ( ) ;
664
+ msg. reason = onion_utils:: encrypt_failure_packet (
665
+ & onion_keys[ 1 ] . shared_secret . as_ref ( ) , & decoded_err_packet. encode ( ) [ ..] )
666
+ } , || nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash) , true , Some ( 0x1000 |7 ) ,
667
+ Some ( NetworkUpdate :: ChannelFailure {
668
+ short_channel_id : channels[ 1 ] . 0 . contents . short_channel_id ,
669
+ is_permanent : false ,
670
+ } ) ,
671
+ Some ( channels[ 1 ] . 0 . contents . short_channel_id ) ) ;
623
672
}
624
673
625
674
#[ test]
0 commit comments