github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/merkle_client.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 "crypto/sha256" 8 "crypto/sha512" 9 "crypto/subtle" 10 "encoding/hex" 11 "encoding/json" 12 "errors" 13 "fmt" 14 "math" 15 "strings" 16 "sync" 17 "time" 18 19 chat1 "github.com/keybase/client/go/protocol/chat1" 20 keybase1 "github.com/keybase/client/go/protocol/keybase1" 21 "github.com/keybase/client/go/sig3" 22 jsonw "github.com/keybase/go-jsonw" 23 ) 24 25 const ( 26 NodeHashLenLong = sha512.Size // = 64 27 NodeHashLenShort = sha256.Size // = 32 28 ) 29 30 type NodeHash interface { 31 Check(s string) bool // Check if the node hashes to this string 32 String() string 33 bytes() []byte 34 IsNil() bool 35 Eq(h NodeHash) bool 36 } 37 38 type NodeHashShort [NodeHashLenShort]byte 39 type NodeHashLong [NodeHashLenLong]byte 40 41 // NodeHashAny incorporates either a short (256-bit) or a long (512-bit) hash. 42 // It's unfortunate we need it, but I didn't see any other way to use the 43 // Go json marshal/unmarshal system where the hashes might be either short 44 // or long. Our hacky solution is to have a union-type struct that supports 45 // both, and just to unmarshal into the relevant field. Note this 46 // type also fits ths NodeHash interface. 47 type NodeHashAny struct { 48 s *NodeHashShort 49 l *NodeHashLong 50 } 51 52 var _ NodeHash = NodeHashShort{} 53 var _ NodeHash = NodeHashLong{} 54 var _ NodeHash = NodeHashAny{} 55 56 func (h1 NodeHashShort) Check(s string) bool { 57 h2 := sha256.Sum256([]byte(s)) 58 return subtle.ConstantTimeCompare(h1[:], h2[:]) == 1 59 } 60 61 func (h1 NodeHashShort) String() string { 62 return hex.EncodeToString(h1[:]) 63 } 64 65 func (h1 NodeHashShort) bytes() []byte { 66 return h1[:] 67 } 68 69 func (h1 NodeHashShort) IsNil() bool { 70 return false 71 } 72 73 func (h1 NodeHashShort) Eq(h2 NodeHash) bool { 74 return subtle.ConstantTimeCompare(h1.bytes(), h2.bytes()) == 1 75 } 76 77 func (h1 NodeHashShort) ExportToHashMeta() keybase1.HashMeta { 78 return keybase1.HashMeta(h1.bytes()) 79 } 80 81 func (h1 NodeHashLong) Check(s string) bool { 82 h2 := sha512.Sum512([]byte(s)) 83 return subtle.ConstantTimeCompare(h1[:], h2[:]) == 1 84 } 85 86 func (h1 NodeHashLong) String() string { 87 return hex.EncodeToString(h1[:]) 88 } 89 90 func (h1 NodeHashLong) bytes() []byte { 91 return h1[:] 92 } 93 94 func (h1 NodeHashLong) IsNil() bool { 95 return false 96 } 97 98 func (h1 NodeHashLong) Eq(h2 NodeHash) bool { 99 return subtle.ConstantTimeCompare(h1.bytes(), h2.bytes()) == 1 100 } 101 102 func hashEq(h1 NodeHash, h2 NodeHash) bool { 103 b1 := h1.bytes() 104 b2 := h2.bytes() 105 return subtle.ConstantTimeCompare(b1, b2) == 1 106 } 107 108 func (h NodeHashAny) Check(s string) bool { 109 switch { 110 case h.s != nil: 111 return h.s.Check(s) 112 case h.l != nil: 113 return h.l.Check(s) 114 default: 115 return false 116 } 117 } 118 119 func (h NodeHashAny) String() string { 120 switch { 121 case h.s != nil: 122 return h.s.String() 123 case h.l != nil: 124 return h.l.String() 125 default: 126 return "" 127 } 128 } 129 130 func (h NodeHashAny) bytes() []byte { 131 switch { 132 case h.s != nil: 133 return h.s.bytes() 134 case h.l != nil: 135 return h.l.bytes() 136 default: 137 return nil 138 } 139 } 140 141 func (h NodeHashAny) Eq(h2 NodeHash) bool { 142 return subtle.ConstantTimeCompare(h.bytes(), h2.bytes()) == 1 143 } 144 145 func (h *NodeHashAny) UnmarshalJSON(b []byte) error { 146 s := keybase1.Unquote(b) 147 148 // empty strings are OK, to mean no hash available 149 if len(s) == 0 { 150 return nil 151 } 152 153 g, err := NodeHashFromHex(s) 154 if err != nil { 155 return err 156 } 157 switch g := g.(type) { 158 case NodeHashShort: 159 h.s = &g 160 case NodeHashLong: 161 h.l = &g 162 default: 163 return errors.New("unknown hash type") 164 } 165 return nil 166 } 167 168 func (h NodeHashAny) IsNil() bool { 169 return h.s == nil && h.l == nil 170 } 171 172 func (h1 *NodeHashShort) UnmarshalJSON(b []byte) error { 173 s := keybase1.Unquote(b) 174 // empty strings are OK, to mean no hash available 175 if len(s) == 0 { 176 return nil 177 } 178 g, err := NodeHashFromHex(s) 179 if err != nil { 180 return err 181 } 182 if ret, ok := g.(NodeHashShort); ok { 183 *h1 = ret 184 return nil 185 } 186 return errors.New("bad SHA256 hash") 187 } 188 189 func (h1 *NodeHashLong) UnmarshalJSON(b []byte) error { 190 s := keybase1.Unquote(b) 191 // empty strings are OK, to mean no hash available 192 if len(s) == 0 { 193 return nil 194 } 195 g, err := NodeHashFromHex(s) 196 if err != nil { 197 return err 198 } 199 if ret, ok := g.(NodeHashLong); ok { 200 *h1 = ret 201 return nil 202 } 203 return errors.New("bad SHA512hash") 204 } 205 206 func (h *NodeHashAny) MarshalJSON() ([]byte, error) { 207 s := h.String() 208 if len(s) == 0 { 209 return nil, nil 210 } 211 return keybase1.Quote(s), nil 212 } 213 214 type MerkleClientInterface interface { 215 CanExamineHistoricalRoot(m MetaContext, q keybase1.Seqno) bool 216 FetchRootFromServerByMinSeqno(m MetaContext, lowerBound keybase1.Seqno) (mr *MerkleRoot, err error) 217 FetchRootFromServer(m MetaContext, freshness time.Duration) (mr *MerkleRoot, err error) 218 FirstExaminableHistoricalRoot(m MetaContext) *keybase1.Seqno 219 FirstMainRootWithHiddenRootHash(m MetaContext) (s keybase1.Seqno, err error) 220 LastRoot(m MetaContext) *MerkleRoot 221 LastRootToSigJSON(m MetaContext) (ret *jsonw.Wrapper, err error) 222 LookupLeafAtHashMeta(m MetaContext, leafID keybase1.UserOrTeamID, hm keybase1.HashMeta) (leaf *MerkleGenericLeaf, err error) 223 LookupLeafAtSeqno(m MetaContext, leafID keybase1.UserOrTeamID, s keybase1.Seqno) (leaf *MerkleGenericLeaf, root *MerkleRoot, err error) 224 LookupLeafAtSeqnoForAudit(m MetaContext, leafID keybase1.UserOrTeamID, s keybase1.Seqno, processHiddenRespFunc ProcessHiddenRespFunc) (leaf *MerkleGenericLeaf, root *MerkleRoot, hiddenResp *MerkleHiddenResponse, err error) 225 LookupRootAtSeqno(m MetaContext, s keybase1.Seqno) (root *MerkleRoot, err error) 226 LookupTeam(m MetaContext, teamID keybase1.TeamID) (leaf *MerkleTeamLeaf, err error) 227 LookupTeamWithHidden(m MetaContext, teamID keybase1.TeamID, processHiddenRespFunc ProcessHiddenRespFunc) (leaf *MerkleTeamLeaf, hiddenResp *MerkleHiddenResponse, lastMerkleRoot *MerkleRoot, err error) 228 LookupUser(m MetaContext, q HTTPArgs, sigHints *SigHints, opts MerkleOpts) (u *MerkleUserLeaf, err error) 229 } 230 231 type MerkleClient struct { 232 Contextified 233 234 // protects whole object 235 // 236 // Warning: Never grab the latestRootLock while holding this lock, as the 237 // opposite happens and so you might introduce deadlocks. 238 sync.RWMutex 239 240 keyring *SpecialKeyRing 241 242 // The most recently-available root 243 lastRoot *MerkleRoot 244 245 // The first node we saw that has skip pointers; not used in production 246 firstSkip *keybase1.Seqno 247 248 // The first merkle root that contains the root of the hidden merkle tree 249 firstRootWithHidden keybase1.Seqno 250 251 // latestRootLock ensures that only one API call to fetch the latest merkle 252 // root is in flight at a time. These calls are expensive and would almost 253 // always get the same answer when concurrent. 254 // 255 // Warning: it is ok, to grab the object Lock while holding this one, but do 256 // not ever go the other way around, or you are risking deadlocks. 257 latestRootLock sync.Mutex 258 } 259 260 var _ MerkleClientInterface = (*MerkleClient)(nil) 261 262 type MerkleRoot struct { 263 sigs *jsonw.Wrapper 264 payload MerkleRootPayload 265 fetched time.Time 266 } 267 268 func (mr MerkleRoot) HashMeta() keybase1.HashMeta { 269 return mr.ShortHash().ExportToHashMeta() 270 } 271 272 func (mr MerkleRoot) IsNil() bool { 273 return mr == MerkleRoot{} 274 } 275 276 type SkipSequence []MerkleRootPayload 277 278 type MerkleTriple struct { 279 Seqno keybase1.Seqno `json:"seqno"` 280 LinkID LinkID `json:"id"` 281 SigID keybase1.SigIDBase `json:"sigid,omitempty"` 282 } 283 284 type MerkleUserLeaf struct { 285 public *MerkleTriple 286 private *MerkleTriple 287 idVersion int64 288 username string 289 uid keybase1.UID 290 eldest keybase1.KID // may be empty 291 resets *MerkleResets 292 } 293 294 type MerkleTeamLeaf struct { 295 TeamID keybase1.TeamID 296 Public *MerkleTriple 297 Private *MerkleTriple 298 } 299 300 type MerkleGenericLeaf struct { 301 LeafID keybase1.UserOrTeamID 302 Public *MerkleTriple 303 Private *MerkleTriple 304 305 // if the leaf is a User leaf, we'll have extra information here, like 306 // reset chain and eldest key. On a team leaf, this will be nil. 307 userExtras *MerkleUserLeaf 308 } 309 310 func (l MerkleTeamLeaf) MerkleGenericLeaf() *MerkleGenericLeaf { 311 return &MerkleGenericLeaf{ 312 LeafID: l.TeamID.AsUserOrTeam(), 313 Public: l.Public, 314 Private: l.Private, 315 } 316 } 317 318 func (mul MerkleUserLeaf) MerkleGenericLeaf() *MerkleGenericLeaf { 319 return &MerkleGenericLeaf{ 320 LeafID: mul.uid.AsUserOrTeam(), 321 Public: mul.public, 322 Private: mul.private, 323 userExtras: &mul, 324 } 325 } 326 327 func (l MerkleGenericLeaf) PartialClone() MerkleGenericLeaf { 328 ret := MerkleGenericLeaf{LeafID: l.LeafID} 329 if l.Public != nil { 330 tmp := *l.Public 331 ret.Public = &tmp 332 } 333 if l.Private != nil { 334 tmp := *l.Private 335 ret.Private = &tmp 336 } 337 return ret 338 } 339 340 type PathSteps []*PathStep 341 342 type merkleUserInfoT struct { 343 uid keybase1.UID 344 uidPath PathSteps 345 idVersion int64 346 username string 347 usernameCased string 348 unverifiedResetChain unverifiedResetChain 349 } 350 351 type VerificationPath struct { 352 Contextified 353 root *MerkleRoot 354 path PathSteps 355 } 356 357 type MerkleRootPayload struct { 358 packed string 359 unpacked *MerkleRootPayloadUnpacked 360 } 361 362 func (mrp MerkleRootPayload) shortHash() NodeHashShort { 363 return sha256.Sum256([]byte(mrp.packed)) 364 } 365 366 func (mrp MerkleRootPayload) hasSkips() bool { 367 return len(mrp.unpacked.Body.Skips) > 0 368 } 369 370 type MerkleRootPayloadUnpacked struct { 371 Body struct { 372 Kbfs struct { 373 Private struct { 374 Root keybase1.KBFSRootHash `json:"root"` 375 Version *keybase1.Seqno `json:"version"` 376 } `json:"private"` 377 Public struct { 378 Root keybase1.KBFSRootHash `json:"root"` 379 Version *keybase1.Seqno `json:"version"` 380 } `json:"public"` 381 PrivateTeam struct { 382 Root keybase1.KBFSRootHash `json:"root"` 383 Version *keybase1.Seqno `json:"version"` 384 } `json:"privateteam"` 385 } `json:"kbfs"` 386 LegacyUIDRoot NodeHashShort `json:"legacy_uid_root"` 387 Prev NodeHashLong `json:"prev"` 388 Root NodeHashLong `json:"root"` 389 Seqno keybase1.Seqno `json:"seqno"` 390 Skips SkipTable `json:"skips"` 391 Txid string `json:"txid"` 392 Type string `json:"type"` 393 Version int `json:"version"` 394 PvlHash string `json:"pvl_hash"` 395 ProofServicesHash string `json:"proof_services_hash"` 396 ExternalURLHash string `json:"external_urls_hash"` 397 BlindMerkleRootHash string `json:"blind_merkle_root_hash"` 398 } `json:"body"` 399 Ctime int64 `json:"ctime"` 400 Tag string `json:"tag"` 401 } 402 403 type SkipTable map[keybase1.Seqno]NodeHashAny 404 405 type PathStep struct { 406 prefix string 407 node string // The JSON-stringified version of the node (to be unpacked lazily) 408 } 409 410 func (mt MerkleTriple) Eq(mt2 MerkleTriple) bool { 411 return mt.Seqno == mt2.Seqno && mt.LinkID.Eq(mt2.LinkID) && mt.SigID.Eq(mt2.SigID) 412 } 413 414 func (mul MerkleUserLeaf) Public() *MerkleTriple { 415 return mul.public 416 } 417 418 func NodeHashFromHex(s string) (NodeHash, error) { 419 switch hex.DecodedLen(len(s)) { 420 case NodeHashLenLong: 421 var buf NodeHashLong 422 err := DecodeHexFixed(buf[:], []byte(s)) 423 if err != nil { 424 return nil, err 425 } 426 return buf, err 427 case NodeHashLenShort: 428 var buf NodeHashShort 429 err := DecodeHexFixed(buf[:], []byte(s)) 430 if err != nil { 431 return nil, err 432 } 433 return buf, err 434 default: 435 return nil, fmt.Errorf("Bad NodeHash; wrong length: %d", len(s)) 436 } 437 } 438 439 func GetNodeHash(w *jsonw.Wrapper) (NodeHash, error) { 440 s, err := w.GetString() 441 if err != nil { 442 return nil, err 443 } 444 ret, err := NodeHashFromHex(s) 445 return ret, err 446 } 447 448 func GetNodeHashVoid(w *jsonw.Wrapper, nhp *NodeHash, errp *error) { 449 nh, err := GetNodeHash(w) 450 if err != nil { 451 *errp = err 452 } else { 453 *nhp = nh 454 } 455 } 456 457 func computeSetBitsBigEndian(x uint) []uint { 458 if x == 0 { 459 return nil 460 } else if x == 1 { 461 return []uint{1} 462 } 463 // Allocate maximum array size necessary 464 high := int(math.Ceil(math.Log2(float64(x)))) 465 ret := make([]uint, 0, high) 466 for i, bit := 0, uint(1); i <= high; i, bit = i+1, bit*2 { 467 if x&bit != 0 { 468 ret = append(ret, bit) 469 } 470 } 471 return ret 472 } 473 474 func computeLogPatternMerkleSkips(startSeqno keybase1.Seqno, endSeqno keybase1.Seqno) (ret []uint, err error) { 475 if endSeqno < startSeqno { 476 return ret, fmt.Errorf("got startSeqno > endSeqno (%d > %d) in merkle skip sequence", startSeqno, endSeqno) 477 } 478 if endSeqno == startSeqno { 479 return ret, nil 480 } 481 end := uint(endSeqno) 482 start := uint(startSeqno) 483 diff := end - start 484 skips := computeSetBitsBigEndian(diff) 485 curr := end 486 // Ignore first set bit 487 for i := len(skips) - 1; i > 0; i-- { 488 curr -= skips[i] 489 ret = append(ret, curr) 490 } 491 return ret, nil 492 } 493 494 func NewMerkleClient(g *GlobalContext) *MerkleClient { 495 return &MerkleClient{ 496 keyring: NewSpecialKeyRing(g.Env.GetMerkleKIDs(), g), 497 lastRoot: nil, 498 Contextified: NewContextified(g), 499 } 500 } 501 502 func (mc *MerkleClient) init(m MetaContext) error { 503 err := mc.loadRoot(m) 504 return err 505 } 506 507 func merkleHeadKey() DbKey { 508 // DBMerkleRoot was once used to store specific roots with Key: fmt.Sprintf("%d", int) 509 return DbKey{ 510 Typ: DBMerkleRoot, 511 Key: "HEAD", 512 } 513 } 514 515 func (mc *MerkleClient) dbGet(m MetaContext, k DbKey) (ret *MerkleRoot, err error) { 516 defer m.VTrace(VLog1, fmt.Sprintf("MerkleClient#dbGet(%+v)", k), &err)() 517 curr, err := m.G().LocalDb.Get(k) 518 if err != nil { 519 return nil, err 520 } 521 if curr == nil { 522 m.VLogf(VLog1, "| MerkleClient#dbGet(%+v) found not results", k) 523 return nil, nil 524 } 525 526 mr, err := NewMerkleRootFromJSON(curr, MerkleOpts{}) 527 if err != nil { 528 return nil, err 529 } 530 return mr, err 531 } 532 533 func (mc *MerkleClient) loadRoot(m MetaContext) (err error) { 534 defer m.VTrace(VLog1, "MerkleClient#loadRoot()", &err)() 535 var mr *MerkleRoot 536 mr, err = mc.dbGet(m, merkleHeadKey()) 537 if mr == nil || err != nil { 538 return err 539 } 540 mc.Lock() 541 mc.lastRoot = mr 542 mc.Unlock() 543 return nil 544 } 545 546 func (mr *MerkleRoot) HasSkips() bool { 547 return mr.payload.hasSkips() 548 } 549 550 func (mr *MerkleRoot) ToJSON() (jw *jsonw.Wrapper) { 551 ret := jsonw.NewDictionary() 552 _ = ret.SetKey("sigs", mr.sigs) 553 _ = ret.SetKey("payload_json", jsonw.NewString(mr.payload.packed)) 554 _ = ret.SetKey("fetched_ns", jsonw.NewInt64(mr.fetched.UnixNano())) 555 return ret 556 } 557 558 func (mr MerkleRoot) ShortHash() NodeHashShort { 559 return mr.payload.shortHash() 560 } 561 562 func NewMerkleRootPayloadFromJSONString(s string) (ret MerkleRootPayload, err error) { 563 ret = MerkleRootPayload{packed: s} 564 err = json.Unmarshal([]byte(s), &ret.unpacked) 565 if err != nil { 566 return ret, err 567 } 568 return ret, nil 569 } 570 571 func NewMerkleRootFromJSON(jw *jsonw.Wrapper, opts MerkleOpts) (ret *MerkleRoot, err error) { 572 var sigs *jsonw.Wrapper 573 var payloadJSONString string 574 var mrp MerkleRootPayload 575 576 if !opts.noSigCheck { 577 if sigs, err = jw.AtKey("sigs").ToDictionary(); err != nil { 578 return nil, err 579 } 580 } 581 582 if payloadJSONString, err = jw.AtKey("payload_json").GetString(); err != nil { 583 return nil, err 584 } 585 586 if mrp, err = NewMerkleRootPayloadFromJSONString(payloadJSONString); err != nil { 587 return nil, err 588 } 589 590 ret = &MerkleRoot{ 591 sigs: sigs, 592 payload: mrp, 593 fetched: time.Time{}, 594 } 595 596 fetchedNs, err := jw.AtKey("fetched_ns").GetInt64() 597 if err == nil { 598 ret.fetched = time.Unix(0, fetchedNs) 599 } 600 601 return ret, nil 602 } 603 604 func importPathFromJSON(jw *jsonw.Wrapper) (out []*PathStep, err error) { 605 if jw.IsNil() { 606 return 607 } 608 609 var path *jsonw.Wrapper 610 if path, err = jw.ToArray(); err != nil { 611 return 612 } 613 614 var l int 615 if l, err = path.Len(); err != nil { 616 return 617 } 618 619 for i := 0; i < l; i++ { 620 var step *PathStep 621 if step, err = pathStepFromJSON(path.AtIndex(i)); err != nil { 622 return 623 } 624 out = append(out, step) 625 } 626 return 627 } 628 629 // FetchRootFromServerByMinSeqno returns the latest root this client knows 630 // about. If the seqno of the latest root is smaller than the lowerBound 631 // argument, a new api call is made to the server. However, if the server 632 // returns a root at a seqno smaller than lowerBound, no errors are raised. 633 func (mc *MerkleClient) FetchRootFromServerByMinSeqno(m MetaContext, lowerBound keybase1.Seqno) (mr *MerkleRoot, err error) { 634 defer m.VTrace(VLog0, "MerkleClient#FetchRootFromServerByMinSeqno", &err)() 635 636 checkFreshness := func() (ok bool, root *MerkleRoot) { 637 root = mc.LastRoot(m) 638 if root != nil && *root.Seqno() >= lowerBound { 639 m.VLogf(VLog0, "seqno=%d, and was current enough, so returning non-nil previously fetched root", *root.Seqno()) 640 return true, root 641 } 642 return false, root 643 } 644 645 if ok, root := checkFreshness(); ok { 646 return root, nil 647 } 648 649 mc.latestRootLock.Lock() 650 defer mc.latestRootLock.Unlock() 651 // by the time we got the lock, the root might have been updated to a recent enough one, so check again 652 ok, root := checkFreshness() 653 if ok { 654 return root, nil 655 } 656 657 return mc.fetchAndStoreRootFromServerLocked(m, root) 658 } 659 660 // FetchRootFromServer fetches a root from the server. If the last-fetched root was fetched within 661 // freshness ago, then OK to return the last-fetched root. Otherwise refetch. Similarly, if the freshness 662 // passed is 0, then always refresh. 663 func (mc *MerkleClient) FetchRootFromServer(m MetaContext, freshness time.Duration) (mr *MerkleRoot, err error) { 664 defer m.VTrace(VLog0, "MerkleClient#FetchRootFromServer", &err)() 665 666 now := m.G().Clock().Now() 667 668 checkFreshness := func() (ok bool, root *MerkleRoot) { 669 root = mc.LastRoot(m) 670 if root != nil && freshness > 0 && now.Sub(root.fetched) < freshness { 671 m.VLogf(VLog0, "freshness=%s, and was current enough, so returning non-nil previously fetched root", freshness) 672 return true, root 673 } 674 return false, root 675 } 676 677 if ok, root := checkFreshness(); ok { 678 return root, nil 679 } 680 681 mc.latestRootLock.Lock() 682 defer mc.latestRootLock.Unlock() 683 // by the time we got the lock, the root might have been updated to a recent enough one, so check again 684 ok, root := checkFreshness() 685 if ok { 686 return root, nil 687 } 688 689 return mc.fetchAndStoreRootFromServerLocked(m, root) 690 } 691 692 func (mc *MerkleClient) fetchAndStoreRootFromServerLocked(m MetaContext, lastRoot *MerkleRoot) (mr *MerkleRoot, err error) { 693 defer m.VTrace(VLog0, "MerkleClient#fetchRootFromServerLocked", &err)() 694 var ss SkipSequence 695 var apiRes *APIRes 696 var opts MerkleOpts 697 698 mr, ss, apiRes, err = mc.lookupRootAndSkipSequence(m, lastRoot, opts) 699 if err != nil { 700 return nil, err 701 } 702 703 if mr == nil { 704 // The server indicated that last root is the most recent one: updating 705 // the fetch time and skipping verification 706 lastRoot.fetched = m.G().Clock().Now() 707 mc.Lock() 708 defer mc.Unlock() 709 mc.storeRoot(m, lastRoot) 710 return lastRoot, nil 711 } 712 713 if err = mc.verifySkipSequenceAndRoot(m, ss, mr, lastRoot, apiRes, opts); err != nil { 714 return nil, err 715 } 716 717 mc.Lock() 718 defer mc.Unlock() 719 mc.storeRoot(m, mr) 720 721 return mr, nil 722 } 723 724 // if both mr and err are nil, this indicates the server did not send a new root 725 // as lastRoot was the most recent one. 726 func (mc *MerkleClient) lookupRootAndSkipSequence(m MetaContext, lastRoot *MerkleRoot, opts MerkleOpts) (mr *MerkleRoot, ss SkipSequence, apiRes *APIRes, err error) { 727 728 // c=1 invokes server-side compression 729 q := HTTPArgs{ 730 "c": B{true}, 731 } 732 733 // Get back a series of skips from the last merkle root we had to the new 734 // one we're getting back, and hold the server to it. 735 lastSeqno := lastRoot.Seqno() 736 if lastSeqno != nil { 737 q.Add("last", I{int(*lastSeqno)}) 738 // If the last root known to the server has seqno last, we do not need 739 // to receive it again. 740 q.Add("skip_last", B{true}) 741 } 742 743 apiRes, err = m.G().API.Get(m, APIArg{ 744 Endpoint: "merkle/root", 745 SessionType: APISessionTypeNONE, 746 Args: q, 747 AppStatusCodes: []int{SCOk}, 748 }) 749 750 if err != nil { 751 return nil, nil, nil, err 752 } 753 754 seqno, err := apiRes.Body.AtKey("seqno").GetInt64() 755 if err != nil { 756 return nil, nil, nil, fmt.Errorf("merkle/root response does not contain seqno: %v", err) 757 } 758 if lastSeqno != nil && *lastSeqno == keybase1.Seqno(seqno) { 759 // here we can ignore the rest of the server response (the server 760 // should not send it anyways), as lastRoot is still the most recent 761 // root 762 m.Debug("The server indicated that the root at seqno %v (which we have) is the most recent, shortcircuiting the root parsing and validation.", seqno) 763 return nil, nil, nil, nil 764 } 765 766 mr, err = readRootFromAPIRes(m, apiRes.Body, opts) 767 if err != nil { 768 return nil, nil, nil, err 769 } 770 ss, err = mc.readSkipSequenceFromAPIRes(m, apiRes, mr, lastRoot) 771 if err != nil { 772 return nil, nil, nil, err 773 } 774 return mr, ss, apiRes, err 775 } 776 777 func (mc *MerkleClient) lookupLeafAndPathUser(m MetaContext, q HTTPArgs, sigHints *SigHints, root *MerkleRoot, opts MerkleOpts) (vp *VerificationPath, userInfo *merkleUserInfoT, apiRes *APIRes, err error) { 778 opts.isUser = true 779 vp, apiRes, err = mc.lookupLeafAndPath(m, q, root, sigHints, opts) 780 if err != nil { 781 return nil, nil, nil, err 782 } 783 784 if sigHints != nil { 785 if err = sigHints.RefreshWith(m, apiRes.Body.AtKey("sigs")); err != nil { 786 return nil, nil, nil, err 787 } 788 } 789 790 userInfo, err = mc.readUserFromAPIRes(m, apiRes) 791 if err != nil { 792 return nil, nil, nil, err 793 } 794 795 return vp, userInfo, apiRes, nil 796 } 797 798 func (mc *MerkleClient) lookupLeafAndPath(m MetaContext, q HTTPArgs, root *MerkleRoot, sigHints *SigHints, opts MerkleOpts) (vp *VerificationPath, res *APIRes, err error) { 799 apiRes, root, err := mc.lookupLeafAndPathHelper(m, q, sigHints, root, opts) 800 if err != nil { 801 return nil, nil, err 802 } 803 804 vp, err = mc.readPathFromAPIRes(m, apiRes, opts) 805 if err != nil { 806 return nil, nil, err 807 } 808 vp.root = root 809 810 return vp, apiRes, nil 811 } 812 813 // `MerkleOpts.isUser` is true for loading a user and false for loading a team. 814 func (mc *MerkleClient) lookupLeafAndPathHelper(m MetaContext, q HTTPArgs, sigHints *SigHints, root *MerkleRoot, opts MerkleOpts) (apiRes *APIRes, newRoot *MerkleRoot, err error) { 815 defer m.VTrace(VLog1, "MerkleClient#lookupLeafAndPathHelper", &err)() 816 817 for i := 0; i < 5; i++ { 818 apiRes, rootRefreshNeeded, err := mc.lookupLeafAndPathHelperOnce(m, q, sigHints, root, opts) 819 if err != nil { 820 return nil, nil, err 821 } 822 if !rootRefreshNeeded { 823 return apiRes, root, err 824 } 825 826 m.Debug("Server suggested a root refresh is necessary") 827 root, err = mc.FetchRootFromServer(m, 0) 828 if err != nil { 829 return nil, nil, err 830 } 831 } 832 833 return nil, nil, fmt.Errorf("Too many server requests to refresh the merkle root") 834 } 835 836 // `isUser` is true for loading a user and false for loading a team. 837 func (mc *MerkleClient) lookupLeafAndPathHelperOnce(m MetaContext, q HTTPArgs, sigHints *SigHints, root *MerkleRoot, opts MerkleOpts) (apiRes *APIRes, rootRefreshNeeded bool, err error) { 838 defer m.VTrace(VLog1, "MerkleClient#lookupLeafAndPathHelperOnce", &err)() 839 840 if !opts.NoServerPolling { 841 // Poll for 10s and ask for a race-free state. 842 w := 10 * int(CITimeMultiplier(mc.G())) 843 q.Add("poll", I{w}) 844 } 845 846 q.Add("c", B{true}) 847 if opts.isUser { 848 q.Add("load_deleted", B{true}) 849 q.Add("load_reset_chain", B{true}) 850 } 851 852 // Add the local db sigHints version 853 if sigHints != nil { 854 q.Add("sig_hints_low", I{sigHints.version}) 855 } 856 857 // Get back a path from the leaf to the current merkle root. The root itself 858 // is not included. 859 tail := root.Seqno() 860 if tail != nil { 861 q.Add("tail", I{int(*tail)}) 862 } 863 864 apiRes, err = m.G().API.Get(m, APIArg{ 865 Endpoint: "merkle/path", 866 SessionType: APISessionTypeOPTIONAL, 867 Args: q, 868 AppStatusCodes: []int{SCOk, SCNotFound, SCDeleted, SCMerkleUpdateRoot}, 869 }) 870 871 if err != nil { 872 return nil, false, err 873 } 874 875 switch apiRes.AppStatus.Code { 876 case SCMerkleUpdateRoot: 877 // Server indicated that a refetch of the root is needed 878 return nil, true, nil 879 case SCOk: 880 err = assertRespSeqnoPrecedesCurrentRoot(apiRes, root) 881 if err != nil { 882 return nil, false, err 883 } 884 // TRIAGE-2068 885 case SCNotFound: 886 return nil, false, NotFoundError{} 887 case SCDeleted: 888 return nil, false, UserDeletedError{} 889 } 890 return apiRes, false, nil 891 } 892 893 func assertRespSeqnoPrecedesCurrentRoot(apiRes *APIRes, root *MerkleRoot) error { 894 resSeqno, err := apiRes.Body.AtKey("root").AtKey("seqno").GetInt64() 895 if err != nil { 896 return err 897 } 898 if keybase1.Seqno(resSeqno) > *root.Seqno() { 899 // The server should have returned SCMerkleUpdateRoot instead 900 return MerkleClientError{m: fmt.Sprintf("The server unexpectedly returned root (%v) ahead of the last one we know about (%v) instead of asking to update", keybase1.Seqno(resSeqno), *root.Seqno())} 901 } 902 return nil 903 } 904 905 func readSkipSequenceFromStringList(v []string) (ret SkipSequence, err error) { 906 for _, s := range v { 907 var p MerkleRootPayload 908 if p, err = NewMerkleRootPayloadFromJSONString(s); err != nil { 909 return nil, err 910 } 911 ret = append(ret, p) 912 } 913 return ret, nil 914 } 915 916 func (mc *MerkleClient) readAndCheckRootFromAPIRes(m MetaContext, apiRes *APIRes, currentRoot *MerkleRoot, opts MerkleOpts) (newRoot *MerkleRoot, err error) { 917 newRoot, err = readRootFromAPIRes(m, apiRes.Body.AtKey("root"), opts) 918 if err != nil { 919 return nil, err 920 } 921 ss, err := mc.readSkipSequenceFromAPIRes(m, apiRes, newRoot, currentRoot) 922 if err != nil { 923 return nil, err 924 } 925 err = mc.verifySkipSequenceAndRoot(m, ss, newRoot, currentRoot, apiRes, opts) 926 if err != nil { 927 return nil, err 928 } 929 return newRoot, nil 930 } 931 932 func readRootFromAPIRes(m MetaContext, jw *jsonw.Wrapper, opts MerkleOpts) (*MerkleRoot, error) { 933 ret, err := NewMerkleRootFromJSON(jw, opts) 934 if err != nil { 935 return nil, err 936 } 937 if chk := GetMerkleCheckpoint(m); chk != nil && *ret.Seqno() < *chk.Seqno() { 938 msg := fmt.Sprintf("got unexpected early root %d < %d", *ret.Seqno(), *chk.Seqno()) 939 m.Error("checkpoint failure: %s", msg) 940 return nil, NewClientMerkleFailedCheckpointError(msg) 941 } 942 ret.fetched = m.G().Clock().Now() 943 return ret, nil 944 } 945 946 // readSkipSequenceFromAPIRes returns a SkipSequence. We construct the sequence by starting with the 947 // most recent merkle root, adding the "skip" pointers returned by the server, and finally bookending 948 // with the merkle root we last fetched from the DB. In verifySkipSequence, we walk over this Sequence 949 // to make sure that it obeys proper construction. 950 func (mc *MerkleClient) readSkipSequenceFromAPIRes(m MetaContext, res *APIRes, thisRoot *MerkleRoot, lastRoot *MerkleRoot) (ret SkipSequence, err error) { 951 defer m.VTrace(VLog1, "MerkleClient#readSkipSequenceFromAPIRes", &err)() 952 if lastRoot == nil { 953 m.VLogf(VLog0, "| lastRoot==nil") 954 return nil, nil 955 } 956 if !thisRoot.HasSkips() { 957 m.VLogf(VLog0, "| thisRoot has no skips") 958 return nil, nil 959 } 960 skips := res.Body.AtKey("skips") 961 962 if skips.IsNil() { 963 m.VLogf(VLog1, "| skip list from API server is nil") 964 return nil, nil 965 } 966 967 var v []string 968 if err = skips.UnmarshalAgain(&v); err != nil { 969 m.VLogf(VLog0, "| failed to unmarshal skip list as a list of strings") 970 return nil, err 971 } 972 973 ret, err = readSkipSequenceFromStringList(v) 974 if err != nil { 975 return nil, err 976 } 977 978 // Create the skip sequence by bookending the list the server replies with 979 // with: (1) the most recent root, sent back in this reply; and (2) our last 980 // root, which we read out of cache (in memory or on disk). HOWEVER, in the 981 // case of lookup up historical roots, the ordering might be reversed. So 982 // we swap in that case. 983 984 left, right := thisRoot.payload, lastRoot.payload 985 if left.seqno() < right.seqno() { 986 left, right = right, left 987 } 988 989 ret = append(SkipSequence{left}, ret...) 990 ret = append(ret, right) 991 992 return ret, nil 993 } 994 995 func (mc *MerkleClient) readUserFromAPIRes(m MetaContext, res *APIRes) (userInfo *merkleUserInfoT, err error) { 996 userInfo = &merkleUserInfoT{} 997 998 userInfo.uid, err = GetUID(res.Body.AtKey("uid")) 999 if err != nil { 1000 return nil, err 1001 } 1002 1003 // We don't trust this version, but it's useful to tell us if there 1004 // are new versions unsigned data, like basics, and maybe uploaded 1005 // keys 1006 userInfo.idVersion, err = res.Body.AtKey("id_version").GetInt64() 1007 if err != nil { 1008 return nil, err 1009 } 1010 1011 userInfo.uidPath, err = importPathFromJSON(res.Body.AtKey("uid_proof_path")) 1012 if err != nil { 1013 return nil, err 1014 } 1015 1016 userInfo.username, err = res.Body.AtKey("username").GetString() 1017 if err != nil { 1018 return nil, err 1019 } 1020 userInfo.usernameCased, _ = res.Body.AtKey("username_cased").GetString() 1021 1022 userInfo.unverifiedResetChain, err = importResetChainFromServer(m, res.Body.AtKey("reset_chain")) 1023 if err != nil { 1024 return nil, err 1025 } 1026 1027 return userInfo, nil 1028 } 1029 1030 func (mc *MerkleClient) readPathFromAPIRes(m MetaContext, res *APIRes, opts MerkleOpts) (vp *VerificationPath, err error) { 1031 defer m.VTrace(VLog1, "MerkleClient#readPathFromAPIRes", &err)() 1032 1033 vp = &VerificationPath{ 1034 Contextified: NewContextified(mc.G()), 1035 } 1036 1037 vp.path, err = importPathFromJSON(res.Body.AtKey("path")) 1038 if err != nil { 1039 return nil, err 1040 } 1041 1042 return vp, nil 1043 } 1044 1045 func pathStepFromJSON(jw *jsonw.Wrapper) (ps *PathStep, err error) { 1046 1047 var prefix string 1048 pw := jw.AtKey("prefix") 1049 if !pw.IsNil() { 1050 var s string 1051 if s, err = pw.GetString(); err != nil { 1052 return 1053 } 1054 prefix = s 1055 } 1056 node, err := jw.AtKey("node").AtKey("val").GetString() 1057 if err != nil { 1058 return 1059 } 1060 ps = &PathStep{prefix, node} 1061 return 1062 } 1063 1064 func (mc *MerkleClient) LastRoot(m MetaContext) *MerkleRoot { 1065 mc.RLock() 1066 defer mc.RUnlock() 1067 if mc.lastRoot == nil { 1068 return nil 1069 } 1070 ret := mc.lastRoot 1071 chk := GetMerkleCheckpoint(m) 1072 if chk != nil && *ret.Seqno() < *chk.Seqno() { 1073 ret = chk 1074 } 1075 return ret.ShallowCopy() 1076 } 1077 1078 func (mr MerkleRoot) ExportToAVDL(g *GlobalContext) keybase1.MerkleRootAndTime { 1079 hashMeta := mr.ShortHash() 1080 return keybase1.MerkleRootAndTime{ 1081 Root: keybase1.MerkleRootV2{ 1082 Seqno: mr.payload.unpacked.Body.Seqno, 1083 HashMeta: hashMeta[:], 1084 }, 1085 UpdateTime: keybase1.TimeFromSeconds(mr.payload.unpacked.Ctime), 1086 FetchTime: keybase1.ToTime(mr.fetched), 1087 } 1088 } 1089 1090 // storeRoot stores the root in the db and mem. 1091 // Must be called from under a lock. 1092 func (mc *MerkleClient) storeRoot(m MetaContext, root *MerkleRoot) { 1093 m.VLogf(VLog0, "storing merkle root: %d", *root.Seqno()) 1094 err := mc.G().LocalDb.Put(merkleHeadKey(), nil, root.ToJSON()) 1095 if err != nil { 1096 m.Error("Cannot commit Merkle root to local DB: %s", err) 1097 } else { 1098 mc.lastRoot = root 1099 } 1100 } 1101 1102 func (mc *MerkleClient) firstExaminableHistoricalRootProd(m MetaContext) *keybase1.Seqno { 1103 chk := GetMerkleCheckpoint(m) 1104 var ret *keybase1.Seqno 1105 if chk != nil { 1106 ret = chk.Seqno() 1107 } 1108 if ret == nil || FirstProdMerkleSeqnoWithSkips > *ret { 1109 ret = &FirstProdMerkleSeqnoWithSkips 1110 } 1111 return ret 1112 } 1113 1114 func (mc *MerkleClient) FirstExaminableHistoricalRoot(m MetaContext) *keybase1.Seqno { 1115 1116 if mc.G().Env.GetRunMode() == ProductionRunMode { 1117 return mc.firstExaminableHistoricalRootProd(m) 1118 } 1119 1120 ret := mc.getFirstSkip() 1121 if ret != nil { 1122 return ret 1123 } 1124 1125 ret = mc.getFirstSkipFromServer(m) 1126 return ret 1127 } 1128 1129 func (mc *MerkleClient) getFirstSkip() *keybase1.Seqno { 1130 mc.RLock() 1131 defer mc.RUnlock() 1132 return mc.firstSkip 1133 } 1134 1135 type firstSkipRaw struct { 1136 Status AppStatus `json:"status"` 1137 Seqno keybase1.Seqno `json:"seqno"` 1138 } 1139 1140 func (r *firstSkipRaw) GetAppStatus() *AppStatus { 1141 return &r.Status 1142 } 1143 1144 func (mc *MerkleClient) getFirstSkipFromServer(m MetaContext) *keybase1.Seqno { 1145 1146 var raw firstSkipRaw 1147 err := m.G().API.GetDecode(m, APIArg{ 1148 Endpoint: "merkle/first_root_with_skips", 1149 SessionType: APISessionTypeNONE, 1150 AppStatusCodes: []int{SCOk}, 1151 }, &raw) 1152 1153 if err != nil { 1154 m.Debug("failed to fetch first skip from server: %v", err) 1155 return nil 1156 } 1157 1158 m.Debug("Got back seqno=%v as first merkle root with skips", raw.Seqno) 1159 1160 mc.Lock() 1161 mc.firstSkip = &raw.Seqno 1162 mc.Unlock() 1163 1164 return &raw.Seqno 1165 } 1166 1167 func (mc *MerkleClient) firstMainRootWithHiddenRootHashProd(m MetaContext) (s keybase1.Seqno) { 1168 return FirstProdMerkleSeqnoWithHiddenRootHash 1169 } 1170 1171 func (mc *MerkleClient) FirstMainRootWithHiddenRootHash(m MetaContext) (s keybase1.Seqno, err error) { 1172 if mc.G().Env.GetRunMode() == ProductionRunMode { 1173 return mc.firstMainRootWithHiddenRootHashProd(m), nil 1174 } 1175 1176 s = mc.getFirstMainRootWithHiddenRootHash() 1177 if s != 0 { 1178 return s, nil 1179 } 1180 1181 return mc.getFirstMainRootWithHiddenRootHashFromServer(m) 1182 } 1183 1184 func (mc *MerkleClient) getFirstMainRootWithHiddenRootHash() keybase1.Seqno { 1185 mc.RLock() 1186 defer mc.RUnlock() 1187 return mc.firstRootWithHidden 1188 } 1189 1190 type firstHiddenSeqnoRaw struct { 1191 Status AppStatus `json:"status"` 1192 Seqno keybase1.Seqno `json:"seqno"` 1193 } 1194 1195 func (r *firstHiddenSeqnoRaw) GetAppStatus() *AppStatus { 1196 return &r.Status 1197 } 1198 1199 func (mc *MerkleClient) getFirstMainRootWithHiddenRootHashFromServer(m MetaContext) (s keybase1.Seqno, err error) { 1200 1201 var raw firstHiddenSeqnoRaw 1202 err = m.G().API.GetDecode(m, APIArg{ 1203 Endpoint: "merkle/first_root_with_hidden", 1204 SessionType: APISessionTypeNONE, 1205 AppStatusCodes: []int{SCOk}, 1206 }, &raw) 1207 1208 if err != nil { 1209 m.Debug("failed to fetch first main root with hidden from server: %v", err) 1210 return 0, fmt.Errorf("failed to fetch first main root with hidden from server: %v", err) 1211 } 1212 1213 m.Debug("Got back seqno=%v as first merkle root with hidden root hash", raw.Seqno) 1214 1215 mc.Lock() 1216 mc.firstRootWithHidden = raw.Seqno 1217 mc.Unlock() 1218 1219 return raw.Seqno, nil 1220 } 1221 1222 func (mc *MerkleClient) findValidKIDAndSig(root *MerkleRoot) (keybase1.KID, string, error) { 1223 if v, err := root.sigs.Keys(); err == nil { 1224 for _, s := range v { 1225 kid := keybase1.KIDFromString(s) 1226 if !mc.keyring.IsValidKID(kid) { 1227 continue 1228 } else if sig, err := root.sigs.AtKey(s).AtKey("sig").GetString(); err == nil { 1229 return kid, sig, nil 1230 } 1231 } 1232 } 1233 var nilKID keybase1.KID 1234 return nilKID, "", MerkleClientError{"no known verifying key", merkleErrorNoKnownKey} 1235 } 1236 1237 func (mc *MerkleClient) verifySkipSequence(m MetaContext, ss SkipSequence, thisRoot *MerkleRoot, lastRoot *MerkleRoot, opts MerkleOpts) (err error) { 1238 defer m.VTrace(VLog1, "MerkleClient#verifySkipSequence", &err)() 1239 1240 var left, right keybase1.Seqno 1241 if thisRoot.Seqno() != nil { 1242 left = *thisRoot.Seqno() 1243 } 1244 if lastRoot.Seqno() != nil { 1245 right = *lastRoot.Seqno() 1246 } 1247 1248 // In historical queries (for which we fetch old roots), we check the skip 1249 // sequence in the opposite direction. 1250 if opts.historical { 1251 left, right = right, left 1252 } 1253 1254 // In this case, the server did not return a skip sequence. It's OK if 1255 // the last known root is too old. It's not OK if the last known root is 1256 // from after the server starting providing skip pointers. 1257 if ss == nil { 1258 m.VLogf(VLog1, "| nil SkipSequence") 1259 fss := mc.FirstExaminableHistoricalRoot(m) 1260 if lastRoot == nil { 1261 m.VLogf(VLog1, "| lastRoot==nil, so OK") 1262 return nil 1263 } 1264 if fss == nil { 1265 m.VLogf(VLog1, "| no known root with skips, so OK") 1266 return nil 1267 } 1268 if *fss > right { 1269 m.VLogf(VLog1, "| right marker (%d) is from before first known root with skips (%d), so OK", int(right), int(*fss)) 1270 return nil 1271 } 1272 if *fss > left { 1273 m.VLogf(VLog1, "| left marker (%d) is from before first known root with skips (%d), so OK", int(left), int(*fss)) 1274 return nil 1275 } 1276 if thisRoot != nil && *lastRoot.Seqno() == *thisRoot.Seqno() { 1277 m.VLogf(VLog1, "| thisRoot is the same as lastRoot (%d), so OK", int(*lastRoot.Seqno())) 1278 return nil 1279 } 1280 return MerkleClientError{fmt.Sprintf("Expected a skip sequence with last=%d", int(*lastRoot.Seqno())), merkleErrorNoSkipSequence} 1281 } 1282 1283 if left == right { 1284 m.VLogf(VLog1, "| No change since last check (seqno %d)", *thisRoot.Seqno()) 1285 return nil 1286 } 1287 return ss.verify(m, left, right) 1288 } 1289 1290 // verify verifies the raw "Skip Sequence" ss. ss contains a list of MerkleRootPayloads beginning 1291 // with the most recently returned root, and ending with the last root that we fetched. So for instance, 1292 // it might contain: [ 100, 84, 82, 81 ] in that case that we last fetched Seqno=81 and the server is 1293 // currently at Seqno=100. 1294 func (ss SkipSequence) verify(m MetaContext, thisRoot keybase1.Seqno, lastRoot keybase1.Seqno) (err error) { 1295 defer m.VTrace(VLog1, "SkipSequence#verify", &err)() 1296 1297 expectedSkips, err := computeLogPatternMerkleSkips(lastRoot, thisRoot) 1298 if err != nil { 1299 return MerkleClientError{fmt.Sprintf("Failed to compute expected skip pattern: %s", err), merkleErrorWrongSkipSequence} 1300 } 1301 // Don't check bookends that were added by client 1302 if len(expectedSkips)+2 != len(ss) { 1303 return MerkleClientError{fmt.Sprintf("Wrong number of skips: expected %d, got %d.", len(expectedSkips)+2, len(ss)), merkleErrorWrongSkipSequence} 1304 } 1305 1306 for index := 1; index < len(ss)-1; index++ { 1307 root := ss[index].seqno() 1308 if keybase1.Seqno(expectedSkips[index-1]) != root { 1309 return MerkleClientError{fmt.Sprintf("Unexpected skip index: expected %d, got %d.", expectedSkips[index-1], root), merkleErrorWrongSkipSequence} 1310 } 1311 } 1312 1313 const maxClockDriftSeconds int64 = 5 * 60 1314 var totalDrift int64 1315 1316 for index := 0; index < len(ss)-1; index++ { 1317 nextIndex := index + 1 1318 thisRoot, prevRoot := ss[index].seqno(), ss[nextIndex].seqno() 1319 m.VLogf(VLog1, "| Checking skip %d->%d", thisRoot, prevRoot) 1320 1321 // Next compare the skip pointer in this merkle root against the hash of the previous 1322 // root in the merkle root sequence. They must be equal. 1323 hash := ss[index].skipToSeqno(prevRoot) 1324 if hash == nil || hash.IsNil() { 1325 return MerkleClientError{fmt.Sprintf("Skip missing at %d->%d", thisRoot, prevRoot), merkleErrorSkipMissing} 1326 } 1327 if !hashEq(hash, ss[nextIndex].shortHash()) { 1328 m.VLogf(VLog0, "| Failure in hashes: %s != %s", hash.String(), ss[nextIndex].shortHash().String()) 1329 return MerkleClientError{fmt.Sprintf("Skip pointer mismatch at %d->%d", thisRoot, prevRoot), merkleErrorSkipHashMismatch} 1330 } 1331 1332 // Check that ctimes in the sequence are nearly strictly ordered; we have to make sure we can handle slight 1333 // clock jitters since the server might need to rewind time due to leap seconds or NTP issues. 1334 // We'll allow at most 5 minutes of "time-travel" between 2 updates, and no more than 5minutes of time travel 1335 // across the whole sequence 1336 thisCTime, prevCTime := ss[index].ctime(), ss[nextIndex].ctime() 1337 if prevCTime > thisCTime { 1338 drift := prevCTime - thisCTime 1339 if drift > maxClockDriftSeconds { 1340 return MerkleClientError{ 1341 fmt.Sprintf("Out of order ctimes: %d at %d should not have come before %d at %d (even with %ds tolerance)", thisRoot, thisCTime, prevRoot, prevCTime, maxClockDriftSeconds), 1342 merkleErrorOutOfOrderCtime, 1343 } 1344 } 1345 totalDrift += drift 1346 } 1347 } 1348 1349 if totalDrift > maxClockDriftSeconds { 1350 return MerkleClientError{ 1351 fmt.Sprintf("Too much clock drift detected (%ds) in skip sequence", totalDrift), 1352 merkleErrorTooMuchClockDrift, 1353 } 1354 1355 } 1356 1357 return nil 1358 } 1359 1360 func (mc *MerkleClient) verifyRootHelper(m MetaContext, newRoot *MerkleRoot, currentRoot *MerkleRoot, opts MerkleOpts) (err error) { 1361 defer m.VTrace(VLog1, fmt.Sprintf("merkleClient#verifyRootHelper(root=%d, cached=%v, opts=%+v)", int(*newRoot.Seqno()), currentRoot.Seqno() == nil, opts), &err)() 1362 1363 // First make sure it's not a rollback. If we're doing an historical lookup, it's 1364 // actual OK. 1365 if !opts.historical && currentRoot != nil && *currentRoot.Seqno() > *newRoot.Seqno() { 1366 return fmt.Errorf("Server rolled back Merkle tree: %d > %d", *currentRoot.Seqno(), *newRoot.Seqno()) 1367 } 1368 1369 if currentRoot != nil && currentRoot.ShortHash() == newRoot.ShortHash() { 1370 // the new root is the same as the old one, no need to check it again 1371 return nil 1372 } 1373 1374 kid, sig, err := mc.findValidKIDAndSig(newRoot) 1375 if err != nil { 1376 return err 1377 } 1378 m.VLogf(VLog1, "+ Merkle: using KID=%s for verifying server sig", kid) 1379 1380 key, err := mc.keyring.Load(m, kid) 1381 if err != nil { 1382 return err 1383 } 1384 1385 if key == nil { 1386 return MerkleClientError{"no known verifying key", merkleErrorNoKnownKey} 1387 } 1388 1389 // Actually run the PGP verification over the signature 1390 _, err = key.VerifyString(mc.G().Log, sig, []byte(newRoot.payload.packed)) 1391 if err != nil { 1392 return err 1393 } 1394 1395 skips := newRoot.payload.unpacked.Body.Skips 1396 if err := verifyRootSkips(*newRoot.Seqno(), skips); err != nil { 1397 return err 1398 } 1399 1400 m.VLogf(VLog1, "- Merkle: server sig verified") 1401 1402 return nil 1403 } 1404 1405 func verifyRootSkips(rootSeqno keybase1.Seqno, skips SkipTable) error { 1406 expectedSkips := computeExpectedRootSkips(uint(rootSeqno)) 1407 if len(expectedSkips) != len(skips) { 1408 return MerkleClientError{fmt.Sprintf("Root check: wrong number of skips: expected %d, got %d.", len(expectedSkips), len(skips)), merkleErrorWrongRootSkips} 1409 } 1410 for _, expectedSkip := range expectedSkips { 1411 seqno := keybase1.Seqno(expectedSkip) 1412 _, ok := skips[seqno] 1413 if !ok { 1414 return MerkleClientError{fmt.Sprintf("Root check: unexpected skip index: wanted %d, but did not exist.", seqno), merkleErrorWrongRootSkips} 1415 } 1416 } 1417 return nil 1418 } 1419 1420 func computeExpectedRootSkips(start uint) []uint { 1421 if start <= 1 { 1422 return nil 1423 } 1424 high := int(math.Ceil(math.Log2(float64(start)))) 1425 ret := make([]uint, high) 1426 for i, skip := 0, uint(1); i < high; i, skip = i+1, skip*2 { 1427 ret[i] = start - skip 1428 } 1429 return ret 1430 } 1431 1432 func parseTriple(jw *jsonw.Wrapper) (*MerkleTriple, error) { 1433 if jw.IsNil() { 1434 return nil, nil 1435 } 1436 1437 l, err := jw.Len() 1438 if err != nil { 1439 return nil, err 1440 } 1441 if l == 0 { 1442 return nil, nil 1443 } 1444 if l == 1 { 1445 return nil, fmt.Errorf("Bad merkle 'triple', with < 2 values") 1446 } 1447 if l > 3 { 1448 return nil, fmt.Errorf("Bad merkle triple, with > 3 values") 1449 } 1450 seqno, err := jw.AtIndex(0).GetInt64() 1451 if err != nil { 1452 return nil, err 1453 } 1454 li, err := GetLinkID(jw.AtIndex(1)) 1455 if err != nil { 1456 return nil, err 1457 } 1458 1459 var si keybase1.SigIDBase 1460 if l == 3 { 1461 si, err = GetSigIDBase(jw.AtIndex(2)) 1462 if err != nil { 1463 return nil, err 1464 } 1465 } 1466 1467 return &MerkleTriple{keybase1.Seqno(seqno), li, si}, nil 1468 1469 } 1470 1471 func parseV1(jw *jsonw.Wrapper) (user *MerkleUserLeaf, err error) { 1472 var t *MerkleTriple 1473 if t, err = parseTriple(jw); err == nil { 1474 user = &MerkleUserLeaf{ 1475 public: t, 1476 private: nil, 1477 } 1478 } 1479 return 1480 } 1481 func parseV2(jw *jsonw.Wrapper) (*MerkleUserLeaf, error) { 1482 user := MerkleUserLeaf{} 1483 1484 l, err := jw.Len() 1485 if err != nil { 1486 return nil, err 1487 } 1488 if l < 2 { 1489 return nil, fmt.Errorf("No public chain.") 1490 } 1491 1492 user.public, err = parseTriple(jw.AtIndex(1)) 1493 if err != nil { 1494 return nil, err 1495 } 1496 1497 if l >= 3 { 1498 user.private, err = parseTriple(jw.AtIndex(2)) 1499 if err != nil { 1500 return nil, err 1501 } 1502 } 1503 1504 if l >= 4 && !jw.AtIndex(3).IsNil() { 1505 eldest, err := GetKID(jw.AtIndex(3)) 1506 if err != nil { 1507 return nil, err 1508 } 1509 user.eldest = eldest 1510 } 1511 1512 if l >= 5 { 1513 user.resets, err = parseV2LeafResetChainTail(jw.AtIndex(4)) 1514 if err != nil { 1515 return nil, err 1516 } 1517 } 1518 1519 return &user, nil 1520 } 1521 1522 func parseMerkleUserLeaf(m MetaContext, jw *jsonw.Wrapper, g *GlobalContext) (user *MerkleUserLeaf, err error) { 1523 m.VLogf(VLog1, "+ ParsingMerkleUserLeaf") 1524 1525 if jw == nil { 1526 m.VLogf(VLog0, "| empty leaf found; user wasn't in tree") 1527 user = &MerkleUserLeaf{} 1528 return 1529 } 1530 1531 l, err := jw.Len() 1532 if err != nil { 1533 return 1534 } 1535 if l < 2 { 1536 err = fmt.Errorf("Expected an array of length 2 or more") 1537 return 1538 } 1539 1540 v, err := jw.AtIndex(0).GetInt() 1541 1542 if err != nil { 1543 return 1544 } 1545 1546 // We messed up and didn't version the initial leafs of the tree 1547 if _, e2 := jw.AtIndex(1).GetString(); e2 == nil { 1548 v = 1 1549 } 1550 1551 switch v { 1552 case 1: 1553 user, err = parseV1(jw) 1554 case 2: 1555 user, err = parseV2(jw) 1556 default: 1557 err = fmt.Errorf("Unexpected version: %d", v) 1558 } 1559 1560 m.VLogf(VLog1, "- ParsingMerkleUserLeaf -> %v", ErrToOk(err)) 1561 return 1562 } 1563 1564 func parseMerkleTeamLeaf(m MetaContext, jw *jsonw.Wrapper, g *GlobalContext) (leaf *MerkleTeamLeaf, err error) { 1565 m.VLogf(VLog1, "+ ParsingMerkleTeamLeaf") 1566 1567 if jw == nil { 1568 m.VLogf(VLog0, "| empty leaf found; team wasn't in tree") 1569 leaf = &MerkleTeamLeaf{} 1570 return 1571 } 1572 1573 l, err := jw.Len() 1574 if err != nil { 1575 return 1576 } 1577 // length should be 4, but only use the first 3, and allow larger for forward compatibility. 1578 if l < 3 { 1579 err = fmt.Errorf("Expected an array of length >=3 but got %v", l) 1580 return 1581 } 1582 1583 v, err := jw.AtIndex(0).GetInt() 1584 if err != nil { 1585 return 1586 } 1587 if v != 2 { 1588 err = fmt.Errorf("Expected version 2 but got %v", v) 1589 return 1590 } 1591 1592 public, err := parseTriple(jw.AtIndex(1)) 1593 if err != nil { 1594 return 1595 } 1596 1597 private, err := parseTriple(jw.AtIndex(2)) 1598 if err != nil { 1599 return 1600 } 1601 1602 m.VLogf(VLog1, "- ParsingMerkleTeamLeaf -> %v", ErrToOk(err)) 1603 return &MerkleTeamLeaf{ 1604 // TeamID is filled in by the caller 1605 Public: public, 1606 Private: private, 1607 }, err 1608 } 1609 1610 func (vp *VerificationPath) verifyUsername(m MetaContext, userInfo merkleUserInfoT) (username string, err error) { 1611 if CheckUIDAgainstUsername(userInfo.uid, userInfo.username) == nil { 1612 m.VLogf(VLog1, "| Username %s mapped to %s via direct hash", userInfo.username, userInfo.uid) 1613 username = userInfo.username 1614 return 1615 } 1616 1617 m.VLogf(VLog1, "| Failed to map Username %s -> UID %s via direct hash", userInfo.username, userInfo.uid) 1618 1619 if userInfo.usernameCased != userInfo.username && strings.ToLower(userInfo.usernameCased) == userInfo.username { 1620 m.VLogf(VLog1, "| Checking cased username difference: %s v %s", userInfo.username, userInfo.usernameCased) 1621 if checkUIDAgainstCasedUsername(userInfo.uid, userInfo.usernameCased) == nil { 1622 m.VLogf(VLog1, "| Username %s mapped to %s via direct hash (w/ username casing)", userInfo.usernameCased, userInfo.uid) 1623 username = userInfo.username 1624 return 1625 } 1626 } 1627 1628 hsh := sha256.Sum256([]byte(strings.ToLower(userInfo.username))) 1629 hshS := hex.EncodeToString(hsh[:]) 1630 var leaf *jsonw.Wrapper 1631 1632 if vp.root.LegacyUIDRootHash() == nil { 1633 err = MerkleClientError{"no legacy UID root hash found in root", merkleErrorNoLegacyUIDRoot} 1634 return 1635 } 1636 1637 if leaf, err = userInfo.uidPath.VerifyPath(vp.root.LegacyUIDRootHash(), hshS); err != nil { 1638 return 1639 } 1640 1641 var uid2 keybase1.UID 1642 if uid2, err = GetUID(leaf); err != nil { 1643 return 1644 } 1645 if userInfo.uid.NotEqual(uid2) { 1646 err = UIDMismatchError{fmt.Sprintf("UID %s != %s via merkle tree", uid2, userInfo.uid)} 1647 return 1648 } 1649 1650 m.VLogf(VLog1, "| Username %s mapped to %s via Merkle lookup", userInfo.username, userInfo.uid) 1651 username = userInfo.username 1652 1653 return 1654 } 1655 1656 func (vp *VerificationPath) verifyUser(m MetaContext, uid keybase1.UID) (user *MerkleUserLeaf, err error) { 1657 curr := vp.root.RootHash() 1658 1659 var leaf *jsonw.Wrapper 1660 leaf, err = vp.path.VerifyPath(curr, uid.String()) 1661 1662 if leaf != nil && err == nil { 1663 if leaf, err = leaf.ToArray(); err != nil { 1664 msg := fmt.Sprintf("Didn't find a leaf for user in tree: %s", err) 1665 err = MerklePathNotFoundError{uid.String(), msg} 1666 } 1667 } 1668 1669 if err == nil { 1670 // noop 1671 } else if _, ok := err.(MerklePathNotFoundError); ok { 1672 m.VLogf(VLog0, fmt.Sprintf("In checking Merkle tree: %s", err)) 1673 } else { 1674 return 1675 } 1676 1677 user, err = parseMerkleUserLeaf(m, leaf, vp.G()) 1678 if user != nil { 1679 user.uid = uid 1680 } 1681 return 1682 } 1683 1684 func (vp *VerificationPath) verifyTeam(m MetaContext, teamID keybase1.TeamID) (teamLeaf *MerkleTeamLeaf, err error) { 1685 curr := vp.root.RootHash() 1686 1687 var leaf *jsonw.Wrapper 1688 leaf, err = vp.path.VerifyPath(curr, teamID.String()) 1689 1690 if leaf != nil && err == nil { 1691 if leaf, err = leaf.ToArray(); err != nil { 1692 msg := fmt.Sprintf("Didn't find a leaf for team in tree: %s", err) 1693 err = MerklePathNotFoundError{teamID.String(), msg} 1694 } 1695 } 1696 1697 if err == nil { 1698 // noop 1699 } else if _, ok := err.(MerklePathNotFoundError); ok { 1700 m.VLogf(VLog0, fmt.Sprintf("In checking Merkle tree: %s", err)) 1701 } else { 1702 return 1703 } 1704 1705 teamLeaf, err = parseMerkleTeamLeaf(m, leaf, vp.G()) 1706 if teamLeaf != nil { 1707 teamLeaf.TeamID = teamID 1708 } 1709 return 1710 } 1711 1712 func (path PathSteps) VerifyPath(curr NodeHash, uidS string) (juser *jsonw.Wrapper, err error) { 1713 1714 bpath := uidS 1715 lastTyp := 0 1716 1717 for i, step := range path { 1718 payload := step.node 1719 if !curr.Check(payload) { 1720 err = fmt.Errorf("Hash mismatch at level=%d", i) 1721 break 1722 } 1723 1724 var jw *jsonw.Wrapper 1725 jw, err = jsonw.Unmarshal([]byte(payload)) 1726 if err != nil { 1727 err = fmt.Errorf("Can't parse JSON at level=%d: %s", i, err) 1728 break 1729 } 1730 1731 plen := len(step.prefix) 1732 if plen > len(bpath) { 1733 err = fmt.Errorf("Path prefix longer than identifier: %v > %v", plen, len(bpath)) 1734 return nil, err 1735 } 1736 if plen > 0 && bpath[:plen] != step.prefix { 1737 err = fmt.Errorf("Path mismatch at level %d: %s != %s", i, bpath[:plen], step.prefix) 1738 break 1739 } 1740 1741 lastTyp, err = jw.AtKey("type").GetInt() 1742 if err != nil { 1743 err = fmt.Errorf("At level %d, failed to get a valid 'type'", i) 1744 break 1745 } 1746 1747 if lastTyp == MerkleTreeNode { 1748 if plen == 0 { 1749 err = fmt.Errorf("Empty prefix len at level=%d", i) 1750 return 1751 } 1752 curr, err = GetNodeHash(jw.AtKey("tab").AtKey(step.prefix)) 1753 if err != nil { 1754 err = MerklePathNotFoundError{uidS, err.Error()} 1755 break 1756 } 1757 juser = nil 1758 } else { 1759 juser = jw.AtKey("tab").AtKey(uidS) 1760 } 1761 } 1762 1763 if err == nil && juser == nil { 1764 err = MerklePathNotFoundError{uidS, "tree path didn't end in a leaf"} 1765 } 1766 return 1767 } 1768 1769 func (mc *MerkleClient) verifySkipSequenceAndRoot(m MetaContext, ss SkipSequence, curr *MerkleRoot, prev *MerkleRoot, apiRes *APIRes, opts MerkleOpts) (err error) { 1770 1771 defer func() { 1772 if err != nil { 1773 m.VLogf(VLog0, "| Full APIRes was: %s", apiRes.Body.MarshalToDebug()) 1774 } 1775 }() 1776 1777 // It's important to check the merkle skip sequence before verifying the root. 1778 if err = mc.verifySkipSequence(m, ss, curr, prev, opts); err != nil { 1779 return err 1780 } 1781 if opts.noSigCheck { 1782 m.VLogf(VLog0, "| noSigCheck wanted, so skipping out") 1783 return nil 1784 } 1785 return mc.verifyRootHelper(m, curr, prev, opts) 1786 } 1787 1788 func (mc *MerkleClient) LookupUser(m MetaContext, q HTTPArgs, sigHints *SigHints, opts MerkleOpts) (u *MerkleUserLeaf, err error) { 1789 1790 m.VLogf(VLog0, "+ MerkleClient.LookupUser(%v)", q) 1791 1792 if err = mc.init(m); err != nil { 1793 return nil, err 1794 } 1795 1796 root, err := mc.FetchRootFromServer(m, DefaultMerkleRootFreshness) 1797 if err != nil { 1798 return nil, err 1799 } 1800 1801 path, userInfo, _, err := mc.lookupLeafAndPathUser(m, q, sigHints, root, opts) 1802 if err != nil { 1803 return nil, err 1804 } 1805 // spot check that the user-specific path attributes were filled 1806 if userInfo.uid.IsNil() { 1807 return nil, fmt.Errorf("verification path has nil UID") 1808 } 1809 1810 if u, err = path.verifyUser(m, userInfo.uid); err != nil { 1811 return nil, err 1812 } 1813 1814 if u.username, err = path.verifyUsername(m, *userInfo); err != nil { 1815 return nil, err 1816 } 1817 1818 if err = u.resets.verifyAndLoad(m, userInfo.unverifiedResetChain); err != nil { 1819 return nil, err 1820 } 1821 1822 u.idVersion = userInfo.idVersion 1823 1824 m.VLogf(VLog0, "- MerkleClient.LookupUser(%v) -> OK", q) 1825 return u, nil 1826 } 1827 1828 func (vp *VerificationPath) verifyUserOrTeam(m MetaContext, id keybase1.UserOrTeamID) (leaf *MerkleGenericLeaf, err error) { 1829 1830 if id.IsUser() { 1831 user, err := vp.verifyUser(m, id.AsUserOrBust()) 1832 if err != nil { 1833 return nil, err 1834 } 1835 return user.MerkleGenericLeaf(), nil 1836 } 1837 1838 if id.IsTeamOrSubteam() { 1839 team, err := vp.verifyTeam(m, id.AsTeamOrBust()) 1840 if err != nil { 1841 return nil, err 1842 } 1843 return team.MerkleGenericLeaf(), nil 1844 } 1845 1846 return nil, errors.New("id was neither a user or a team") 1847 } 1848 1849 func (mc *MerkleClient) LookupLeafAtHashMeta(m MetaContext, leafID keybase1.UserOrTeamID, hm keybase1.HashMeta) (leaf *MerkleGenericLeaf, err error) { 1850 m.VLogf(VLog0, "+ MerkleClient.LookupLeafAtHashMeta(%v)", leafID) 1851 paramer := func(a *HTTPArgs) { 1852 a.Add("start_hash_meta", S{Val: hm.String()}) 1853 } 1854 checker := func(path *VerificationPath) error { 1855 if !path.root.HashMeta().Eq(hm) { 1856 return MerkleClientError{"hash meta failed to match", merkleErrorHashMeta} 1857 } 1858 return nil 1859 } 1860 leaf, _, _, err = mc.lookupLeafHistorical(m, leafID, paramer, checker, MerkleOpts{}, nil) 1861 return leaf, err 1862 } 1863 1864 func (mc *MerkleClient) checkHistoricalSeqno(s keybase1.Seqno) error { 1865 if mc.G().Env.GetRunMode() == ProductionRunMode && s < FirstProdMerkleSeqnoWithSigs { 1866 return MerkleClientError{fmt.Sprintf("cannot load seqno=%d; must load at %d or higher", s, FirstProdMerkleSeqnoWithSigs), merkleErrorAncientSeqno} 1867 } 1868 return nil 1869 } 1870 1871 type MerkleOpts struct { 1872 // All used internally 1873 noSigCheck bool 1874 historical bool 1875 isUser bool 1876 1877 // Used externally 1878 NoServerPolling bool 1879 } 1880 1881 func (mc *MerkleClient) LookupLeafAtSeqno(m MetaContext, leafID keybase1.UserOrTeamID, s keybase1.Seqno) (leaf *MerkleGenericLeaf, root *MerkleRoot, err error) { 1882 leaf, root, _, err = mc.lookupLeafAtSeqno(m, leafID, s, MerkleOpts{}, nil /* processHiddenResponseFunc */) 1883 return leaf, root, err 1884 } 1885 1886 func (mc *MerkleClient) LookupLeafAtSeqnoForAudit(m MetaContext, leafID keybase1.UserOrTeamID, s keybase1.Seqno, processHiddenResponseFunc ProcessHiddenRespFunc) (leaf *MerkleGenericLeaf, root *MerkleRoot, hiddenResp *MerkleHiddenResponse, err error) { 1887 return mc.lookupLeafAtSeqno(m, leafID, s, MerkleOpts{noSigCheck: true}, processHiddenResponseFunc) 1888 } 1889 1890 func (mc *MerkleClient) lookupLeafAtSeqno(m MetaContext, leafID keybase1.UserOrTeamID, s keybase1.Seqno, opts MerkleOpts, processHiddenResponseFunc ProcessHiddenRespFunc) (leaf *MerkleGenericLeaf, root *MerkleRoot, hiddenResp *MerkleHiddenResponse, err error) { 1891 m.VLogf(VLog0, "+ MerkleClient.lookupLeafAtSeqno(%v,%v,%v)", leafID, s, opts) 1892 if err = mc.checkHistoricalSeqno(s); err != nil { 1893 return nil, nil, nil, err 1894 } 1895 paramer := func(a *HTTPArgs) { 1896 a.Add("start_seqno", I{Val: int(s)}) 1897 if opts.noSigCheck { 1898 a.Add("no_root_sigs", B{Val: true}) 1899 } 1900 } 1901 // Since we are looking up a leaf at a specific seqno, ensure we have root 1902 // at least as recent as that seqno. 1903 _, err = mc.FetchRootFromServerByMinSeqno(m, s) 1904 if err != nil { 1905 return nil, nil, nil, err 1906 } 1907 1908 checker := func(path *VerificationPath) error { 1909 if path.root.Seqno() == nil { 1910 return MerkleClientError{"no such seqno was found", merkleErrorNotFound} 1911 } 1912 if *path.root.Seqno() != s { 1913 return MerkleClientError{"seqno mismatch", merkleErrorBadSeqno} 1914 } 1915 return nil 1916 } 1917 return mc.lookupLeafHistorical(m, leafID, paramer, checker, opts, processHiddenResponseFunc) 1918 } 1919 1920 func (mc *MerkleClient) LookupRootAtSeqno(m MetaContext, s keybase1.Seqno) (root *MerkleRoot, err error) { 1921 defer m.VTrace(VLog0, fmt.Sprintf("LookupRootAtSeqno(%d)", s), &err)() 1922 _, root, err = mc.LookupLeafAtSeqno(m, keybase1.UserOrTeamID(""), s) 1923 return root, err 1924 } 1925 1926 func (mc *MerkleClient) lookupLeafHistorical(m MetaContext, leafID keybase1.UserOrTeamID, paramer func(*HTTPArgs), checker func(*VerificationPath) error, opts MerkleOpts, processHiddenResponseFunc ProcessHiddenRespFunc) (leaf *MerkleGenericLeaf, root *MerkleRoot, hiddenResp *MerkleHiddenResponse, err error) { 1927 opts.historical = true 1928 1929 var path *VerificationPath 1930 var apiRes *APIRes 1931 1932 if err = mc.init(m); err != nil { 1933 return nil, nil, nil, err 1934 } 1935 1936 // The most current root we got. This might be slightly out of date, but all 1937 // we really care is that it points back to another historical root, which 1938 // should be before currentRoot. If it's not, we'll refresh currentRoot in 1939 // the process. 1940 currentRoot := mc.LastRoot(m) 1941 1942 q := NewHTTPArgs() 1943 if leafID.IsNil() { 1944 q.Add("no_leaf", B{Val: true}) 1945 } else { 1946 q.Add("leaf_id", S{Val: leafID.String()}) 1947 } 1948 paramer(&q) 1949 1950 if apiRes, currentRoot, err = mc.lookupLeafAndPathHelper(m, q, nil, currentRoot, opts); err != nil { 1951 return nil, nil, nil, err 1952 } 1953 1954 path, err = mc.readPathFromAPIRes(m, apiRes, opts) 1955 if err != nil { 1956 return nil, nil, nil, err 1957 } 1958 resSeqno, err := apiRes.Body.AtKey("root").AtKey("seqno").GetInt64() 1959 if err != nil { 1960 return nil, nil, nil, err 1961 } 1962 if keybase1.Seqno(resSeqno) == *currentRoot.Seqno() { 1963 path.root = currentRoot 1964 } else { 1965 path.root, err = mc.readAndCheckRootFromAPIRes(m, apiRes, currentRoot, opts) 1966 if err != nil { 1967 return nil, nil, nil, err 1968 } 1969 } 1970 1971 if err = checker(path); err != nil { 1972 return nil, nil, nil, err 1973 } 1974 1975 if !leafID.IsNil() { 1976 leaf, err = path.verifyUserOrTeam(m, leafID) 1977 if err != nil { 1978 return nil, nil, nil, err 1979 } 1980 1981 if processHiddenResponseFunc != nil { 1982 hiddenResp, err = processHiddenResponseFunc(m, leafID.AsTeamOrBust(), apiRes, path.root.BlindMerkleRootHash()) 1983 if err != nil { 1984 return nil, nil, nil, err 1985 } 1986 } 1987 } 1988 1989 return leaf, path.root, hiddenResp, nil 1990 } 1991 1992 func (mc *MerkleClient) LookupTeamWithHidden(m MetaContext, teamID keybase1.TeamID, processHiddenRespFunc ProcessHiddenRespFunc) (leaf *MerkleTeamLeaf, hiddenResp *MerkleHiddenResponse, lastMerkleRoot *MerkleRoot, err error) { 1993 // Copied from LookupUser. These methods should be kept relatively in sync. 1994 return mc.lookupTeam(m, teamID, processHiddenRespFunc) 1995 } 1996 1997 func (mc *MerkleClient) LookupTeam(m MetaContext, teamID keybase1.TeamID) (leaf *MerkleTeamLeaf, err error) { 1998 // Copied from LookupUser. These methods should be kept relatively in sync. 1999 leaf, _, _, err = mc.lookupTeam(m, teamID, nil) 2000 return leaf, err 2001 } 2002 2003 type MerkleHiddenResponseType uint8 2004 2005 const ( 2006 // the server did not include any hidden chain data 2007 MerkleHiddenResponseTypeNONE MerkleHiddenResponseType = 1 2008 // the server provided a proof of absence (or inclusion with an empty leaf) for 2009 // the requested key 2010 MerkleHiddenResponseTypeABSENCEPROOF MerkleHiddenResponseType = 2 2011 // the server provided a valid inclusion proof for the returned leaf in the tree 2012 MerkleHiddenResponseTypeOK MerkleHiddenResponseType = 3 2013 2014 // All hidden checks should be skipped as the feature flag is off 2015 MerkleHiddenResponseTypeFLAGOFF MerkleHiddenResponseType = 127 2016 ) 2017 2018 type MerkleHiddenResponse struct { 2019 RespType MerkleHiddenResponseType `json:"resp_type"` 2020 CommittedHiddenTail *sig3.Tail `json:"committed_hidden_tail"` 2021 UncommittedSeqno keybase1.Seqno `json:"uncommitted_seqno"` 2022 } 2023 2024 func (m *MerkleHiddenResponse) GetUncommittedSeqno() keybase1.Seqno { 2025 if m == nil { 2026 return 0 2027 } 2028 return m.UncommittedSeqno 2029 } 2030 2031 func (m *MerkleHiddenResponse) GetCommittedSeqno() keybase1.Seqno { 2032 if m == nil || m.RespType != MerkleHiddenResponseTypeOK { 2033 return 0 2034 } 2035 return m.CommittedHiddenTail.Seqno 2036 } 2037 2038 type ProcessHiddenRespFunc func(m MetaContext, teamID keybase1.TeamID, apiRes *APIRes, blindRootHash string) (*MerkleHiddenResponse, error) 2039 2040 func (mc *MerkleClient) lookupTeam(m MetaContext, teamID keybase1.TeamID, processHiddenResponseFunc ProcessHiddenRespFunc) (leaf *MerkleTeamLeaf, hiddenResp *MerkleHiddenResponse, lastMerkleRoot *MerkleRoot, err error) { 2041 2042 m.VLogf(VLog0, "+ MerkleClient.LookupTeam(%v)", teamID) 2043 2044 var path *VerificationPath 2045 var apiRes *APIRes 2046 var opts MerkleOpts 2047 2048 if err = mc.init(m); err != nil { 2049 return nil, nil, nil, err 2050 } 2051 2052 root, err := mc.FetchRootFromServer(m, DefaultMerkleRootFreshness) 2053 if err != nil { 2054 return nil, nil, nil, err 2055 } 2056 q := NewHTTPArgs() 2057 q.Add("leaf_id", S{Val: teamID.String()}) 2058 2059 if path, apiRes, err = mc.lookupLeafAndPath(m, q, root, nil, opts); err != nil { 2060 return nil, nil, nil, err 2061 } 2062 2063 if leaf, err = path.verifyTeam(m, teamID); err != nil { 2064 return nil, nil, nil, err 2065 } 2066 2067 if processHiddenResponseFunc != nil { 2068 hiddenResp, err = processHiddenResponseFunc(m, teamID, apiRes, path.root.BlindMerkleRootHash()) 2069 if err != nil { 2070 return nil, nil, nil, err 2071 } 2072 } 2073 2074 m.VLogf(VLog0, "- MerkleClient.LookupTeam(%v) -> OK", teamID) 2075 return leaf, hiddenResp, path.root, err 2076 } 2077 2078 func (mr *MerkleRoot) ToSigJSON() (ret *jsonw.Wrapper) { 2079 2080 ret = jsonw.NewDictionary() 2081 _ = ret.SetKey("seqno", jsonw.NewInt(int(*mr.Seqno()))) 2082 _ = ret.SetKey("ctime", jsonw.NewInt64(mr.Ctime())) 2083 _ = ret.SetKey("hash", jsonw.NewString(mr.RootHash().String())) 2084 _ = ret.SetKey("hash_meta", jsonw.NewString(mr.ShortHash().String())) 2085 2086 return 2087 } 2088 2089 func (mr *MerkleRoot) ToInfo() chat1.MerkleRoot { 2090 return chat1.MerkleRoot{ 2091 Seqno: int64(*mr.Seqno()), 2092 Hash: mr.RootHash().bytes(), 2093 } 2094 } 2095 2096 func (mr *MerkleRoot) ToMerkleRootV2() keybase1.MerkleRootV2 { 2097 return keybase1.MerkleRootV2{ 2098 Seqno: *mr.Seqno(), 2099 HashMeta: mr.HashMeta(), 2100 } 2101 } 2102 2103 func (mc *MerkleClient) LastRootToSigJSON(m MetaContext) (ret *jsonw.Wrapper, err error) { 2104 // Lazy-init, only when needed. 2105 if err = mc.init(m); err == nil { 2106 mc.RLock() 2107 if mc.lastRoot != nil { 2108 ret = mc.lastRoot.ToSigJSON() 2109 } 2110 mc.RUnlock() 2111 } 2112 return 2113 } 2114 2115 func (mul *MerkleUserLeaf) MatchUser(u *User, uid keybase1.UID, nun NormalizedUsername) (err error) { 2116 if mul.username != u.GetName() { 2117 err = MerkleClashError{fmt.Sprintf("vs loaded object: username %s != %s", mul.username, u.GetName())} 2118 } else if mul.uid.NotEqual(u.GetUID()) { 2119 err = MerkleClientError{fmt.Sprintf("vs loaded object: UID %s != %s", mul.uid, u.GetUID()), merkleErrorUIDMismatch} 2120 } else if !nun.IsNil() && !NewNormalizedUsername(mul.username).Eq(nun) { 2121 err = MerkleClashError{fmt.Sprintf("vs given arg: username %s != %s", mul.username, nun)} 2122 } else if uid.NotEqual(mul.uid) { 2123 err = MerkleClashError{fmt.Sprintf("vs given arg: UID %s != %s", uid, mul.uid)} 2124 } 2125 return 2126 } 2127 2128 func (mt MerkleTriple) Less(mt2 MerkleTriple) bool { 2129 return mt.Seqno < mt2.Seqno 2130 } 2131 2132 func GetMerkleTriple(jw *jsonw.Wrapper) (ret *MerkleTriple, err error) { 2133 var tmp MerkleTriple 2134 if err = jw.UnmarshalAgain(&tmp); err != nil { 2135 ret = &tmp 2136 } 2137 return ret, err 2138 } 2139 2140 func (mr MerkleRoot) ShallowCopy() *MerkleRoot { 2141 return &mr 2142 } 2143 2144 func (mr *MerkleRoot) Seqno() *keybase1.Seqno { 2145 if mr == nil { 2146 return nil 2147 } 2148 tmp := mr.payload.seqno() 2149 return &tmp 2150 } 2151 2152 func (mr *MerkleRoot) RootHash() NodeHash { 2153 if mr == nil { 2154 return nil 2155 } 2156 return mr.payload.rootHash() 2157 } 2158 2159 func (mr *MerkleRoot) LegacyUIDRootHash() NodeHash { 2160 if mr == nil { 2161 return nil 2162 } 2163 return mr.payload.legacyUIDRootHash() 2164 } 2165 2166 func (mr *MerkleRoot) PvlHash() string { 2167 if mr == nil { 2168 return "" 2169 } 2170 return mr.payload.pvlHash() 2171 } 2172 2173 func (mr *MerkleRoot) ProofServicesHash() string { 2174 if mr == nil { 2175 return "" 2176 } 2177 return mr.payload.proofServicesHash() 2178 } 2179 2180 func (mr *MerkleRoot) ExternalURLHash() string { 2181 if mr == nil { 2182 return "" 2183 } 2184 return mr.payload.externalURLHash() 2185 } 2186 2187 func (mr *MerkleRoot) BlindMerkleRootHash() string { 2188 if mr == nil { 2189 return "" 2190 } 2191 return mr.payload.blindMerkleRootHash() 2192 } 2193 2194 func (mr *MerkleRoot) SkipToSeqno(s keybase1.Seqno) NodeHash { 2195 if mr == nil { 2196 return nil 2197 } 2198 return mr.payload.skipToSeqno(s) 2199 } 2200 2201 func (mr *MerkleRoot) Ctime() int64 { 2202 if mr == nil { 2203 return 0 2204 } 2205 return mr.payload.ctime() 2206 } 2207 2208 func (mr *MerkleRoot) Fetched() time.Time { 2209 if mr == nil { 2210 return time.Time{} 2211 } 2212 return mr.fetched 2213 } 2214 2215 func (mr *MerkleRoot) KBFSPrivate() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2216 if mr == nil { 2217 return nil, nil 2218 } 2219 return mr.payload.kbfsPrivate() 2220 } 2221 2222 func (mr *MerkleRoot) KBFSPublic() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2223 if mr == nil { 2224 return nil, nil 2225 } 2226 return mr.payload.kbfsPublic() 2227 } 2228 2229 func (mr *MerkleRoot) KBFSPrivateTeam() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2230 if mr == nil { 2231 return nil, nil 2232 } 2233 return mr.payload.kbfsPrivateTeam() 2234 } 2235 2236 func (mrp MerkleRootPayload) skipToSeqno(s keybase1.Seqno) NodeHash { 2237 if mrp.unpacked.Body.Skips == nil { 2238 return nil 2239 } 2240 return mrp.unpacked.Body.Skips[s] 2241 } 2242 2243 func (mrp MerkleRootPayload) seqno() keybase1.Seqno { return mrp.unpacked.Body.Seqno } 2244 func (mrp MerkleRootPayload) rootHash() NodeHash { return mrp.unpacked.Body.Root } 2245 func (mrp MerkleRootPayload) legacyUIDRootHash() NodeHash { return mrp.unpacked.Body.LegacyUIDRoot } 2246 func (mrp MerkleRootPayload) pvlHash() string { return mrp.unpacked.Body.PvlHash } 2247 func (mrp MerkleRootPayload) proofServicesHash() string { return mrp.unpacked.Body.ProofServicesHash } 2248 func (mrp MerkleRootPayload) externalURLHash() string { return mrp.unpacked.Body.ExternalURLHash } 2249 func (mrp MerkleRootPayload) blindMerkleRootHash() string { 2250 return mrp.unpacked.Body.BlindMerkleRootHash 2251 } 2252 func (mrp MerkleRootPayload) ctime() int64 { return mrp.unpacked.Ctime } 2253 func (mrp MerkleRootPayload) kbfsPrivate() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2254 return mrp.unpacked.Body.Kbfs.Private.Root, mrp.unpacked.Body.Kbfs.Private.Version 2255 } 2256 func (mrp MerkleRootPayload) kbfsPublic() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2257 return mrp.unpacked.Body.Kbfs.Public.Root, mrp.unpacked.Body.Kbfs.Public.Version 2258 } 2259 func (mrp MerkleRootPayload) kbfsPrivateTeam() (keybase1.KBFSRootHash, *keybase1.Seqno) { 2260 return mrp.unpacked.Body.Kbfs.PrivateTeam.Root, mrp.unpacked.Body.Kbfs.PrivateTeam.Version 2261 } 2262 2263 func (mc *MerkleClient) CanExamineHistoricalRoot(m MetaContext, q keybase1.Seqno) bool { 2264 chk := mc.FirstExaminableHistoricalRoot(m) 2265 if chk == nil { 2266 return true 2267 } 2268 return q >= *chk 2269 }