@@ -510,7 +510,8 @@ func (r *Router) Stop() {
510
510
// processOnionCfg is a set of config values that can be used to modify how an
511
511
// onion is processed.
512
512
type processOnionCfg struct {
513
- blindingPoint * btcec.PublicKey
513
+ blindingPoint * btcec.PublicKey
514
+ isOnionMessage bool
514
515
}
515
516
516
517
// ProcessOnionOpt defines the signature of a function option that can be used
@@ -525,6 +526,14 @@ func WithBlindingPoint(point *btcec.PublicKey) ProcessOnionOpt {
525
526
}
526
527
}
527
528
529
+ // WithIsOnionMessage is a functional option that signals that the onion packet
530
+ // being processed is from onion message.
531
+ func WithIsOnionMessage () ProcessOnionOpt {
532
+ return func (cfg * processOnionCfg ) {
533
+ cfg .isOnionMessage = true
534
+ }
535
+ }
536
+
528
537
// ProcessOnionPacket processes an incoming onion packet which has been forward
529
538
// to the target Sphinx router. If the encoded ephemeral key isn't on the
530
539
// target Elliptic Curve, then the packet is rejected. Similarly, if the
@@ -560,7 +569,9 @@ func (r *Router) ProcessOnionPacket(onionPkt *OnionPacket, assocData []byte,
560
569
// Continue to optimistically process this packet, deferring replay
561
570
// protection until the end to reduce the penalty of multiple IO
562
571
// operations.
563
- packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
572
+ packet , err := processOnionPacket (
573
+ onionPkt , & sharedSecret , assocData , cfg .isOnionMessage ,
574
+ )
564
575
if err != nil {
565
576
return nil , err
566
577
}
@@ -594,7 +605,9 @@ func (r *Router) ReconstructOnionPacket(onionPkt *OnionPacket, assocData []byte,
594
605
return nil , err
595
606
}
596
607
597
- return processOnionPacket (onionPkt , & sharedSecret , assocData )
608
+ return processOnionPacket (
609
+ onionPkt , & sharedSecret , assocData , cfg .isOnionMessage ,
610
+ )
598
611
}
599
612
600
613
// DecryptBlindedHopData uses the router's private key to decrypt data encrypted
@@ -625,7 +638,8 @@ func (r *Router) OnionPublicKey() *btcec.PublicKey {
625
638
// packet. This function returns the next inner onion packet layer, along with
626
639
// the hop data extracted from the outer onion packet.
627
640
func unwrapPacket (onionPkt * OnionPacket , sharedSecret * Hash256 ,
628
- assocData []byte ) (* OnionPacket , * HopPayload , error ) {
641
+ assocData []byte , isOnionMessage bool ) (* OnionPacket , * HopPayload ,
642
+ error ) {
629
643
630
644
dhKey := onionPkt .EphemeralKey
631
645
routeInfo := onionPkt .RoutingInfo
@@ -660,8 +674,9 @@ func unwrapPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
660
674
// With the MAC checked, and the payload decrypted, we can now parse
661
675
// out the payload so we can derive the specified forwarding
662
676
// instructions.
663
- var hopPayload HopPayload
664
- if err := hopPayload .Decode (bytes .NewReader (hopInfo [:])); err != nil {
677
+ hopPayload := HopPayload {TLVPayloadGuaranteed : isOnionMessage }
678
+ err := hopPayload .Decode (bytes .NewReader (hopInfo [:]))
679
+ if err != nil {
665
680
return nil , nil , err
666
681
}
667
682
@@ -683,7 +698,7 @@ func unwrapPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
683
698
// packets. The processed packets returned from this method should only be used
684
699
// if the packet was not flagged as a replayed packet.
685
700
func processOnionPacket (onionPkt * OnionPacket , sharedSecret * Hash256 ,
686
- assocData []byte ) (* ProcessedPacket , error ) {
701
+ assocData []byte , isOnionMessage bool ) (* ProcessedPacket , error ) {
687
702
688
703
// First, we'll unwrap an initial layer of the onion packet. Typically,
689
704
// we'll only have a single layer to unwrap, However, if the sender has
@@ -693,7 +708,7 @@ func processOnionPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
693
708
// they can properly check the HMAC and unwrap a layer for their
694
709
// handoff hop.
695
710
innerPkt , outerHopPayload , err := unwrapPacket (
696
- onionPkt , sharedSecret , assocData ,
711
+ onionPkt , sharedSecret , assocData , isOnionMessage ,
697
712
)
698
713
if err != nil {
699
714
return nil , err
@@ -703,7 +718,7 @@ func processOnionPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
703
718
// However if the uncovered 'nextMac' is all zeroes, then this
704
719
// indicates that we're the final hop in the route.
705
720
var action ProcessCode = MoreHops
706
- if bytes .Compare (zeroHMAC [:], outerHopPayload .HMAC [:]) == 0 {
721
+ if bytes .Equal (zeroHMAC [:], outerHopPayload .HMAC [:]) {
707
722
action = ExitNode
708
723
}
709
724
@@ -794,7 +809,9 @@ func (t *Tx) ProcessOnionPacket(seqNum uint16, onionPkt *OnionPacket,
794
809
// Continue to optimistically process this packet, deferring replay
795
810
// protection until the end to reduce the penalty of multiple IO
796
811
// operations.
797
- packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
812
+ packet , err := processOnionPacket (
813
+ onionPkt , & sharedSecret , assocData , cfg .isOnionMessage ,
814
+ )
798
815
if err != nil {
799
816
return err
800
817
}
0 commit comments