github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/kbfsmd/root_metadata_v3.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 kbfsmd 6 7 import ( 8 "fmt" 9 "runtime" 10 11 goerrors "github.com/go-errors/errors" 12 "github.com/keybase/client/go/kbfs/kbfscodec" 13 "github.com/keybase/client/go/kbfs/kbfscrypto" 14 "github.com/keybase/client/go/kbfs/tlf" 15 "github.com/keybase/client/go/protocol/keybase1" 16 "github.com/keybase/go-codec/codec" 17 "github.com/pkg/errors" 18 "golang.org/x/net/context" 19 ) 20 21 // WriterMetadataV3 stores the metadata for a TLF that is 22 // only editable by users with writer permissions. 23 type WriterMetadataV3 struct { 24 // Serialized, possibly encrypted, version of the PrivateMetadata 25 SerializedPrivateMetadata []byte `codec:"data"` 26 27 // The last KB user with writer permissions to this TLF 28 // who modified this WriterMetadata 29 LastModifyingWriter keybase1.UID `codec:"lmw"` 30 31 // For public and single-team TLFs (since those don't have any 32 // keys at all). 33 Writers []keybase1.UserOrTeamID `codec:",omitempty"` 34 // Writers identified by unresolved social assertions. 35 UnresolvedWriters []keybase1.SocialAssertion `codec:"uw,omitempty"` 36 // Pointer to the writer key bundle for private TLFs. 37 WKeyBundleID TLFWriterKeyBundleID `codec:"wkid"` 38 // Latest key generation. 39 LatestKeyGen KeyGen `codec:"lkg"` 40 41 // The directory ID, signed over to make verification easier 42 ID tlf.ID 43 // The branch ID, currently only set if this is in unmerged per-device history. 44 BID BranchID 45 // Flags 46 WFlags WriterFlags 47 48 // Estimated disk usage at this revision 49 DiskUsage uint64 50 // Estimated MD disk usage at this revision 51 MDDiskUsage uint64 `codec:",omitempty"` 52 // The total number of bytes in new data blocks 53 RefBytes uint64 54 // The total number of bytes in unreferenced blocks 55 UnrefBytes uint64 56 // The total number of bytes in new MD blocks 57 MDRefBytes uint64 `codec:",omitempty"` 58 59 codec.UnknownFieldSetHandler 60 } 61 62 // RootMetadataV3 is the MD that is signed by the reader or 63 // writer. Unlike RootMetadata, it contains exactly the serializable 64 // metadata. 65 type RootMetadataV3 struct { 66 // The metadata that is only editable by the writer. 67 WriterMetadata WriterMetadataV3 `codec:"wmd"` 68 69 // The last KB user who modified this RootMetadata 70 LastModifyingUser keybase1.UID 71 // Flags 72 Flags MetadataFlags 73 // The revision number 74 Revision Revision 75 // Pointer to the previous root block ID 76 PrevRoot ID 77 78 // For private TLFs. Any unresolved social assertions for readers. 79 UnresolvedReaders []keybase1.SocialAssertion `codec:"ur,omitempty"` 80 // Pointer to the reader key bundle for private TLFs. 81 RKeyBundleID TLFReaderKeyBundleID `codec:"rkid"` 82 83 // ConflictInfo is set if there's a conflict for the given folder's 84 // handle after a social assertion resolution. 85 ConflictInfo *tlf.HandleExtension `codec:"ci,omitempty"` 86 // FinalizedInfo is set if there are no more valid writer keys capable 87 // of writing to the given folder. 88 FinalizedInfo *tlf.HandleExtension `codec:"fi,omitempty"` 89 90 // KBMerkleRoot is now DEPRECATED, and shouldn't be relied on for 91 // future features. Below is the original text for historians: 92 // 93 // The root of the global Keybase Merkle tree at the time this 94 // update was created (from the writer's perspective). This field 95 // was added to V3 after it was live for a while, and older 96 // clients that don't know about this field yet might copy it into 97 // new updates via the unknown fields copier. Which means new MD 98 // updates might end up referring to older Merkle roots. That's 99 // ok since this is just a hint anyway, and shouldn't be fully 100 // trusted when checking MD updates against the Merkle tree. 101 // NOTE: this is a pointer in order to get the correct "omitempty" 102 // behavior, so that old MDs are still verifiable. 103 KBMerkleRoot *keybase1.MerkleRootV2 `codec:"mr,omitempty"` 104 105 codec.UnknownFieldSetHandler 106 } 107 108 // TODO: Use pkg/errors instead. 109 type missingKeyBundlesError struct { 110 stack []uintptr 111 } 112 113 func (e missingKeyBundlesError) Error() string { 114 s := "Missing key bundles: \n" 115 for _, pc := range e.stack { 116 f := goerrors.NewStackFrame(pc) 117 s += f.String() 118 } 119 return s 120 } 121 122 func makeMissingKeyBundlesError() missingKeyBundlesError { 123 stack := make([]uintptr, 20) 124 n := runtime.Callers(2, stack) 125 return missingKeyBundlesError{stack[:n]} 126 } 127 128 // ExtraMetadataV3 contains references to key bundles stored outside of metadata 129 // blocks. This only ever exists in memory and is never serialized itself. 130 type ExtraMetadataV3 struct { 131 wkb TLFWriterKeyBundleV3 132 rkb TLFReaderKeyBundleV3 133 // Set if wkb is new and should be sent to the server on an MD 134 // put. 135 wkbNew bool 136 // Set if rkb is new and should be sent to the server on an MD 137 // put. 138 rkbNew bool 139 } 140 141 // NewExtraMetadataV3 creates a new ExtraMetadataV3 given a pair of key bundles 142 func NewExtraMetadataV3( 143 wkb TLFWriterKeyBundleV3, rkb TLFReaderKeyBundleV3, 144 wkbNew, rkbNew bool) *ExtraMetadataV3 { 145 return &ExtraMetadataV3{wkb, rkb, wkbNew, rkbNew} 146 } 147 148 // MetadataVersion implements the ExtraMetadata interface for ExtraMetadataV3. 149 func (extra ExtraMetadataV3) MetadataVersion() MetadataVer { 150 return SegregatedKeyBundlesVer 151 } 152 153 func (extra *ExtraMetadataV3) updateNew(wkbNew, rkbNew bool) { 154 extra.wkbNew = extra.wkbNew || wkbNew 155 extra.rkbNew = extra.rkbNew || rkbNew 156 } 157 158 // DeepCopy implements the ExtraMetadata interface for ExtraMetadataV3. 159 func (extra ExtraMetadataV3) DeepCopy(codec kbfscodec.Codec) ( 160 ExtraMetadata, error) { 161 wkb, err := extra.wkb.DeepCopy(codec) 162 if err != nil { 163 return nil, err 164 } 165 rkb, err := extra.rkb.DeepCopy(codec) 166 if err != nil { 167 return nil, err 168 } 169 return NewExtraMetadataV3(wkb, rkb, extra.wkbNew, extra.rkbNew), nil 170 } 171 172 // MakeSuccessorCopy implements the ExtraMetadata interface for ExtraMetadataV3. 173 func (extra ExtraMetadataV3) MakeSuccessorCopy(codec kbfscodec.Codec) ( 174 ExtraMetadata, error) { 175 wkb, err := extra.wkb.DeepCopy(codec) 176 if err != nil { 177 return nil, err 178 } 179 rkb, err := extra.rkb.DeepCopy(codec) 180 if err != nil { 181 return nil, err 182 } 183 return NewExtraMetadataV3(wkb, rkb, false, false), nil 184 } 185 186 // GetWriterKeyBundle returns the contained writer key bundle. 187 func (extra ExtraMetadataV3) GetWriterKeyBundle() TLFWriterKeyBundleV3 { 188 return extra.wkb 189 } 190 191 // GetReaderKeyBundle returns the contained reader key bundle. 192 func (extra ExtraMetadataV3) GetReaderKeyBundle() TLFReaderKeyBundleV3 { 193 return extra.rkb 194 } 195 196 // IsWriterKeyBundleNew returns whether or not the writer key bundle 197 // is new and should be sent to the server on an MD put. 198 func (extra ExtraMetadataV3) IsWriterKeyBundleNew() bool { 199 return extra.wkbNew 200 } 201 202 // IsReaderKeyBundleNew returns whether or not the reader key bundle 203 // is new and should be sent to the server on an MD put. 204 func (extra ExtraMetadataV3) IsReaderKeyBundleNew() bool { 205 return extra.rkbNew 206 } 207 208 // MakeInitialRootMetadataV3 creates a new RootMetadataV3 object with 209 // revision RevisionInitial, and the given TLF ID and handle. Note 210 // that if the given ID/handle are private, rekeying must be done 211 // separately. Since they are data-compatible, this also creates V4 212 // MD objects. 213 func MakeInitialRootMetadataV3(tlfID tlf.ID, h tlf.Handle) ( 214 *RootMetadataV3, error) { 215 switch { 216 case h.TypeForKeying() == tlf.TeamKeying && 217 tlfID.Type() == tlf.SingleTeam && h.Type() != tlf.SingleTeam: 218 fallthrough 219 case h.TypeForKeying() != tlf.TeamKeying && tlfID.Type() != h.Type(): 220 return nil, errors.New("TlfID and TlfHandle disagree on TLF type") 221 default: 222 } 223 224 var writers []keybase1.UserOrTeamID 225 if h.TypeForKeying() != tlf.PrivateKeying { 226 writers = make([]keybase1.UserOrTeamID, len(h.Writers)) 227 copy(writers, h.Writers) 228 } 229 230 var unresolvedWriters, unresolvedReaders []keybase1.SocialAssertion 231 if len(h.UnresolvedWriters) > 0 { 232 unresolvedWriters = make( 233 []keybase1.SocialAssertion, len(h.UnresolvedWriters)) 234 copy(unresolvedWriters, h.UnresolvedWriters) 235 } 236 237 if len(h.UnresolvedReaders) > 0 { 238 unresolvedReaders = make( 239 []keybase1.SocialAssertion, len(h.UnresolvedReaders)) 240 copy(unresolvedReaders, h.UnresolvedReaders) 241 } 242 243 return &RootMetadataV3{ 244 WriterMetadata: WriterMetadataV3{ 245 Writers: writers, 246 ID: tlfID, 247 UnresolvedWriters: unresolvedWriters, 248 }, 249 Revision: RevisionInitial, 250 UnresolvedReaders: unresolvedReaders, 251 // Normally an MD wouldn't start out with extensions, but this 252 // is useful for tests. 253 ConflictInfo: h.ConflictInfo, 254 FinalizedInfo: h.FinalizedInfo, 255 }, nil 256 } 257 258 // TlfID implements the RootMetadata interface for RootMetadataV3. 259 func (md *RootMetadataV3) TlfID() tlf.ID { 260 return md.WriterMetadata.ID 261 } 262 263 // KeyGenerationsToUpdate implements the RootMetadata interface 264 // for RootMetadataV3. 265 func (md *RootMetadataV3) KeyGenerationsToUpdate() (KeyGen, KeyGen) { 266 latest := md.LatestKeyGeneration() 267 if latest < FirstValidKeyGen { 268 return 0, 0 269 } 270 // We only keep track of the latest key generation in extra. 271 return latest, latest + 1 272 } 273 274 // LatestKeyGeneration implements the RootMetadata interface for 275 // RootMetadataV3. 276 func (md *RootMetadataV3) LatestKeyGeneration() KeyGen { 277 if md.TypeForKeying() == tlf.PublicKeying { 278 return PublicKeyGen 279 } 280 return md.WriterMetadata.LatestKeyGen 281 } 282 283 func (md *RootMetadataV3) haveOnlyUserRKeysChanged( 284 codec kbfscodec.Codec, prevMD *RootMetadataV3, 285 user keybase1.UID, prevRkb, rkb TLFReaderKeyBundleV3) (bool, error) { 286 if len(rkb.Keys) != len(prevRkb.Keys) { 287 return false, nil 288 } 289 for u, keys := range rkb.Keys { 290 if u != user { 291 prevKeys := prevRkb.Keys[u] 292 keysEqual, err := kbfscodec.Equal(codec, keys, prevKeys) 293 if err != nil { 294 return false, err 295 } 296 if !keysEqual { 297 return false, nil 298 } 299 } 300 } 301 return true, nil 302 } 303 304 // IsValidRekeyRequest implements the RootMetadata interface for RootMetadataV3. 305 func (md *RootMetadataV3) IsValidRekeyRequest( 306 codec kbfscodec.Codec, prevBareMd RootMetadata, 307 user keybase1.UID, prevExtra, extra ExtraMetadata) ( 308 bool, error) { 309 if !md.IsWriterMetadataCopiedSet() { 310 // Not a copy. 311 return false, nil 312 } 313 prevMd, ok := prevBareMd.(*RootMetadataV3) 314 if !ok { 315 // Not the same type so not a copy. 316 return false, nil 317 } 318 prevExtraV3, ok := prevExtra.(*ExtraMetadataV3) 319 if !ok { 320 return false, errors.New("Invalid previous extra metadata") 321 } 322 extraV3, ok := extra.(*ExtraMetadataV3) 323 if !ok { 324 return false, errors.New("Invalid extra metadata") 325 } 326 writerEqual, err := kbfscodec.Equal( 327 codec, md.WriterMetadata, prevMd.WriterMetadata) 328 if err != nil { 329 return false, err 330 } 331 if !writerEqual { 332 // Copy mismatch. 333 return false, nil 334 } 335 onlyUserRKeysChanged, err := md.haveOnlyUserRKeysChanged( 336 codec, prevMd, user, prevExtraV3.rkb, extraV3.rkb) 337 if err != nil { 338 return false, err 339 } 340 if !onlyUserRKeysChanged { 341 // Keys outside of this user's reader key set have changed. 342 return false, nil 343 } 344 return true, nil 345 } 346 347 // MergedStatus implements the RootMetadata interface for RootMetadataV3. 348 func (md *RootMetadataV3) MergedStatus() MergeStatus { 349 if md.WriterMetadata.WFlags&MetadataFlagUnmerged != 0 { 350 return Unmerged 351 } 352 return Merged 353 } 354 355 // IsRekeySet implements the RootMetadata interface for RootMetadataV3. 356 func (md *RootMetadataV3) IsRekeySet() bool { 357 return md.Flags&MetadataFlagRekey != 0 358 } 359 360 // IsWriterMetadataCopiedSet implements the RootMetadata interface for RootMetadataV3. 361 func (md *RootMetadataV3) IsWriterMetadataCopiedSet() bool { 362 return md.Flags&MetadataFlagWriterMetadataCopied != 0 363 } 364 365 // IsFinal implements the RootMetadata interface for RootMetadataV3. 366 func (md *RootMetadataV3) IsFinal() bool { 367 return md.Flags&MetadataFlagFinal != 0 368 } 369 370 func (md *RootMetadataV3) checkNonPrivateExtra(extra ExtraMetadata) error { 371 if md.TypeForKeying() == tlf.PrivateKeying { 372 return errors.New("checkNonPrivateExtra called on private TLF") 373 } 374 375 if extra != nil { 376 return errors.Errorf("Expected nil, got %T", extra) 377 } 378 379 return nil 380 } 381 382 func (md *RootMetadataV3) getTLFKeyBundles(extra ExtraMetadata) ( 383 *TLFWriterKeyBundleV3, *TLFReaderKeyBundleV3, error) { 384 if md.TypeForKeying() != tlf.PrivateKeying { 385 return nil, nil, InvalidNonPrivateTLFOperation{ 386 md.TlfID(), "getTLFKeyBundles", md.Version(), 387 } 388 } 389 390 if extra == nil { 391 return nil, nil, makeMissingKeyBundlesError() 392 } 393 394 extraV3, ok := extra.(*ExtraMetadataV3) 395 if !ok { 396 return nil, nil, errors.Errorf( 397 "Expected *ExtraMetadataV3, got %T", extra) 398 } 399 400 return &extraV3.wkb, &extraV3.rkb, nil 401 } 402 403 // GetTLFKeyBundlesForTest returns the writer and reader key bundles 404 // from extra. 405 func (md *RootMetadataV3) GetTLFKeyBundlesForTest(extra ExtraMetadata) ( 406 *TLFWriterKeyBundleV3, *TLFReaderKeyBundleV3, error) { 407 return md.getTLFKeyBundles(extra) 408 } 409 410 func (md *RootMetadataV3) isNonTeamWriter( 411 ctx context.Context, user keybase1.UID, 412 cryptKey kbfscrypto.CryptPublicKey, extra ExtraMetadata) (bool, error) { 413 switch md.TlfID().Type() { 414 case tlf.Public: 415 err := md.checkNonPrivateExtra(extra) 416 if err != nil { 417 return false, err 418 } 419 420 for _, w := range md.WriterMetadata.Writers { 421 if w == user.AsUserOrTeam() { 422 return true, nil 423 } 424 } 425 return false, nil 426 case tlf.Private: 427 wkb, _, err := md.getTLFKeyBundles(extra) 428 if err != nil { 429 return false, err 430 } 431 return wkb.IsWriter(user, cryptKey), nil 432 default: 433 return false, errors.Errorf("Unknown TLF type: %s", md.TlfID().Type()) 434 } 435 } 436 437 // IsWriter implements the RootMetadata interface for RootMetadataV3. 438 func (md *RootMetadataV3) IsWriter( 439 ctx context.Context, user keybase1.UID, 440 cryptKey kbfscrypto.CryptPublicKey, verifyingKey kbfscrypto.VerifyingKey, 441 teamMemChecker TeamMembershipChecker, extra ExtraMetadata, 442 offline keybase1.OfflineAvailability) (bool, error) { 443 switch md.TypeForKeying() { 444 case tlf.TeamKeying: 445 err := md.checkNonPrivateExtra(extra) 446 if err != nil { 447 return false, err 448 } 449 450 tid, err := md.WriterMetadata.Writers[0].AsTeam() 451 if err != nil { 452 return false, err 453 } 454 455 // TODO: Eventually this will have to use a Merkle sequence 456 // number to check historic versions. 457 isWriter, err := teamMemChecker.IsTeamWriter( 458 ctx, tid, user, verifyingKey, offline) 459 if err != nil { 460 return false, err 461 } 462 return isWriter, nil 463 default: 464 return md.isNonTeamWriter(ctx, user, cryptKey, extra) 465 } 466 } 467 468 // IsReader implements the RootMetadata interface for RootMetadataV3. 469 func (md *RootMetadataV3) IsReader( 470 ctx context.Context, user keybase1.UID, 471 cryptKey kbfscrypto.CryptPublicKey, teamMemChecker TeamMembershipChecker, 472 extra ExtraMetadata, offline keybase1.OfflineAvailability) (bool, error) { 473 switch md.TypeForKeying() { 474 case tlf.PublicKeying: 475 err := md.checkNonPrivateExtra(extra) 476 if err != nil { 477 return false, err 478 } 479 return true, nil 480 case tlf.PrivateKeying: 481 // Writers are also readers. 482 isWriter, err := md.isNonTeamWriter(ctx, user, cryptKey, extra) 483 if err != nil { 484 return false, err 485 } 486 if isWriter { 487 return true, nil 488 } 489 490 _, rkb, err := md.getTLFKeyBundles(extra) 491 if err != nil { 492 return false, err 493 } 494 return rkb.IsReader(user, cryptKey), nil 495 case tlf.TeamKeying: 496 err := md.checkNonPrivateExtra(extra) 497 if err != nil { 498 return false, err 499 } 500 501 tid, err := md.WriterMetadata.Writers[0].AsTeam() 502 if err != nil { 503 return false, err 504 } 505 506 if tid.IsPublic() { 507 return true, nil 508 } 509 510 // TODO: Eventually this will have to use a Merkle sequence 511 // number to check historic versions. 512 isReader, err := teamMemChecker.IsTeamReader(ctx, tid, user, offline) 513 if err != nil { 514 return false, err 515 } 516 return isReader, nil 517 default: 518 panic(fmt.Sprintf("Unknown TLF keying type: %s", md.TypeForKeying())) 519 } 520 } 521 522 // DeepCopy implements the RootMetadata interface for RootMetadataV3. 523 func (md *RootMetadataV3) DeepCopy( 524 codec kbfscodec.Codec) (MutableRootMetadata, error) { 525 var newMd RootMetadataV3 526 if err := kbfscodec.Update(codec, &newMd, md); err != nil { 527 return nil, err 528 } 529 return &newMd, nil 530 } 531 532 // MakeSuccessorCopy implements the ImmutableRootMetadata interface for RootMetadataV3. 533 func (md *RootMetadataV3) MakeSuccessorCopy( 534 codec kbfscodec.Codec, extra ExtraMetadata, _ MetadataVer, 535 _ func() ([]kbfscrypto.TLFCryptKey, error), isReadableAndWriter bool) ( 536 MutableRootMetadata, ExtraMetadata, error) { 537 var extraCopy ExtraMetadata 538 if extra != nil { 539 var err error 540 extraCopy, err = extra.MakeSuccessorCopy(codec) 541 if err != nil { 542 return nil, nil, err 543 } 544 } 545 mdCopy, err := md.DeepCopy(codec) 546 if err != nil { 547 return nil, nil, err 548 } 549 // TODO: If there is ever a RootMetadataV4 this will need to perform the conversion. 550 return mdCopy, extraCopy, nil 551 } 552 553 // CheckValidSuccessor implements the RootMetadata interface for RootMetadataV3. 554 func (md *RootMetadataV3) CheckValidSuccessor( 555 currID ID, nextMd RootMetadata) error { 556 // (1) Verify current metadata is non-final. 557 if md.IsFinal() { 558 return MetadataIsFinalError{} 559 } 560 561 // (2) Check TLF ID. 562 if nextMd.TlfID() != md.TlfID() { 563 return MDTlfIDMismatch{ 564 CurrID: md.TlfID(), 565 NextID: nextMd.TlfID(), 566 } 567 } 568 569 // (3) Check revision. 570 if nextMd.RevisionNumber() != md.RevisionNumber()+1 { 571 return MDRevisionMismatch{ 572 Rev: nextMd.RevisionNumber(), 573 Curr: md.RevisionNumber(), 574 } 575 } 576 577 // (4) Check PrevRoot pointer. 578 expectedPrevRoot := currID 579 if nextMd.IsFinal() { 580 expectedPrevRoot = md.GetPrevRoot() 581 } 582 if nextMd.GetPrevRoot() != expectedPrevRoot { 583 return MDPrevRootMismatch{ 584 prevRoot: nextMd.GetPrevRoot(), 585 expectedPrevRoot: expectedPrevRoot, 586 } 587 } 588 589 // (5) Check branch ID. 590 if md.MergedStatus() == nextMd.MergedStatus() && md.BID() != nextMd.BID() { 591 return errors.Errorf("Unexpected branch ID on successor: %s vs. %s", 592 md.BID(), nextMd.BID()) 593 } else if md.MergedStatus() == Unmerged && nextMd.MergedStatus() == Merged { 594 return errors.New("merged MD can't follow unmerged MD") 595 } 596 597 // (6) Check disk usage. 598 expectedUsage := md.DiskUsage() 599 if !nextMd.IsWriterMetadataCopiedSet() { 600 expectedUsage += nextMd.RefBytes() - nextMd.UnrefBytes() 601 } 602 if nextMd.DiskUsage() != expectedUsage { 603 return MDDiskUsageMismatch{ 604 expectedDiskUsage: expectedUsage, 605 actualDiskUsage: nextMd.DiskUsage(), 606 } 607 } 608 expectedMDUsage := md.MDDiskUsage() 609 if !nextMd.IsWriterMetadataCopiedSet() { 610 expectedMDUsage += nextMd.MDRefBytes() 611 } 612 // Add an exception for the case where MDRefBytes is equal, since 613 // it probably indicates an older client just copied the previous 614 // MDRefBytes value as an unknown field. 615 if nextMd.MDDiskUsage() != expectedMDUsage && 616 md.MDRefBytes() != nextMd.MDRefBytes() { 617 return MDDiskUsageMismatch{ 618 expectedDiskUsage: expectedMDUsage, 619 actualDiskUsage: nextMd.MDDiskUsage(), 620 } 621 } 622 623 // TODO: Check that the successor (bare) TLF handle is the 624 // same or more resolved. 625 626 return nil 627 } 628 629 // CheckValidSuccessorForServer implements the RootMetadata interface for RootMetadataV3. 630 func (md *RootMetadataV3) CheckValidSuccessorForServer( 631 currID ID, nextMd RootMetadata) error { 632 err := md.CheckValidSuccessor(currID, nextMd) 633 switch err := err.(type) { 634 case nil: 635 break 636 637 case MDRevisionMismatch: 638 return ServerErrorConflictRevision{ 639 Expected: err.Curr + 1, 640 Actual: err.Rev, 641 } 642 643 case MDPrevRootMismatch: 644 return ServerErrorConflictPrevRoot{ 645 Expected: err.expectedPrevRoot, 646 Actual: err.prevRoot, 647 } 648 649 case MDDiskUsageMismatch: 650 return ServerErrorConflictDiskUsage{ 651 Expected: err.expectedDiskUsage, 652 Actual: err.actualDiskUsage, 653 } 654 655 default: 656 return ServerError{Err: err} 657 } 658 659 return nil 660 } 661 662 // isBackedByTeam returns true if md is for a TLF backed by a team. It could be 663 // either a SingleTeam TLF or a private/public TLF backed by an implicit team. 664 func (md *RootMetadataV3) isBackedByTeam() bool { 665 if len(md.WriterMetadata.UnresolvedWriters) != 0 { 666 return false 667 } 668 if len(md.WriterMetadata.Writers) != 1 { 669 return false 670 } 671 if !md.WriterMetadata.Writers[0].IsTeamOrSubteam() { 672 return false 673 } 674 return true 675 } 676 677 // TypeForKeying implements the RootMetadata interface for RootMetadataV3. 678 func (md *RootMetadataV3) TypeForKeying() tlf.KeyingType { 679 if md.isBackedByTeam() { 680 return tlf.TeamKeying 681 } 682 return md.TlfID().Type().ToKeyingType() 683 } 684 685 // MakeBareTlfHandle implements the RootMetadata interface for RootMetadataV3. 686 func (md *RootMetadataV3) MakeBareTlfHandle(extra ExtraMetadata) ( 687 tlf.Handle, error) { 688 var writers, readers []keybase1.UserOrTeamID 689 if md.TypeForKeying() == tlf.PrivateKeying { 690 wkb, rkb, err := md.getTLFKeyBundles(extra) 691 if err != nil { 692 return tlf.Handle{}, err 693 } 694 writers = make([]keybase1.UserOrTeamID, 0, len(wkb.Keys)) 695 readers = make([]keybase1.UserOrTeamID, 0, len(rkb.Keys)) 696 for w := range wkb.Keys { 697 writers = append(writers, w.AsUserOrTeam()) 698 } 699 for r := range rkb.Keys { 700 // TODO: Return an error instead if r is 701 // PublicUID. Maybe return an error if r is in 702 // WKeys also. Or do all this in 703 // MakeBareTlfHandle. 704 if _, ok := wkb.Keys[r]; !ok && 705 r != keybase1.PublicUID { 706 readers = append(readers, r.AsUserOrTeam()) 707 } 708 } 709 } else { 710 err := md.checkNonPrivateExtra(extra) 711 if err != nil { 712 return tlf.Handle{}, err 713 } 714 715 writers = md.WriterMetadata.Writers 716 if md.TypeForKeying() == tlf.PublicKeying { 717 readers = []keybase1.UserOrTeamID{keybase1.PublicUID.AsUserOrTeam()} 718 } 719 } 720 721 return tlf.MakeHandle( 722 writers, readers, 723 md.WriterMetadata.UnresolvedWriters, md.UnresolvedReaders, 724 md.TlfHandleExtensions()) 725 } 726 727 // TlfHandleExtensions implements the RootMetadata interface for RootMetadataV3. 728 func (md *RootMetadataV3) TlfHandleExtensions() ( 729 extensions []tlf.HandleExtension) { 730 if md.ConflictInfo != nil { 731 extensions = append(extensions, *md.ConflictInfo) 732 } 733 if md.FinalizedInfo != nil { 734 extensions = append(extensions, *md.FinalizedInfo) 735 } 736 return extensions 737 } 738 739 // PromoteReaders implements the RootMetadata interface for 740 // RootMetadataV3. 741 func (md *RootMetadataV3) PromoteReaders( 742 readersToPromote map[keybase1.UID]bool, extra ExtraMetadata) error { 743 if md.TypeForKeying() != tlf.PrivateKeying { 744 return InvalidNonPrivateTLFOperation{md.TlfID(), "PromoteReaders", md.Version()} 745 } 746 747 if len(readersToPromote) == 0 { 748 return nil 749 } 750 751 wkb, rkb, err := md.getTLFKeyBundles(extra) 752 if err != nil { 753 return err 754 } 755 756 for reader := range readersToPromote { 757 dkim, ok := rkb.Keys[reader] 758 if !ok { 759 return errors.Errorf("Could not find %s in rkb", reader) 760 } 761 // TODO: This is incorrect, since dkim contains offsets info 762 // rkb.TLFEphemeralPublicKeys, which don't directly translate 763 // to offsets into wkb.TLFEphemeralPublicKeys. 764 // 765 // Also, doing this may leave some entries in 766 // rkb.TLFEphemeralPublicKeys unreferenced, so they should be 767 // removed. 768 // 769 // See KBFS-1719. 770 wkb.Keys[reader] = dkim 771 delete(rkb.Keys, reader) 772 } 773 return nil 774 } 775 776 // RevokeRemovedDevices implements the RootMetadata interface for 777 // RootMetadataV3. 778 func (md *RootMetadataV3) RevokeRemovedDevices( 779 updatedWriterKeys, updatedReaderKeys UserDevicePublicKeys, 780 extra ExtraMetadata) (ServerHalfRemovalInfo, error) { 781 if md.TypeForKeying() != tlf.PrivateKeying { 782 return nil, InvalidNonPrivateTLFOperation{ 783 md.TlfID(), "RevokeRemovedDevices", md.Version()} 784 } 785 786 wkb, rkb, err := md.getTLFKeyBundles(extra) 787 if err != nil { 788 return nil, err 789 } 790 791 wRemovalInfo := wkb.Keys.RemoveDevicesNotIn(updatedWriterKeys) 792 rRemovalInfo := rkb.Keys.RemoveDevicesNotIn(updatedReaderKeys) 793 return wRemovalInfo.MergeUsers(rRemovalInfo) 794 } 795 796 // GetUserDevicePublicKeys implements the RootMetadata interface 797 // for RootMetadataV3. 798 func (md *RootMetadataV3) GetUserDevicePublicKeys(extra ExtraMetadata) ( 799 writerDeviceKeys, readerDeviceKeys UserDevicePublicKeys, err error) { 800 if md.TypeForKeying() != tlf.PrivateKeying { 801 return nil, nil, InvalidNonPrivateTLFOperation{ 802 md.TlfID(), "GetUserDevicePublicKeys", md.Version()} 803 } 804 805 wkb, rkb, err := md.getTLFKeyBundles(extra) 806 if err != nil { 807 return nil, nil, err 808 } 809 810 return wkb.Keys.ToPublicKeys(), rkb.Keys.ToPublicKeys(), nil 811 } 812 813 // GetTLFCryptKeyParams implements the RootMetadata interface for RootMetadataV3. 814 func (md *RootMetadataV3) GetTLFCryptKeyParams( 815 keyGen KeyGen, user keybase1.UID, 816 key kbfscrypto.CryptPublicKey, extra ExtraMetadata) ( 817 kbfscrypto.TLFEphemeralPublicKey, 818 kbfscrypto.EncryptedTLFCryptKeyClientHalf, 819 kbfscrypto.TLFCryptKeyServerHalfID, bool, error) { 820 if keyGen != md.LatestKeyGeneration() { 821 return kbfscrypto.TLFEphemeralPublicKey{}, 822 kbfscrypto.EncryptedTLFCryptKeyClientHalf{}, 823 kbfscrypto.TLFCryptKeyServerHalfID{}, false, 824 TLFCryptKeyNotPerDeviceEncrypted{md.TlfID(), keyGen} 825 } 826 wkb, rkb, err := md.getTLFKeyBundles(extra) 827 if err != nil { 828 return kbfscrypto.TLFEphemeralPublicKey{}, 829 kbfscrypto.EncryptedTLFCryptKeyClientHalf{}, 830 kbfscrypto.TLFCryptKeyServerHalfID{}, false, err 831 } 832 isWriter := true 833 dkim := wkb.Keys[user] 834 if dkim == nil { 835 dkim = rkb.Keys[user] 836 if dkim == nil { 837 return kbfscrypto.TLFEphemeralPublicKey{}, 838 kbfscrypto.EncryptedTLFCryptKeyClientHalf{}, 839 kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil 840 } 841 isWriter = false 842 } 843 info, ok := dkim[key] 844 if !ok { 845 return kbfscrypto.TLFEphemeralPublicKey{}, 846 kbfscrypto.EncryptedTLFCryptKeyClientHalf{}, 847 kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil 848 } 849 850 var publicKeys kbfscrypto.TLFEphemeralPublicKeys 851 var keyType string 852 if isWriter { 853 publicKeys = wkb.TLFEphemeralPublicKeys 854 keyType = "writer" 855 } else { 856 publicKeys = rkb.TLFEphemeralPublicKeys 857 keyType = "reader" 858 } 859 keyCount := len(publicKeys) 860 index := info.EPubKeyIndex 861 if index >= keyCount { 862 return kbfscrypto.TLFEphemeralPublicKey{}, 863 kbfscrypto.EncryptedTLFCryptKeyClientHalf{}, 864 kbfscrypto.TLFCryptKeyServerHalfID{}, false, 865 errors.Errorf("Invalid %s key index %d >= %d", 866 keyType, index, keyCount) 867 } 868 return publicKeys[index], info.ClientHalf, info.ServerHalfID, true, nil 869 } 870 871 // CheckWKBID returns an error if the ID of the given writer key 872 // bundle doesn't match the given one. 873 func CheckWKBID(codec kbfscodec.Codec, 874 wkbID TLFWriterKeyBundleID, wkb TLFWriterKeyBundleV3) error { 875 computedWKBID, err := MakeTLFWriterKeyBundleID(codec, wkb) 876 if err != nil { 877 return err 878 } 879 880 if wkbID != computedWKBID { 881 return errors.Errorf("Expected WKB ID %s, got %s", 882 wkbID, computedWKBID) 883 } 884 885 return nil 886 } 887 888 // CheckRKBID returns an error if the ID of the given reader key 889 // bundle doesn't match the given one. 890 func CheckRKBID(codec kbfscodec.Codec, 891 rkbID TLFReaderKeyBundleID, rkb TLFReaderKeyBundleV3) error { 892 computedRKBID, err := MakeTLFReaderKeyBundleID(codec, rkb) 893 if err != nil { 894 return err 895 } 896 897 if rkbID != computedRKBID { 898 return errors.Errorf("Expected RKB ID %s, got %s", 899 rkbID, computedRKBID) 900 } 901 902 return nil 903 } 904 905 // IsValidAndSigned implements the RootMetadata interface for RootMetadataV3. 906 func (md *RootMetadataV3) IsValidAndSigned( 907 ctx context.Context, codec kbfscodec.Codec, 908 teamMemChecker TeamMembershipChecker, extra ExtraMetadata, 909 writerVerifyingKey kbfscrypto.VerifyingKey, 910 offline keybase1.OfflineAvailability) error { 911 if md.TypeForKeying() == tlf.PrivateKeying { 912 wkb, rkb, err := md.getTLFKeyBundles(extra) 913 if err != nil { 914 return err 915 } 916 917 err = CheckWKBID(codec, md.GetTLFWriterKeyBundleID(), *wkb) 918 if err != nil { 919 return err 920 } 921 922 err = CheckRKBID(codec, md.GetTLFReaderKeyBundleID(), *rkb) 923 if err != nil { 924 return err 925 } 926 } else { 927 err := md.checkNonPrivateExtra(extra) 928 if err != nil { 929 return err 930 } 931 } 932 933 if md.IsFinal() { 934 if md.Revision < RevisionInitial+1 { 935 return errors.Errorf("Invalid final revision %d", md.Revision) 936 } 937 938 if md.Revision == (RevisionInitial + 1) { 939 if md.PrevRoot != (ID{}) { 940 return errors.Errorf("Invalid PrevRoot %s for initial final revision", md.PrevRoot) 941 } 942 } else { 943 if md.PrevRoot == (ID{}) { 944 return errors.New("No PrevRoot for non-initial final revision") 945 } 946 } 947 } else { 948 if md.Revision < RevisionInitial { 949 return errors.Errorf("Invalid revision %d", md.Revision) 950 } 951 952 if md.Revision == RevisionInitial { 953 if md.PrevRoot != (ID{}) { 954 return errors.Errorf("Invalid PrevRoot %s for initial revision", md.PrevRoot) 955 } 956 } else { 957 if md.PrevRoot == (ID{}) { 958 return errors.New("No PrevRoot for non-initial revision") 959 } 960 } 961 } 962 963 if len(md.WriterMetadata.SerializedPrivateMetadata) == 0 { 964 return errors.New("No private metadata") 965 } 966 967 if (md.MergedStatus() == Merged) != (md.BID() == NullBranchID) { 968 return errors.Errorf("Branch ID %s doesn't match merged status %s", 969 md.BID(), md.MergedStatus()) 970 } 971 972 handle, err := md.MakeBareTlfHandle(extra) 973 if err != nil { 974 return err 975 } 976 977 writer := md.LastModifyingWriter() 978 user := md.LastModifyingUser 979 var isWriter, isReader bool 980 if md.TypeForKeying() == tlf.TeamKeying { 981 tid, err := md.WriterMetadata.Writers[0].AsTeam() 982 if err != nil { 983 return err 984 } 985 986 isWriter, err = teamMemChecker.IsTeamWriter( 987 ctx, tid, writer, writerVerifyingKey, offline) 988 if err != nil { 989 return err 990 } 991 992 isReader, err = teamMemChecker.IsTeamReader(ctx, tid, user, offline) 993 if err != nil { 994 return err 995 } 996 } else { 997 isWriter = handle.IsWriter(writer.AsUserOrTeam()) 998 isReader = handle.IsReader(user.AsUserOrTeam()) 999 } 1000 1001 // Make sure the last writer is valid. 1002 if !isWriter { 1003 return errors.Errorf("Invalid modifying writer %s", writer) 1004 } 1005 // Make sure the last modifier is valid. 1006 if !isReader { 1007 return errors.Errorf("Invalid modifying user %s", user) 1008 } 1009 1010 return nil 1011 } 1012 1013 // IsLastModifiedBy implements the RootMetadata interface for 1014 // RootMetadataV3. 1015 func (md *RootMetadataV3) IsLastModifiedBy( 1016 uid keybase1.UID, key kbfscrypto.VerifyingKey) error { 1017 // Verify the user and device are the writer. 1018 writer := md.LastModifyingWriter() 1019 if !md.IsWriterMetadataCopiedSet() { 1020 if writer != uid { 1021 return errors.Errorf("Last writer %s != %s", writer, uid) 1022 } 1023 } 1024 1025 // Verify the user and device are the last modifier. 1026 user := md.GetLastModifyingUser() 1027 if user != uid { 1028 return errors.Errorf("Last modifier %s != %s", user, uid) 1029 } 1030 1031 return nil 1032 } 1033 1034 // LastModifyingWriter implements the RootMetadata interface for RootMetadataV3. 1035 func (md *RootMetadataV3) LastModifyingWriter() keybase1.UID { 1036 return md.WriterMetadata.LastModifyingWriter 1037 } 1038 1039 // GetLastModifyingUser implements the RootMetadata interface for RootMetadataV3. 1040 func (md *RootMetadataV3) GetLastModifyingUser() keybase1.UID { 1041 return md.LastModifyingUser 1042 } 1043 1044 // RefBytes implements the RootMetadata interface for RootMetadataV3. 1045 func (md *RootMetadataV3) RefBytes() uint64 { 1046 return md.WriterMetadata.RefBytes 1047 } 1048 1049 // UnrefBytes implements the RootMetadata interface for RootMetadataV3. 1050 func (md *RootMetadataV3) UnrefBytes() uint64 { 1051 return md.WriterMetadata.UnrefBytes 1052 } 1053 1054 // MDRefBytes implements the RootMetadata interface for RootMetadataV3. 1055 func (md *RootMetadataV3) MDRefBytes() uint64 { 1056 return md.WriterMetadata.MDRefBytes 1057 } 1058 1059 // DiskUsage implements the RootMetadata interface for RootMetadataV3. 1060 func (md *RootMetadataV3) DiskUsage() uint64 { 1061 return md.WriterMetadata.DiskUsage 1062 } 1063 1064 // MDDiskUsage implements the RootMetadata interface for RootMetadataV3. 1065 func (md *RootMetadataV3) MDDiskUsage() uint64 { 1066 return md.WriterMetadata.MDDiskUsage 1067 } 1068 1069 // SetRefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1070 func (md *RootMetadataV3) SetRefBytes(refBytes uint64) { 1071 md.WriterMetadata.RefBytes = refBytes 1072 } 1073 1074 // SetUnrefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1075 func (md *RootMetadataV3) SetUnrefBytes(unrefBytes uint64) { 1076 md.WriterMetadata.UnrefBytes = unrefBytes 1077 } 1078 1079 // SetMDRefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1080 func (md *RootMetadataV3) SetMDRefBytes(mdRefBytes uint64) { 1081 md.WriterMetadata.MDRefBytes = mdRefBytes 1082 } 1083 1084 // SetDiskUsage implements the MutableRootMetadata interface for RootMetadataV3. 1085 func (md *RootMetadataV3) SetDiskUsage(diskUsage uint64) { 1086 md.WriterMetadata.DiskUsage = diskUsage 1087 } 1088 1089 // SetMDDiskUsage implements the MutableRootMetadata interface for RootMetadataV3. 1090 func (md *RootMetadataV3) SetMDDiskUsage(mdDiskUsage uint64) { 1091 md.WriterMetadata.MDDiskUsage = mdDiskUsage 1092 } 1093 1094 // AddRefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1095 func (md *RootMetadataV3) AddRefBytes(refBytes uint64) { 1096 md.WriterMetadata.RefBytes += refBytes 1097 } 1098 1099 // AddUnrefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1100 func (md *RootMetadataV3) AddUnrefBytes(unrefBytes uint64) { 1101 md.WriterMetadata.UnrefBytes += unrefBytes 1102 } 1103 1104 // AddMDRefBytes implements the MutableRootMetadata interface for RootMetadataV3. 1105 func (md *RootMetadataV3) AddMDRefBytes(mdRefBytes uint64) { 1106 md.WriterMetadata.MDRefBytes += mdRefBytes 1107 } 1108 1109 // AddDiskUsage implements the MutableRootMetadata interface for RootMetadataV3. 1110 func (md *RootMetadataV3) AddDiskUsage(diskUsage uint64) { 1111 md.WriterMetadata.DiskUsage += diskUsage 1112 } 1113 1114 // AddMDDiskUsage implements the MutableRootMetadata interface for RootMetadataV3. 1115 func (md *RootMetadataV3) AddMDDiskUsage(mdDiskUsage uint64) { 1116 md.WriterMetadata.MDDiskUsage += mdDiskUsage 1117 } 1118 1119 // RevisionNumber implements the RootMetadata interface for RootMetadataV3. 1120 func (md *RootMetadataV3) RevisionNumber() Revision { 1121 return md.Revision 1122 } 1123 1124 // BID implements the RootMetadata interface for RootMetadataV3. 1125 func (md *RootMetadataV3) BID() BranchID { 1126 return md.WriterMetadata.BID 1127 } 1128 1129 // GetPrevRoot implements the RootMetadata interface for RootMetadataV3. 1130 func (md *RootMetadataV3) GetPrevRoot() ID { 1131 return md.PrevRoot 1132 } 1133 1134 // ClearRekeyBit implements the MutableRootMetadata interface for RootMetadataV3. 1135 func (md *RootMetadataV3) ClearRekeyBit() { 1136 md.Flags &= ^MetadataFlagRekey 1137 } 1138 1139 // ClearWriterMetadataCopiedBit implements the MutableRootMetadata interface for RootMetadataV3. 1140 func (md *RootMetadataV3) ClearWriterMetadataCopiedBit() { 1141 md.Flags &= ^MetadataFlagWriterMetadataCopied 1142 } 1143 1144 // IsUnmergedSet implements the MutableRootMetadata interface for RootMetadataV3. 1145 func (md *RootMetadataV3) IsUnmergedSet() bool { 1146 return (md.WriterMetadata.WFlags & MetadataFlagUnmerged) != 0 1147 } 1148 1149 // SetUnmerged implements the MutableRootMetadata interface for RootMetadataV3. 1150 func (md *RootMetadataV3) SetUnmerged() { 1151 md.WriterMetadata.WFlags |= MetadataFlagUnmerged 1152 } 1153 1154 // SetBranchID implements the MutableRootMetadata interface for RootMetadataV3. 1155 func (md *RootMetadataV3) SetBranchID(bid BranchID) { 1156 md.WriterMetadata.BID = bid 1157 } 1158 1159 // SetPrevRoot implements the MutableRootMetadata interface for RootMetadataV3. 1160 func (md *RootMetadataV3) SetPrevRoot(mdID ID) { 1161 md.PrevRoot = mdID 1162 } 1163 1164 // GetSerializedPrivateMetadata implements the RootMetadata interface for RootMetadataV3. 1165 func (md *RootMetadataV3) GetSerializedPrivateMetadata() []byte { 1166 return md.WriterMetadata.SerializedPrivateMetadata 1167 } 1168 1169 // SetSerializedPrivateMetadata implements the MutableRootMetadata interface for RootMetadataV3. 1170 func (md *RootMetadataV3) SetSerializedPrivateMetadata(spmd []byte) { 1171 md.WriterMetadata.SerializedPrivateMetadata = spmd 1172 } 1173 1174 // GetSerializedWriterMetadata implements the RootMetadata interface for RootMetadataV3. 1175 func (md *RootMetadataV3) GetSerializedWriterMetadata( 1176 codec kbfscodec.Codec) ([]byte, error) { 1177 return codec.Encode(md.WriterMetadata) 1178 } 1179 1180 // SignWriterMetadataInternally implements the MutableRootMetadata interface for RootMetadataV2. 1181 func (md *RootMetadataV3) SignWriterMetadataInternally( 1182 ctx context.Context, codec kbfscodec.Codec, 1183 signer kbfscrypto.Signer) error { 1184 // Nothing to do. 1185 // 1186 // TODO: Set a flag, and a way to check it so that we can 1187 // verify that this is called before sending to the server. 1188 return nil 1189 } 1190 1191 // SetLastModifyingWriter implements the MutableRootMetadata interface for RootMetadataV3. 1192 func (md *RootMetadataV3) SetLastModifyingWriter(user keybase1.UID) { 1193 md.WriterMetadata.LastModifyingWriter = user 1194 } 1195 1196 // SetLastModifyingUser implements the MutableRootMetadata interface for RootMetadataV3. 1197 func (md *RootMetadataV3) SetLastModifyingUser(user keybase1.UID) { 1198 md.LastModifyingUser = user 1199 } 1200 1201 // SetRekeyBit implements the MutableRootMetadata interface for RootMetadataV3. 1202 func (md *RootMetadataV3) SetRekeyBit() { 1203 md.Flags |= MetadataFlagRekey 1204 } 1205 1206 // SetFinalBit implements the MutableRootMetadata interface for RootMetadataV3. 1207 func (md *RootMetadataV3) SetFinalBit() { 1208 md.Flags |= MetadataFlagFinal 1209 } 1210 1211 // SetWriterMetadataCopiedBit implements the MutableRootMetadata interface for RootMetadataV3. 1212 func (md *RootMetadataV3) SetWriterMetadataCopiedBit() { 1213 md.Flags |= MetadataFlagWriterMetadataCopied 1214 } 1215 1216 // SetRevision implements the MutableRootMetadata interface for RootMetadataV3. 1217 func (md *RootMetadataV3) SetRevision(revision Revision) { 1218 md.Revision = revision 1219 } 1220 1221 func (md *RootMetadataV3) updateKeyBundles(codec kbfscodec.Codec, 1222 extra ExtraMetadata, 1223 updatedWriterKeys, updatedReaderKeys UserDevicePublicKeys, 1224 ePubKey kbfscrypto.TLFEphemeralPublicKey, 1225 ePrivKey kbfscrypto.TLFEphemeralPrivateKey, 1226 tlfCryptKey kbfscrypto.TLFCryptKey) (UserDeviceKeyServerHalves, error) { 1227 if md.TypeForKeying() != tlf.PrivateKeying { 1228 return nil, InvalidNonPrivateTLFOperation{ 1229 md.TlfID(), "updateKeyBundles", md.Version()} 1230 } 1231 1232 wkb, rkb, err := md.getTLFKeyBundles(extra) 1233 if err != nil { 1234 return nil, err 1235 } 1236 1237 // No need to explicitly handle the reader rekey case. 1238 1239 var newWriterIndex int 1240 if len(updatedWriterKeys) > 0 { 1241 newWriterIndex = len(wkb.TLFEphemeralPublicKeys) 1242 } 1243 wServerHalves, err := wkb.Keys.FillInUserInfos( 1244 newWriterIndex, updatedWriterKeys, 1245 ePrivKey, tlfCryptKey) 1246 if err != nil { 1247 return nil, err 1248 } 1249 // If we didn't fill in any new writer infos, don't add a new 1250 // writer ephemeral key. 1251 if len(wServerHalves) > 0 { 1252 wkb.TLFEphemeralPublicKeys = 1253 append(wkb.TLFEphemeralPublicKeys, ePubKey) 1254 } 1255 1256 var newReaderIndex int 1257 if len(updatedReaderKeys) > 0 { 1258 newReaderIndex = len(rkb.TLFEphemeralPublicKeys) 1259 } 1260 rServerHalves, err := rkb.Keys.FillInUserInfos( 1261 newReaderIndex, updatedReaderKeys, 1262 ePrivKey, tlfCryptKey) 1263 if err != nil { 1264 return nil, err 1265 } 1266 // If we didn't fill in any new reader infos, don't add a new 1267 // reader ephemeral key. 1268 if len(rServerHalves) > 0 { 1269 rkb.TLFEphemeralPublicKeys = 1270 append(rkb.TLFEphemeralPublicKeys, ePubKey) 1271 } 1272 1273 return wServerHalves.MergeUsers(rServerHalves) 1274 } 1275 1276 // AddKeyGeneration implements the MutableRootMetadata interface 1277 // for RootMetadataV3. 1278 func (md *RootMetadataV3) AddKeyGeneration( 1279 codec kbfscodec.Codec, currExtra ExtraMetadata, 1280 updatedWriterKeys, updatedReaderKeys UserDevicePublicKeys, 1281 ePubKey kbfscrypto.TLFEphemeralPublicKey, 1282 ePrivKey kbfscrypto.TLFEphemeralPrivateKey, 1283 pubKey kbfscrypto.TLFPublicKey, 1284 currCryptKey, nextCryptKey kbfscrypto.TLFCryptKey) ( 1285 nextExtra ExtraMetadata, 1286 serverHalves UserDeviceKeyServerHalves, err error) { 1287 if md.TypeForKeying() != tlf.PrivateKeying { 1288 return nil, nil, InvalidNonPrivateTLFOperation{ 1289 md.TlfID(), "AddKeyGeneration", md.Version()} 1290 } 1291 1292 if len(updatedWriterKeys) == 0 { 1293 return nil, nil, errors.New( 1294 "updatedWriterKeys unexpectedly empty") 1295 } 1296 1297 if nextCryptKey == (kbfscrypto.TLFCryptKey{}) { 1298 return nil, nil, errors.New("Zero next crypt key") 1299 } 1300 1301 latestKeyGen := md.LatestKeyGeneration() 1302 var encryptedHistoricKeys kbfscrypto.EncryptedTLFCryptKeys 1303 if currCryptKey == (kbfscrypto.TLFCryptKey{}) { 1304 if latestKeyGen >= FirstValidKeyGen { 1305 return nil, nil, errors.Errorf( 1306 "Zero current crypt key with latest key generation %d", 1307 latestKeyGen) 1308 } 1309 } else { 1310 currExtraV3, ok := currExtra.(*ExtraMetadataV3) 1311 if !ok { 1312 return nil, nil, errors.New("Invalid curr extra metadata") 1313 } 1314 1315 existingWriterKeys := currExtraV3.wkb.Keys.ToPublicKeys() 1316 if !existingWriterKeys.Equals(updatedWriterKeys) { 1317 return nil, nil, fmt.Errorf( 1318 "existingWriterKeys=%+v != updatedWriterKeys=%+v", 1319 existingWriterKeys, updatedWriterKeys) 1320 } 1321 1322 existingReaderKeys := currExtraV3.rkb.Keys.ToPublicKeys() 1323 if !existingReaderKeys.Equals(updatedReaderKeys) { 1324 return nil, nil, fmt.Errorf( 1325 "existingReaderKeys=%+v != updatedReaderKeys=%+v", 1326 existingReaderKeys, updatedReaderKeys) 1327 } 1328 1329 if latestKeyGen < FirstValidKeyGen { 1330 return nil, nil, errors.New( 1331 "Non-zero current crypt key with no existing key generations") 1332 } 1333 var historicKeys []kbfscrypto.TLFCryptKey 1334 if latestKeyGen > FirstValidKeyGen { 1335 var err error 1336 historicKeys, err = kbfscrypto.DecryptTLFCryptKeys( 1337 codec, 1338 currExtraV3.wkb.EncryptedHistoricTLFCryptKeys, 1339 currCryptKey) 1340 if err != nil { 1341 return nil, nil, err 1342 } 1343 expectedHistoricKeyCount := 1344 int(md.LatestKeyGeneration() - FirstValidKeyGen) 1345 if len(historicKeys) != expectedHistoricKeyCount { 1346 return nil, nil, errors.Errorf( 1347 "Expected %d historic keys, got %d", 1348 expectedHistoricKeyCount, 1349 len(historicKeys)) 1350 } 1351 } 1352 historicKeys = append(historicKeys, currCryptKey) 1353 var err error 1354 encryptedHistoricKeys, err = kbfscrypto.EncryptTLFCryptKeys( 1355 codec, historicKeys, nextCryptKey) 1356 if err != nil { 1357 return nil, nil, err 1358 } 1359 } 1360 1361 newWriterKeys := TLFWriterKeyBundleV3{ 1362 Keys: make(UserDeviceKeyInfoMapV3), 1363 TLFPublicKey: pubKey, 1364 EncryptedHistoricTLFCryptKeys: encryptedHistoricKeys, 1365 } 1366 newReaderKeys := TLFReaderKeyBundleV3{ 1367 Keys: make(UserDeviceKeyInfoMapV3), 1368 } 1369 md.WriterMetadata.LatestKeyGen++ 1370 nextExtra = NewExtraMetadataV3(newWriterKeys, newReaderKeys, true, true) 1371 1372 serverHalves, err = md.updateKeyBundles(codec, nextExtra, 1373 updatedWriterKeys, updatedReaderKeys, 1374 ePubKey, ePrivKey, nextCryptKey) 1375 if err != nil { 1376 return nil, nil, err 1377 } 1378 1379 return nextExtra, serverHalves, nil 1380 } 1381 1382 // SetLatestKeyGenerationForTeamTLF implements the 1383 // MutableRootMetadata interface for RootMetadataV3. 1384 func (md *RootMetadataV3) SetLatestKeyGenerationForTeamTLF(keyGen KeyGen) { 1385 if md.TypeForKeying() != tlf.TeamKeying { 1386 panic(fmt.Sprintf( 1387 "Can't call SetLatestKeyGenerationForTeamTLF on a %s TLF", 1388 md.TypeForKeying())) 1389 } 1390 1391 md.WriterMetadata.LatestKeyGen = keyGen 1392 } 1393 1394 // SetUnresolvedReaders implements the MutableRootMetadata interface for RootMetadataV3. 1395 func (md *RootMetadataV3) SetUnresolvedReaders(readers []keybase1.SocialAssertion) { 1396 md.UnresolvedReaders = readers 1397 } 1398 1399 // SetUnresolvedWriters implements the MutableRootMetadata interface for RootMetadataV3. 1400 func (md *RootMetadataV3) SetUnresolvedWriters(writers []keybase1.SocialAssertion) { 1401 md.WriterMetadata.UnresolvedWriters = writers 1402 } 1403 1404 // SetConflictInfo implements the MutableRootMetadata interface for RootMetadataV3. 1405 func (md *RootMetadataV3) SetConflictInfo(ci *tlf.HandleExtension) { 1406 md.ConflictInfo = ci 1407 } 1408 1409 // SetFinalizedInfo implements the MutableRootMetadata interface for RootMetadataV3. 1410 func (md *RootMetadataV3) SetFinalizedInfo(fi *tlf.HandleExtension) { 1411 md.FinalizedInfo = fi 1412 } 1413 1414 // SetWriters implements the MutableRootMetadata interface for RootMetadataV3. 1415 func (md *RootMetadataV3) SetWriters(writers []keybase1.UserOrTeamID) { 1416 md.WriterMetadata.Writers = writers 1417 } 1418 1419 // ClearForV4Migration implements the MutableRootMetadata interface 1420 // for RootMetadataV3. 1421 func (md *RootMetadataV3) ClearForV4Migration() { 1422 md.WriterMetadata.WKeyBundleID = TLFWriterKeyBundleID{} 1423 md.RKeyBundleID = TLFReaderKeyBundleID{} 1424 } 1425 1426 // SetTlfID implements the MutableRootMetadata interface for RootMetadataV3. 1427 func (md *RootMetadataV3) SetTlfID(tlf tlf.ID) { 1428 md.WriterMetadata.ID = tlf 1429 } 1430 1431 // ClearFinalBit implements the MutableRootMetadata interface for RootMetadataV3. 1432 func (md *RootMetadataV3) ClearFinalBit() { 1433 md.Flags &= ^MetadataFlagFinal 1434 } 1435 1436 // Version implements the MutableRootMetadata interface for RootMetadataV3. 1437 func (md *RootMetadataV3) Version() MetadataVer { 1438 if md.TlfID().Type() != tlf.SingleTeam && 1439 md.TypeForKeying() == tlf.TeamKeying { 1440 return ImplicitTeamsVer 1441 } 1442 return SegregatedKeyBundlesVer 1443 } 1444 1445 // GetCurrentTLFPublicKey implements the RootMetadata interface 1446 // for RootMetadataV3. 1447 func (md *RootMetadataV3) GetCurrentTLFPublicKey( 1448 extra ExtraMetadata) (kbfscrypto.TLFPublicKey, error) { 1449 wkb, _, err := md.getTLFKeyBundles(extra) 1450 if err != nil { 1451 return kbfscrypto.TLFPublicKey{}, err 1452 } 1453 return wkb.TLFPublicKey, nil 1454 } 1455 1456 // GetUnresolvedParticipants implements the RootMetadata interface for RootMetadataV3. 1457 func (md *RootMetadataV3) GetUnresolvedParticipants() []keybase1.SocialAssertion { 1458 writers := md.WriterMetadata.UnresolvedWriters 1459 readers := md.UnresolvedReaders 1460 users := make([]keybase1.SocialAssertion, 0, len(writers)+len(readers)) 1461 users = append(users, writers...) 1462 users = append(users, readers...) 1463 return users 1464 } 1465 1466 // UpdateKeyBundles implements the MutableRootMetadata interface 1467 // for RootMetadataV3. 1468 func (md *RootMetadataV3) UpdateKeyBundles(codec kbfscodec.Codec, 1469 extra ExtraMetadata, 1470 updatedWriterKeys, updatedReaderKeys UserDevicePublicKeys, 1471 ePubKey kbfscrypto.TLFEphemeralPublicKey, 1472 ePrivKey kbfscrypto.TLFEphemeralPrivateKey, 1473 tlfCryptKeys []kbfscrypto.TLFCryptKey) ( 1474 []UserDeviceKeyServerHalves, error) { 1475 if len(tlfCryptKeys) != 1 { 1476 return nil, fmt.Errorf( 1477 "(MDv3) Expected 1 TLF crypt key, got %d", 1478 len(tlfCryptKeys)) 1479 } 1480 1481 serverHalves, err := md.updateKeyBundles(codec, extra, 1482 updatedWriterKeys, updatedReaderKeys, 1483 ePubKey, ePrivKey, tlfCryptKeys[0]) 1484 if err != nil { 1485 return nil, err 1486 } 1487 1488 return []UserDeviceKeyServerHalves{serverHalves}, nil 1489 } 1490 1491 // GetTLFWriterKeyBundleID implements the RootMetadata interface for RootMetadataV3. 1492 func (md *RootMetadataV3) GetTLFWriterKeyBundleID() TLFWriterKeyBundleID { 1493 return md.WriterMetadata.WKeyBundleID 1494 } 1495 1496 // GetTLFReaderKeyBundleID implements the RootMetadata interface for RootMetadataV3. 1497 func (md *RootMetadataV3) GetTLFReaderKeyBundleID() TLFReaderKeyBundleID { 1498 return md.RKeyBundleID 1499 } 1500 1501 // FinalizeRekey implements the MutableRootMetadata interface for RootMetadataV3. 1502 func (md *RootMetadataV3) FinalizeRekey( 1503 codec kbfscodec.Codec, extra ExtraMetadata) error { 1504 extraV3, ok := extra.(*ExtraMetadataV3) 1505 if !ok { 1506 return errors.New("Invalid extra metadata") 1507 } 1508 oldWKBID := md.WriterMetadata.WKeyBundleID 1509 oldRKBID := md.RKeyBundleID 1510 1511 newWKBID, err := MakeTLFWriterKeyBundleID(codec, extraV3.wkb) 1512 if err != nil { 1513 return err 1514 } 1515 newRKBID, err := MakeTLFReaderKeyBundleID(codec, extraV3.rkb) 1516 if err != nil { 1517 return err 1518 } 1519 1520 md.WriterMetadata.WKeyBundleID = newWKBID 1521 md.RKeyBundleID = newRKBID 1522 1523 extraV3.updateNew(newWKBID != oldWKBID, newRKBID != oldRKBID) 1524 1525 return nil 1526 } 1527 1528 // StoresHistoricTLFCryptKeys implements the RootMetadata interface for RootMetadataV3. 1529 func (md *RootMetadataV3) StoresHistoricTLFCryptKeys() bool { 1530 return true 1531 } 1532 1533 // GetHistoricTLFCryptKey implements the RootMetadata interface for RootMetadataV3. 1534 func (md *RootMetadataV3) GetHistoricTLFCryptKey(codec kbfscodec.Codec, 1535 keyGen KeyGen, currentKey kbfscrypto.TLFCryptKey, extra ExtraMetadata) ( 1536 kbfscrypto.TLFCryptKey, error) { 1537 extraV3, ok := extra.(*ExtraMetadataV3) 1538 if !ok { 1539 return kbfscrypto.TLFCryptKey{}, errors.New( 1540 "Invalid extra metadata") 1541 } 1542 if keyGen < FirstValidKeyGen || keyGen >= md.LatestKeyGeneration() { 1543 return kbfscrypto.TLFCryptKey{}, errors.Errorf( 1544 "Invalid key generation %d", keyGen) 1545 } 1546 oldKeys, err := kbfscrypto.DecryptTLFCryptKeys( 1547 codec, extraV3.wkb.EncryptedHistoricTLFCryptKeys, currentKey) 1548 if err != nil { 1549 return kbfscrypto.TLFCryptKey{}, err 1550 } 1551 index := int(keyGen - FirstValidKeyGen) 1552 if index >= len(oldKeys) || index < 0 { 1553 return kbfscrypto.TLFCryptKey{}, errors.Errorf( 1554 "Index %d out of range (max: %d)", index, len(oldKeys)) 1555 } 1556 return oldKeys[index], nil 1557 }