@@ -31,20 +31,24 @@ use bitcoin::{secp256k1, Witness};
3131use  bitcoin:: blockdata:: script:: Script ; 
3232use  bitcoin:: hash_types:: { Txid ,  BlockHash } ; 
3333
34+ use  crate :: blinded_path:: payment:: { BlindedPaymentTlvs ,  ForwardTlvs ,  ReceiveTlvs } ; 
3435use  crate :: ln:: { ChannelId ,  PaymentPreimage ,  PaymentHash ,  PaymentSecret } ; 
3536use  crate :: ln:: features:: { ChannelFeatures ,  ChannelTypeFeatures ,  InitFeatures ,  NodeFeatures } ; 
3637use  crate :: ln:: onion_utils; 
3738use  crate :: onion_message; 
39+ use  crate :: sign:: { NodeSigner ,  Recipient } ; 
3840
3941use  crate :: prelude:: * ; 
4042use  core:: fmt; 
4143use  core:: fmt:: Debug ; 
42- use  crate :: io:: { self ,  Read } ; 
44+ use  core:: ops:: Deref ; 
45+ use  crate :: io:: { self ,  Cursor ,  Read } ; 
4346use  crate :: io_extras:: read_to_end; 
4447
4548use  crate :: events:: { MessageSendEventsProvider ,  OnionMessageProvider } ; 
49+ use  crate :: util:: chacha20poly1305rfc:: ChaChaPolyReadAdapter ; 
4650use  crate :: util:: logger; 
47- use  crate :: util:: ser:: { LengthReadable ,  Readable ,  ReadableArgs ,  Writeable ,  Writer ,  WithoutLength ,  FixedLengthReader ,  HighZeroBytesDroppedBigSize ,  Hostname ,  TransactionU16LenLimited ,  BigSize } ; 
51+ use  crate :: util:: ser:: { LengthReadable ,  LengthReadableArgs ,   Readable ,  ReadableArgs ,  Writeable ,  Writer ,  WithoutLength ,  FixedLengthReader ,  HighZeroBytesDroppedBigSize ,  Hostname ,  TransactionU16LenLimited ,  BigSize } ; 
4852
4953use  crate :: routing:: gossip:: { NodeAlias ,  NodeId } ; 
5054
@@ -1420,8 +1424,10 @@ pub trait OnionMessageHandler : OnionMessageProvider {
14201424
14211425mod  fuzzy_internal_msgs { 
14221426	use  bitcoin:: secp256k1:: PublicKey ; 
1427+ 	use  crate :: blinded_path:: payment:: { PaymentConstraints ,  PaymentRelay } ; 
14231428	use  crate :: prelude:: * ; 
14241429	use  crate :: ln:: { PaymentPreimage ,  PaymentSecret } ; 
1430+ 	use  crate :: ln:: features:: BlindedHopFeatures ; 
14251431
14261432	// These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize 
14271433	// them from untrusted input): 
@@ -1448,6 +1454,21 @@ mod fuzzy_internal_msgs {
14481454			amt_msat :  u64 , 
14491455			outgoing_cltv_value :  u32 , 
14501456		} , 
1457+ 		BlindedForward  { 
1458+ 			short_channel_id :  u64 , 
1459+ 			payment_relay :  PaymentRelay , 
1460+ 			payment_constraints :  PaymentConstraints , 
1461+ 			features :  BlindedHopFeatures , 
1462+ 			intro_node_blinding_point :  Option < PublicKey > , 
1463+ 		} , 
1464+ 		BlindedReceive  { 
1465+ 			amt_msat :  u64 , 
1466+ 			total_msat :  u64 , 
1467+ 			outgoing_cltv_value :  u32 , 
1468+ 			payment_secret :  PaymentSecret , 
1469+ 			payment_constraints :  PaymentConstraints , 
1470+ 			intro_node_blinding_point :  Option < PublicKey > , 
1471+ 		} 
14511472	} 
14521473
14531474	pub ( crate )  enum  OutboundOnionPayload  { 
@@ -2035,24 +2056,33 @@ impl Writeable for OutboundOnionPayload {
20352056	} 
20362057} 
20372058
2038- impl  Readable  for  InboundOnionPayload  { 
2039- 	fn  read < R :  Read > ( r :  & mut  R )  -> Result < Self ,  DecodeError >  { 
2040- 		let  mut  amt = HighZeroBytesDroppedBigSize ( 0u64 ) ; 
2041- 		let  mut  cltv_value = HighZeroBytesDroppedBigSize ( 0u32 ) ; 
2059+ impl < NS :  Deref >  ReadableArgs < ( Option < PublicKey > ,  & NS ) >  for  InboundOnionPayload  where  NS :: Target :  NodeSigner  { 
2060+ 	fn  read < R :  Read > ( r :  & mut  R ,  args :  ( Option < PublicKey > ,  & NS ) )  -> Result < Self ,  DecodeError >  { 
2061+ 		// TODO if we are the intro node and hit an error here, we won't correctly return the malformed 
2062+ 		// error atm 
2063+ 		let  ( update_add_blinding_point,  node_signer)  = args; 
2064+ 		let  mut  amt = None ; 
2065+ 		let  mut  cltv_value = None ; 
20422066		let  mut  short_id:  Option < u64 >  = None ; 
20432067		let  mut  payment_data:  Option < FinalOnionHopData >  = None ; 
2068+ 		let  mut  encrypted_tlvs_opt:  Option < WithoutLength < Vec < u8 > > >  = None ; 
2069+ 		let  mut  intro_node_blinding_point = None ; 
20442070		let  mut  payment_metadata:  Option < WithoutLength < Vec < u8 > > >  = None ; 
2071+ 		let  mut  total_msat = None ; 
20452072		let  mut  keysend_preimage:  Option < PaymentPreimage >  = None ; 
20462073		let  mut  custom_tlvs = Vec :: new ( ) ; 
20472074
20482075		let  tlv_len = BigSize :: read ( r) ?; 
20492076		let  rd = FixedLengthReader :: new ( r,  tlv_len. 0 ) ; 
20502077		decode_tlv_stream_with_custom_tlv_decode ! ( rd,  { 
2051- 			( 2 ,  amt,  required ) , 
2052- 			( 4 ,  cltv_value,  required ) , 
2078+ 			( 2 ,  amt,  ( option ,  encoding :   ( u64 ,   HighZeroBytesDroppedBigSize ) ) ) , 
2079+ 			( 4 ,  cltv_value,  ( option ,  encoding :   ( u32 ,   HighZeroBytesDroppedBigSize ) ) ) , 
20532080			( 6 ,  short_id,  option) , 
20542081			( 8 ,  payment_data,  option) , 
2082+ 			( 10 ,  encrypted_tlvs_opt,  option) , 
2083+ 			( 12 ,  intro_node_blinding_point,  option) , 
20552084			( 16 ,  payment_metadata,  option) , 
2085+ 			( 18 ,  total_msat,  ( option,  encoding:  ( u64 ,  HighZeroBytesDroppedBigSize ) ) ) , 
20562086			// See https://github.com/lightning/blips/blob/master/blip-0003.md 
20572087			( 5482373484 ,  keysend_preimage,  option) 
20582088		} ,  |msg_type:  u64 ,  msg_reader:  & mut  FixedLengthReader <_>| -> Result <bool ,  DecodeError > { 
@@ -2063,41 +2093,82 @@ impl Readable for InboundOnionPayload {
20632093			Ok ( true ) 
20642094		} ) ; 
20652095
2066- 		if  amt. 0  > MAX_VALUE_MSAT  {  return  Err ( DecodeError :: InvalidValue )  } 
2067- 		if  let  Some ( short_channel_id)  = short_id { 
2068- 			if  payment_data. is_some ( )  {  return  Err ( DecodeError :: InvalidValue )  } 
2069- 			if  payment_metadata. is_some ( )  {  return  Err ( DecodeError :: InvalidValue ) ;  } 
2096+ 		if  update_add_blinding_point. is_some ( )  && intro_node_blinding_point. is_some ( )  { 
2097+ 			return  Err ( DecodeError :: InvalidValue ) 
2098+ 		} 
2099+ 		if  amt. unwrap_or ( 0 )  > MAX_VALUE_MSAT  {  return  Err ( DecodeError :: InvalidValue )  } 
2100+ 
2101+ 		if  let  Some ( blinding_point)  = update_add_blinding_point. or ( intro_node_blinding_point)  { 
2102+ 			if  short_id. is_some ( )  || payment_data. is_some ( )  || payment_metadata. is_some ( )  { 
2103+ 				return  Err ( DecodeError :: InvalidValue ) 
2104+ 			} 
2105+ 			let  enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ; 
2106+ 			let  enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node ,  & blinding_point,  None ) 
2107+ 				. map_err ( |_| DecodeError :: InvalidValue ) ?; 
2108+ 			let  rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ; 
2109+ 			let  mut  s = Cursor :: new ( & enc_tlvs) ; 
2110+ 			let  mut  reader = FixedLengthReader :: new ( & mut  s,  enc_tlvs. len ( )  as  u64 ) ; 
2111+ 			match  ChaChaPolyReadAdapter :: read ( & mut  reader,  rho) ? { 
2112+ 				ChaChaPolyReadAdapter  {  readable :  BlindedPaymentTlvs :: Forward ( ForwardTlvs  { 
2113+ 					short_channel_id,  payment_relay,  payment_constraints,  features
2114+ 				} ) }  => { 
2115+ 					if  amt. is_some ( )  || cltv_value. is_some ( )  || total_msat. is_some ( )  { 
2116+ 						return  Err ( DecodeError :: InvalidValue ) 
2117+ 					} 
2118+ 					Ok ( Self :: BlindedForward  { 
2119+ 						short_channel_id, 
2120+ 						payment_relay, 
2121+ 						payment_constraints, 
2122+ 						features, 
2123+ 						intro_node_blinding_point, 
2124+ 					} ) 
2125+ 				} , 
2126+ 				ChaChaPolyReadAdapter  {  readable :  BlindedPaymentTlvs :: Receive ( ReceiveTlvs  { 
2127+ 					payment_secret,  payment_constraints
2128+ 				} ) }  => { 
2129+ 					if  total_msat. unwrap_or ( 0 )  > MAX_VALUE_MSAT  {  return  Err ( DecodeError :: InvalidValue )  } 
2130+ 					Ok ( Self :: BlindedReceive  { 
2131+ 						amt_msat :  amt. ok_or ( DecodeError :: InvalidValue ) ?, 
2132+ 						total_msat :  total_msat. ok_or ( DecodeError :: InvalidValue ) ?, 
2133+ 						outgoing_cltv_value :  cltv_value. ok_or ( DecodeError :: InvalidValue ) ?, 
2134+ 						payment_secret, 
2135+ 						payment_constraints, 
2136+ 						intro_node_blinding_point, 
2137+ 					} ) 
2138+ 				} , 
2139+ 			} 
2140+ 		}  else  if  let  Some ( short_channel_id)  = short_id { 
2141+ 			if  payment_data. is_some ( )  || payment_metadata. is_some ( )  || encrypted_tlvs_opt. is_some ( )  ||
2142+ 				total_msat. is_some ( ) 
2143+ 			{ 
2144+ 				return  Err ( DecodeError :: InvalidValue ) 
2145+ 			} 
20702146			Ok ( Self :: Forward  { 
20712147				short_channel_id, 
2072- 				amt_to_forward :  amt. 0 , 
2073- 				outgoing_cltv_value :  cltv_value. 0 , 
2148+ 				amt_to_forward :  amt. ok_or ( DecodeError :: InvalidValue ) ? , 
2149+ 				outgoing_cltv_value :  cltv_value. ok_or ( DecodeError :: InvalidValue ) ? , 
20742150			} ) 
20752151		}  else  { 
2152+ 			if  encrypted_tlvs_opt. is_some ( )  || total_msat. is_some ( )  { 
2153+ 				return  Err ( DecodeError :: InvalidValue ) 
2154+ 			} 
20762155			if  let  Some ( data)  = & payment_data { 
20772156				if  data. total_msat  > MAX_VALUE_MSAT  { 
2078- 					return  Err ( DecodeError :: InvalidValue ) ; 
2157+ 					return  Err ( DecodeError :: InvalidValue ) 
20792158				} 
20802159			} 
20812160			Ok ( Self :: Receive  { 
20822161				payment_data, 
20832162				payment_metadata :  payment_metadata. map ( |w| w. 0 ) , 
20842163				keysend_preimage, 
2085- 				amt_msat :  amt. 0 , 
2086- 				outgoing_cltv_value :  cltv_value. 0 , 
2164+ 				amt_msat :  amt. ok_or ( DecodeError :: InvalidValue ) ? , 
2165+ 				outgoing_cltv_value :  cltv_value. ok_or ( DecodeError :: InvalidValue ) ? , 
20872166				custom_tlvs, 
20882167			} ) 
20892168		} 
20902169	} 
20912170} 
20922171
2093- // ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and 
2094- // onion message packets. 
2095- impl  ReadableArgs < ( ) >  for  InboundOnionPayload  { 
2096- 	fn  read < R :  Read > ( r :  & mut  R ,  _arg :  ( ) )  -> Result < Self ,  DecodeError >  { 
2097- 		<Self  as  Readable >:: read ( r) 
2098- 	} 
2099- } 
2100- 
21012172impl  Writeable  for  Ping  { 
21022173	fn  write < W :  Writer > ( & self ,  w :  & mut  W )  -> Result < ( ) ,  io:: Error >  { 
21032174		self . ponglen . write ( w) ?; 
@@ -2513,7 +2584,8 @@ mod tests {
25132584	use  crate :: ln:: features:: { ChannelFeatures ,  ChannelTypeFeatures ,  InitFeatures ,  NodeFeatures } ; 
25142585	use  crate :: ln:: msgs:: { self ,  FinalOnionHopData ,  OnionErrorPacket } ; 
25152586	use  crate :: routing:: gossip:: { NodeAlias ,  NodeId } ; 
2516- 	use  crate :: util:: ser:: { Writeable ,  Readable ,  Hostname ,  TransactionU16LenLimited } ; 
2587+ 	use  crate :: util:: ser:: { Writeable ,  Readable ,  ReadableArgs ,  Hostname ,  TransactionU16LenLimited } ; 
2588+ 	use  crate :: util:: test_utils; 
25172589
25182590	use  bitcoin:: hashes:: hex:: FromHex ; 
25192591	use  bitcoin:: util:: address:: Address ; 
@@ -3604,8 +3676,11 @@ mod tests {
36043676		let  target_value = hex:: decode ( "1a02080badf00d010203040404ffffffff0608deadbeef1bad1dea" ) . unwrap ( ) ; 
36053677		assert_eq ! ( encoded_value,  target_value) ; 
36063678
3607- 		let  inbound_msg = Readable :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ) . unwrap ( ) ; 
3608- 		if  let  msgs:: InboundOnionPayload :: Forward  {  short_channel_id,  amt_to_forward,  outgoing_cltv_value }  = inbound_msg { 
3679+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3680+ 		let  inbound_msg = ReadableArgs :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ,  ( None ,  & & node_signer) ) . unwrap ( ) ; 
3681+ 		if  let  msgs:: InboundOnionPayload :: Forward  { 
3682+ 			short_channel_id,  amt_to_forward,  outgoing_cltv_value
3683+ 		}  = inbound_msg { 
36093684			assert_eq ! ( short_channel_id,  0xdeadbeef1bad1dea ) ; 
36103685			assert_eq ! ( amt_to_forward,  0x0badf00d01020304 ) ; 
36113686			assert_eq ! ( outgoing_cltv_value,  0xffffffff ) ; 
@@ -3626,8 +3701,11 @@ mod tests {
36263701		let  target_value = hex:: decode ( "1002080badf00d010203040404ffffffff" ) . unwrap ( ) ; 
36273702		assert_eq ! ( encoded_value,  target_value) ; 
36283703
3629- 		let  inbound_msg = Readable :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ) . unwrap ( ) ; 
3630- 		if  let  msgs:: InboundOnionPayload :: Receive  {  payment_data :  None ,  amt_msat,  outgoing_cltv_value,  .. }  = inbound_msg { 
3704+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3705+ 		let  inbound_msg = ReadableArgs :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ,  ( None ,  & & node_signer) ) . unwrap ( ) ; 
3706+ 		if  let  msgs:: InboundOnionPayload :: Receive  { 
3707+ 			payment_data :  None ,  amt_msat,  outgoing_cltv_value,  ..
3708+ 		}  = inbound_msg { 
36313709			assert_eq ! ( amt_msat,  0x0badf00d01020304 ) ; 
36323710			assert_eq ! ( outgoing_cltv_value,  0xffffffff ) ; 
36333711		}  else  {  panic ! ( ) ;  } 
@@ -3651,7 +3729,8 @@ mod tests {
36513729		let  target_value = hex:: decode ( "3602080badf00d010203040404ffffffff082442424242424242424242424242424242424242424242424242424242424242421badca1f" ) . unwrap ( ) ; 
36523730		assert_eq ! ( encoded_value,  target_value) ; 
36533731
3654- 		let  inbound_msg = Readable :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ) . unwrap ( ) ; 
3732+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3733+ 		let  inbound_msg = ReadableArgs :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ,  ( None ,  & & node_signer) ) . unwrap ( ) ; 
36553734		if  let  msgs:: InboundOnionPayload :: Receive  { 
36563735			payment_data :  Some ( FinalOnionHopData  { 
36573736				payment_secret, 
@@ -3686,7 +3765,8 @@ mod tests {
36863765			outgoing_cltv_value :  0xffffffff , 
36873766		} ; 
36883767		let  encoded_value = msg. encode ( ) ; 
3689- 		assert ! ( msgs:: InboundOnionPayload :: read( & mut  Cursor :: new( & encoded_value[ ..] ) ) . is_err( ) ) ; 
3768+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3769+ 		assert ! ( msgs:: InboundOnionPayload :: read( & mut  Cursor :: new( & encoded_value[ ..] ) ,  ( None ,  &&node_signer) ) . is_err( ) ) ; 
36903770		let  good_type_range_tlvs = vec ! [ 
36913771			( ( 1  << 16 )  - 3 ,  vec![ 42 ] ) , 
36923772			( ( 1  << 16 )  - 1 ,  vec![ 42 ;  32 ] ) , 
@@ -3695,7 +3775,7 @@ mod tests {
36953775			* custom_tlvs = good_type_range_tlvs. clone ( ) ; 
36963776		} 
36973777		let  encoded_value = msg. encode ( ) ; 
3698- 		let  inbound_msg = Readable :: read ( & mut  Cursor :: new ( & encoded_value[ ..] ) ) . unwrap ( ) ; 
3778+ 		let  inbound_msg = ReadableArgs :: read ( & mut  Cursor :: new ( & encoded_value[ ..] ) ,   ( None ,   & & node_signer ) ) . unwrap ( ) ; 
36993779		match  inbound_msg { 
37003780			msgs:: InboundOnionPayload :: Receive  {  custom_tlvs,  .. }  => assert ! ( custom_tlvs. is_empty( ) ) , 
37013781			_ => panic ! ( ) , 
@@ -3719,7 +3799,8 @@ mod tests {
37193799		let  encoded_value = msg. encode ( ) ; 
37203800		let  target_value = hex:: decode ( "2e02080badf00d010203040404ffffffffff0000000146c6616b021234ff0000000146c6616f084242424242424242" ) . unwrap ( ) ; 
37213801		assert_eq ! ( encoded_value,  target_value) ; 
3722- 		let  inbound_msg:  msgs:: InboundOnionPayload  = Readable :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ) . unwrap ( ) ; 
3802+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3803+ 		let  inbound_msg:  msgs:: InboundOnionPayload  = ReadableArgs :: read ( & mut  Cursor :: new ( & target_value[ ..] ) ,  ( None ,  & & node_signer) ) . unwrap ( ) ; 
37233804		if  let  msgs:: InboundOnionPayload :: Receive  { 
37243805			payment_data :  None , 
37253806			payment_metadata :  None , 
@@ -3882,7 +3963,10 @@ mod tests {
38823963		// payload length to be encoded over multiple bytes rather than a single u8. 
38833964		let  big_payload = encode_big_payload ( ) . unwrap ( ) ; 
38843965		let  mut  rd = Cursor :: new ( & big_payload[ ..] ) ; 
3885- 		<msgs:: InboundOnionPayload  as  Readable >:: read ( & mut  rd) . unwrap ( ) ; 
3966+ 
3967+ 		let  node_signer = test_utils:: TestKeysInterface :: new ( & [ 42 ;  32 ] ,  Network :: Testnet ) ; 
3968+ 		<msgs:: InboundOnionPayload  as  ReadableArgs < ( Option < PublicKey > ,  & & test_utils:: TestKeysInterface ) > >
3969+ 			:: read ( & mut  rd,  ( None ,  & & node_signer) ) . unwrap ( ) ; 
38863970	} 
38873971	// see above test, needs to be a separate method for use of the serialization macros. 
38883972	fn  encode_big_payload ( )  -> Result < Vec < u8 > ,  io:: Error >  { 
0 commit comments