1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
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
18type UserBasic interface {
19	GetUID() keybase1.UID
20	GetName() string
21}
22
23var _ UserBasic = keybase1.UserPlusKeys{}
24
25type 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
51func NewUserThin(name string, uid keybase1.UID) *User {
52	return &User{name: name, id: uid}
53}
54
55func 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
95func 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
103func NewUserFromLocalStorage(g *GlobalContext, o *jsonw.Wrapper) (*User, error) {
104	u, err := newUser(g, o, true)
105	return u, err
106}
107
108func (u *User) GetNormalizedName() NormalizedUsername { return NewNormalizedUsername(u.name) }
109func (u *User) GetName() string                       { return u.name }
110func (u *User) GetUID() keybase1.UID                  { return u.id }
111func (u *User) GetStatus() keybase1.StatusCode        { return u.status }
112
113func (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
125func (u *User) GetIDVersion() (int64, error) {
126	return u.basics.AtKey("id_version").GetInt64()
127}
128
129func (u *User) GetSigChainLastKnownSeqno() keybase1.Seqno {
130	if u.sigChain() == nil {
131		return 0
132	}
133	return u.sigChain().GetLastKnownSeqno()
134}
135
136func (u *User) GetSigChainLastKnownID() LinkID {
137	if u.sigChain() == nil {
138		return nil
139	}
140	return u.sigChain().GetLastKnownID()
141}
142
143func (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
151func (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
158func (u *User) GetLastLink() *ChainLink {
159	if u.sigChain() == nil {
160		return nil
161	}
162	return u.sigChain().GetLastLink()
163}
164
165func (u *User) ToUserVersion() keybase1.UserVersion {
166	return keybase1.UserVersion{
167		Uid:         u.GetUID(),
168		EldestSeqno: u.GetCurrentEldestSeqno(),
169	}
170}
171
172func (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
187func (u *User) GetKeyFamily() *KeyFamily {
188	return u.keyFamily
189}
190
191func (u *User) GetComputedKeyInfos() *ComputedKeyInfos {
192	if u.sigChain() == nil {
193		return nil
194	}
195	return u.sigChain().GetComputedKeyInfos()
196}
197
198func (u *User) GetSigHintsVersion() int {
199	if u.sigHints == nil {
200		return 0
201	}
202	return u.sigHints.version
203}
204
205func (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.
221func (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.
230func (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.
244func (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
251func (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
258func (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
270func (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
284func (u *User) HasEncryptionSubkey() bool {
285	if ckf := u.GetComputedKeyFamily(); ckf != nil {
286		return ckf.HasActiveEncryptionSubkey()
287	}
288	return false
289}
290
291func (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
304func (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
312func (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
331func (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
360func (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
391func (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
398func (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
414func (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
440func (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
453func (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.
478func (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
497func (u *User) SyncSecrets(m MetaContext) error {
498	_, err := m.SyncSecretsForUID(u.GetUID())
499	return err
500}
501
502// May return an empty KID
503func (u *User) GetEldestKID() (ret keybase1.KID) {
504	return u.leaf.eldest
505}
506
507func (u *User) GetPublicChainTail() *MerkleTriple {
508	if u.sigChainMem == nil {
509		return nil
510	}
511	return u.sigChain().GetCurrentTailTriple()
512}
513
514func (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.
520func (u *User) StellarAccountID() *stellar1.AccountID {
521	if u.idTable == nil {
522		return nil
523	}
524	return u.idTable.StellarAccountID()
525}
526
527func (u *User) sigChain() *SigChain {
528	return u.sigChainMem
529}
530
531func (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.
545func (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
562func (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
580func (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
588func (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
616func (u *User) Equal(other *User) bool {
617	return u.id == other.id
618}
619
620func (u *User) TmpTrackChainLinkFor(m MetaContext, username string, uid keybase1.UID) (tcl *TrackChainLink, err error) {
621	return TmpTrackChainLinkFor(m, u.id, uid)
622}
623
624func 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
631func (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
638func 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
670func (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.
680func (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.
695func (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
711func (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.
730func (u *User) SigChainBump(linkID LinkID, sigID keybase1.SigID, isHighDelegator bool) {
731	u.SigChainBumpMT(MerkleTriple{LinkID: linkID, SigID: sigID.StripSuffix()}, isHighDelegator)
732}
733
734func (u *User) SigChainBumpMT(mt MerkleTriple, isHighDelegator bool) {
735	u.sigChain().Bump(mt, isHighDelegator)
736}
737
738func (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
749func (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.
770func (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
780func (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
788func (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
810func (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
821func (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
836func (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
851func (u *User) LinkFromSigID(sigID keybase1.SigID) *ChainLink {
852	return u.sigChain().GetLinkFromSigID(sigID)
853}
854
855func (u *User) SigChainDump(w io.Writer) {
856	u.sigChain().Dump(w)
857}
858
859func (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.
878func (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
895func 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
911type UserForSignatures struct {
912	uid         keybase1.UID
913	name        NormalizedUsername
914	eldestKID   keybase1.KID
915	eldestSeqno keybase1.Seqno
916	latestPUK   *keybase1.PerUserKey
917}
918
919func (u UserForSignatures) GetUID() keybase1.UID                  { return u.uid }
920func (u UserForSignatures) GetName() string                       { return u.name.String() }
921func (u UserForSignatures) GetEldestKID() keybase1.KID            { return u.eldestKID }
922func (u UserForSignatures) GetEldestSeqno() keybase1.Seqno        { return u.eldestSeqno }
923func (u UserForSignatures) GetNormalizedName() NormalizedUsername { return u.name }
924func (u UserForSignatures) ToUserVersion() keybase1.UserVersion {
925	return keybase1.UserVersion{Uid: u.uid, EldestSeqno: u.eldestSeqno}
926}
927func (u UserForSignatures) GetLatestPerUserKey() *keybase1.PerUserKey { return u.latestPUK }
928
929func (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
948var _ UserBasic = UserForSignatures{}
949
950// VID gets the VID that corresponds to the given UID. A VID is a pseudonymous UID.
951// Should never error.
952func 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}
981