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 }