From be63c7d286bdcbbc386528c13eeb1460e94bfc1b Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 30 Apr 2019 18:27:11 -0700 Subject: [PATCH] htlcswitch: properly convert multi-hop malformed HTLC failures In this commit, we now properly convert multi-hop malformed HTLC failures. Before this commit, we wouldn't properly add a layer of encryption to these errors meaning that the destination would fail to decrypt the error as it was actually plaintext. To remedy this, we'll now check if we need to convert an error, and if so we'll encrypt it as if it we were the source of the error (the true source is our direct channel peer). --- htlcswitch/switch.go | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 3e1ad107d..988c33ddf 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -1155,13 +1155,12 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error { fail, isFail := htlc.(*lnwire.UpdateFailHTLC) if isFail && !packet.hasSource { switch { + // No message to encrypt, locally sourced payment. case circuit.ErrorEncrypter == nil: - // No message to encrypt, locally sourced - // payment. + // If this is a resolution message, then we'll need to + // encrypt it as it's actually internally sourced. case packet.isResolution: - // If this is a resolution message, then we'll need to encrypt - // it as it's actually internally sourced. var err error // TODO(roasbeef): don't need to pass actually? failure := &lnwire.FailPermanentChannelFailure{} @@ -1174,6 +1173,25 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error { log.Error(err) } + // Alternatively, if the remote party send us an + // UpdateFailMalformedHTLC, then we'll need to convert + // this into a proper well formatted onion error as + // there's no HMAC currently. + case packet.convertedError: + log.Infof("Converting malformed HTLC error "+ + "for circuit for Circuit(%x: "+ + "(%s, %d) <-> (%s, %d))", packet.circuit.PaymentHash, + packet.incomingChanID, packet.incomingHTLCID, + packet.outgoingChanID, packet.outgoingHTLCID) + + fail.Reason = circuit.ErrorEncrypter.EncryptMalformedError( + fail.Reason, + ) + if err != nil { + err = fmt.Errorf("unable to obfuscate "+ + "error: %v", err) + log.Error(err) + } default: // Otherwise, it's a forwarded error, so we'll perform a // wrapper encryption as normal.