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