github.com/iDigitalFlame/xmt@v0.5.4/c2/x_key.go (about)

     1  //go:build !nokeyset
     2  // +build !nokeyset
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package c2
    21  
    22  import (
    23  	"time"
    24  
    25  	"github.com/iDigitalFlame/xmt/c2/cout"
    26  	"github.com/iDigitalFlame/xmt/com"
    27  	"github.com/iDigitalFlame/xmt/data"
    28  	"github.com/iDigitalFlame/xmt/util"
    29  	"github.com/iDigitalFlame/xmt/util/bugtrack"
    30  	"github.com/iDigitalFlame/xmt/util/xerr"
    31  )
    32  
    33  func (s *Session) keyCheckRevert() {
    34  	if s.keysNext = nil; bugtrack.Enabled {
    35  		bugtrack.Track("c2.(*Session).keyCheckRevert(): %s KeyPair queued sync canceled!", s.ID)
    36  	}
    37  }
    38  func (s *Session) keyCheckSync() error {
    39  	if s.keysNext == nil {
    40  		return nil
    41  	}
    42  	if cout.Enabled {
    43  		s.log.Debug("[%s/Crypt] Syncing KeyPair shared secret.", s.ID)
    44  	}
    45  	v := s.keysNext
    46  	s.keysNext = nil
    47  	if err := s.keys.FillPrivate(v.Private); err != nil {
    48  		if cout.Enabled {
    49  			s.log.Error("[%s/Crypt] KeyPair shared secret sync failed: %s!", s.ID, err)
    50  		}
    51  		return err
    52  	}
    53  	if v = nil; bugtrack.Enabled {
    54  		bugtrack.Track("c2.(*Session).keyNextSync(): %s KeyPair shared secret sync completed! [Public: %s, Shared: %v]", s.ID, s.keys.Public, s.keys.Shared())
    55  	}
    56  	if cout.Enabled {
    57  		s.log.Trace("[%s/Crypt] KeyPair shared secret sync completed!", s.ID)
    58  	}
    59  	return nil
    60  }
    61  func (s *Session) keyNextSync() *com.Packet {
    62  	if !s.IsClient() || s.keysNext != nil || s.state.Moving() {
    63  		return nil
    64  	}
    65  	// Have the % chance of changing be a factor of how LONG we sleep for, so
    66  	// implants that wait a longer period of time won't necessarily change keys
    67  	// less than ones that update in shorter periods.
    68  	d := 60 - int(s.sleep/time.Minute)
    69  	if d < 0 {
    70  		d = 0 // Base will ALWAYS be 50.
    71  	}
    72  	if util.FastRandN(50+d) != 0 {
    73  		return nil
    74  	}
    75  	if cout.Enabled {
    76  		s.log.Info("[%s/Crypt] Generating new public/private KeyPair for sync.", s.ID)
    77  	}
    78  	var (
    79  		n = &com.Packet{Device: s.ID, Flags: com.FlagCrypt}
    80  		v data.KeyPair
    81  	)
    82  	v.Fill()
    83  	v.Write(n)
    84  	if s.keysNext = &v; bugtrack.Enabled {
    85  		bugtrack.Track("c2.(*Session).keyNextSync(): %s KeyPair details queued for next sync. [Public: %s]", s.ID, v.Public)
    86  	}
    87  	return n
    88  }
    89  func (s *Session) keySessionGenerate(n *com.Packet) {
    90  	s.keys.Fill()
    91  	s.keys.Write(n)
    92  	if n.Flags |= com.FlagCrypt; cout.Enabled {
    93  		s.log.Debug("[%s/Crypt] Generated KeyPair details!", s.ID)
    94  	}
    95  	if bugtrack.Enabled {
    96  		bugtrack.Track("c2.(*Session).keySessionGenerate(): %s KeyPair generated! [Public: %s]", s.ID, s.keys.Public)
    97  	}
    98  }
    99  func (s *Session) keySessionSync(n *com.Packet) error {
   100  	if s.keys.IsSynced() {
   101  		if cout.Enabled {
   102  			s.log.Warning(`[%s/Crypt] Packet "%s" has un-matched KeyPair data, did the server change?`, s.ID)
   103  		}
   104  		return nil
   105  	}
   106  	if err := s.keys.Read(n); err != nil {
   107  		if cout.Enabled {
   108  			s.log.Error(`[%s/Crypt] KeyPair read failed: %s!`, s.ID, err)
   109  		}
   110  		return err
   111  	}
   112  	// Check server PublicKey here if we have any TrustedKeys set in our profile.
   113  	if s.p != nil && !s.p.TrustedKey(s.keys.Public) {
   114  		if cout.Enabled {
   115  			s.log.Error(`[%s/Crypt] Server PublicKey "%s" is NOT in our Trusted Keys list!`, s.ID, s.keys.Public)
   116  		}
   117  		return xerr.Sub("non-trusted server PublicKey", 0x79)
   118  	}
   119  	if err := s.keys.Sync(); err != nil {
   120  		if cout.Enabled {
   121  			s.log.Error(`[%s/Crypt] KeyPair sync failed: %s!`, s.ID, err)
   122  		}
   123  		return err
   124  	}
   125  	if cout.Enabled {
   126  		s.log.Debug(`[%s/Crypt] KeyPair sync with server "%s" completed!`, s.ID, s.keys.Public)
   127  	}
   128  	if bugtrack.Enabled {
   129  		bugtrack.Track("c2.(*Session).keySessionSync(): %s KeyPair synced! [Public: %s, Shared: %v]", s.ID, s.keys.Public, s.keys.Shared())
   130  	}
   131  	return nil
   132  }