github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/keyfamily.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  // A KeyFamily is a group of sibling keys that have equal power for a user.
     5  // A family can consist of 1 PGP keys, and arbitrarily many NaCl Sibkeys.
     6  // There also can be some subkeys dangling off for ECDH.
     7  package libkb
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"runtime/debug"
    13  	"sort"
    14  	"time"
    15  
    16  	"github.com/keybase/client/go/kbcrypto"
    17  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    18  	jsonw "github.com/keybase/go-jsonw"
    19  )
    20  
    21  // We have two notions of time we can use -- standard UTC which might
    22  // be screwy (skewy) based upon local clock problems; or MerkleRoot seqno,
    23  // which is totally ordered and all clients and server ought to agree on it.
    24  // The issue is that we're not uniformly signing Merkle roots into signatures,
    25  // especially those generated on the Web site.
    26  type KeybaseTime struct {
    27  	Unix  int64          // UTC wallclock time
    28  	Chain keybase1.Seqno // Merkle root chain time
    29  }
    30  
    31  // Struct for the DelegationsList
    32  type Delegation struct {
    33  	KID   keybase1.KID
    34  	SigID keybase1.SigID
    35  }
    36  
    37  type ComputedKeyInfosVersion int
    38  
    39  const (
    40  	ComputedKeyInfosV1             ComputedKeyInfosVersion = ComputedKeyInfosVersion(1)
    41  	ComputedKeyInfosV2             ComputedKeyInfosVersion = ComputedKeyInfosVersion(2)
    42  	ComputedKeyInfosV3             ComputedKeyInfosVersion = ComputedKeyInfosVersion(3)
    43  	ComputedKeyInfosV4             ComputedKeyInfosVersion = ComputedKeyInfosVersion(4)
    44  	ComputedKeyInfosVersionCurrent                         = ComputedKeyInfosV4
    45  )
    46  
    47  // refers to exactly one ServerKeyInfo.
    48  type ComputedKeyInfo struct {
    49  	Contextified
    50  
    51  	// Repeat the KID inside, for lookups if we get here via the
    52  	// `Sigs` map in ComputedKeyInfos
    53  	KID keybase1.KID
    54  
    55  	Status KeyStatus
    56  	Eldest bool
    57  	Sibkey bool
    58  
    59  	// These have to be ints so they can be written to disk and read
    60  	// back in.
    61  	CTime int64 // In Seconds since the Epoch
    62  	ETime int64 // In Seconds since the Epoch or 0 if none
    63  
    64  	// For subkeys, the KID of our parent (if valid)
    65  	Parent keybase1.KID
    66  
    67  	// For sibkeys, the KID of last-added subkey (if valid)
    68  	Subkey keybase1.KID
    69  
    70  	// Map of SigID -> KID
    71  	Delegations map[keybase1.SigIDMapKey]keybase1.KID
    72  
    73  	// List of the same delegations as above, in a way that preserves ordering.
    74  	// NOTE: This is not populated in older cached CKI's.
    75  	DelegationsList []Delegation
    76  
    77  	// Merkle Timestamps and Friends for delegation. Suboptimal grouping of concerns
    78  	// due to backwards compatibility and sensitivity to preexisting ondisk representations.
    79  	DelegatedAt                 *KeybaseTime              // The Seqno/Ctime signed into the link, so jus before the actual delegation!
    80  	DelegatedAtHashMeta         keybase1.HashMeta         // The HashMeta at the time of the delegation
    81  	FirstAppearedUnverified     keybase1.Seqno            // What the server claims was the first merkle appearance of this seqno
    82  	DelegatedAtSigChainLocation keybase1.SigChainLocation // Where the delegation was in our sigchain
    83  
    84  	// Merkle Timestamps and Friends for revocation.
    85  	RevokedAt                     *KeybaseTime // The Seqno/Ctime signed into the signature
    86  	RevokedBy                     keybase1.KID
    87  	RevokedAtHashMeta             keybase1.HashMeta          // The hash_meta signed in at the time of the revocation
    88  	RevokeFirstAppearedUnverified keybase1.Seqno             // What the server claims was the first merkle appearance of this revoke
    89  	RevokedAtSigChainLocation     *keybase1.SigChainLocation // Where the revocation was in our sigchain
    90  
    91  	// For PGP keys, the active version of the key. If unspecified, use the
    92  	// legacy behavior of combining every instance of this key that we got from
    93  	// the server minus revocations.
    94  	ActivePGPHash string
    95  }
    96  
    97  func (cki ComputedKeyInfo) GetCTime() time.Time {
    98  	return time.Unix(cki.CTime, 0)
    99  }
   100  
   101  func (cki ComputedKeyInfo) GetETime() time.Time {
   102  	return UnixToTimeMappingZero(cki.ETime)
   103  }
   104  
   105  // When we play a sigchain forward, it yields ComputedKeyInfos (CKIs). We're going to
   106  // store CKIs separately from the keys, since the server can clobber the
   107  // former.  We should rewrite CKIs every time we (re)check a user's SigChain
   108  type ComputedKeyInfos struct {
   109  	Contextified
   110  
   111  	// Now set to 1. Everything before that is thrown away on sigchain load.
   112  	Version ComputedKeyInfosVersion
   113  
   114  	dirty bool // whether it needs to be written to disk or not
   115  
   116  	// Map of KID to a computed info
   117  	Infos map[keybase1.KID]*ComputedKeyInfo
   118  
   119  	// Map of a SigID (in binary) to the ComputedKeyInfo describing when the key was
   120  	// delegated.
   121  	Sigs map[keybase1.SigIDMapKey]*ComputedKeyInfo
   122  
   123  	// Map of DeviceID to the most current device object
   124  	Devices map[keybase1.DeviceID]*Device
   125  
   126  	// Map of KID -> DeviceID
   127  	KIDToDeviceID map[keybase1.KID]keybase1.DeviceID
   128  
   129  	// For each generation, the public KIDs that correspond to the
   130  	// per-user-key for a given generation.
   131  	// Starts at gen=1.
   132  	PerUserKeys map[keybase1.PerUserKeyGeneration]keybase1.PerUserKey
   133  }
   134  
   135  // As returned by user/lookup.json
   136  type RawKeyFamily struct {
   137  	AllBundles []string `json:"all_bundles"`
   138  }
   139  
   140  // PGPKeySet represents a collection of versions of a PGP key. It includes a
   141  // merged version of the key without revocations, and each individual version
   142  // of the key with revocations intact.
   143  type PGPKeySet struct {
   144  	Contextified
   145  	PermissivelyMergedKey *PGPKeyBundle
   146  	KeysByHash            map[string]*PGPKeyBundle
   147  }
   148  
   149  func (s *PGPKeySet) addKey(key *PGPKeyBundle) error {
   150  	fullHash, err := key.FullHash()
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	// Only the KID (and sometimes the fingerprint) of PGP keys has
   156  	// historically been signed into the sigchain. When validating a sigchain
   157  	// and multiple versions of the PGP key are available (which may be
   158  	// different in terms of subkeys, UIDs, and revocations) we chose to merge
   159  	// every version and ignore revocations. This stops anyone from breaking
   160  	// their sigchain by uploading a revoked version of their PGP key, but also
   161  	// creates a vulnerability when Alice's key is compromised and she revokes
   162  	// it PGP-style without revoking it sigchain-style: Keybase clients will
   163  	// continue to accept the key, Mallory can now make sigchain links as
   164  	// Alice.
   165  	//
   166  	// As a long term solution, we decided that PGP keys' full hashes over time
   167  	// should be tracked in the sigchain so that the client can know which
   168  	// version to use to validate each link. This is detailed in issue #544.
   169  	//
   170  	// PGPKeySet keeps both the individual versions of the key, indexed by
   171  	// hash, and the permissively-merged version to support both the old
   172  	// behavior (for sigchains or sections of sigchains with no specific PGP
   173  	// key hash) and the new behavior.
   174  
   175  	s.G().Log.Debug("adding PGP kid %s with full hash %s", key.GetKID().String(), fullHash)
   176  	s.KeysByHash[fullHash] = key
   177  
   178  	strippedKey := key.StripRevocations()
   179  	if s.PermissivelyMergedKey == nil {
   180  		s.PermissivelyMergedKey = strippedKey
   181  	} else {
   182  		s.PermissivelyMergedKey.MergeKey(strippedKey)
   183  	}
   184  	return nil
   185  }
   186  
   187  // Once the client downloads a RawKeyFamily, it converts it into a KeyFamily,
   188  // which has some additional information about Fingerprints and PGP keys
   189  type KeyFamily struct {
   190  	// These fields are computed on the client side, so they can be trusted.
   191  	pgp2kid map[PGPFingerprint]keybase1.KID
   192  	kid2pgp map[keybase1.KID]PGPFingerprint
   193  
   194  	AllKIDs map[keybase1.KID]bool
   195  
   196  	// PGP keys have a permissively merged version and individual versions by
   197  	// hash. See the comment in PGPKeySet.addKey, above, for details.
   198  	PGPKeySets map[keybase1.KID]*PGPKeySet
   199  	SingleKeys map[keybase1.KID]GenericKey // Currently just NaCl keys
   200  
   201  	BundlesForTesting []string
   202  
   203  	Contextified
   204  }
   205  
   206  // ComputedKeyFamily is a joining of two sets of data; the KeyFamily is
   207  // what the server returned and is not to be trusted; the ComputedKeyInfos
   208  // is what we compute as a result of playing the user's sigchain forward.
   209  type ComputedKeyFamily struct {
   210  	Contextified
   211  	kf  *KeyFamily
   212  	cki *ComputedKeyInfos
   213  }
   214  
   215  // Insert inserts the given ComputedKeyInfo object 1 or 2 times,
   216  // depending on if a KID or PGPFingerprint or both are available.
   217  func (cki *ComputedKeyInfos) Insert(i *ComputedKeyInfo) {
   218  	cki.Infos[i.KID] = i
   219  	cki.dirty = true
   220  }
   221  
   222  // PaperDevices returns a list of all the paperkey devices.
   223  func (cki *ComputedKeyInfos) PaperDevices() []*Device {
   224  	var d []*Device
   225  	for _, v := range cki.Devices {
   226  		if v.Status == nil {
   227  			continue
   228  		}
   229  		if *v.Status != DeviceStatusActive {
   230  			continue
   231  		}
   232  		if v.Type != keybase1.DeviceTypeV2_PAPER {
   233  			continue
   234  		}
   235  		d = append(d, v)
   236  	}
   237  	return d
   238  }
   239  
   240  // TODO: Figure out whether this needs to be a deep copy. See
   241  // https://github.com/keybase/client/issues/414 .
   242  func (cki ComputedKeyInfos) ShallowCopy() *ComputedKeyInfos {
   243  	ret := &ComputedKeyInfos{
   244  		Contextified:  NewContextified(cki.G()),
   245  		dirty:         cki.dirty,
   246  		Version:       cki.Version,
   247  		Infos:         make(map[keybase1.KID]*ComputedKeyInfo, len(cki.Infos)),
   248  		Sigs:          make(map[keybase1.SigIDMapKey]*ComputedKeyInfo, len(cki.Sigs)),
   249  		Devices:       make(map[keybase1.DeviceID]*Device, len(cki.Devices)),
   250  		KIDToDeviceID: make(map[keybase1.KID]keybase1.DeviceID, len(cki.KIDToDeviceID)),
   251  		PerUserKeys:   make(map[keybase1.PerUserKeyGeneration]keybase1.PerUserKey),
   252  	}
   253  	for k, v := range cki.Infos {
   254  		ret.Infos[k] = v
   255  	}
   256  
   257  	for k, v := range cki.Sigs {
   258  		ret.Sigs[k] = v
   259  	}
   260  
   261  	for k, v := range cki.Devices {
   262  		ret.Devices[k] = v
   263  	}
   264  
   265  	for k, v := range cki.KIDToDeviceID {
   266  		ret.KIDToDeviceID[k] = v
   267  	}
   268  
   269  	for k, v := range cki.PerUserKeys {
   270  		ret.PerUserKeys[k] = v
   271  	}
   272  
   273  	return ret
   274  }
   275  
   276  func (kf KeyFamily) ShallowCopy() *KeyFamily {
   277  	ret := &KeyFamily{
   278  		Contextified: NewContextified(kf.G()),
   279  		pgp2kid:      make(map[PGPFingerprint]keybase1.KID),
   280  		kid2pgp:      make(map[keybase1.KID]PGPFingerprint),
   281  		AllKIDs:      make(map[keybase1.KID]bool),
   282  		PGPKeySets:   make(map[keybase1.KID]*PGPKeySet),
   283  		SingleKeys:   make(map[keybase1.KID]GenericKey),
   284  	}
   285  
   286  	for k, v := range kf.pgp2kid {
   287  		ret.pgp2kid[k] = v
   288  	}
   289  
   290  	for k, v := range kf.kid2pgp {
   291  		ret.kid2pgp[k] = v
   292  	}
   293  
   294  	for k, v := range kf.AllKIDs {
   295  		ret.AllKIDs[k] = v
   296  	}
   297  
   298  	for k, v := range kf.PGPKeySets {
   299  		ret.PGPKeySets[k] = v
   300  	}
   301  
   302  	for k, v := range kf.SingleKeys {
   303  		ret.SingleKeys[k] = v
   304  	}
   305  
   306  	return ret
   307  }
   308  
   309  func (ckf ComputedKeyFamily) ShallowCopy() *ComputedKeyFamily {
   310  	ret := &ComputedKeyFamily{
   311  		Contextified: NewContextified(ckf.G()),
   312  	}
   313  	if ckf.kf != nil {
   314  		ret.kf = ckf.kf.ShallowCopy()
   315  	}
   316  	if ckf.cki != nil {
   317  		ret.cki = ckf.cki.ShallowCopy()
   318  	}
   319  	return ret
   320  }
   321  
   322  func NewComputedKeyInfos(g *GlobalContext) *ComputedKeyInfos {
   323  	return &ComputedKeyInfos{
   324  		Contextified:  NewContextified(g),
   325  		Version:       ComputedKeyInfosVersionCurrent,
   326  		Infos:         make(map[keybase1.KID]*ComputedKeyInfo),
   327  		Sigs:          make(map[keybase1.SigIDMapKey]*ComputedKeyInfo),
   328  		Devices:       make(map[keybase1.DeviceID]*Device),
   329  		KIDToDeviceID: make(map[keybase1.KID]keybase1.DeviceID),
   330  		PerUserKeys:   make(map[keybase1.PerUserKeyGeneration]keybase1.PerUserKey),
   331  	}
   332  }
   333  
   334  func NewComputedKeyInfo(kid keybase1.KID, eldest, sibkey bool, status KeyStatus, ctime, etime int64, activePGPHash string) ComputedKeyInfo {
   335  	return ComputedKeyInfo{
   336  		KID:           kid,
   337  		Eldest:        eldest,
   338  		Sibkey:        sibkey,
   339  		Status:        status,
   340  		CTime:         ctime,
   341  		ETime:         etime,
   342  		Delegations:   make(map[keybase1.SigIDMapKey]keybase1.KID),
   343  		ActivePGPHash: activePGPHash,
   344  	}
   345  }
   346  
   347  func (cki ComputedKeyInfos) InsertLocalEldestKey(kid keybase1.KID) {
   348  	// CTime and ETime are both initialized to zero, meaning that (until we get
   349  	// updates from the server) this key never expires.
   350  	eldestCki := NewComputedKeyInfo(kid, true, true, KeyUncancelled, 0, 0, "" /* activePGPHash */)
   351  	cki.Insert(&eldestCki)
   352  }
   353  
   354  // For use when there are no chain links at all, so all we can do is trust the
   355  // eldest key that the server reported.
   356  func (cki ComputedKeyInfos) InsertServerEldestKey(eldestKey GenericKey, un NormalizedUsername) error {
   357  	kbid := KeybaseIdentity(cki.G(), un)
   358  	if pgp, ok := eldestKey.(*PGPKeyBundle); ok {
   359  
   360  		// In the future, we might choose to ignore this etime, as we do in
   361  		// InsertEldestLink below. When we do make that change, be certain
   362  		// to update the comment in PGPKeyBundle#CheckIdentity to reflect it.
   363  		// For now, we continue to honor the foo_user@keybase.io etime in the case
   364  		// there's no sigchain link over the key to specify a different etime.
   365  		match, ctime, etime := pgp.CheckIdentity(kbid)
   366  		etime = cki.G().HonorPGPExpireTime(etime)
   367  		if match {
   368  			kid := eldestKey.GetKID()
   369  			eldestCki := NewComputedKeyInfo(kid, true, true, KeyUncancelled, ctime, etime, "" /* activePGPHash */)
   370  			cki.Insert(&eldestCki)
   371  			return nil
   372  		}
   373  		return KeyFamilyError{"InsertServerEldestKey found a non-matching eldest key."}
   374  	}
   375  	return KeyFamilyError{"InsertServerEldestKey found a non-PGP key."}
   376  }
   377  
   378  func (ckf ComputedKeyFamily) InsertEldestLink(tcl TypedChainLink, username NormalizedUsername) (err error) {
   379  	ckf.G().Log.Debug("ComputedKeyFamily#InsertEldestLink %s", tcl.ToDebugString())
   380  
   381  	kid := tcl.GetKID()
   382  	tm := TclToKeybaseTime(tcl)
   383  
   384  	_, err = ckf.FindKeyWithKIDUnsafe(kid)
   385  	if err != nil {
   386  		return
   387  	}
   388  
   389  	mhm, err := tcl.GetMerkleHashMeta()
   390  	if err != nil {
   391  		return err
   392  	}
   393  
   394  	// We don't need to check the signature on the first link, because
   395  	// verifySubchain will take care of that.
   396  	ctime := tcl.GetCTime().Unix()
   397  	etime := ckf.G().HonorSigchainExpireTime(tcl.GetETime().Unix())
   398  
   399  	eldestCki := NewComputedKeyInfo(kid, true, true, KeyUncancelled, ctime, etime, tcl.GetPGPFullHash())
   400  	eldestCki.DelegatedAt = tm
   401  	eldestCki.DelegatedAtHashMeta = mhm
   402  	eldestCki.DelegatedAtSigChainLocation = tcl.ToSigChainLocation()
   403  
   404  	// Tricky legacy detail: Note that we have not inserted the eldest sig into
   405  	// the Delegations map here. verifySubchain() might go on to do that after
   406  	// we return if the link is of a delegating type (type:eldest or
   407  	// type:sibkey), but that's not always the case. Omitting the delegation
   408  	// from that map means that revoking the signature does *not* revoke the
   409  	// key it (implicitly) delegated. For example, Max's eldest link is a
   410  	// twitter proof, which is revoked. That *must not* count as a revocation
   411  	// of his eldest key. We have a copy of Max's sigchain as one of our test
   412  	// vectors, to cover this behavior. See also the note in RevokeSig.
   413  
   414  	ckf.cki.Insert(&eldestCki)
   415  	return nil
   416  }
   417  
   418  // ParseKeyFamily takes as input a dictionary from a JSON file and returns
   419  // a parsed version for manipulation in the program.
   420  func ParseKeyFamily(g *GlobalContext, jw *jsonw.Wrapper) (ret *KeyFamily, err error) {
   421  	defer g.Trace("ParseKeyFamily", &err)()
   422  
   423  	if jw == nil || jw.IsNil() {
   424  		err = KeyFamilyError{"nil record from server"}
   425  		return
   426  	}
   427  
   428  	kf := KeyFamily{
   429  		Contextified: NewContextified(g),
   430  		pgp2kid:      make(map[PGPFingerprint]keybase1.KID),
   431  		kid2pgp:      make(map[keybase1.KID]PGPFingerprint),
   432  	}
   433  
   434  	// Fill in AllKeys. Somewhat wasteful but probably faster than
   435  	// using Jsonw wrappers, and less error-prone.
   436  	var rkf RawKeyFamily
   437  	if err = jw.UnmarshalAgain(&rkf); err != nil {
   438  		return
   439  	}
   440  	kf.BundlesForTesting = rkf.AllBundles
   441  
   442  	// Parse the keys, and collect the PGP keys to map their fingerprints.
   443  	kf.AllKIDs = make(map[keybase1.KID]bool)
   444  	kf.PGPKeySets = make(map[keybase1.KID]*PGPKeySet)
   445  	kf.SingleKeys = make(map[keybase1.KID]GenericKey)
   446  	for i, bundle := range rkf.AllBundles {
   447  		newKey, w, err := ParseGenericKey(bundle)
   448  
   449  		// Some users have some historical bad keys, so no reason to crap
   450  		// out if we can't parse them, especially if there are others than
   451  		// can do just as well.
   452  		if err != nil {
   453  			g.Log.Notice("Failed to parse public key at position %d", i)
   454  			g.Log.Debug("Key parsing error: %s", err)
   455  			g.Log.Debug("Full key dump follows")
   456  			g.Log.Debug(bundle)
   457  			continue
   458  		}
   459  		w.Warn(g)
   460  
   461  		kid := newKey.GetKID()
   462  
   463  		if pgp, isPGP := newKey.(*PGPKeyBundle); isPGP {
   464  			ks, ok := kf.PGPKeySets[kid]
   465  			if !ok {
   466  				ks = &PGPKeySet{NewContextified(g), nil, make(map[string]*PGPKeyBundle)}
   467  				kf.PGPKeySets[kid] = ks
   468  
   469  				fp := pgp.GetFingerprint()
   470  				kf.pgp2kid[fp] = kid
   471  				kf.kid2pgp[kid] = fp
   472  			}
   473  			err = ks.addKey(pgp)
   474  			if err != nil {
   475  				return nil, err
   476  			}
   477  		} else {
   478  			kf.SingleKeys[kid] = newKey
   479  		}
   480  		kf.AllKIDs[kid] = true
   481  	}
   482  
   483  	ret = &kf
   484  	return
   485  }
   486  
   487  // FindKeyWithKIDUnsafe returns a key given a KID. It doesn't check if the key
   488  // is expired or revoked, so most callers should use the FindActive* methods.
   489  func (ckf ComputedKeyFamily) FindKeyWithKIDUnsafe(kid keybase1.KID) (GenericKey, error) {
   490  	if key, ok := ckf.kf.SingleKeys[kid]; ok {
   491  		return key, nil
   492  	}
   493  	if ks, ok := ckf.kf.PGPKeySets[kid]; ok {
   494  		if ckf.cki != nil {
   495  			if cki, found := ckf.cki.Infos[kid]; found && cki.ActivePGPHash != "" {
   496  				if key, ok := ks.KeysByHash[cki.ActivePGPHash]; ok {
   497  					return key, nil
   498  				}
   499  				return nil, NoKeyError{fmt.Sprintf("Sigchain specified that KID %s is a PGP key with hash %s but no version of the key with that hash was found", kid, cki.ActivePGPHash)}
   500  			}
   501  		}
   502  		return ks.PermissivelyMergedKey, nil
   503  	}
   504  	return nil, KeyFamilyError{fmt.Sprintf("No key found for %s", kid)}
   505  }
   506  
   507  func (ckf ComputedKeyFamily) getCkiUnchecked(kid keybase1.KID) (ret *ComputedKeyInfo) {
   508  	return ckf.cki.Infos[kid]
   509  }
   510  
   511  func (ckf ComputedKeyFamily) getCkiIfActiveAtTime(kid keybase1.KID, t time.Time) (ret *ComputedKeyInfo, err error) {
   512  	unixTime := t.Unix()
   513  	if ki := ckf.cki.Infos[kid]; ki == nil {
   514  		err = NoKeyError{fmt.Sprintf("The key '%s' wasn't found", kid)}
   515  	} else if ki.Status != KeyUncancelled {
   516  		err = KeyRevokedError{fmt.Sprintf("The key '%s' is no longer active", kid)}
   517  	} else if ki.ETime > 0 && unixTime > ki.ETime {
   518  		formatStr := "Mon Jan 2 15:04:05 -0700 MST 2006"
   519  		ckf.G().Log.Warning("Checking status of key %s\n    with respect to time [%s],\n    found it had expired at [%s].",
   520  			kid, t.Format(formatStr), time.Unix(ki.ETime, 0).Format(formatStr))
   521  		err = KeyExpiredError{fmt.Sprintf("The key '%s' expired at %s", kid, time.Unix(ki.ETime, 0))}
   522  	} else {
   523  		ret = ki
   524  	}
   525  	return
   526  }
   527  
   528  func (ckf ComputedKeyFamily) getCkiIfActiveNow(kid keybase1.KID) (ret *ComputedKeyInfo, err error) {
   529  	return ckf.getCkiIfActiveAtTime(kid, time.Now())
   530  }
   531  
   532  // FindActiveSibkey takes a given KID and finds the corresponding active sibkey
   533  // in the current key family. If it cannot find the key, or if the key is no
   534  // longer active (either by revocation, or by expiring), it will return an
   535  // error saying why. Otherwise, it will return the key.  In this case either
   536  // key is non-nil, or err is non-nil.
   537  func (ckf ComputedKeyFamily) FindActiveSibkey(kid keybase1.KID) (key GenericKey, cki ComputedKeyInfo, err error) {
   538  	return ckf.FindActiveSibkeyAtTime(kid, time.Now())
   539  }
   540  
   541  // As FindActiveSibkey, but for a specific time. Note that going back in time
   542  // only affects expiration, not revocation. Thus this function is mainly useful
   543  // for validating the sigchain, when each delegation and revocation is getting
   544  // replayed in order.
   545  func (ckf ComputedKeyFamily) FindActiveSibkeyAtTime(kid keybase1.KID, t time.Time) (key GenericKey, cki ComputedKeyInfo, err error) {
   546  	liveCki, err := ckf.getCkiIfActiveAtTime(kid, t)
   547  	if liveCki == nil || err != nil {
   548  		// err gets returned.
   549  	} else if !liveCki.Sibkey {
   550  		err = kbcrypto.BadKeyError{Msg: fmt.Sprintf("The key '%s' wasn't delegated as a sibkey", kid)}
   551  	} else {
   552  		key, err = ckf.FindKeyWithKIDUnsafe(kid)
   553  		cki = *liveCki
   554  	}
   555  	return
   556  }
   557  
   558  // FindActiveEncryptionSubkey takes a given KID and finds the corresponding
   559  // active encryption subkey in the current key family.  If for any reason it
   560  // cannot find the key, it will return an error saying why.  Otherwise, it will
   561  // return the key.  In this case either key is non-nil, or err is non-nil.
   562  func (ckf ComputedKeyFamily) FindActiveEncryptionSubkey(kid keybase1.KID) (ret GenericKey, cki ComputedKeyInfo, err error) {
   563  	ckip, err := ckf.getCkiIfActiveNow(kid)
   564  	if err != nil {
   565  		return nil, cki, err
   566  	}
   567  	if ckip.Sibkey {
   568  		return nil, cki, kbcrypto.BadKeyError{Msg: fmt.Sprintf("The key '%s' was delegated as a sibkey", kid.String())}
   569  	}
   570  	key, err := ckf.FindKeyWithKIDUnsafe(kid)
   571  	if err != nil {
   572  		return nil, cki, err
   573  	}
   574  	if !CanEncrypt(key) {
   575  		return nil, cki, kbcrypto.BadKeyError{Msg: fmt.Sprintf("The key '%s' cannot encrypt", kid.String())}
   576  	}
   577  	return key, *ckip, nil
   578  }
   579  
   580  func (ckf ComputedKeyFamily) FindKIDFromFingerprint(fp PGPFingerprint) (kid keybase1.KID, err error) {
   581  	kid, ok := ckf.kf.pgp2kid[fp]
   582  	if !ok {
   583  		return kid, NoKeyError{fmt.Sprintf("No key found in key family for %q", fp)}
   584  	}
   585  	return kid, nil
   586  }
   587  
   588  // TclToKeybaseTime turns a TypedChainLink into a KeybaseTime tuple, looking
   589  // inside the chainlink for the Unix wallclock and the global MerkleChain seqno.
   590  func TclToKeybaseTime(tcl TypedChainLink) *KeybaseTime {
   591  	return &KeybaseTime{
   592  		Unix:  tcl.GetCTime().Unix(),
   593  		Chain: tcl.GetMerkleSeqno(),
   594  	}
   595  }
   596  
   597  // NowAsKeybaseTime makes a representation of now.  IF we don't know the MerkleTree
   598  // chain seqno, just use 0
   599  func NowAsKeybaseTime(seqno keybase1.Seqno) *KeybaseTime {
   600  	return &KeybaseTime{
   601  		Unix:  time.Now().Unix(),
   602  		Chain: seqno,
   603  	}
   604  }
   605  
   606  // Delegate performs a delegation to the key described in the given TypedChainLink.
   607  // This maybe be a sub- or sibkey delegation.
   608  func (ckf *ComputedKeyFamily) Delegate(tcl TypedChainLink) (err error) {
   609  
   610  	kid := tcl.GetDelegatedKid()
   611  	sigid := tcl.GetSigID()
   612  	tm := TclToKeybaseTime(tcl)
   613  
   614  	if kid.IsNil() {
   615  		debug.PrintStack()
   616  		return KeyFamilyError{fmt.Sprintf("Delegated KID is nil %T", tcl)}
   617  	}
   618  
   619  	if _, err := ckf.FindKeyWithKIDUnsafe(kid); err != nil {
   620  		return KeyFamilyError{fmt.Sprintf("Delegated KID %s is not in the key family", kid.String())}
   621  	}
   622  
   623  	mhm, err := tcl.GetMerkleHashMeta()
   624  	if err != nil {
   625  		return err
   626  	}
   627  
   628  	err = ckf.cki.Delegate(kid, tm, sigid, tcl.GetKID(), tcl.GetParentKid(),
   629  		tcl.GetPGPFullHash(), (tcl.GetRole() == DLGSibkey), tcl.GetCTime(), tcl.GetETime(),
   630  		mhm, tcl.GetFirstAppearedMerkleSeqnoUnverified(), tcl.ToSigChainLocation())
   631  	return
   632  }
   633  
   634  func (ckf *ComputedKeyFamily) DelegatePerUserKey(perUserKey keybase1.PerUserKey) (err error) {
   635  	return ckf.cki.DelegatePerUserKey(perUserKey)
   636  }
   637  
   638  // Delegate marks the given ComputedKeyInfos object that the given kid is now
   639  // delegated, as of time tm, in sigid, as signed by signingKid, etc.
   640  // fau = "FirstAppearedUnverified", a hint from the server that we're going to persist.
   641  // dascl = "DelegatedAtSigChainLocation"
   642  func (cki *ComputedKeyInfos) Delegate(kid keybase1.KID, tm *KeybaseTime, sigid keybase1.SigID, signingKid, parentKID keybase1.KID,
   643  	pgpHash string, isSibkey bool, ctime, etime time.Time,
   644  	merkleHashMeta keybase1.HashMeta, fau keybase1.Seqno,
   645  	dascl keybase1.SigChainLocation) (err error) {
   646  
   647  	cki.G().Log.Debug("ComputeKeyInfos#Delegate To %s with %s at sig %s", kid.String(), signingKid, sigid.ToDisplayString(true))
   648  	info, found := cki.Infos[kid]
   649  	etimeUnix := cki.G().HonorSigchainExpireTime(etime.Unix())
   650  	if !found {
   651  		newInfo := NewComputedKeyInfo(kid, false, isSibkey, KeyUncancelled, ctime.Unix(), etimeUnix, pgpHash)
   652  		newInfo.DelegatedAt = tm
   653  		info = &newInfo
   654  		cki.Infos[kid] = info
   655  	} else {
   656  		info.Status = KeyUncancelled
   657  		info.CTime = ctime.Unix()
   658  		info.ETime = etimeUnix
   659  		info.ActivePGPHash = pgpHash
   660  	}
   661  	info.Delegations[sigid.ToMapKey()] = signingKid
   662  	info.DelegationsList = append(info.DelegationsList, Delegation{signingKid, sigid})
   663  	info.Sibkey = isSibkey
   664  	info.DelegatedAtHashMeta = merkleHashMeta.DeepCopy()
   665  	info.DelegatedAtSigChainLocation = dascl.DeepCopy()
   666  	info.FirstAppearedUnverified = fau
   667  
   668  	cki.Sigs[sigid.ToMapKey()] = info
   669  
   670  	// If it's a subkey, make a pointer from it to its parent,
   671  	// and also from its parent to it.
   672  	if parentKID.Exists() {
   673  		info.Parent = parentKID
   674  		if parent, found := cki.Infos[parentKID]; found {
   675  			parent.Subkey = kid
   676  		}
   677  	}
   678  	return
   679  }
   680  
   681  func (cki *ComputedKeyInfos) IsStaleVersion() bool {
   682  	return cki.Version < ComputedKeyInfosVersionCurrent
   683  }
   684  
   685  // DelegatePerUserKey inserts the new per-user key into the list of known per-user keys.
   686  func (cki *ComputedKeyInfos) DelegatePerUserKey(perUserKey keybase1.PerUserKey) (err error) {
   687  	if perUserKey.Gen <= 0 {
   688  		return fmt.Errorf("invalid per-user-key generation %v", perUserKey.Gen)
   689  	}
   690  	if perUserKey.Seqno == 0 {
   691  		return fmt.Errorf("invalid per-user-key seqno: %v", perUserKey.Seqno)
   692  	}
   693  	if perUserKey.SigKID.IsNil() {
   694  		return errors.New("nil per-user-key sig kid")
   695  	}
   696  	if perUserKey.EncKID.IsNil() {
   697  		return errors.New("nil per-user-key enc kid")
   698  	}
   699  	if perUserKey.SignedByKID.IsNil() {
   700  		return errors.New("nil per-user-key signed-by kid")
   701  	}
   702  	cki.PerUserKeys[keybase1.PerUserKeyGeneration(perUserKey.Gen)] = perUserKey
   703  	return nil
   704  }
   705  
   706  // Revoke examines a TypeChainLink and applies any revocations in the link
   707  // to the current ComputedKeyInfos.
   708  func (ckf *ComputedKeyFamily) Revoke(tcl TypedChainLink) (err error) {
   709  	err = ckf.revokeSigs(tcl.GetRevocations(), tcl)
   710  	if err == nil {
   711  		err = ckf.revokeKids(tcl.GetRevokeKids(), tcl)
   712  	}
   713  	return err
   714  }
   715  
   716  // SetPGPHash sets the authoritative version (by hash) of a PGP key
   717  func (ckf *ComputedKeyFamily) SetActivePGPHash(kid keybase1.KID, hash string) {
   718  	found := false
   719  	if ks, ok := ckf.kf.PGPKeySets[kid]; ok && ks != nil && ks.KeysByHash[hash] != nil {
   720  		found = true
   721  	}
   722  	if !found {
   723  		// We've noted this case in the wild (see CORE-4771). It occured
   724  		// because the server accepted a new Cv25519 key, but an old client
   725  		// failed to parse it in ParseKeyFamily above. So just warn here.
   726  		// We expect, though, that if you get this Warning there is trouble ahead,
   727  		// and FindKeyWithKIDUnsafe will return nil.
   728  		ckf.G().Log.Warning("Didn't have a PGP key for %s with hash %s", kid, hash)
   729  	}
   730  	if _, ok := ckf.cki.Infos[kid]; ok {
   731  		ckf.cki.Infos[kid].ActivePGPHash = hash
   732  	} else {
   733  		ckf.G().Log.Debug("| Skipped setting active hash, since key was never delegated")
   734  	}
   735  }
   736  
   737  // ClearActivePGPHash clears authoritative hash of PGP key, after a revoke.
   738  func (ckf *ComputedKeyFamily) ClearActivePGPHash(kid keybase1.KID) {
   739  	if _, ok := ckf.cki.Infos[kid]; ok {
   740  		ckf.cki.Infos[kid].ActivePGPHash = ""
   741  	} else {
   742  		ckf.G().Log.Debug("| Skipped clearing active hash, since key was never delegated")
   743  	}
   744  }
   745  
   746  // revokeSigs operates on the per-signature revocations in the given
   747  // TypedChainLink and applies them accordingly.
   748  func (ckf *ComputedKeyFamily) revokeSigs(sigs []keybase1.SigID, tcl TypedChainLink) error {
   749  	for _, s := range sigs {
   750  		if len(s) == 0 {
   751  			continue
   752  		}
   753  		if err := ckf.RevokeSig(s, tcl); err != nil {
   754  			return err
   755  		}
   756  	}
   757  	return nil
   758  }
   759  
   760  // revokeKids operates on the per-kid revocations in the given
   761  // TypedChainLink and applies them accordingly.
   762  func (ckf *ComputedKeyFamily) revokeKids(kids []keybase1.KID, tcl TypedChainLink) (err error) {
   763  	for _, k := range kids {
   764  		if k.Exists() {
   765  			if err = ckf.RevokeKid(k, tcl); err != nil {
   766  				return
   767  			}
   768  		}
   769  	}
   770  	return
   771  }
   772  
   773  func (ckf *ComputedKeyFamily) RevokeSig(sig keybase1.SigID, tcl TypedChainLink) (err error) {
   774  	if info, found := ckf.cki.Sigs[sig.ToMapKey()]; !found {
   775  		// silently no-op if the signature doesn't exist
   776  	} else if _, found := info.Delegations[sig.ToMapKey()]; found {
   777  		// Tricky legacy detail: For some eldest links that implicitly delegate
   778  		// keys, the info.Delegations map will not contain the delegation, and
   779  		// we will skip this branch. We rely on this behavior to avoid revoking
   780  		// keys that shouldn't be revoked. See the note in InsertEldestLink.
   781  
   782  		info.Status = KeyRevoked
   783  		info.RevokedAt = TclToKeybaseTime(tcl)
   784  		info.RevokedBy = tcl.GetKID()
   785  		tmp := tcl.ToSigChainLocation()
   786  		info.RevokedAtSigChainLocation = &tmp
   787  		mhm, err := tcl.GetMerkleHashMeta()
   788  		if err != nil {
   789  			return err
   790  		}
   791  		info.RevokedAtHashMeta = mhm
   792  		info.RevokeFirstAppearedUnverified = tcl.GetFirstAppearedMerkleSeqnoUnverified()
   793  		kid := info.KID
   794  
   795  		if KIDIsPGP(kid) {
   796  			ckf.ClearActivePGPHash(kid)
   797  		}
   798  	} else {
   799  		err = BadRevocationError{fmt.Sprintf("Can't find sigID %s in delegation list", sig)}
   800  	}
   801  	return
   802  }
   803  
   804  func (ckf *ComputedKeyFamily) RevokeKid(kid keybase1.KID, tcl TypedChainLink) (err error) {
   805  	if info, found := ckf.cki.Infos[kid]; found {
   806  		info.Status = KeyRevoked
   807  		info.RevokedAt = TclToKeybaseTime(tcl)
   808  		info.RevokedBy = tcl.GetKID()
   809  		tmp := tcl.ToSigChainLocation()
   810  		info.RevokedAtSigChainLocation = &tmp
   811  		mhm, err := tcl.GetMerkleHashMeta()
   812  		if err != nil {
   813  			return err
   814  		}
   815  		info.RevokedAtHashMeta = mhm
   816  		info.RevokeFirstAppearedUnverified = tcl.GetFirstAppearedMerkleSeqnoUnverified()
   817  
   818  		if KIDIsPGP(kid) {
   819  			ckf.ClearActivePGPHash(kid)
   820  		}
   821  	}
   822  	return
   823  }
   824  
   825  // FindKeybaseName looks at all PGP keys in this key family that are active
   826  // sibkeys to find a key with a signed identity of <name@keybase.io>. IF
   827  // found return true, and otherwise false.
   828  func (ckf ComputedKeyFamily) FindKeybaseName(s string) bool {
   829  	kem := KeybaseEmailAddress(s)
   830  	for kid := range ckf.kf.PGPKeySets {
   831  		if info, found := ckf.cki.Infos[kid]; !found {
   832  			continue
   833  		} else if info.Status != KeyUncancelled || !info.Sibkey {
   834  			continue
   835  		}
   836  		pgp := ckf.kf.PGPKeySets[kid].PermissivelyMergedKey
   837  		if pgp.FindEmail(kem) {
   838  			ckf.G().Log.Debug("| Found self-sig for %s in key ID: %s", s, kid)
   839  			return true
   840  		}
   841  	}
   842  	return false
   843  }
   844  
   845  // LocalDelegate performs a local key delegation, without the server's permissions.
   846  // We'll need to do this when a key is locally generated.
   847  func (kf *KeyFamily) LocalDelegate(key GenericKey) (err error) {
   848  	if pgp, ok := key.(*PGPKeyBundle); ok {
   849  		kid := pgp.GetKID()
   850  		kf.pgp2kid[pgp.GetFingerprint()] = kid
   851  	}
   852  	kf.SingleKeys[key.GetKID()] = key
   853  	return
   854  }
   855  
   856  // GetKeyRoleAtTime returns the KeyRole (sibkey/subkey/none), taking into
   857  // account whether the key has been cancelled at time t.
   858  func (ckf ComputedKeyFamily) GetKeyRoleAtTime(kid keybase1.KID, t time.Time) (ret KeyRole) {
   859  	if info, err := ckf.getCkiIfActiveAtTime(kid, t); err != nil {
   860  		ckf.G().Log.Debug("GetKeyRoleAtTime %s, %s => err %s", kid, t, err)
   861  		ret = DLGNone
   862  	} else if info.Sibkey {
   863  		ret = DLGSibkey
   864  	} else {
   865  		ret = DLGSubkey
   866  	}
   867  	return
   868  }
   869  
   870  // GetAllSibkeysUnchecked gets all sibkeys, dead or otherwise, that were at one point associated
   871  // with this key family.
   872  func (ckf ComputedKeyFamily) GetAllSibkeysUnchecked() (ret []GenericKey) {
   873  	return ckf.getAllKeysUnchecked(DLGSibkey)
   874  }
   875  
   876  // GetAllSubkeysUnchecked gets all sibkeys, dead or otherwise, that were at one point associated
   877  // with this key family.
   878  func (ckf ComputedKeyFamily) GetAllSubkeysUnchecked() (ret []GenericKey) {
   879  	return ckf.getAllKeysUnchecked(DLGSubkey)
   880  }
   881  
   882  func (ckf ComputedKeyFamily) getAllKeysUnchecked(role KeyRole) (ret []GenericKey) {
   883  	for kid := range ckf.kf.AllKIDs {
   884  		info := ckf.getCkiUnchecked(kid)
   885  		if info != nil && ((info.Sibkey && role == DLGSibkey) || (!info.Sibkey && role == DLGSubkey)) {
   886  			key, err := ckf.FindKeyWithKIDUnsafe(kid)
   887  			if err != nil {
   888  				ckf.G().Log.Warning("GetAllSibkeys: Error in getting KID %s: %s", kid, err)
   889  			}
   890  			ret = append(ret, key)
   891  		}
   892  	}
   893  	return ret
   894  }
   895  
   896  // GetKeyRole returns the KeyRole (sibkey/subkey/none), taking into account
   897  // whether the key has been cancelled.
   898  func (ckf ComputedKeyFamily) GetKeyRole(kid keybase1.KID) (ret KeyRole) {
   899  	return ckf.GetKeyRoleAtTime(kid, time.Now())
   900  }
   901  
   902  // GetAllActiveSibkeys gets all active Sibkeys from given ComputedKeyFamily.
   903  func (ckf ComputedKeyFamily) GetAllActiveKeysWithRoleAtTime(role KeyRole, t time.Time) (ret []GenericKey) {
   904  	for kid := range ckf.kf.AllKIDs {
   905  		if ckf.GetKeyRoleAtTime(kid, t) == role {
   906  			key, err := ckf.FindKeyWithKIDUnsafe(kid)
   907  			if err != nil {
   908  				ckf.G().Log.Warning("GetAllActiveKeysWithRoleAtTime: Error in getting KID %s: %s", kid, err)
   909  			}
   910  			if key == nil {
   911  				ckf.G().Log.Warning("GetAllActiveKeysWithRoleAtTime: Null key for KID %s", kid)
   912  			} else {
   913  				ret = append(ret, key)
   914  			}
   915  		}
   916  	}
   917  	return
   918  }
   919  
   920  // GetAllActiveSibkeys gets all active Sibkeys from given ComputedKeyFamily.
   921  func (ckf ComputedKeyFamily) GetAllActiveSibkeysAtTime(t time.Time) []GenericKey {
   922  	return ckf.GetAllActiveKeysWithRoleAtTime(DLGSibkey, t)
   923  }
   924  
   925  // GetAllActiveSibkeys gets all active Sibkeys from given ComputedKeyFamily.
   926  func (ckf ComputedKeyFamily) GetAllActiveSibkeys() []GenericKey {
   927  	return ckf.GetAllActiveSibkeysAtTime(time.Now())
   928  }
   929  
   930  func (ckf ComputedKeyFamily) GetAllActiveSubkeysAtTime(t time.Time) (ret []GenericKey) {
   931  	return ckf.GetAllActiveKeysWithRoleAtTime(DLGSubkey, t)
   932  }
   933  
   934  func (ckf ComputedKeyFamily) GetAllActiveSubkeys() []GenericKey {
   935  	return ckf.GetAllActiveSubkeysAtTime(time.Now())
   936  }
   937  
   938  func (ckf ComputedKeyFamily) GetAllActiveKeysForDevice(deviceID keybase1.DeviceID) ([]keybase1.KID, error) {
   939  	_, deviceExists := ckf.cki.Devices[deviceID]
   940  	if !deviceExists {
   941  		return nil, fmt.Errorf("Device %s does not exist.", deviceID)
   942  	}
   943  	var ret []keybase1.KID
   944  	// Find the sibkey(s) that belong to this device.
   945  	for _, sibkey := range ckf.GetAllActiveSibkeys() {
   946  		sibkeyKID := sibkey.GetKID()
   947  		if ckf.cki.KIDToDeviceID[sibkeyKID] == deviceID {
   948  			ret = append(ret, sibkeyKID)
   949  			// For each sibkey we find, get all its subkeys too.
   950  			for _, subkey := range ckf.GetAllActiveSubkeys() {
   951  				subkeyKID := subkey.GetKID()
   952  				if ckf.cki.Infos[subkeyKID].Parent.Equal(sibkeyKID) {
   953  					ret = append(ret, subkeyKID)
   954  				}
   955  			}
   956  		}
   957  	}
   958  	return ret, nil
   959  }
   960  
   961  // HasActiveKey returns if the given ComputeKeyFamily has any active keys.
   962  // The key has to be in the server-given KeyFamily and also in our ComputedKeyFamily.
   963  // The former check is so that we can handle the case nuked sigchains.
   964  func (ckf ComputedKeyFamily) HasActiveKey() bool {
   965  	for kid := range ckf.kf.AllKIDs {
   966  		if ckf.GetKeyRole(kid) == DLGSibkey {
   967  			return true
   968  		}
   969  	}
   970  	return false
   971  }
   972  
   973  // GetActivePGPKeys gets the active PGP keys from the ComputedKeyFamily.
   974  // If sibkey is False it will return all active PGP keys. Otherwise, it
   975  // will return only the Sibkeys. Note the keys need to be non-canceled,
   976  // and non-expired.
   977  func (ckf ComputedKeyFamily) GetActivePGPKeys(sibkey bool) (ret []*PGPKeyBundle) {
   978  	for kid := range ckf.kf.PGPKeySets {
   979  		role := ckf.GetKeyRole(kid)
   980  		if (sibkey && role == DLGSibkey) || role != DLGNone {
   981  			if key, err := ckf.FindKeyWithKIDUnsafe(kid); err == nil {
   982  				ret = append(ret, key.(*PGPKeyBundle))
   983  			} else {
   984  				ckf.G().Log.Errorf("KID %s was in a KeyFamily's list of PGP keys, but the key doesn't exist: %s", kid, err)
   985  			}
   986  		}
   987  	}
   988  	return
   989  }
   990  
   991  type RevokedKey struct {
   992  	Key       GenericKey
   993  	RevokedAt *KeybaseTime
   994  	RevokedBy keybase1.KID
   995  }
   996  
   997  func (ckf ComputedKeyFamily) GetRevokedKeys() []RevokedKey {
   998  	ckf.G().Log.Debug("+ GetRevokedKeys")
   999  	defer ckf.G().Log.Debug("- GetRevokedKeys")
  1000  
  1001  	var revokedKeys []RevokedKey
  1002  	for kid := range ckf.kf.AllKIDs {
  1003  		ki, ok := ckf.cki.Infos[kid]
  1004  		if !ok || ki == nil {
  1005  			ckf.G().Log.Debug("KID %s not in cki.Infos (likely belongs to a previous subchain). Skipping.", kid)
  1006  			continue
  1007  		}
  1008  		if ki.Status != KeyRevoked {
  1009  			continue
  1010  		}
  1011  		if ki.RevokedAt == nil {
  1012  			ckf.G().Log.Errorf("KID %s: status is KeyRevoked, but RevokedAt is nil", kid)
  1013  			continue
  1014  		}
  1015  		if ki.RevokedBy.IsNil() {
  1016  			ckf.G().Log.Debug("KID %s: RevokedAt is non-nil, but RevokedBy is nil, probably just old", kid)
  1017  		}
  1018  
  1019  		key, err := ckf.FindKeyWithKIDUnsafe(kid)
  1020  		if err != nil {
  1021  			ckf.G().Log.Errorf("No key found for %s in ckf", kid)
  1022  			continue
  1023  		}
  1024  
  1025  		revokedKeys = append(revokedKeys, RevokedKey{Key: key, RevokedAt: ki.RevokedAt, RevokedBy: ki.RevokedBy})
  1026  	}
  1027  
  1028  	return revokedKeys
  1029  }
  1030  
  1031  func (ckf ComputedKeyFamily) GetDeletedKeys() []GenericKey {
  1032  	ckf.G().Log.Debug("+ GetDeletedKeys")
  1033  	defer ckf.G().Log.Debug("- GetDeletedKeys")
  1034  
  1035  	var keys []GenericKey
  1036  	for kid := range ckf.kf.AllKIDs {
  1037  		_, ok := ckf.cki.Infos[kid]
  1038  		if ok {
  1039  			// key in cki.Infos, so it is in the current subchain, skip it.
  1040  			continue
  1041  		}
  1042  		key, err := ckf.FindKeyWithKIDUnsafe(kid)
  1043  		if err != nil {
  1044  			ckf.G().Log.Errorf("No key found for %s in ckf", kid)
  1045  			continue
  1046  		}
  1047  		keys = append(keys, key)
  1048  	}
  1049  	return keys
  1050  }
  1051  
  1052  // UpdateDevices takes the Device object from the given ChainLink
  1053  // and updates keys to reflects any device changes encoded therein.
  1054  func (ckf *ComputedKeyFamily) UpdateDevices(tcl TypedChainLink) (err error) {
  1055  
  1056  	var dobj *Device
  1057  	if dobj = tcl.GetDevice(); dobj == nil {
  1058  		ckf.G().VDL.Log(VLog1, "Short-circuit of UpdateDevices(); not a device link")
  1059  		return
  1060  	}
  1061  
  1062  	defer ckf.G().Trace("UpdateDevice", &err)()
  1063  
  1064  	did := dobj.ID
  1065  	kid := dobj.Kid
  1066  
  1067  	ckf.G().Log.Debug("| Device ID=%s; KID=%s", did, kid.String())
  1068  
  1069  	var prevKid keybase1.KID
  1070  	if existing, found := ckf.cki.Devices[did]; found {
  1071  		ckf.G().Log.Debug("| merge with existing")
  1072  		prevKid = existing.Kid
  1073  		existing.Merge(dobj)
  1074  		dobj = existing
  1075  	} else {
  1076  		ckf.G().Log.Debug("| New insert")
  1077  		ckf.cki.Devices[did] = dobj
  1078  	}
  1079  
  1080  	// If a KID is specified, we should clear out any previous KID from the
  1081  	// KID->Device map. But if not, leave the map as it is. Later "device"
  1082  	// blobs in the sigchain aren't required to repeat the KID every time.
  1083  	if kid.IsValid() {
  1084  		if prevKid.IsValid() {
  1085  			ckf.G().Log.Debug("| Clear out old key")
  1086  			delete(ckf.cki.KIDToDeviceID, prevKid)
  1087  		}
  1088  		ckf.cki.KIDToDeviceID[kid] = did
  1089  	}
  1090  
  1091  	return
  1092  }
  1093  
  1094  func (ckf *ComputedKeyFamily) getSibkeyKidForDevice(did keybase1.DeviceID) (keybase1.KID, error) {
  1095  	ckf.G().Log.Debug("+ getSibkeyKidForDevice(%v)", did)
  1096  	ckf.G().Log.Debug("| Devices map: %+v", ckf.cki.Devices)
  1097  
  1098  	var kid keybase1.KID
  1099  	device, found := ckf.cki.Devices[did]
  1100  	if !found {
  1101  		ckf.G().Log.Debug("device %s not found in cki.Devices", did)
  1102  		return kid, NoDeviceError{Reason: fmt.Sprintf("for device ID %s", did)}
  1103  	}
  1104  	if !device.Kid.IsValid() {
  1105  		ckf.G().Log.Debug("device found, but Kid invalid")
  1106  		return kid, fmt.Errorf("invalid kid for device %s", did)
  1107  	}
  1108  
  1109  	ckf.G().Log.Debug("device found, kid: %s", device.Kid.String())
  1110  	return device.Kid, nil
  1111  }
  1112  
  1113  // GetSibkeyForDevice gets the current per-device key for the given Device. Will
  1114  // return nil if one isn't found, and set err for a real error. The sibkey should
  1115  // be a signing key, not an encryption key of course.
  1116  func (ckf *ComputedKeyFamily) GetSibkeyForDevice(did keybase1.DeviceID) (key GenericKey, err error) {
  1117  	var kid keybase1.KID
  1118  	kid, err = ckf.getSibkeyKidForDevice(did)
  1119  	if kid.Exists() {
  1120  		key, _, err = ckf.FindActiveSibkey(kid)
  1121  	}
  1122  	return
  1123  }
  1124  
  1125  // GetCurrentDevice returns the current device.
  1126  func (ckf *ComputedKeyFamily) GetCurrentDevice(g *GlobalContext) (*Device, error) {
  1127  	did := g.Env.GetDeviceID()
  1128  	if did.IsNil() {
  1129  		return nil, NotProvisionedError{}
  1130  	}
  1131  
  1132  	dev, ok := ckf.cki.Devices[did]
  1133  	if !ok {
  1134  		return nil, NotFoundError{}
  1135  	}
  1136  
  1137  	return dev, nil
  1138  }
  1139  
  1140  // GetEncryptionSubkeyForDevice gets the current encryption subkey for the given device.
  1141  func (ckf *ComputedKeyFamily) GetEncryptionSubkeyForDevice(did keybase1.DeviceID) (key GenericKey, err error) {
  1142  	var kid keybase1.KID
  1143  	if kid, err = ckf.getSibkeyKidForDevice(did); err != nil {
  1144  		return
  1145  	}
  1146  	if kid.IsNil() {
  1147  		return
  1148  	}
  1149  	if cki, found := ckf.cki.Infos[kid]; !found {
  1150  		return
  1151  	} else if !cki.Subkey.IsValid() {
  1152  		return
  1153  	} else {
  1154  		key, _, err = ckf.FindActiveEncryptionSubkey(cki.Subkey)
  1155  	}
  1156  	return
  1157  }
  1158  
  1159  func (ckf *ComputedKeyFamily) HasActiveEncryptionSubkey() bool {
  1160  	for kid := range ckf.cki.Infos {
  1161  		if !kid.IsValid() {
  1162  			continue
  1163  		}
  1164  		if key, _, err := ckf.FindActiveEncryptionSubkey(kid); key != nil && err == nil {
  1165  			return true
  1166  		}
  1167  	}
  1168  	return false
  1169  }
  1170  
  1171  // GetDeviceForKey gets the device that this key is bound to, if any.
  1172  func (ckf *ComputedKeyFamily) GetDeviceForKey(key GenericKey) (*Device, error) {
  1173  	return ckf.GetDeviceForKID(key.GetKID())
  1174  }
  1175  
  1176  func (ckf *ComputedKeyFamily) GetDeviceForKID(kid keybase1.KID) (*Device, error) {
  1177  	dev, err := ckf.getDeviceForKidHelper(kid)
  1178  	if err == nil && dev != nil {
  1179  		return dev, nil
  1180  	}
  1181  
  1182  	// this could be a subkey, so try to find device for the parent
  1183  	cki, found := ckf.cki.Infos[kid]
  1184  	if !found {
  1185  		return nil, NoDeviceError{Reason: fmt.Sprintf("for key ID %s", kid)}
  1186  	}
  1187  	parent := cki.Parent
  1188  	if parent.IsNil() {
  1189  		return nil, NoDeviceError{Reason: fmt.Sprintf("for key ID %s", kid)}
  1190  	}
  1191  
  1192  	return ckf.getDeviceForKidHelper(parent)
  1193  
  1194  }
  1195  
  1196  func (ckf *ComputedKeyFamily) getDeviceForKidHelper(kid keybase1.KID) (ret *Device, err error) {
  1197  	if didString, found := ckf.cki.KIDToDeviceID[kid]; found {
  1198  		ret = ckf.cki.Devices[didString]
  1199  	}
  1200  	return
  1201  }
  1202  
  1203  type byAge []*Device
  1204  
  1205  func (a byAge) Len() int           { return len(a) }
  1206  func (a byAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  1207  func (a byAge) Less(i, j int) bool { return a[i].CTime < a[j].CTime }
  1208  
  1209  func (ckf *ComputedKeyFamily) GetAllDevices() []DeviceWithDeviceNumber {
  1210  	devicesNoNum := make([]*Device, 0, len(ckf.cki.Devices))
  1211  	for _, device := range ckf.cki.Devices {
  1212  		devicesNoNum = append(devicesNoNum, device)
  1213  	}
  1214  	sort.Sort(byAge(devicesNoNum))
  1215  	devices := make([]DeviceWithDeviceNumber, 0, len(devicesNoNum))
  1216  	deviceNumMap := make(map[keybase1.DeviceTypeV2]int)
  1217  	for _, device := range devicesNoNum {
  1218  
  1219  		devices = append(devices, DeviceWithDeviceNumber{device, deviceNumMap[device.Type]})
  1220  
  1221  		deviceNumMap[device.Type]++
  1222  	}
  1223  	return devices
  1224  }
  1225  
  1226  func (ckf *ComputedKeyFamily) GetAllActiveDevices() []DeviceWithDeviceNumber {
  1227  	devices := make([]DeviceWithDeviceNumber, 0)
  1228  	for _, device := range ckf.GetAllDevices() {
  1229  		if device.IsActive() {
  1230  			devices = append(devices, device)
  1231  		}
  1232  	}
  1233  	return devices
  1234  }
  1235  
  1236  func (ckf *ComputedKeyFamily) HasActiveDevice() bool {
  1237  	for _, device := range ckf.cki.Devices {
  1238  		if device.IsActive() {
  1239  			return true
  1240  		}
  1241  	}
  1242  	return false
  1243  }
  1244  
  1245  // Returns (&senderType, err). A non-nil error indicates some unexpected
  1246  // condition (like the key doesn't exist at all), which should be propagated.
  1247  // If the sender type is nil, the key is active, and the caller should proceed
  1248  // with an identify. Otherwise the key is no longer active, and the sender type
  1249  // indicates why.
  1250  func (ckf ComputedKeyFamily) GetSaltpackSenderTypeIfInactive(kid keybase1.KID) (*keybase1.SaltpackSenderType, error) {
  1251  	info := ckf.cki.Infos[kid]
  1252  	if info == nil {
  1253  		// This shouldn't happen without a server bug/attack or a very unlikely
  1254  		// race condition (e.g. a user account reset between the API server
  1255  		// telling us they own a key, and the loaduser confirming it.)
  1256  		return nil, fmt.Errorf("Key %s not found in key infos", kid.String())
  1257  	}
  1258  	if info.Status == KeyRevoked {
  1259  		ret := keybase1.SaltpackSenderType_REVOKED
  1260  		return &ret, nil
  1261  	}
  1262  	if info.Status == KeyUncancelled {
  1263  		// TODO: Get rid of the whole concept of expiration?
  1264  		if info.GetETime().Before(time.Now()) && !info.GetETime().IsZero() {
  1265  			ret := keybase1.SaltpackSenderType_EXPIRED
  1266  			return &ret, nil
  1267  		}
  1268  		// An active key. The caller needs to do an identify to determine the
  1269  		// final sender type (UNTRACKED, TRACKING_BROKE, etc.).
  1270  		return nil, nil
  1271  	}
  1272  	// This also shouldn't happen without a server bug or a very unlikely race
  1273  	// condition.
  1274  	return nil, fmt.Errorf("Key %s neither active nor revoked (%d)", kid.String(), info.Status)
  1275  }
  1276  
  1277  // If there aren't any per-user-keys for the user, return nil.
  1278  func (ckf *ComputedKeyFamily) GetLatestPerUserKey() *keybase1.PerUserKey {
  1279  	var currentGeneration keybase1.PerUserKeyGeneration
  1280  	var ret *keybase1.PerUserKey
  1281  	if ckf == nil {
  1282  		panic("nil ckf") // with a nil ckf, we can't log and this method will crash anyway.
  1283  	}
  1284  	if ckf.cki == nil {
  1285  		ckf.G().Log.Debug("ComputedKeyFamily#GetLatestPerUserKey: nil cki")
  1286  	}
  1287  	for generation, key := range ckf.cki.PerUserKeys {
  1288  		if generation > currentGeneration {
  1289  			currentGeneration = generation
  1290  			// Avoid taking references to the loop variable.
  1291  			currentKey := key
  1292  			ret = &currentKey
  1293  		}
  1294  	}
  1295  	return ret
  1296  }