github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/root_metadata.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "fmt" 9 "reflect" 10 "strings" 11 "time" 12 13 "github.com/keybase/client/go/kbfs/data" 14 "github.com/keybase/client/go/kbfs/idutil" 15 "github.com/keybase/client/go/kbfs/kbfscodec" 16 "github.com/keybase/client/go/kbfs/kbfscrypto" 17 "github.com/keybase/client/go/kbfs/kbfsmd" 18 "github.com/keybase/client/go/kbfs/libkey" 19 "github.com/keybase/client/go/kbfs/tlf" 20 "github.com/keybase/client/go/kbfs/tlfhandle" 21 "github.com/keybase/client/go/libkb" 22 "github.com/keybase/client/go/logger" 23 "github.com/keybase/client/go/protocol/keybase1" 24 "github.com/keybase/go-codec/codec" 25 "github.com/pkg/errors" 26 "golang.org/x/net/context" 27 ) 28 29 // PrivateMetadata contains the portion of metadata that's secret for private 30 // directories 31 type PrivateMetadata struct { 32 // directory entry for the root directory block 33 Dir data.DirEntry 34 35 // m_f as described in ยง 4.1.1 of https://keybase.io/docs/crypto/kbfs. 36 TLFPrivateKey kbfscrypto.TLFPrivateKey 37 // The block changes done as part of the update that created this MD 38 Changes BlockChanges 39 40 // The last revision up to and including which garbage collection 41 // was performed on this TLF. 42 LastGCRevision kbfsmd.Revision `codec:"lgc"` 43 44 codec.UnknownFieldSetHandler 45 46 // When the above Changes field gets unembedded into its own 47 // block, we may want to temporarily keep around the old 48 // BlockChanges for easy reference. 49 cachedChanges BlockChanges 50 } 51 52 type verboseOp struct { 53 op 54 indent string 55 } 56 57 func (o verboseOp) String() string { 58 return o.op.StringWithRefs(o.indent) 59 } 60 61 // DumpPrivateMetadata returns a detailed dump of the given 62 // PrivateMetadata's contents. 63 func DumpPrivateMetadata( 64 codec kbfscodec.Codec, serializedPMDLength int, pmd PrivateMetadata) (string, error) { 65 s := fmt.Sprintf("Size: %d bytes\n", serializedPMDLength) 66 67 eq, err := kbfscodec.Equal(codec, pmd, PrivateMetadata{}) 68 if err != nil { 69 return "", err 70 } 71 72 if eq { 73 s += "<Undecryptable>\n" 74 } else { 75 c := kbfsmd.DumpConfig() 76 // Hardcode the indent level, which depends on the 77 // position of the Ops list. 78 indent := strings.Repeat(c.Indent, 4) 79 80 var pmdCopy PrivateMetadata 81 err := kbfscodec.Update(codec, &pmdCopy, pmd) 82 if err != nil { 83 return "", err 84 } 85 ops := pmdCopy.Changes.Ops 86 for i, op := range ops { 87 ops[i] = verboseOp{op, indent} 88 } 89 90 s += c.Sdump(pmdCopy) 91 } 92 return s, nil 93 } 94 95 func (p PrivateMetadata) checkValid() error { 96 for i, op := range p.Changes.Ops { 97 err := op.checkValid() 98 if err != nil { 99 return fmt.Errorf("op[%d]=%v invalid: %v", i, op, err) 100 } 101 } 102 return nil 103 } 104 105 // ChangesBlockInfo returns the block info for any unembedded changes. 106 func (p PrivateMetadata) ChangesBlockInfo() data.BlockInfo { 107 return p.cachedChanges.Info 108 } 109 110 // A RootMetadata is a BareRootMetadata but with a deserialized 111 // PrivateMetadata. However, note that it is possible that the 112 // PrivateMetadata has to be left serialized due to not having the 113 // right keys. 114 type RootMetadata struct { 115 bareMd kbfsmd.MutableRootMetadata 116 117 // ExtraMetadata currently contains key bundles for post-v2 118 // metadata. 119 extra kbfsmd.ExtraMetadata 120 121 // The plaintext, deserialized PrivateMetadata 122 // 123 // TODO: This should really be a pointer so that it's more 124 // clear when the data has been successfully deserialized. 125 data PrivateMetadata 126 127 // The TLF handle for this MD. May be nil if this object was 128 // deserialized (more common on the server side). 129 tlfHandle *tlfhandle.Handle 130 } 131 132 var _ libkey.KeyMetadata = (*RootMetadata)(nil) 133 134 // makeRootMetadata makes a RootMetadata object from the given 135 // parameters. 136 func makeRootMetadata(bareMd kbfsmd.MutableRootMetadata, 137 extra kbfsmd.ExtraMetadata, handle *tlfhandle.Handle) *RootMetadata { 138 if bareMd == nil { 139 panic("nil kbfsmd.MutableRootMetadata") 140 } 141 // extra can be nil. 142 if handle == nil { 143 panic("nil handle") 144 } 145 return &RootMetadata{ 146 bareMd: bareMd, 147 extra: extra, 148 tlfHandle: handle, 149 } 150 } 151 152 // makeInitialRootMetadata creates a new RootMetadata with the given 153 // MetadataVer, revision RevisionInitial, and the given TLF ID 154 // and handle. Note that if the given ID/handle are private, rekeying 155 // must be done separately. 156 func makeInitialRootMetadata( 157 ver kbfsmd.MetadataVer, tlfID tlf.ID, h *tlfhandle.Handle) (*RootMetadata, error) { 158 bh, err := h.ToBareHandle() 159 if err != nil { 160 return nil, err 161 } 162 163 bareMD, err := kbfsmd.MakeInitialRootMetadata(ver, tlfID, bh) 164 if err != nil { 165 return nil, err 166 } 167 // Need to keep the TLF handle around long enough to rekey the 168 // metadata for the first time. 169 rmd := makeRootMetadata(bareMD, nil, h) 170 // The initial revision never has any unrefs, so set the 171 // last GC revision to 1 to avoid having to walk backwards 172 // through all the MDs during the first QR for this TLF. 173 rmd.data.LastGCRevision = kbfsmd.RevisionInitial 174 return rmd, nil 175 } 176 177 // Data returns the private metadata of this RootMetadata. 178 func (md *RootMetadata) Data() *PrivateMetadata { 179 return &md.data 180 } 181 182 // GetRootDirEntry implements the KeyMetadataWithRootDirEntry 183 // interface for RootMetadata. 184 func (md *RootMetadata) GetRootDirEntry() data.DirEntry { 185 return md.data.Dir 186 } 187 188 // Extra returns the extra metadata of this RootMetadata. 189 func (md *RootMetadata) Extra() kbfsmd.ExtraMetadata { 190 return md.extra 191 } 192 193 // IsReadable returns true if the private metadata can be read. 194 func (md *RootMetadata) IsReadable() bool { 195 return md.TlfID().Type() == tlf.Public || md.data.Dir.IsInitialized() 196 } 197 198 func (md *RootMetadata) clearLastRevision() { 199 md.ClearBlockChanges() 200 // remove the copied flag (if any.) 201 md.clearWriterMetadataCopiedBit() 202 } 203 204 func (md *RootMetadata) deepCopy(codec kbfscodec.Codec) (*RootMetadata, error) { 205 brmdCopy, err := md.bareMd.DeepCopy(codec) 206 if err != nil { 207 return nil, err 208 } 209 210 var extraCopy kbfsmd.ExtraMetadata 211 if md.extra != nil { 212 extraCopy, err = md.extra.DeepCopy(codec) 213 if err != nil { 214 return nil, err 215 } 216 } 217 218 handleCopy := md.tlfHandle.DeepCopy() 219 220 rmd := makeRootMetadata(brmdCopy, extraCopy, handleCopy) 221 222 err = kbfscodec.Update(codec, &rmd.data, md.data) 223 if err != nil { 224 return nil, err 225 } 226 err = kbfscodec.Update( 227 codec, &rmd.data.cachedChanges, md.data.cachedChanges) 228 if err != nil { 229 return nil, err 230 } 231 232 // Preserve all the final op paths in the copy. 233 for i, op := range md.data.Changes.Ops { 234 rmd.data.Changes.Ops[i].setFinalPath(op.getFinalPath()) 235 } 236 237 return rmd, nil 238 } 239 240 // MakeSuccessor returns a complete copy of this RootMetadata (but 241 // with cleared block change lists and cleared serialized metadata), 242 // with the revision incremented and a correct backpointer. 243 func (md *RootMetadata) MakeSuccessor( 244 ctx context.Context, latestMDVer kbfsmd.MetadataVer, codec kbfscodec.Codec, 245 keyManager KeyManager, merkleGetter idutil.MerkleRootGetter, 246 teamKeyer teamKeysGetter, osg idutil.OfflineStatusGetter, mdID kbfsmd.ID, 247 isWriter bool) (*RootMetadata, error) { 248 if mdID == (kbfsmd.ID{}) { 249 return nil, errors.New("Empty MdID in MakeSuccessor") 250 } 251 if md.IsFinal() { 252 return nil, kbfsmd.MetadataIsFinalError{} 253 } 254 255 isReadableAndWriter := md.IsReadable() && isWriter 256 257 brmdCopy, extraCopy, err := md.bareMd.MakeSuccessorCopy( 258 codec, md.extra, latestMDVer, 259 func() ([]kbfscrypto.TLFCryptKey, error) { 260 return keyManager.GetTLFCryptKeyOfAllGenerations(ctx, md) 261 }, isReadableAndWriter) 262 if err != nil { 263 return nil, err 264 } 265 266 handleCopy := md.tlfHandle.DeepCopy() 267 268 newMd := makeRootMetadata(brmdCopy, extraCopy, handleCopy) 269 if err := kbfscodec.Update(codec, &newMd.data, md.data); err != nil { 270 return nil, err 271 } 272 273 if isReadableAndWriter { 274 newMd.clearLastRevision() 275 // clear the serialized data. 276 newMd.SetSerializedPrivateMetadata(nil) 277 if newMd.TypeForKeying() == tlf.TeamKeying { 278 tid, err := handleCopy.FirstResolvedWriter().AsTeam() 279 if err != nil { 280 return nil, err 281 } 282 283 offline := keybase1.OfflineAvailability_NONE 284 if osg != nil { 285 offline = osg.OfflineAvailabilityForID(md.TlfID()) 286 } 287 288 _, keyGen, err := teamKeyer.GetTeamTLFCryptKeys( 289 ctx, tid, kbfsmd.UnspecifiedKeyGen, offline) 290 if err != nil { 291 return nil, err 292 } 293 newMd.bareMd.SetLatestKeyGenerationForTeamTLF(keyGen) 294 } 295 } else { 296 // if we can't read it it means we're simply setting the rekey bit 297 // and copying the previous data. 298 newMd.SetRekeyBit() 299 newMd.SetWriterMetadataCopiedBit() 300 } 301 302 newMd.SetPrevRoot(mdID) 303 // bump revision 304 if md.Revision() < kbfsmd.RevisionInitial { 305 return nil, errors.New("MD with invalid revision") 306 } 307 newMd.SetRevision(md.Revision() + 1) 308 return newMd, nil 309 } 310 311 // MakeSuccessorWithNewHandle does the same thing as MakeSuccessor, 312 // plus it changes the handle. (The caller is responsible for 313 // ensuring that the handle change is valid.) 314 func (md *RootMetadata) MakeSuccessorWithNewHandle( 315 ctx context.Context, newHandle *tlfhandle.Handle, latestMDVer kbfsmd.MetadataVer, 316 codec kbfscodec.Codec, keyManager KeyManager, 317 merkleGetter idutil.MerkleRootGetter, teamKeyer teamKeysGetter, 318 osg idutil.OfflineStatusGetter, mdID kbfsmd.ID, isWriter bool) ( 319 *RootMetadata, error) { 320 mdCopy, err := md.deepCopy(codec) 321 if err != nil { 322 return nil, err 323 } 324 325 mdCopy.extra = nil 326 mdCopy.tlfHandle = newHandle.DeepCopy() 327 mdCopy.SetWriters(newHandle.ResolvedWriters()) 328 // Readers are not tracked explicitly in the MD, but their key 329 // bundles are cleared out with the `ClearForV4Migration()` call 330 // below. 331 mdCopy.SetUnresolvedWriters(newHandle.UnresolvedWriters()) 332 mdCopy.SetUnresolvedReaders(newHandle.UnresolvedReaders()) 333 mdCopy.bareMd.ClearForV4Migration() 334 335 return mdCopy.MakeSuccessor( 336 ctx, latestMDVer, codec, keyManager, merkleGetter, teamKeyer, osg, 337 mdID, isWriter) 338 } 339 340 // GetTlfHandle returns the TlfHandle for this RootMetadata. 341 func (md *RootMetadata) GetTlfHandle() *tlfhandle.Handle { 342 if md.tlfHandle == nil { 343 panic(fmt.Sprintf("RootMetadata %v with no handle", md)) 344 } 345 346 return md.tlfHandle 347 } 348 349 // TypeForKeying returns the keying type for the RootMetadata. 350 func (md *RootMetadata) TypeForKeying() tlf.KeyingType { 351 return md.bareMd.TypeForKeying() 352 } 353 354 // MakeBareTlfHandle makes a BareTlfHandle for this 355 // RootMetadata. Should be used only by servers and MDOps. 356 func (md *RootMetadata) MakeBareTlfHandle() (tlf.Handle, error) { 357 if md.tlfHandle != nil { 358 panic(errors.New("MakeBareTlfHandle called when md.tlfHandle exists")) 359 } 360 361 return md.bareMd.MakeBareTlfHandle(md.extra) 362 } 363 364 // IsInitialized returns whether or not this RootMetadata has been initialized 365 func (md *RootMetadata) IsInitialized() bool { 366 keyGen := md.LatestKeyGeneration() 367 if md.TypeForKeying() == tlf.PublicKeying { 368 return keyGen == kbfsmd.PublicKeyGen 369 } 370 // The data is only initialized once we have at least one set of keys 371 return keyGen >= kbfsmd.FirstValidKeyGen 372 } 373 374 // AddRefBlock adds the newly-referenced block to the add block change list. 375 func (md *RootMetadata) AddRefBlock(info data.BlockInfo) { 376 md.AddRefBytes(uint64(info.EncodedSize)) 377 md.AddDiskUsage(uint64(info.EncodedSize)) 378 md.data.Changes.AddRefBlock(info.BlockPointer) 379 } 380 381 // AddUnrefBlock adds the newly-unreferenced block to the add block change list. 382 func (md *RootMetadata) AddUnrefBlock(info data.BlockInfo) { 383 if info.EncodedSize > 0 { 384 md.AddUnrefBytes(uint64(info.EncodedSize)) 385 md.SetDiskUsage(md.DiskUsage() - uint64(info.EncodedSize)) 386 md.data.Changes.AddUnrefBlock(info.BlockPointer) 387 } 388 } 389 390 // AddUpdate adds the newly-updated block to the add block change list. 391 func (md *RootMetadata) AddUpdate(oldInfo data.BlockInfo, newInfo data.BlockInfo) { 392 md.AddUnrefBytes(uint64(oldInfo.EncodedSize)) 393 md.AddRefBytes(uint64(newInfo.EncodedSize)) 394 md.AddDiskUsage(uint64(newInfo.EncodedSize)) 395 md.SetDiskUsage(md.DiskUsage() - uint64(oldInfo.EncodedSize)) 396 md.data.Changes.AddUpdate(oldInfo.BlockPointer, newInfo.BlockPointer) 397 } 398 399 // AddOp starts a new operation for this MD update. Subsequent 400 // AddRefBlock, AddUnrefBlock, and AddUpdate calls will be applied to 401 // this operation. 402 func (md *RootMetadata) AddOp(o op) { 403 md.data.Changes.AddOp(o) 404 } 405 406 // ClearBlockChanges resets the block change lists to empty for this 407 // RootMetadata. 408 func (md *RootMetadata) ClearBlockChanges() { 409 md.SetRefBytes(0) 410 md.SetUnrefBytes(0) 411 md.SetMDRefBytes(0) 412 md.data.Changes.sizeEstimate = 0 413 md.data.Changes.Info = data.BlockInfo{} 414 md.data.Changes.Ops = nil 415 } 416 417 // SetLastGCRevision sets the last revision up to and including which 418 // garbage collection was performed on this TLF. 419 func (md *RootMetadata) SetLastGCRevision(rev kbfsmd.Revision) { 420 md.data.LastGCRevision = rev 421 } 422 423 // updateFromTlfHandle updates the current RootMetadata's fields to 424 // reflect the given handle, which must be the result of running the 425 // current handle with ResolveAgain(). 426 func (md *RootMetadata) updateFromTlfHandle(newHandle *tlfhandle.Handle) error { 427 // TODO: Strengthen check, e.g. make sure every writer/reader 428 // in the old handle is also a writer/reader of the new 429 // handle. 430 newBareHandle, err := newHandle.ToBareHandle() 431 if err != nil { 432 return err 433 } 434 var valid bool 435 switch md.TypeForKeying() { 436 case tlf.PrivateKeying: 437 // Private-keyed TLFs can move to team keying, but not to 438 // public keying. 439 valid = newBareHandle.TypeForKeying() != tlf.PublicKeying 440 case tlf.PublicKeying: 441 // Public-keyed TLFs can move to team keying, but not to 442 // private keying. 443 valid = newBareHandle.TypeForKeying() != tlf.PrivateKeying 444 case tlf.TeamKeying: 445 // Team-keyed TLFs must always remain team-keyed. 446 valid = newBareHandle.TypeForKeying() == tlf.TeamKeying 447 default: 448 return fmt.Errorf("Unexpected keying type %s", md.TypeForKeying()) 449 } 450 if !valid { 451 return fmt.Errorf( 452 "Trying to update rmd with id type=%s, keying type=%s with "+ 453 "handle of type=%s, keying type=%s", 454 md.TlfID().Type(), md.TypeForKeying(), 455 newHandle.Type(), newBareHandle.TypeForKeying()) 456 } 457 458 if newBareHandle.TypeForKeying() == tlf.PrivateKeying { 459 md.SetUnresolvedReaders(newHandle.UnresolvedReaders()) 460 } else { 461 md.SetWriters(newHandle.ResolvedWriters()) 462 } 463 464 md.SetUnresolvedWriters(newHandle.UnresolvedWriters()) 465 md.SetConflictInfo(newHandle.ConflictInfo()) 466 md.SetFinalizedInfo(newHandle.FinalizedInfo()) 467 468 bareHandle, err := md.bareMd.MakeBareTlfHandle(md.extra) 469 if err != nil { 470 return err 471 } 472 473 if !reflect.DeepEqual(bareHandle, newBareHandle) { 474 return fmt.Errorf( 475 "bareHandle=%+v != newBareHandle=%+v", 476 bareHandle, newBareHandle) 477 } 478 479 md.tlfHandle = newHandle 480 return nil 481 } 482 483 // loadCachedBlockChanges swaps any cached block changes so that 484 // future local accesses to this MD (from the cache) can directly 485 // access the ops without needing to re-embed the block changes. 486 // Possibly copies the MD, returns the copy if so, and whether copied. 487 func (md *RootMetadata) loadCachedBlockChanges( 488 ctx context.Context, bps data.BlockPutState, log logger.Logger, 489 vlog *libkb.VDebugLog, codec kbfscodec.Codec) (*RootMetadata, error) { 490 if md.data.Changes.Ops != nil || len(md.data.cachedChanges.Ops) == 0 { 491 return md, nil 492 } 493 md, err := md.deepCopy(codec) 494 if err != nil { 495 return nil, err 496 } 497 498 md.data.Changes, md.data.cachedChanges = 499 md.data.cachedChanges, md.data.Changes 500 501 // We always add the ref blocks to the first operation in the MD 502 // update. Most MD updates will only have one op anyway, and for 503 // those that have more (like conflict resolution), it is 504 // arbitrary which one lists them as references, so putting them 505 // in the first op is the easiest thing to do. 506 md.data.Changes.Ops[0]. 507 AddRefBlock(md.data.cachedChanges.Info.BlockPointer) 508 // Find the block and ref any children, if any. 509 if bps == nil { 510 panic("Must provide blocks when changes are unembedded") 511 } 512 513 // Prepare a map of all FileBlocks for easy access by fileData 514 // below. 515 fileBlocks := make(map[data.BlockPointer]*data.FileBlock) 516 for _, ptr := range bps.Ptrs() { 517 if block, err := bps.GetBlock(ctx, ptr); err == nil { 518 if fblock, ok := block.(*data.FileBlock); ok { 519 fileBlocks[ptr] = fblock 520 } 521 } 522 } 523 524 // uid, crypto and bsplitter aren't used for simply getting the 525 // indirect pointers, so set them to nil. 526 var id keybase1.UserOrTeamID 527 file := data.Path{ 528 FolderBranch: data.FolderBranch{ 529 Tlf: md.TlfID(), Branch: data.MasterBranch}, 530 Path: []data.PathNode{{ 531 BlockPointer: md.data.cachedChanges.Info.BlockPointer, 532 Name: data.NewPathPartString( 533 fmt.Sprintf("<MD with revision %d>", md.Revision()), nil), 534 }}, 535 } 536 fd := data.NewFileData(file, id, nil, md.ReadOnly(), 537 func(_ context.Context, _ libkey.KeyMetadata, ptr data.BlockPointer, 538 _ data.Path, _ data.BlockReqType) (*data.FileBlock, bool, error) { 539 fblock, ok := fileBlocks[ptr] 540 if !ok { 541 return nil, false, fmt.Errorf( 542 "No unembedded block change pointer %v in bps", ptr) 543 } 544 return fblock, false, nil 545 }, 546 func(_ context.Context, ptr data.BlockPointer, block data.Block) error { 547 return nil 548 }, log, vlog) 549 550 infos, err := fd.GetIndirectFileBlockInfos(ctx) 551 if err != nil { 552 return nil, err 553 } 554 555 for _, info := range infos { 556 md.data.Changes.Ops[0].AddRefBlock(info.BlockPointer) 557 } 558 return md, nil 559 } 560 561 // GetTLFCryptKeyParams wraps the respective method of the underlying BareRootMetadata for convenience. 562 func (md *RootMetadata) GetTLFCryptKeyParams( 563 keyGen kbfsmd.KeyGen, user keybase1.UID, key kbfscrypto.CryptPublicKey) ( 564 kbfscrypto.TLFEphemeralPublicKey, kbfscrypto.EncryptedTLFCryptKeyClientHalf, 565 kbfscrypto.TLFCryptKeyServerHalfID, bool, error) { 566 return md.bareMd.GetTLFCryptKeyParams(keyGen, user, key, md.extra) 567 } 568 569 // KeyGenerationsToUpdate wraps the respective method of the underlying BareRootMetadata for convenience. 570 func (md *RootMetadata) KeyGenerationsToUpdate() (kbfsmd.KeyGen, kbfsmd.KeyGen) { 571 return md.bareMd.KeyGenerationsToUpdate() 572 } 573 574 // LatestKeyGeneration wraps the respective method of the underlying BareRootMetadata for convenience. 575 func (md *RootMetadata) LatestKeyGeneration() kbfsmd.KeyGen { 576 return md.bareMd.LatestKeyGeneration() 577 } 578 579 // TlfID wraps the respective method of the underlying BareRootMetadata for convenience. 580 func (md *RootMetadata) TlfID() tlf.ID { 581 if md == nil || md.bareMd == nil { 582 return tlf.NullID 583 } 584 return md.bareMd.TlfID() 585 } 586 587 // LastModifyingWriter wraps the respective method of the underlying BareRootMetadata for convenience. 588 func (md *RootMetadata) LastModifyingWriter() keybase1.UID { 589 return md.bareMd.LastModifyingWriter() 590 } 591 592 // LastModifyingUser wraps the respective method of the underlying BareRootMetadata for convenience. 593 func (md *RootMetadata) LastModifyingUser() keybase1.UID { 594 return md.bareMd.GetLastModifyingUser() 595 } 596 597 // RefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 598 func (md *RootMetadata) RefBytes() uint64 { 599 return md.bareMd.RefBytes() 600 } 601 602 // UnrefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 603 func (md *RootMetadata) UnrefBytes() uint64 { 604 return md.bareMd.UnrefBytes() 605 } 606 607 // MDRefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 608 func (md *RootMetadata) MDRefBytes() uint64 { 609 return md.bareMd.MDRefBytes() 610 } 611 612 // DiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 613 func (md *RootMetadata) DiskUsage() uint64 { 614 return md.bareMd.DiskUsage() 615 } 616 617 // MDDiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 618 func (md *RootMetadata) MDDiskUsage() uint64 { 619 return md.bareMd.MDDiskUsage() 620 } 621 622 // SetRefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 623 func (md *RootMetadata) SetRefBytes(refBytes uint64) { 624 md.bareMd.SetRefBytes(refBytes) 625 } 626 627 // SetUnrefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 628 func (md *RootMetadata) SetUnrefBytes(unrefBytes uint64) { 629 md.bareMd.SetUnrefBytes(unrefBytes) 630 } 631 632 // SetMDRefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 633 func (md *RootMetadata) SetMDRefBytes(mdRefBytes uint64) { 634 md.bareMd.SetMDRefBytes(mdRefBytes) 635 } 636 637 // SetDiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 638 func (md *RootMetadata) SetDiskUsage(diskUsage uint64) { 639 md.bareMd.SetDiskUsage(diskUsage) 640 } 641 642 // SetMDDiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 643 func (md *RootMetadata) SetMDDiskUsage(mdDiskUsage uint64) { 644 md.bareMd.SetMDDiskUsage(mdDiskUsage) 645 } 646 647 // AddRefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 648 func (md *RootMetadata) AddRefBytes(refBytes uint64) { 649 md.bareMd.AddRefBytes(refBytes) 650 } 651 652 // AddUnrefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 653 func (md *RootMetadata) AddUnrefBytes(unrefBytes uint64) { 654 md.bareMd.AddUnrefBytes(unrefBytes) 655 } 656 657 // AddMDRefBytes wraps the respective method of the underlying BareRootMetadata for convenience. 658 func (md *RootMetadata) AddMDRefBytes(mdRefBytes uint64) { 659 md.bareMd.AddMDRefBytes(mdRefBytes) 660 } 661 662 // AddDiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 663 func (md *RootMetadata) AddDiskUsage(diskUsage uint64) { 664 md.bareMd.AddDiskUsage(diskUsage) 665 } 666 667 // AddMDDiskUsage wraps the respective method of the underlying BareRootMetadata for convenience. 668 func (md *RootMetadata) AddMDDiskUsage(mdDiskUsage uint64) { 669 md.bareMd.AddMDDiskUsage(mdDiskUsage) 670 } 671 672 // IsWriterMetadataCopiedSet wraps the respective method of the underlying BareRootMetadata for convenience. 673 func (md *RootMetadata) IsWriterMetadataCopiedSet() bool { 674 return md.bareMd.IsWriterMetadataCopiedSet() 675 } 676 677 // IsRekeySet wraps the respective method of the underlying BareRootMetadata for convenience. 678 func (md *RootMetadata) IsRekeySet() bool { 679 return md.bareMd.IsRekeySet() 680 } 681 682 // IsUnmergedSet wraps the respective method of the underlying BareRootMetadata for convenience. 683 func (md *RootMetadata) IsUnmergedSet() bool { 684 return md.bareMd.IsUnmergedSet() 685 } 686 687 // Revision wraps the respective method of the underlying BareRootMetadata for convenience. 688 func (md *RootMetadata) Revision() kbfsmd.Revision { 689 return md.bareMd.RevisionNumber() 690 } 691 692 // MergedStatus wraps the respective method of the underlying BareRootMetadata for convenience. 693 func (md *RootMetadata) MergedStatus() kbfsmd.MergeStatus { 694 return md.bareMd.MergedStatus() 695 } 696 697 // BID wraps the respective method of the underlying BareRootMetadata for convenience. 698 func (md *RootMetadata) BID() kbfsmd.BranchID { 699 return md.bareMd.BID() 700 } 701 702 // PrevRoot wraps the respective method of the underlying BareRootMetadata for convenience. 703 func (md *RootMetadata) PrevRoot() kbfsmd.ID { 704 return md.bareMd.GetPrevRoot() 705 } 706 707 // Version returns the underlying BareRootMetadata version. 708 func (md *RootMetadata) Version() kbfsmd.MetadataVer { 709 return md.bareMd.Version() 710 } 711 712 func (md *RootMetadata) clearRekeyBit() { 713 md.bareMd.ClearRekeyBit() 714 } 715 716 func (md *RootMetadata) clearWriterMetadataCopiedBit() { 717 md.bareMd.ClearWriterMetadataCopiedBit() 718 } 719 720 // SetUnmerged wraps the respective method of the underlying BareRootMetadata for convenience. 721 func (md *RootMetadata) SetUnmerged() { 722 md.bareMd.SetUnmerged() 723 } 724 725 // SetBranchID wraps the respective method of the underlying BareRootMetadata for convenience. 726 func (md *RootMetadata) SetBranchID(bid kbfsmd.BranchID) { 727 md.bareMd.SetBranchID(bid) 728 } 729 730 // SetPrevRoot wraps the respective method of the underlying BareRootMetadata for convenience. 731 func (md *RootMetadata) SetPrevRoot(mdID kbfsmd.ID) { 732 md.bareMd.SetPrevRoot(mdID) 733 } 734 735 // GetSerializedPrivateMetadata wraps the respective method of the underlying BareRootMetadata for convenience. 736 func (md *RootMetadata) GetSerializedPrivateMetadata() []byte { 737 return md.bareMd.GetSerializedPrivateMetadata() 738 } 739 740 // GetSerializedWriterMetadata wraps the respective method of the underlying BareRootMetadata for convenience. 741 func (md *RootMetadata) GetSerializedWriterMetadata( 742 codec kbfscodec.Codec) ([]byte, error) { 743 return md.bareMd.GetSerializedWriterMetadata(codec) 744 } 745 746 // IsFinal wraps the respective method of the underlying BareRootMetadata for convenience. 747 func (md *RootMetadata) IsFinal() bool { 748 return md.bareMd.IsFinal() 749 } 750 751 // SetSerializedPrivateMetadata wraps the respective method of the underlying BareRootMetadata for convenience. 752 func (md *RootMetadata) SetSerializedPrivateMetadata(spmd []byte) { 753 md.bareMd.SetSerializedPrivateMetadata(spmd) 754 } 755 756 // SetRekeyBit wraps the respective method of the underlying BareRootMetadata for convenience. 757 func (md *RootMetadata) SetRekeyBit() { 758 md.bareMd.SetRekeyBit() 759 } 760 761 // SetFinalBit wraps the respective method of the underlying BareRootMetadata for convenience. 762 func (md *RootMetadata) SetFinalBit() { 763 md.bareMd.SetFinalBit() 764 } 765 766 // SetWriterMetadataCopiedBit wraps the respective method of the underlying BareRootMetadata for convenience. 767 func (md *RootMetadata) SetWriterMetadataCopiedBit() { 768 md.bareMd.SetWriterMetadataCopiedBit() 769 } 770 771 // SetRevision wraps the respective method of the underlying BareRootMetadata for convenience. 772 func (md *RootMetadata) SetRevision(revision kbfsmd.Revision) { 773 md.bareMd.SetRevision(revision) 774 } 775 776 // SetWriters wraps the respective method of the underlying BareRootMetadata for convenience. 777 func (md *RootMetadata) SetWriters(writers []keybase1.UserOrTeamID) { 778 md.bareMd.SetWriters(writers) 779 } 780 781 // SetUnresolvedReaders wraps the respective method of the underlying BareRootMetadata for convenience. 782 func (md *RootMetadata) SetUnresolvedReaders(readers []keybase1.SocialAssertion) { 783 md.bareMd.SetUnresolvedReaders(readers) 784 } 785 786 // SetUnresolvedWriters wraps the respective method of the underlying BareRootMetadata for convenience. 787 func (md *RootMetadata) SetUnresolvedWriters(writers []keybase1.SocialAssertion) { 788 md.bareMd.SetUnresolvedWriters(writers) 789 } 790 791 // SetConflictInfo wraps the respective method of the underlying BareRootMetadata for convenience. 792 func (md *RootMetadata) SetConflictInfo(ci *tlf.HandleExtension) { 793 md.bareMd.SetConflictInfo(ci) 794 } 795 796 // SetFinalizedInfo wraps the respective method of the underlying BareRootMetadata for convenience. 797 func (md *RootMetadata) SetFinalizedInfo(fi *tlf.HandleExtension) { 798 md.bareMd.SetFinalizedInfo(fi) 799 } 800 801 // SetLastModifyingWriter wraps the respective method of the underlying BareRootMetadata for convenience. 802 func (md *RootMetadata) SetLastModifyingWriter(user keybase1.UID) { 803 md.bareMd.SetLastModifyingWriter(user) 804 } 805 806 // SetLastModifyingUser wraps the respective method of the underlying BareRootMetadata for convenience. 807 func (md *RootMetadata) SetLastModifyingUser(user keybase1.UID) { 808 md.bareMd.SetLastModifyingUser(user) 809 } 810 811 // SetTlfID wraps the respective method of the underlying BareRootMetadata for convenience. 812 func (md *RootMetadata) SetTlfID(tlf tlf.ID) { 813 md.bareMd.SetTlfID(tlf) 814 } 815 816 // HasKeyForUser wraps the respective method of the underlying BareRootMetadata for convenience. 817 func (md *RootMetadata) HasKeyForUser(user keybase1.UID) ( 818 bool, error) { 819 writers, readers, err := md.bareMd.GetUserDevicePublicKeys(md.extra) 820 if err != nil { 821 return false, err 822 } 823 return len(writers[user]) > 0 || len(readers[user]) > 0, nil 824 } 825 826 // fakeInitialRekey wraps the FakeInitialRekey test function for 827 // convenience. 828 func (md *RootMetadata) fakeInitialRekey() { 829 bh, err := md.tlfHandle.ToBareHandle() 830 if err != nil { 831 panic(err) 832 } 833 md.extra = kbfsmd.FakeInitialRekey(md.bareMd, bh, kbfscrypto.TLFPublicKey{}) 834 } 835 836 // GetBareRootMetadata returns an interface to the underlying serializeable metadata. 837 func (md *RootMetadata) GetBareRootMetadata() kbfsmd.RootMetadata { 838 return md.bareMd 839 } 840 841 // AddKeyGeneration adds a new key generation to this revision of metadata. 842 func (md *RootMetadata) AddKeyGeneration(codec kbfscodec.Codec, 843 wKeys, rKeys kbfsmd.UserDevicePublicKeys, 844 ePubKey kbfscrypto.TLFEphemeralPublicKey, 845 ePrivKey kbfscrypto.TLFEphemeralPrivateKey, 846 pubKey kbfscrypto.TLFPublicKey, 847 privKey kbfscrypto.TLFPrivateKey, 848 currCryptKey, nextCryptKey kbfscrypto.TLFCryptKey) ( 849 serverHalves kbfsmd.UserDeviceKeyServerHalves, err error) { 850 nextExtra, serverHalves, err := md.bareMd.AddKeyGeneration( 851 codec, md.extra, wKeys, rKeys, ePubKey, ePrivKey, 852 pubKey, currCryptKey, nextCryptKey) 853 if err != nil { 854 return nil, err 855 } 856 md.extra = nextExtra 857 md.data.TLFPrivateKey = privKey 858 return serverHalves, nil 859 } 860 861 func (md *RootMetadata) promoteReaders( 862 readersToPromote map[keybase1.UID]bool) error { 863 return md.bareMd.PromoteReaders(readersToPromote, md.extra) 864 } 865 866 func (md *RootMetadata) revokeRemovedDevices( 867 wKeys, rKeys kbfsmd.UserDevicePublicKeys) ( 868 kbfsmd.ServerHalfRemovalInfo, error) { 869 return md.bareMd.RevokeRemovedDevices(wKeys, rKeys, md.extra) 870 } 871 872 func (md *RootMetadata) updateKeyBundles( 873 codec kbfscodec.Codec, wKeys, rKeys kbfsmd.UserDevicePublicKeys, 874 ePubKey kbfscrypto.TLFEphemeralPublicKey, 875 ePrivKey kbfscrypto.TLFEphemeralPrivateKey, 876 tlfCryptKeys []kbfscrypto.TLFCryptKey) ( 877 []kbfsmd.UserDeviceKeyServerHalves, error) { 878 return md.bareMd.UpdateKeyBundles(codec, md.extra, 879 wKeys, rKeys, ePubKey, ePrivKey, tlfCryptKeys) 880 } 881 882 func (md *RootMetadata) finalizeRekey(codec kbfscodec.Codec) error { 883 return md.bareMd.FinalizeRekey(codec, md.extra) 884 } 885 886 func (md *RootMetadata) getUserDevicePublicKeys() ( 887 writers, readers kbfsmd.UserDevicePublicKeys, err error) { 888 return md.bareMd.GetUserDevicePublicKeys(md.extra) 889 } 890 891 // GetTLFWriterKeyBundleID returns the ID of the externally-stored 892 // writer key bundle, or the zero value if this object stores it 893 // internally. 894 func (md *RootMetadata) GetTLFWriterKeyBundleID() kbfsmd.TLFWriterKeyBundleID { 895 return md.bareMd.GetTLFWriterKeyBundleID() 896 } 897 898 // GetTLFReaderKeyBundleID returns the ID of the externally-stored 899 // reader key bundle, or the zero value if this object stores it 900 // internally. 901 func (md *RootMetadata) GetTLFReaderKeyBundleID() kbfsmd.TLFReaderKeyBundleID { 902 return md.bareMd.GetTLFReaderKeyBundleID() 903 } 904 905 // StoresHistoricTLFCryptKeys implements the KeyMetadata interface for RootMetadata. 906 func (md *RootMetadata) StoresHistoricTLFCryptKeys() bool { 907 return md.bareMd.StoresHistoricTLFCryptKeys() 908 } 909 910 // GetHistoricTLFCryptKey implements the KeyMetadata interface for RootMetadata. 911 func (md *RootMetadata) GetHistoricTLFCryptKey( 912 codec kbfscodec.Codec, keyGen kbfsmd.KeyGen, 913 currentKey kbfscrypto.TLFCryptKey) (kbfscrypto.TLFCryptKey, error) { 914 return md.bareMd.GetHistoricTLFCryptKey( 915 codec, keyGen, currentKey, md.extra) 916 } 917 918 // IsWriter checks that the given user is a valid writer of the TLF 919 // right now. Implements the KeyMetadata interface for RootMetadata. 920 func (md *RootMetadata) IsWriter( 921 ctx context.Context, checker kbfsmd.TeamMembershipChecker, 922 osg idutil.OfflineStatusGetter, uid keybase1.UID, 923 verifyingKey kbfscrypto.VerifyingKey) (bool, error) { 924 h := md.GetTlfHandle() 925 return IsWriterFromHandle(ctx, h, checker, osg, uid, verifyingKey) 926 } 927 928 // IsReader checks that the given user is a valid reader of the TLF 929 // right now. 930 func (md *RootMetadata) IsReader( 931 ctx context.Context, checker kbfsmd.TeamMembershipChecker, 932 osg idutil.OfflineStatusGetter, uid keybase1.UID) (bool, error) { 933 h := md.GetTlfHandle() 934 return isReaderFromHandle(ctx, h, checker, osg, uid) 935 } 936 937 // A ReadOnlyRootMetadata is a thin wrapper around a 938 // *RootMetadata. Functions that take a ReadOnlyRootMetadata parameter 939 // must not modify it, and therefore code that passes a 940 // ReadOnlyRootMetadata to a function can assume that it is not 941 // modified by that function. However, callers that convert a 942 // *RootMetadata to a ReadOnlyRootMetadata may still modify the 943 // underlying RootMetadata through the original pointer, so care must 944 // be taken if a function stores a ReadOnlyRootMetadata object past 945 // the end of the function, or when a function takes both a 946 // *RootMetadata and a ReadOnlyRootMetadata (see 947 // decryptMDPrivateData). 948 type ReadOnlyRootMetadata struct { 949 *RootMetadata 950 } 951 952 // CheckValidSuccessor makes sure the given ReadOnlyRootMetadata is a 953 // valid successor to the current one, and returns an error otherwise. 954 func (md ReadOnlyRootMetadata) CheckValidSuccessor( 955 currID kbfsmd.ID, nextMd ReadOnlyRootMetadata) error { 956 return md.bareMd.CheckValidSuccessor(currID, nextMd.bareMd) 957 } 958 959 // ReadOnly makes a ReadOnlyRootMetadata from the current 960 // *RootMetadata. 961 func (md *RootMetadata) ReadOnly() ReadOnlyRootMetadata { 962 return ReadOnlyRootMetadata{md} 963 } 964 965 // ImmutableRootMetadata is a thin wrapper around a 966 // ReadOnlyRootMetadata that takes ownership of it and does not ever 967 // modify it again. Thus, its MdID can be calculated and 968 // stored. Unlike ReadOnlyRootMetadata, ImmutableRootMetadata objects 969 // can be assumed to never alias a (modifiable) *RootMetadata. 970 type ImmutableRootMetadata struct { 971 ReadOnlyRootMetadata 972 mdID kbfsmd.ID 973 lastWriterVerifyingKey kbfscrypto.VerifyingKey 974 // localTimestamp represents the time at which the MD update was 975 // applied at the server, adjusted for the local clock. So for 976 // example, it can be used to show how long ago a particular 977 // update happened (e.g., "5 hours ago"). Note that the update 978 // time supplied by the server is technically untrusted (i.e., not 979 // signed by a writer of the TLF, only provided by the server). 980 // If this ImmutableRootMetadata was generated locally and still 981 // persists in the journal or in the cache, localTimestamp comes 982 // directly from the local clock. 983 localTimestamp time.Time 984 // putToServer indicates whether this MD has been put successfully 985 // to the remote server (e.g., it isn't just local to the 986 // process's journal). 987 putToServer bool 988 } 989 990 // MakeImmutableRootMetadata makes a new ImmutableRootMetadata from 991 // the given RMD and its corresponding MdID. 992 func MakeImmutableRootMetadata( 993 rmd *RootMetadata, writerVerifyingKey kbfscrypto.VerifyingKey, 994 mdID kbfsmd.ID, localTimestamp time.Time, 995 putToServer bool) ImmutableRootMetadata { 996 if writerVerifyingKey == (kbfscrypto.VerifyingKey{}) { 997 panic("zero writerVerifyingKey passed to MakeImmutableRootMetadata") 998 } 999 if mdID == (kbfsmd.ID{}) { 1000 panic("zero mdID passed to MakeImmutableRootMetadata") 1001 } 1002 if localTimestamp.IsZero() { 1003 panic("zero localTimestamp passed to MakeImmutableRootMetadata") 1004 } 1005 if bareMDV2, ok := rmd.bareMd.(*kbfsmd.RootMetadataV2); ok { 1006 writerSig := bareMDV2.WriterMetadataSigInfo 1007 if writerSig.IsNil() { 1008 panic("MDV2 with nil writer signature") 1009 } 1010 if writerSig.VerifyingKey != writerVerifyingKey { 1011 panic(fmt.Sprintf("key mismatch: sig has %s, expected %s", 1012 writerSig.VerifyingKey, writerVerifyingKey)) 1013 } 1014 } 1015 return ImmutableRootMetadata{ 1016 rmd.ReadOnly(), mdID, writerVerifyingKey, localTimestamp, putToServer} 1017 } 1018 1019 // MdID returns the pre-computed MdID of the contained RootMetadata 1020 // object. 1021 func (irmd ImmutableRootMetadata) MdID() kbfsmd.ID { 1022 return irmd.mdID 1023 } 1024 1025 // LocalTimestamp returns the timestamp associated with this 1026 // RootMetadata object. 1027 func (irmd ImmutableRootMetadata) LocalTimestamp() time.Time { 1028 return irmd.localTimestamp 1029 } 1030 1031 // LastModifyingWriterVerifyingKey returns the VerifyingKey used by the last 1032 // writer of this MD. 1033 func (irmd ImmutableRootMetadata) LastModifyingWriterVerifyingKey() kbfscrypto.VerifyingKey { 1034 return irmd.lastWriterVerifyingKey 1035 } 1036 1037 // RootMetadataSigned is a wrapper around kbfsmd.RootMetadataSigned 1038 // that adds an untrusted server timestamp. 1039 type RootMetadataSigned struct { 1040 kbfsmd.RootMetadataSigned 1041 // When does the server say this MD update was received? (This is 1042 // not necessarily trustworthy, just for informational purposes.) 1043 untrustedServerTimestamp time.Time 1044 } 1045 1046 // makeRootMetadataSigned makes a RootMetadataSigned object from the 1047 // given info. If md stores the writer signature info internally, it 1048 // must match the given one. 1049 func makeRootMetadataSigned(rmds *kbfsmd.RootMetadataSigned, 1050 untrustedServerTimestamp time.Time) *RootMetadataSigned { 1051 return &RootMetadataSigned{ 1052 RootMetadataSigned: *rmds, 1053 untrustedServerTimestamp: untrustedServerTimestamp, 1054 } 1055 } 1056 1057 // SignBareRootMetadata signs the given BareRootMetadata and returns a 1058 // *RootMetadataSigned object. rootMetadataSigner and 1059 // writerMetadataSigner should be the same, except in tests. 1060 func SignBareRootMetadata( 1061 ctx context.Context, codec kbfscodec.Codec, 1062 rootMetadataSigner, writerMetadataSigner kbfscrypto.Signer, 1063 md kbfsmd.RootMetadata, untrustedServerTimestamp time.Time) ( 1064 *RootMetadataSigned, error) { 1065 rmds, err := kbfsmd.SignRootMetadata(ctx, codec, rootMetadataSigner, writerMetadataSigner, md) 1066 if err != nil { 1067 return nil, err 1068 } 1069 return makeRootMetadataSigned(rmds, untrustedServerTimestamp), nil 1070 } 1071 1072 // MakeFinalCopy returns a complete copy of this RootMetadataSigned 1073 // with the revision incremented and the final bit set. 1074 func (rmds *RootMetadataSigned) MakeFinalCopy( 1075 codec kbfscodec.Codec, now time.Time, 1076 finalizedInfo *tlf.HandleExtension) (*RootMetadataSigned, error) { 1077 rmdsCopy, err := rmds.RootMetadataSigned.MakeFinalCopy(codec, finalizedInfo) 1078 if err != nil { 1079 return nil, err 1080 } 1081 return makeRootMetadataSigned(rmdsCopy, now), nil 1082 } 1083 1084 // DecodeRootMetadataSigned deserializes a metadata block into the 1085 // specified versioned structure. 1086 func DecodeRootMetadataSigned( 1087 codec kbfscodec.Codec, tlf tlf.ID, ver, max kbfsmd.MetadataVer, buf []byte, 1088 untrustedServerTimestamp time.Time) ( 1089 *RootMetadataSigned, error) { 1090 rmds, err := kbfsmd.DecodeRootMetadataSigned(codec, tlf, ver, max, buf) 1091 if err != nil { 1092 return nil, err 1093 } 1094 return makeRootMetadataSigned(rmds, untrustedServerTimestamp), nil 1095 }