github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/user.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  	"encoding/hex"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"regexp"
    12  
    13  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    14  	stellar1 "github.com/keybase/client/go/protocol/stellar1"
    15  	jsonw "github.com/keybase/go-jsonw"
    16  )
    17  
    18  type UserBasic interface {
    19  	GetUID() keybase1.UID
    20  	GetName() string
    21  }
    22  
    23  var _ UserBasic = keybase1.UserPlusKeys{}
    24  
    25  type User struct {
    26  	// Raw JSON element read from the server or our local DB.
    27  	basics     *jsonw.Wrapper
    28  	publicKeys *jsonw.Wrapper
    29  	pictures   *jsonw.Wrapper
    30  
    31  	// Processed fields
    32  	id          keybase1.UID
    33  	name        string
    34  	sigChainMem *SigChain
    35  	idTable     *IdentityTable
    36  	sigHints    *SigHints
    37  	status      keybase1.StatusCode
    38  
    39  	leaf MerkleUserLeaf
    40  
    41  	// Loaded from publicKeys
    42  	keyFamily *KeyFamily
    43  
    44  	// Available on partially-copied clones of the User object
    45  	ckfShallowCopy *ComputedKeyFamily
    46  
    47  	dirty bool
    48  	Contextified
    49  }
    50  
    51  func NewUserThin(name string, uid keybase1.UID) *User {
    52  	return &User{name: name, id: uid}
    53  }
    54  
    55  func newUser(g *GlobalContext, o *jsonw.Wrapper, fromStorage bool) (*User, error) {
    56  	uid, err := GetUID(o.AtKey("id"))
    57  	if err != nil {
    58  		return nil, fmt.Errorf("user object lacks an ID: %s", err)
    59  	}
    60  	name, err := o.AtKey("basics").AtKey("username").GetString()
    61  	if err != nil {
    62  		return nil, fmt.Errorf("user object for %s lacks a name", uid)
    63  	}
    64  
    65  	// This field was a late addition, so cached objects might not have it.
    66  	// If we load from storage and it wasn't there, then it's safe to assume
    67  	// it's a 0. All server replies should have this field though.
    68  	status, err := o.AtPath("basics.status").GetInt()
    69  	if err != nil {
    70  		if fromStorage {
    71  			status = SCOk
    72  		} else {
    73  			return nil, fmt.Errorf("user object for %s lacks a status field", uid)
    74  		}
    75  	}
    76  
    77  	kf, err := ParseKeyFamily(g, o.AtKey("public_keys"))
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return &User{
    83  		basics:       o.AtKey("basics"),
    84  		publicKeys:   o.AtKey("public_keys"),
    85  		pictures:     o.AtKey("pictures"),
    86  		keyFamily:    kf,
    87  		id:           uid,
    88  		name:         name,
    89  		status:       keybase1.StatusCode(status),
    90  		dirty:        false,
    91  		Contextified: NewContextified(g),
    92  	}, nil
    93  }
    94  
    95  func NewUserFromServer(g *GlobalContext, o *jsonw.Wrapper) (*User, error) {
    96  	u, e := newUser(g, o, false)
    97  	if e == nil {
    98  		u.dirty = true
    99  	}
   100  	return u, e
   101  }
   102  
   103  func NewUserFromLocalStorage(g *GlobalContext, o *jsonw.Wrapper) (*User, error) {
   104  	u, err := newUser(g, o, true)
   105  	return u, err
   106  }
   107  
   108  func (u *User) GetNormalizedName() NormalizedUsername { return NewNormalizedUsername(u.name) }
   109  func (u *User) GetName() string                       { return u.name }
   110  func (u *User) GetUID() keybase1.UID                  { return u.id }
   111  func (u *User) GetStatus() keybase1.StatusCode        { return u.status }
   112  
   113  func (u *User) GetSalt() (salt []byte, err error) {
   114  	saltHex, err := u.basics.AtKey("salt").GetString()
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	salt, err = hex.DecodeString(saltHex)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	return salt, nil
   123  }
   124  
   125  func (u *User) GetIDVersion() (int64, error) {
   126  	return u.basics.AtKey("id_version").GetInt64()
   127  }
   128  
   129  func (u *User) GetSigChainLastKnownSeqno() keybase1.Seqno {
   130  	if u.sigChain() == nil {
   131  		return 0
   132  	}
   133  	return u.sigChain().GetLastKnownSeqno()
   134  }
   135  
   136  func (u *User) GetSigChainLastKnownID() LinkID {
   137  	if u.sigChain() == nil {
   138  		return nil
   139  	}
   140  	return u.sigChain().GetLastKnownID()
   141  }
   142  
   143  func (u *User) GetCurrentEldestSeqno() keybase1.Seqno {
   144  	if u.sigChain() == nil {
   145  		// Note that NameWithEldestSeqno will return an error if you call it with zero.
   146  		return 0
   147  	}
   148  	return u.sigChain().currentSubchainStart
   149  }
   150  
   151  func (u *User) GetExpectedNextHighSkip(mctx MetaContext) (HighSkip, error) {
   152  	if u.sigChain() == nil {
   153  		return NewInitialHighSkip(), nil
   154  	}
   155  	return u.sigChain().GetExpectedNextHighSkip(mctx, u.GetUID())
   156  }
   157  
   158  func (u *User) GetLastLink() *ChainLink {
   159  	if u.sigChain() == nil {
   160  		return nil
   161  	}
   162  	return u.sigChain().GetLastLink()
   163  }
   164  
   165  func (u *User) ToUserVersion() keybase1.UserVersion {
   166  	return keybase1.UserVersion{
   167  		Uid:         u.GetUID(),
   168  		EldestSeqno: u.GetCurrentEldestSeqno(),
   169  	}
   170  }
   171  
   172  func (u *User) IsNewerThan(v *User) (bool, error) {
   173  	var idvU, idvV int64
   174  	var err error
   175  	idvU, err = u.GetIDVersion()
   176  	if err != nil {
   177  		return false, err
   178  	}
   179  	idvV, err = v.GetIDVersion()
   180  	if err != nil {
   181  		return false, err
   182  	}
   183  	return ((idvU > idvV && u.GetSigChainLastKnownSeqno() >= v.GetSigChainLastKnownSeqno()) ||
   184  		(idvU >= idvV && u.GetSigChainLastKnownSeqno() > v.GetSigChainLastKnownSeqno())), nil
   185  }
   186  
   187  func (u *User) GetKeyFamily() *KeyFamily {
   188  	return u.keyFamily
   189  }
   190  
   191  func (u *User) GetComputedKeyInfos() *ComputedKeyInfos {
   192  	if u.sigChain() == nil {
   193  		return nil
   194  	}
   195  	return u.sigChain().GetComputedKeyInfos()
   196  }
   197  
   198  func (u *User) GetSigHintsVersion() int {
   199  	if u.sigHints == nil {
   200  		return 0
   201  	}
   202  	return u.sigHints.version
   203  }
   204  
   205  func (u *User) GetComputedKeyFamily() (ret *ComputedKeyFamily) {
   206  	if u.sigChain() != nil && u.keyFamily != nil {
   207  		cki := u.sigChain().GetComputedKeyInfos()
   208  		if cki == nil {
   209  			return nil
   210  		}
   211  		ret = &ComputedKeyFamily{cki: cki, kf: u.keyFamily, Contextified: u.Contextified}
   212  	} else if u.ckfShallowCopy != nil {
   213  		ret = u.ckfShallowCopy
   214  	}
   215  	return ret
   216  }
   217  
   218  // GetActivePGPKeys looks into the user's ComputedKeyFamily and
   219  // returns only the active PGP keys.  If you want only sibkeys, then
   220  // specify sibkey=true.
   221  func (u *User) GetActivePGPKeys(sibkey bool) (ret []*PGPKeyBundle) {
   222  	if ckf := u.GetComputedKeyFamily(); ckf != nil {
   223  		ret = ckf.GetActivePGPKeys(sibkey)
   224  	}
   225  	return
   226  }
   227  
   228  // FilterActivePGPKeys returns the active pgp keys that match
   229  // query.
   230  func (u *User) FilterActivePGPKeys(sibkey bool, query string) []*PGPKeyBundle {
   231  	keys := u.GetActivePGPKeys(sibkey)
   232  	var res []*PGPKeyBundle
   233  	for _, k := range keys {
   234  		if KeyMatchesQuery(k, query, false) {
   235  			res = append(res, k)
   236  		}
   237  	}
   238  	return res
   239  }
   240  
   241  // GetActivePGPFingerprints looks into the user's ComputedKeyFamily and
   242  // returns only the fingerprint of the active PGP keys.
   243  // If you want only sibkeys, then // specify sibkey=true.
   244  func (u *User) GetActivePGPFingerprints(sibkey bool) (ret []PGPFingerprint) {
   245  	for _, pgp := range u.GetActivePGPKeys(sibkey) {
   246  		ret = append(ret, pgp.GetFingerprint())
   247  	}
   248  	return
   249  }
   250  
   251  func (u *User) GetActivePGPKIDs(sibkey bool) (ret []keybase1.KID) {
   252  	for _, pgp := range u.GetActivePGPKeys(sibkey) {
   253  		ret = append(ret, pgp.GetKID())
   254  	}
   255  	return
   256  }
   257  
   258  func (u *User) GetDeviceSibkey() (GenericKey, error) {
   259  	did := u.G().Env.GetDeviceIDForUsername(u.GetNormalizedName())
   260  	if did.IsNil() {
   261  		return nil, NotProvisionedError{}
   262  	}
   263  	ckf := u.GetComputedKeyFamily()
   264  	if ckf == nil {
   265  		return nil, KeyFamilyError{"no key family available"}
   266  	}
   267  	return ckf.GetSibkeyForDevice(did)
   268  }
   269  
   270  func (u *User) GetDeviceSubkey() (subkey GenericKey, err error) {
   271  	ckf := u.GetComputedKeyFamily()
   272  	if ckf == nil {
   273  		err = KeyFamilyError{"no key family available"}
   274  		return
   275  	}
   276  	did := u.G().Env.GetDeviceIDForUsername(u.GetNormalizedName())
   277  	if did.IsNil() {
   278  		err = NotProvisionedError{}
   279  		return
   280  	}
   281  	return ckf.GetEncryptionSubkeyForDevice(did)
   282  }
   283  
   284  func (u *User) HasEncryptionSubkey() bool {
   285  	if ckf := u.GetComputedKeyFamily(); ckf != nil {
   286  		return ckf.HasActiveEncryptionSubkey()
   287  	}
   288  	return false
   289  }
   290  
   291  func (u *User) CheckBasicsFreshness(server int64) (current bool, reason string, err error) {
   292  	var stored int64
   293  	if stored, err = u.GetIDVersion(); err != nil {
   294  		return false, "", err
   295  	}
   296  	if stored >= server {
   297  		u.G().Log.Debug("| Local basics version is up-to-date @ version %d", stored)
   298  		return true, "", nil
   299  	}
   300  	u.G().Log.Debug("| Local basics version is out-of-date: %d < %d", stored, server)
   301  	return false, fmt.Sprintf("idv %v < %v", stored, server), nil
   302  }
   303  
   304  func (u *User) StoreSigChain(m MetaContext) error {
   305  	var err error
   306  	if u.sigChain() != nil {
   307  		err = u.sigChain().Store(m)
   308  	}
   309  	return err
   310  }
   311  
   312  func (u *User) LoadSigChains(m MetaContext, f *MerkleUserLeaf, self bool, stubMode StubMode) (err error) {
   313  	defer TimeLog(fmt.Sprintf("LoadSigChains: %s", u.name), u.G().Clock().Now(), u.G().Log.Debug)
   314  
   315  	loader := SigChainLoader{
   316  		user:             u,
   317  		self:             self,
   318  		leaf:             f,
   319  		chainType:        PublicChain,
   320  		preload:          u.sigChain(),
   321  		stubMode:         stubMode,
   322  		MetaContextified: NewMetaContextified(m),
   323  	}
   324  
   325  	u.sigChainMem, err = loader.Load()
   326  
   327  	// Eventually load the others, but for now, this one is good enough
   328  	return err
   329  }
   330  
   331  func (u *User) Store(m MetaContext) error {
   332  
   333  	m.Debug("+ Store user %s", u.name)
   334  
   335  	// These might be dirty, in which case we can write it back
   336  	// to local storage. Note, this can be dirty even if the user is clean.
   337  	if err := u.sigHints.Store(m); err != nil {
   338  		return err
   339  	}
   340  
   341  	if !u.dirty {
   342  		m.Debug("- Store for %s skipped; user wasn't dirty", u.name)
   343  		return nil
   344  	}
   345  
   346  	if err := u.StoreSigChain(m); err != nil {
   347  		return err
   348  	}
   349  
   350  	if err := u.StoreTopLevel(m); err != nil {
   351  		return err
   352  	}
   353  
   354  	u.dirty = false
   355  	m.Debug("- Store user %s -> OK", u.name)
   356  
   357  	return nil
   358  }
   359  
   360  func (u *User) StoreTopLevel(m MetaContext) error {
   361  
   362  	jw := jsonw.NewDictionary()
   363  	err := jw.SetKey("id", UIDWrapper(u.id))
   364  	if err != nil {
   365  		return err
   366  	}
   367  	err = jw.SetKey("basics", u.basics)
   368  	if err != nil {
   369  		return err
   370  	}
   371  	err = jw.SetKey("public_keys", u.publicKeys)
   372  	if err != nil {
   373  		return err
   374  	}
   375  	err = jw.SetKey("pictures", u.pictures)
   376  	if err != nil {
   377  		return err
   378  	}
   379  
   380  	err = u.G().LocalDb.Put(
   381  		DbKeyUID(DBUser, u.id),
   382  		[]DbKey{{Typ: DBLookupUsername, Key: u.name}},
   383  		jw,
   384  	)
   385  	if err != nil {
   386  		m.Debug("StoreTopLevel -> %s", ErrToOk(err))
   387  	}
   388  	return err
   389  }
   390  
   391  func (u *User) SyncedSecretKey(m MetaContext) (ret *SKB, err error) {
   392  	if lctx := m.LoginContext(); lctx != nil {
   393  		return u.getSyncedSecretKeyLogin(m, lctx)
   394  	}
   395  	return u.GetSyncedSecretKey(m)
   396  }
   397  
   398  func (u *User) getSyncedSecretKeyLogin(m MetaContext, lctx LoginContext) (ret *SKB, err error) {
   399  	defer m.Trace("User#getSyncedSecretKeyLogin", &err)()
   400  
   401  	if err = lctx.RunSecretSyncer(m, u.id); err != nil {
   402  		return
   403  	}
   404  	ckf := u.GetComputedKeyFamily()
   405  	if ckf == nil {
   406  		m.Debug("| short-circuit; no Computed key family")
   407  		return
   408  	}
   409  
   410  	ret, err = lctx.SecretSyncer().FindActiveKey(ckf)
   411  	return
   412  }
   413  
   414  func (u *User) SyncedSecretKeyWithSka(m MetaContext, ska SecretKeyArg) (ret *SKB, err error) {
   415  	keys, err := u.GetSyncedSecretKeys(m)
   416  	if err != nil {
   417  		return nil, err
   418  	}
   419  
   420  	var errors []error
   421  	for _, key := range keys {
   422  		pub, err := key.GetPubKey()
   423  		if err != nil {
   424  			errors = append(errors, err)
   425  			continue
   426  		}
   427  		if KeyMatchesQuery(pub, ska.KeyQuery, ska.ExactMatch) {
   428  			return key, nil
   429  		}
   430  	}
   431  
   432  	if len(errors) > 0 {
   433  		// No matching key found and we hit errors.
   434  		return nil, CombineErrors(errors...)
   435  	}
   436  
   437  	return nil, NoSecretKeyError{}
   438  }
   439  
   440  func (u *User) GetSyncedSecretKey(m MetaContext) (ret *SKB, err error) {
   441  	defer m.Trace("User#GetSyncedSecretKey", &err)()
   442  	skbs, err := u.GetSyncedSecretKeys(m)
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  	if len(skbs) == 0 {
   447  		return nil, nil
   448  	}
   449  	m.Debug("NOTE: using GetSyncedSecretKey, returning first secret key from randomly ordered map")
   450  	return skbs[0], nil
   451  }
   452  
   453  func (u *User) GetSyncedSecretKeys(m MetaContext) (ret []*SKB, err error) {
   454  	defer m.Trace("User#GetSyncedSecretKeys", &err)()
   455  
   456  	if err = u.SyncSecrets(m); err != nil {
   457  		return
   458  	}
   459  
   460  	ckf := u.GetComputedKeyFamily()
   461  	if ckf == nil {
   462  		m.Debug("| short-circuit; no Computed key family")
   463  		return
   464  	}
   465  
   466  	syncer, err := m.SyncSecrets()
   467  	if err != nil {
   468  		return nil, err
   469  	}
   470  
   471  	ret, err = syncer.FindActiveKeys(ckf)
   472  	return ret, err
   473  }
   474  
   475  // AllSyncedSecretKeys returns all the PGP key blocks that were
   476  // synced to API server.  LoginContext can be nil if this isn't
   477  // used while logging in, signing up.
   478  func (u *User) AllSyncedSecretKeys(m MetaContext) (keys []*SKB, err error) {
   479  	defer m.Trace("User#AllSyncedSecretKeys", &err)()
   480  	m.Dump()
   481  
   482  	ss, err := m.SyncSecretsForUID(u.GetUID())
   483  	if err != nil {
   484  		return nil, err
   485  	}
   486  
   487  	ckf := u.GetComputedKeyFamily()
   488  	if ckf == nil {
   489  		m.Debug("| short-circuit; no Computed key family")
   490  		return nil, nil
   491  	}
   492  
   493  	keys = ss.AllActiveKeys(ckf)
   494  	return keys, nil
   495  }
   496  
   497  func (u *User) SyncSecrets(m MetaContext) error {
   498  	_, err := m.SyncSecretsForUID(u.GetUID())
   499  	return err
   500  }
   501  
   502  // May return an empty KID
   503  func (u *User) GetEldestKID() (ret keybase1.KID) {
   504  	return u.leaf.eldest
   505  }
   506  
   507  func (u *User) GetPublicChainTail() *MerkleTriple {
   508  	if u.sigChainMem == nil {
   509  		return nil
   510  	}
   511  	return u.sigChain().GetCurrentTailTriple()
   512  }
   513  
   514  func (u *User) IDTable() *IdentityTable {
   515  	return u.idTable
   516  }
   517  
   518  // Return the active stellar public address for a user.
   519  // Returns nil if there is none or it has not been loaded.
   520  func (u *User) StellarAccountID() *stellar1.AccountID {
   521  	if u.idTable == nil {
   522  		return nil
   523  	}
   524  	return u.idTable.StellarAccountID()
   525  }
   526  
   527  func (u *User) sigChain() *SigChain {
   528  	return u.sigChainMem
   529  }
   530  
   531  func (u *User) MakeIDTable(m MetaContext) error {
   532  	kid := u.GetEldestKID()
   533  	if kid.IsNil() {
   534  		return NoKeyError{"Expected a key but didn't find one"}
   535  	}
   536  	idt, err := NewIdentityTable(m, kid, u.sigChain(), u.sigHints)
   537  	if err != nil {
   538  		return err
   539  	}
   540  	u.idTable = idt
   541  	return nil
   542  }
   543  
   544  // GetHighLinkSeqnos gets the list of all high links in the user's sigchain ascending.
   545  func (u *User) GetHighLinkSeqnos(mctx MetaContext) (res []keybase1.Seqno, err error) {
   546  	sigChain := u.sigChain()
   547  	if sigChain == nil {
   548  		return nil, fmt.Errorf("no user sigchain")
   549  	}
   550  	for _, c := range sigChain.chainLinks {
   551  		high, err := c.IsHighUserLink(mctx, u.GetUID())
   552  		if err != nil {
   553  			return nil, fmt.Errorf("error determining link %v", c.GetSeqno())
   554  		}
   555  		if high {
   556  			res = append(res, c.GetSeqno())
   557  		}
   558  	}
   559  	return res, nil
   560  }
   561  
   562  func (u *User) VerifySelfSig() error {
   563  
   564  	u.G().Log.Debug("+ VerifySelfSig for user %s", u.name)
   565  
   566  	if u.IDTable().VerifySelfSig(u.GetNormalizedName(), u.id) {
   567  		u.G().Log.Debug("- VerifySelfSig via SigChain")
   568  		return nil
   569  	}
   570  
   571  	if u.VerifySelfSigByKey() {
   572  		u.G().Log.Debug("- VerifySelfSig via Key")
   573  		return nil
   574  	}
   575  
   576  	u.G().Log.Debug("- VerifySelfSig failed")
   577  	return fmt.Errorf("Failed to find a self-signature for %s", u.name)
   578  }
   579  
   580  func (u *User) VerifySelfSigByKey() (ret bool) {
   581  	name := u.GetName()
   582  	if ckf := u.GetComputedKeyFamily(); ckf != nil {
   583  		ret = ckf.FindKeybaseName(name)
   584  	}
   585  	return
   586  }
   587  
   588  func (u *User) HasActiveKey() (ret bool) {
   589  	u.G().Log.Debug("+ HasActiveKey")
   590  	defer func() {
   591  		u.G().Log.Debug("- HasActiveKey -> %v", ret)
   592  	}()
   593  	if u.GetEldestKID().IsNil() {
   594  		u.G().Log.Debug("| no eldest KID; must have reset or be new")
   595  		ret = false
   596  		return
   597  	}
   598  	if ckf := u.GetComputedKeyFamily(); ckf != nil {
   599  		u.G().Log.Debug("| Checking user's ComputedKeyFamily")
   600  		ret = ckf.HasActiveKey()
   601  		return
   602  	}
   603  
   604  	if u.sigChain() == nil {
   605  		u.G().Log.Debug("User HasActiveKey: sig chain is nil")
   606  	} else if u.sigChain().GetComputedKeyInfos() == nil {
   607  		u.G().Log.Debug("User HasActiveKey: comp key infos is nil")
   608  	}
   609  	if u.keyFamily == nil {
   610  		u.G().Log.Debug("User HasActiveKey: keyFamily is nil")
   611  	}
   612  
   613  	return false
   614  }
   615  
   616  func (u *User) Equal(other *User) bool {
   617  	return u.id == other.id
   618  }
   619  
   620  func (u *User) TmpTrackChainLinkFor(m MetaContext, username string, uid keybase1.UID) (tcl *TrackChainLink, err error) {
   621  	return TmpTrackChainLinkFor(m, u.id, uid)
   622  }
   623  
   624  func TmpTrackChainLinkFor(m MetaContext, me keybase1.UID, them keybase1.UID) (tcl *TrackChainLink, err error) {
   625  	m.Debug("+ TmpTrackChainLinkFor for %s", them)
   626  	tcl, err = LocalTmpTrackChainLinkFor(m, me, them)
   627  	m.Debug("- TmpTrackChainLinkFor for %s -> %v, %v", them, (tcl != nil), err)
   628  	return tcl, err
   629  }
   630  
   631  func (u *User) TrackChainLinkFor(m MetaContext, username NormalizedUsername, uid keybase1.UID) (*TrackChainLink, error) {
   632  	u.G().Log.Debug("+ TrackChainLinkFor for %s", uid)
   633  	defer u.G().Log.Debug("- TrackChainLinkFor for %s", uid)
   634  	remote, e1 := u.remoteTrackChainLinkFor(username, uid)
   635  	return TrackChainLinkFor(m, u.id, uid, remote, e1)
   636  }
   637  
   638  func TrackChainLinkFor(m MetaContext, me keybase1.UID, them keybase1.UID, remote *TrackChainLink, remoteErr error) (*TrackChainLink, error) {
   639  
   640  	local, e2 := LocalTrackChainLinkFor(m, me, them)
   641  
   642  	m.Debug("| Load remote -> %v", (remote != nil))
   643  	m.Debug("| Load local -> %v", (local != nil))
   644  
   645  	if remoteErr != nil && e2 != nil {
   646  		return nil, remoteErr
   647  	}
   648  
   649  	if local == nil && remote == nil {
   650  		return nil, nil
   651  	}
   652  
   653  	if local == nil && remote != nil {
   654  		return remote, nil
   655  	}
   656  
   657  	if remote == nil && local != nil {
   658  		m.Debug("local expire %v: %s", local.tmpExpireTime.IsZero(), local.tmpExpireTime)
   659  		return local, nil
   660  	}
   661  
   662  	if remote.GetCTime().After(local.GetCTime()) {
   663  		m.Debug("| Returning newer remote")
   664  		return remote, nil
   665  	}
   666  
   667  	return local, nil
   668  }
   669  
   670  func (u *User) remoteTrackChainLinkFor(username NormalizedUsername, uid keybase1.UID) (*TrackChainLink, error) {
   671  	if u.IDTable() == nil {
   672  		return nil, nil
   673  	}
   674  
   675  	return u.IDTable().TrackChainLinkFor(username, uid)
   676  }
   677  
   678  // BaseProofSet creates a basic proof set for a user with their
   679  // keybase and uid proofs and any pgp fingerprint proofs.
   680  func (u *User) BaseProofSet() *ProofSet {
   681  	proofs := []Proof{
   682  		{Key: "keybase", Value: u.name},
   683  		{Key: "uid", Value: u.id.String()},
   684  	}
   685  	for _, fp := range u.GetActivePGPFingerprints(true) {
   686  		proofs = append(proofs, Proof{Key: PGPAssertionKey, Value: fp.String()})
   687  	}
   688  
   689  	return NewProofSet(proofs)
   690  }
   691  
   692  // localDelegateKey takes the given GenericKey and provisions it locally so that
   693  // we can use the key without needing a refresh from the server.  The eventual
   694  // refresh we do get from the server will clobber our work here.
   695  func (u *User) localDelegateKey(key GenericKey, sigID keybase1.SigID, kid keybase1.KID, isSibkey bool, isEldest bool, merkleHashMeta keybase1.HashMeta, firstAppearedUnverified keybase1.Seqno) (err error) {
   696  	if err = u.keyFamily.LocalDelegate(key); err != nil {
   697  		return
   698  	}
   699  	if u.sigChain() == nil {
   700  		err = NoSigChainError{}
   701  		return
   702  	}
   703  	err = u.sigChain().LocalDelegate(u.keyFamily, key, sigID, kid, isSibkey, merkleHashMeta, firstAppearedUnverified)
   704  	if isEldest {
   705  		eldestKID := key.GetKID()
   706  		u.leaf.eldest = eldestKID
   707  	}
   708  	return
   709  }
   710  
   711  func (u *User) localDelegatePerUserKey(perUserKey keybase1.PerUserKey) error {
   712  
   713  	// Don't update the u.keyFamily. It doesn't manage per-user-keys.
   714  
   715  	// Update sigchain which will update ckf/cki
   716  	err := u.sigChain().LocalDelegatePerUserKey(perUserKey)
   717  	if err != nil {
   718  		return err
   719  	}
   720  
   721  	u.G().Log.Debug("User LocalDelegatePerUserKey gen:%v seqno:%v sig:%v enc:%v",
   722  		perUserKey.Gen, perUserKey.Seqno, perUserKey.SigKID.String(), perUserKey.EncKID.String())
   723  	return nil
   724  }
   725  
   726  // SigChainBump is called during a multikey post to update the correct seqno, hash, and
   727  // high skip. When a delegator posts a high link, they specify isHighDelegator=true
   728  // in order to set the new high skip pointer to the delegator's link, so subsequent
   729  // keys in the multikey will supply the correct high skip.
   730  func (u *User) SigChainBump(linkID LinkID, sigID keybase1.SigID, isHighDelegator bool) {
   731  	u.SigChainBumpMT(MerkleTriple{LinkID: linkID, SigID: sigID.StripSuffix()}, isHighDelegator)
   732  }
   733  
   734  func (u *User) SigChainBumpMT(mt MerkleTriple, isHighDelegator bool) {
   735  	u.sigChain().Bump(mt, isHighDelegator)
   736  }
   737  
   738  func (u *User) GetDevice(id keybase1.DeviceID) (*Device, error) {
   739  	if u.GetComputedKeyFamily() == nil {
   740  		return nil, fmt.Errorf("no computed key family")
   741  	}
   742  	device, exists := u.GetComputedKeyFamily().cki.Devices[id]
   743  	if !exists {
   744  		return nil, fmt.Errorf("device %s doesn't exist", id)
   745  	}
   746  	return device, nil
   747  }
   748  
   749  func (u *User) DeviceNames() ([]string, error) {
   750  	ckf := u.GetComputedKeyFamily()
   751  	if ckf == nil {
   752  		return nil, fmt.Errorf("no computed key family")
   753  	}
   754  	if ckf.cki == nil {
   755  		return nil, fmt.Errorf("no computed key infos")
   756  	}
   757  
   758  	var names []string
   759  	for _, device := range ckf.cki.Devices {
   760  		if device.Description == nil {
   761  			continue
   762  		}
   763  		names = append(names, *device.Description)
   764  	}
   765  	return names, nil
   766  }
   767  
   768  // Returns whether or not the current install has an active device
   769  // sibkey.
   770  func (u *User) HasDeviceInCurrentInstall(did keybase1.DeviceID) bool {
   771  	ckf := u.GetComputedKeyFamily()
   772  	if ckf == nil {
   773  		return false
   774  	}
   775  
   776  	_, err := ckf.GetSibkeyForDevice(did)
   777  	return err == nil
   778  }
   779  
   780  func (u *User) HasCurrentDeviceInCurrentInstall() bool {
   781  	did := u.G().Env.GetDeviceIDForUsername(u.GetNormalizedName())
   782  	if did.IsNil() {
   783  		return false
   784  	}
   785  	return u.HasDeviceInCurrentInstall(did)
   786  }
   787  
   788  func (u *User) SigningKeyPub() (GenericKey, error) {
   789  	// Get our key that we're going to sign with.
   790  	arg := SecretKeyArg{
   791  		Me:      u,
   792  		KeyType: DeviceSigningKeyType,
   793  	}
   794  	key := u.G().ActiveDevice.SigningKeyForUID(u.GetUID())
   795  	if key != nil {
   796  		return key, nil
   797  	}
   798  
   799  	lockedKey, err := u.G().Keyrings.GetSecretKeyLocked(NewMetaContextTODO(u.G()), arg)
   800  	if err != nil {
   801  		return nil, err
   802  	}
   803  	pubKey, err := lockedKey.GetPubKey()
   804  	if err != nil {
   805  		return nil, err
   806  	}
   807  	return pubKey, nil
   808  }
   809  
   810  func (u *User) GetSigIDFromSeqno(seqno keybase1.Seqno) keybase1.SigID {
   811  	if u.sigChain() == nil {
   812  		return ""
   813  	}
   814  	link := u.sigChain().GetLinkFromSeqno(seqno)
   815  	if link == nil {
   816  		return ""
   817  	}
   818  	return link.GetSigID()
   819  }
   820  
   821  func (u *User) IsSigIDActive(sigID keybase1.SigID) (bool, error) {
   822  	if u.sigChain() == nil {
   823  		return false, fmt.Errorf("User's sig chain is nil.")
   824  	}
   825  
   826  	link := u.sigChain().GetLinkFromSigID(sigID)
   827  	if link == nil {
   828  		return false, fmt.Errorf("Signature with ID '%s' does not exist.", sigID)
   829  	}
   830  	if link.revoked {
   831  		return false, fmt.Errorf("Signature ID '%s' is already revoked.", sigID)
   832  	}
   833  	return true, nil
   834  }
   835  
   836  func (u *User) SigIDSearch(query string) (keybase1.SigID, error) {
   837  	if u.sigChain() == nil {
   838  		return "", fmt.Errorf("User's sig chain is nil.")
   839  	}
   840  
   841  	link := u.sigChain().GetLinkFromSigIDQuery(query)
   842  	if link == nil {
   843  		return "", fmt.Errorf("Signature matching query %q does not exist.", query)
   844  	}
   845  	if link.revoked {
   846  		return "", fmt.Errorf("Signature ID '%s' is already revoked.", link.GetSigID())
   847  	}
   848  	return link.GetSigID(), nil
   849  }
   850  
   851  func (u *User) LinkFromSigID(sigID keybase1.SigID) *ChainLink {
   852  	return u.sigChain().GetLinkFromSigID(sigID)
   853  }
   854  
   855  func (u *User) SigChainDump(w io.Writer) {
   856  	u.sigChain().Dump(w)
   857  }
   858  
   859  func (u *User) IsCachedIdentifyFresh(upk *keybase1.UserPlusKeysV2AllIncarnations) bool {
   860  	idv, _ := u.GetIDVersion()
   861  	if upk.Uvv.Id == 0 || idv != upk.Uvv.Id {
   862  		return false
   863  	}
   864  	shv := u.GetSigHintsVersion()
   865  	if upk.Uvv.SigHints == 0 || shv != upk.Uvv.SigHints {
   866  		return false
   867  	}
   868  	scv := u.GetSigChainLastKnownSeqno()
   869  	if upk.Uvv.SigChain == 0 || int64(scv) != upk.Uvv.SigChain {
   870  		return false
   871  	}
   872  	return true
   873  }
   874  
   875  // PartialCopy copies some fields of the User object, but not all.
   876  // For instance, it doesn't copy the SigChain or IDTable, and it only
   877  // makes a shallow copy of the ComputedKeyFamily.
   878  func (u User) PartialCopy() *User {
   879  	ret := &User{
   880  		Contextified: NewContextified(u.G()),
   881  		id:           u.id,
   882  		name:         u.name,
   883  		leaf:         u.leaf,
   884  		dirty:        false,
   885  	}
   886  	if ckf := u.GetComputedKeyFamily(); ckf != nil {
   887  		ret.ckfShallowCopy = ckf.ShallowCopy()
   888  		ret.keyFamily = ckf.kf
   889  	} else if u.keyFamily != nil {
   890  		ret.keyFamily = u.keyFamily.ShallowCopy()
   891  	}
   892  	return ret
   893  }
   894  
   895  func ValidateNormalizedUsername(username string) (NormalizedUsername, error) {
   896  	res := NormalizedUsername(username)
   897  	if len(username) < 2 {
   898  		return res, errors.New("username too short")
   899  	}
   900  	if len(username) > 16 {
   901  		return res, errors.New("username too long")
   902  	}
   903  	// underscores allowed, just not first or doubled
   904  	re := regexp.MustCompile(`^([a-z0-9][a-z0-9_]?)+$`)
   905  	if !re.MatchString(username) {
   906  		return res, errors.New("invalid username")
   907  	}
   908  	return res, nil
   909  }
   910  
   911  type UserForSignatures struct {
   912  	uid         keybase1.UID
   913  	name        NormalizedUsername
   914  	eldestKID   keybase1.KID
   915  	eldestSeqno keybase1.Seqno
   916  	latestPUK   *keybase1.PerUserKey
   917  }
   918  
   919  func (u UserForSignatures) GetUID() keybase1.UID                  { return u.uid }
   920  func (u UserForSignatures) GetName() string                       { return u.name.String() }
   921  func (u UserForSignatures) GetEldestKID() keybase1.KID            { return u.eldestKID }
   922  func (u UserForSignatures) GetEldestSeqno() keybase1.Seqno        { return u.eldestSeqno }
   923  func (u UserForSignatures) GetNormalizedName() NormalizedUsername { return u.name }
   924  func (u UserForSignatures) ToUserVersion() keybase1.UserVersion {
   925  	return keybase1.UserVersion{Uid: u.uid, EldestSeqno: u.eldestSeqno}
   926  }
   927  func (u UserForSignatures) GetLatestPerUserKey() *keybase1.PerUserKey { return u.latestPUK }
   928  
   929  func (u *User) ToUserForSignatures() (ret UserForSignatures, err error) {
   930  	if u == nil {
   931  		return ret, fmt.Errorf("ToUserForSignatures missing user object")
   932  	}
   933  	ckf := u.GetComputedKeyFamily()
   934  	if ckf == nil {
   935  		return ret, fmt.Errorf("ToUserForSignatures missing ckf")
   936  	}
   937  	if ckf.cki == nil {
   938  		return ret, fmt.Errorf("ToUserForSignatures missing cki")
   939  	}
   940  	ret.uid = u.GetUID()
   941  	ret.name = u.GetNormalizedName()
   942  	ret.eldestKID = u.GetEldestKID()
   943  	ret.eldestSeqno = u.GetCurrentEldestSeqno()
   944  	ret.latestPUK = u.GetComputedKeyFamily().GetLatestPerUserKey()
   945  	return ret, nil
   946  }
   947  
   948  var _ UserBasic = UserForSignatures{}
   949  
   950  // VID gets the VID that corresponds to the given UID. A VID is a pseudonymous UID.
   951  // Should never error.
   952  func VID(mctx MetaContext, uid keybase1.UID) (ret keybase1.VID) {
   953  	mctx.G().vidMu.Lock()
   954  	defer mctx.G().vidMu.Unlock()
   955  
   956  	// Construct the key from the given uid passed in.
   957  	strKey := "vid" + ":" + string(uid)
   958  
   959  	key := DbKey{DBMisc, strKey}
   960  	found, err := mctx.G().LocalDb.GetInto(&ret, key)
   961  	if found {
   962  		return ret
   963  	}
   964  	if err != nil {
   965  		// It's ok, we will just rerandomize in this case.
   966  		mctx.Debug("VID: failure to get: %s", err.Error())
   967  	}
   968  	b, err := RandBytesWithSuffix(16, keybase1.UID_SUFFIX_2)
   969  	if err != nil {
   970  		// This should never happen.
   971  		mctx.Debug("VID: random bytes failed: %s", err.Error())
   972  	}
   973  	ret = keybase1.VID(hex.EncodeToString(b))
   974  	err = mctx.G().LocalDb.PutObj(key, nil, ret)
   975  	if err != nil {
   976  		// It's ok, we will just rerandomize in this case.
   977  		mctx.Debug("VID: store failed: %s", err.Error())
   978  	}
   979  	return ret
   980  }