100 lines
3.6 KiB
Go
100 lines
3.6 KiB
Go
package htlcswitch
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/lightningnetwork/lightning-onion"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
// Deobfuscator is an interface that is used to decrypt the onion encrypted
|
|
// failure reason an extra out a well formed error.
|
|
type Deobfuscator interface {
|
|
// Deobfuscate peels off each layer of onion encryption from the first
|
|
// hop, to the source of the error. A fully populated
|
|
// lnwire.FailureMessage is returned.
|
|
Deobfuscate(lnwire.OpaqueReason) (lnwire.FailureMessage, error)
|
|
}
|
|
|
|
// Obfuscator is an interface that is used to encrypt HTLC related errors at
|
|
// the source of the error, and also at each intermediate hop all the way back
|
|
// to the source of the payment.
|
|
type Obfuscator interface {
|
|
// InitialObfuscate is used to convert the failure into opaque
|
|
// reason.
|
|
|
|
// InitialObfuscate transforms a concrete failure message into an
|
|
// encrypted opaque failure reason. This method will be used at the
|
|
// source that the error occurs. It differs from BackwardObfuscate
|
|
// slightly, in that it computes a proper MAC over the error.
|
|
InitialObfuscate(lnwire.FailureMessage) (lnwire.OpaqueReason, error)
|
|
|
|
// BackwardObfuscate wraps an already encrypted opaque reason error in
|
|
// an additional layer of onion encryption. This process repeats until
|
|
// the error arrives at the source of the payment.
|
|
BackwardObfuscate(lnwire.OpaqueReason) lnwire.OpaqueReason
|
|
}
|
|
|
|
// FailureObfuscator is used to obfuscate the onion failure.
|
|
type FailureObfuscator struct {
|
|
*sphinx.OnionObfuscator
|
|
}
|
|
|
|
// InitialObfuscate transforms a concrete failure message into an encrypted
|
|
// opaque failure reason. This method will be used at the source that the error
|
|
// occurs. It differs from BackwardObfuscate slightly, in that it computes a
|
|
// proper MAC over the error.
|
|
//
|
|
// NOTE: Part of the Obfuscator interface.
|
|
func (o *FailureObfuscator) InitialObfuscate(failure lnwire.FailureMessage) (lnwire.OpaqueReason, error) {
|
|
var b bytes.Buffer
|
|
if err := lnwire.EncodeFailure(&b, failure, 0); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// We pass a true as the first parameter to indicate that a MAC should
|
|
// be added.
|
|
return o.OnionObfuscator.Obfuscate(true, b.Bytes()), nil
|
|
}
|
|
|
|
// BackwardObfuscate wraps an already encrypted opaque reason error in an
|
|
// additional layer of onion encryption. This process repeats until the error
|
|
// arrives at the source of the payment. We re-encrypt the message on the
|
|
// backwards path to ensure that the error is indistinguishable from any other
|
|
// error seen.
|
|
//
|
|
// NOTE: Part of the Obfuscator interface.
|
|
func (o *FailureObfuscator) BackwardObfuscate(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
|
|
return o.OnionObfuscator.Obfuscate(false, reason)
|
|
}
|
|
|
|
// A compile time check to ensure FailureObfuscator implements the Obfuscator
|
|
// interface.
|
|
var _ Obfuscator = (*FailureObfuscator)(nil)
|
|
|
|
// FailureDeobfuscator wraps the sphinx data obfuscator and adds awareness of
|
|
// the lnwire onion failure messages to it.
|
|
type FailureDeobfuscator struct {
|
|
*sphinx.OnionDeobfuscator
|
|
}
|
|
|
|
// Deobfuscate peels off each layer of onion encryption from the first hop, to
|
|
// the source of the error. A fully populated lnwire.FailureMessage is
|
|
// returned.
|
|
//
|
|
// NOTE: Part of the Obfuscator interface.
|
|
func (o *FailureDeobfuscator) Deobfuscate(reason lnwire.OpaqueReason) (lnwire.FailureMessage, error) {
|
|
|
|
_, failureData, err := o.OnionDeobfuscator.Deobfuscate(reason)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
r := bytes.NewReader(failureData)
|
|
return lnwire.DecodeFailure(r, 0)
|
|
}
|
|
|
|
// A compile time check to ensure FailureDeobfuscator implements the
|
|
// Deobfuscator interface.
|
|
var _ Deobfuscator = (*FailureDeobfuscator)(nil)
|