github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/identify_state.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package libkb
     5  
     6  import (
     7  	"github.com/keybase/client/go/gregor"
     8  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
     9  )
    10  
    11  type IdentifyState struct {
    12  	Contextified
    13  	res      *IdentifyOutcome
    14  	u        *User
    15  	track    *TrackLookup
    16  	tmpTrack *TrackLookup
    17  }
    18  
    19  func NewIdentifyStateWithGregorItem(g *GlobalContext, item gregor.Item, u *User) IdentifyState {
    20  	res := NewIdentifyOutcome(g, u.GetNormalizedName(), u.GetUID(), u.GetCurrentEldestSeqno())
    21  	res.ResponsibleGregorItem = item
    22  	return IdentifyState{Contextified: NewContextified(g), res: res, u: u}
    23  }
    24  
    25  func (s *IdentifyState) SetTrackLookup(t *TrackChainLink) {
    26  	s.track = NewTrackLookup(s.G(), t)
    27  	if s.res != nil {
    28  		s.res.TrackUsed = s.track
    29  	}
    30  }
    31  
    32  func (s *IdentifyState) SetTmpTrackLookup(t *TrackChainLink) {
    33  	s.tmpTrack = NewTrackLookup(s.G(), t)
    34  }
    35  
    36  func (s *IdentifyState) TrackLookup() *TrackLookup {
    37  	return s.track
    38  }
    39  
    40  func (s *IdentifyState) HasPreviousTrack() bool {
    41  	return s.track != nil
    42  }
    43  
    44  func (s *IdentifyState) Result() *IdentifyOutcome {
    45  	return s.res
    46  }
    47  
    48  func (s *IdentifyState) TmpTrackLookup() *TrackLookup {
    49  	return s.tmpTrack
    50  }
    51  
    52  func (s *IdentifyState) computeRevokedProofs(rhook func(TrackIDComponent, TrackDiff)) {
    53  	if s.track == nil {
    54  		return
    55  	}
    56  
    57  	found := s.res.TrackSet()
    58  
    59  	tracked := s.track.set
    60  
    61  	// These are the proofs that user previously tracked that
    62  	// are not in the current profile:
    63  	diff := tracked.Subtract(*found)
    64  
    65  	for _, e := range diff {
    66  		if e.GetProofState() != keybase1.ProofState_OK {
    67  			continue
    68  		}
    69  
    70  		// A proof that was previously tracked as GOOD
    71  		// is missing, so it has been REVOKED.
    72  		revokedDetail := ExportTrackIDComponentToRevokedProof(e)
    73  		var td TrackDiff
    74  		if s.tmpTrack == nil {
    75  			td = &TrackDiffRevoked{e}
    76  		} else {
    77  			// There is a snoozed track in s.tmpTrack.
    78  			// The user could have snoozed the revoked proof already.
    79  			// Check s.tmpTrack to see if that is the case.
    80  			if s.tmpTrack.set.HasMember(e) {
    81  				// proof was in snooze, too, so mark it as revoked.
    82  				td = &TrackDiffRevoked{e}
    83  			} else {
    84  				// proof wasn't in snooze, so revoked proof already snoozed.
    85  				td = &TrackDiffSnoozedRevoked{e}
    86  				revokedDetail.Snoozed = true
    87  			}
    88  		}
    89  		if td != nil {
    90  			s.res.Revoked = append(s.res.Revoked, td)
    91  			if rhook != nil {
    92  				rhook(e, td)
    93  			}
    94  		}
    95  		s.res.RevokedDetails = append(s.res.RevokedDetails, revokedDetail)
    96  	}
    97  }
    98  
    99  func (s *IdentifyState) initResultList() {
   100  	idt := s.u.IDTable()
   101  	if idt == nil {
   102  		return
   103  	}
   104  	activeProofs := idt.remoteProofLinks.Active()
   105  	s.res.ProofChecks = make([]*LinkCheckResult, len(activeProofs))
   106  	for i, p := range activeProofs {
   107  		s.res.ProofChecks[i] = &LinkCheckResult{link: p, trackedProofState: keybase1.ProofState_NONE, position: i}
   108  	}
   109  }
   110  
   111  func (s *IdentifyState) computeTrackDiffs() {
   112  	if s.track == nil {
   113  		return
   114  	}
   115  
   116  	s.G().Log.Debug("| with tracking %v", s.track.set)
   117  	for _, c := range s.res.ProofChecks {
   118  		c.diff = c.link.ComputeTrackDiff(s.track)
   119  		c.trackedProofState = s.track.GetProofState(c.link.ToIDString())
   120  		if s.tmpTrack != nil {
   121  			c.tmpTrackedProofState = s.tmpTrack.GetProofState(c.link.ToIDString())
   122  			c.tmpTrackExpireTime = s.tmpTrack.GetTmpExpireTime()
   123  		}
   124  	}
   125  }
   126  
   127  func (s *IdentifyState) Precompute(dhook func(keybase1.IdentifyKey) error, rhook func(TrackIDComponent, TrackDiff)) {
   128  	s.computeKeyDiffs(dhook)
   129  	s.initResultList()
   130  	s.computeTrackDiffs()
   131  	s.computeRevokedProofs(rhook)
   132  }
   133  
   134  func (s *IdentifyState) getLastDelegationSig(kid keybase1.KID) (ret keybase1.SigID) {
   135  	ckf := s.u.GetComputedKeyFamily()
   136  	if ckf == nil {
   137  		return ret
   138  	}
   139  	cki := ckf.getCkiUnchecked(kid)
   140  	if cki == nil {
   141  		return ret
   142  	}
   143  	dels := cki.DelegationsList
   144  	if len(dels) == 0 {
   145  		return ret
   146  	}
   147  	return dels[len(dels)-1].SigID
   148  }
   149  
   150  func (s *IdentifyState) computeKeyDiffs(dhook func(keybase1.IdentifyKey) error) {
   151  	mapify := func(v []keybase1.KID) map[keybase1.KID]bool {
   152  		ret := make(map[keybase1.KID]bool)
   153  		for _, k := range v {
   154  			ret[k] = true
   155  		}
   156  		return ret
   157  	}
   158  
   159  	display := func(kid keybase1.KID, diff TrackDiff) {
   160  		k := keybase1.IdentifyKey{
   161  			TrackDiff: ExportTrackDiff(diff),
   162  		}
   163  		k.KID = kid
   164  		if fp, ok := s.u.GetKeyFamily().kid2pgp[kid]; ok {
   165  			k.PGPFingerprint = fp[:]
   166  		}
   167  
   168  		// Get the last signature chronologically that delegated to
   169  		// this key.
   170  		k.SigID = s.getLastDelegationSig(kid)
   171  
   172  		// Anything other than a no difference here should be displayed to
   173  		// the user.
   174  		if diff != nil {
   175  			k.BreaksTracking = diff.BreaksTracking()
   176  		}
   177  		err := dhook(k)
   178  		if err != nil {
   179  			s.G().Log.Debug("computeKeyDiffs: dhook error: %+v", err)
   180  		}
   181  	}
   182  
   183  	// first check the eldest key
   184  	observedEldest := s.u.GetEldestKID()
   185  	if s.track != nil {
   186  		trackedEldest := s.track.GetEldestKID()
   187  		if observedEldest.NotEqual(trackedEldest) ||
   188  			s.u.GetCurrentEldestSeqno() > s.track.GetTrackedLinkSeqno() {
   189  			diff := TrackDiffNewEldest{tracked: trackedEldest, observed: observedEldest}
   190  			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
   191  			display(observedEldest, diff)
   192  		}
   193  	}
   194  
   195  	found := s.u.GetActivePGPKIDs(true)
   196  	foundMap := mapify(found)
   197  	var tracked []keybase1.KID
   198  	if s.track != nil {
   199  		for _, trackedKey := range s.track.GetTrackedKeys() {
   200  			tracked = append(tracked, trackedKey.KID)
   201  		}
   202  	}
   203  	trackedMap := mapify(tracked)
   204  
   205  	for _, kid := range found {
   206  		var diff TrackDiff
   207  		if s.track != nil && !trackedMap[kid] {
   208  			diff = TrackDiffNew{}
   209  			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
   210  		} else if s.track != nil {
   211  			diff = TrackDiffNone{}
   212  		}
   213  		display(kid, diff)
   214  	}
   215  
   216  	for _, kid := range tracked {
   217  		if !foundMap[kid] {
   218  			fp := s.u.GetKeyFamily().kid2pgp[kid]
   219  			diff := TrackDiffRevoked{fp}
   220  			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
   221  			// the identify outcome should know that this
   222  			// key was revoked, as well as there being
   223  			// a KeyDiff:
   224  			s.res.Revoked = append(s.res.Revoked, diff)
   225  			display(kid, diff)
   226  		}
   227  	}
   228  }