// ToTLFWriterKeyBundleV3 converts a TLFWriterKeyGenerationsV2 to a TLFWriterKeyBundleV3.
336583
func (wkg TLFWriterKeyGenerationsV2) ToTLFWriterKeyBundleV3(
	codec kbfscodec.Codec,
	tlfCryptKeyGetter func() ([]kbfscrypto.TLFCryptKey, error)) (
	TLFWriterKeyBundleV2, TLFWriterKeyBundleV3, error) {
	keyGen := wkg.LatestKeyGeneration()
	if keyGen < FirstValidKeyGen {
		return TLFWriterKeyBundleV2{}, TLFWriterKeyBundleV3{},
			errors.New("No key generations to convert")
	}

	// Copy the latest UserDeviceKeyInfoMap.
	wkbV2 := wkg[keyGen-FirstValidKeyGen]
	ePubKeyCount := len(wkbV2.TLFEphemeralPublicKeys)
	udkimV3, err := writerUDKIMV2ToV3(codec, wkbV2.WKeys, ePubKeyCount)
	if err != nil {
		return TLFWriterKeyBundleV2{}, TLFWriterKeyBundleV3{}, err
	}
	wkbV3 := TLFWriterKeyBundleV3{
		Keys: udkimV3,
		TLFEphemeralPublicKeys: make(
			kbfscrypto.TLFEphemeralPublicKeys, ePubKeyCount),
		TLFPublicKey: wkbV2.TLFPublicKey,
	}
	// Copy all of the TLFEphemeralPublicKeys at this generation.
	copy(wkbV3.TLFEphemeralPublicKeys[:], wkbV2.TLFEphemeralPublicKeys)

	if keyGen > FirstValidKeyGen {
		// Fetch all of the TLFCryptKeys.
		keys, err := tlfCryptKeyGetter()
		if err != nil {
			return TLFWriterKeyBundleV2{}, TLFWriterKeyBundleV3{}, err
		}
		// Sanity check.
		if len(keys) != int(keyGen) {
			return TLFWriterKeyBundleV2{}, TLFWriterKeyBundleV3{},
				fmt.Errorf("expected %d keys, found %d", keyGen, len(keys))
		}
		// Save the current key.
		currKey := keys[len(keys)-1]
		// Get rid of the most current generation as that's in the UserDeviceKeyInfoMap already.
		keys = keys[:len(keys)-1]
		// Encrypt the historic keys with the current key.
		wkbV3.EncryptedHistoricTLFCryptKeys, err = kbfscrypto.EncryptTLFCryptKeys(codec, keys, currKey)
		if err != nil {
			return TLFWriterKeyBundleV2{}, TLFWriterKeyBundleV3{}, err
		}
	}

	return wkbV2, wkbV3, nil
}
580844
func MakeRandomTLFEphemeralKeys() (
	TLFEphemeralPublicKey, TLFEphemeralPrivateKey, error) {
	keyPair, err := libkb.GenerateNaclDHKeyPair()
	if err != nil {
		return TLFEphemeralPublicKey{}, TLFEphemeralPrivateKey{},
			errors.WithStack(err)
	}

	ePubKey := MakeTLFEphemeralPublicKey(keyPair.Public)
	ePrivKey := MakeTLFEphemeralPrivateKey(*keyPair.Private)
	return ePubKey, ePrivKey, nil
}
794069
func (wkb TLFWriterKeyBundleV3) Size() (bytes int) {
	bytes += cache.PtrSize + wkb.Keys.Size() // Keys

	// TLFPublicKey is essentially a 32-byte array.
	bytes += kbfscrypto.TLFPublicKey{}.Size()

	// TLFEphemeralPublicKeys
	bytes += wkb.TLFEphemeralPublicKeys.Size()

	// EncryptedHistoricTLFCryptKeys
	bytes += wkb.EncryptedHistoricTLFCryptKeys.Size()

	// For codec.UnknownFieldSetHandler. It has a private map field which we
	// can't inspect unless extending the codec package. Just assume it's empty
	// for now.
	bytes += cache.PtrSize

	return bytes
}
619886
func IsOnlyWriterInNonTeamTlf(ctx context.Context, kbpki KBPKI,
	h *tlfhandle.Handle) bool {
	session, err := idutil.GetCurrentSessionIfPossible(
		ctx, kbpki, h.Type() == tlf.Public)
	if err != nil {
		return false
	}
	if h.TypeForKeying() == tlf.TeamKeying {
		return false
	}
	return tlf.UserIsOnlyWriter(session.Name, h.GetCanonicalName())
}
787149
func (k *KBPKIClient) IsTeamWriter(
	ctx context.Context, tid keybase1.TeamID, uid keybase1.UID,
	verifyingKey kbfscrypto.VerifyingKey,
	offline keybase1.OfflineAvailability) (bool, error) {
	if uid.IsNil() || verifyingKey.IsNil() {
		// A sessionless user can never be a writer.
		return false, nil
	}

	// Use the verifying key to find out the eldest seqno of the user.
	userInfo, err := k.loadUserPlusKeys(ctx, uid, verifyingKey.KID(), offline)
	if err != nil {
		return false, err
	}

	found := false
	for _, key := range userInfo.VerifyingKeys {
		if verifyingKey.KID().Equal(key.KID()) {
			found = true
			break
		}
	}
	if !found {
		// For the purposes of finding the eldest seqno, we need to
		// check the verified key against the list of revoked keys as
		// well.  (The caller should use `HasVerifyingKey` later to
		// check whether the revoked key was valid at the time of the
		// update or not.)
		_, found = userInfo.RevokedVerifyingKeys[verifyingKey]
	}
	if !found {
		// The user doesn't currently have this KID, therefore they
		// shouldn't be treated as a writer.  The caller should check
		// historical device records and team membership.
		k.log.CDebugf(ctx, "User %s doesn't currently have verifying key %s",
			uid, verifyingKey.KID())
		return false, nil
	}

	desiredUser := keybase1.UserVersion{
		Uid:         uid,
		EldestSeqno: userInfo.EldestSeqno,
	}
	teamInfo, err := k.serviceOwner.KeybaseService().LoadTeamPlusKeys(
		ctx, tid, tlf.Unknown, kbfsmd.UnspecifiedKeyGen, desiredUser,
		kbfscrypto.VerifyingKey{}, keybase1.TeamRole_WRITER, offline)
	if err != nil {
		if tid.IsPublic() {
			if _, notFound := err.(libkb.NotFoundError); notFound {
				// We are probably just not a writer of this public team.
				k.log.CDebugf(ctx,
					"Ignoring not found error for public team: %+v", err)
				return false, nil
			}
		}
		return false, err
	}
	return teamInfo.Writers[uid], nil
}
894929
func (md *RootMetadataV3) GetCurrentTLFPublicKey(
	extra ExtraMetadata) (kbfscrypto.TLFPublicKey, error) {
	wkb, _, err := md.getTLFKeyBundles(extra)
	if err != nil {
		return kbfscrypto.TLFPublicKey{}, err
	}
	return wkb.TLFPublicKey, nil
}
25300
func (rkg TLFReaderKeyGenerationsV2) ToTLFReaderKeyBundleV3(
	codec kbfscodec.Codec, wkb TLFWriterKeyBundleV2) (
	TLFReaderKeyBundleV3, error) {
	keyGen := rkg.LatestKeyGeneration()
	if keyGen < FirstValidKeyGen {
		return TLFReaderKeyBundleV3{}, errors.New("No key generations to convert")
	}

	rkbV3 := TLFReaderKeyBundleV3{
		Keys: make(UserDeviceKeyInfoMapV3),
	}

	// Copy the latest UserDeviceKeyInfoMap.
	rkb := rkg[keyGen-FirstValidKeyGen]

	// Copy all of the TLFReaderEphemeralPublicKeys.
	rkbV3.TLFEphemeralPublicKeys = make(kbfscrypto.TLFEphemeralPublicKeys,
		len(rkb.TLFReaderEphemeralPublicKeys))
	copy(rkbV3.TLFEphemeralPublicKeys[:], rkb.TLFReaderEphemeralPublicKeys)

	// Track a mapping of old writer ephemeral pubkey index to new
	// reader ephemeral pubkey index.
	pubKeyIndicesMap := make(map[int]int)

	// We need to copy these in a slightly annoying way to work around
	// the negative index hack. In V3 readers always have their ePubKey
	// in the TLFReaderEphemeralPublicKeys list. In V2 they only do if
	// the index is negative. Otherwise it's in the writer's list.
	for uid, dkim := range rkb.RKeys {
		dkimV3 := make(DeviceKeyInfoMapV3)
		for kid, info := range dkim {
			var infoCopy TLFCryptKeyInfo
			err := kbfscodec.Update(codec, &infoCopy, info)
			if err != nil {
				return TLFReaderKeyBundleV3{}, err
			}

			keyLocation, index, ePubKey, err :=
				GetEphemeralPublicKeyInfoV2(info, wkb, rkb)
			if err != nil {
				return TLFReaderKeyBundleV3{}, err
			}

			switch keyLocation {
			case WriterEPubKeys:
				// Map the old index in the writer list to a new index
				// at the end of the reader list.
				newIndex, ok := pubKeyIndicesMap[index]
				if !ok {
					rkbV3.TLFEphemeralPublicKeys =
						append(rkbV3.TLFEphemeralPublicKeys, ePubKey)
					// TODO: This index depends on
					// map iteration order, which
					// varies. Impose a consistent
					// order on these indices.
					newIndex = len(rkbV3.TLFEphemeralPublicKeys) - 1
					pubKeyIndicesMap[index] = newIndex
				}
				infoCopy.EPubKeyIndex = newIndex
			case ReaderEPubKeys:
				// Use the real index in the reader list.
				infoCopy.EPubKeyIndex = index
			default:
				return TLFReaderKeyBundleV3{}, fmt.Errorf("Unknown key location %s", keyLocation)
			}
			dkimV3[kbfscrypto.MakeCryptPublicKey(kid)] = infoCopy
		}
		rkbV3.Keys[uid] = dkimV3
	}
	return rkbV3, nil
}
356830
func (md *RootMetadata) IsWriter(
	ctx context.Context, checker kbfsmd.TeamMembershipChecker,
	osg idutil.OfflineStatusGetter, uid keybase1.UID,
	verifyingKey kbfscrypto.VerifyingKey) (bool, error) {
	h := md.GetTlfHandle()
	return IsWriterFromHandle(ctx, h, checker, osg, uid, verifyingKey)
}
1361548
func (c SimpleFSClient) SimpleFSWrite(ctx context.Context, __arg SimpleFSWriteArg) (err error) {
	err = c.Cli.Call(ctx, "keybase.1.SimpleFS.simpleFSWrite", []interface{}{__arg}, nil)
	return
}
799232
func (b KeyCacheMeasured) GetTLFCryptKey(
	tlfID tlf.ID, keyGen kbfsmd.KeyGen) (key kbfscrypto.TLFCryptKey, err error) {
	b.getTimer.Time(func() {
		key, err = b.delegate.GetTLFCryptKey(tlfID, keyGen)
	})
	if err == nil {
		b.hitCountMeter.Mark(1)
	}
	return key, err
}
250372
func (h *TLFWriterKeyBundleID) UnmarshalBinary(data []byte) error {
	return h.h.UnmarshalBinary(data)
}
331264
func (lw *LeveledWriter) LevelWrite(level Level, p []byte) (int, error) {
	w, ok := lw.overrides[level]
	if !ok {
		w = lw.standard
	}
	return w.Write(p)
}
377960
func MakeInitialRootMetadataV2(tlfID tlf.ID, h tlf.Handle) (
	*RootMetadataV2, error) {
	if tlfID.Type() != h.Type() {
		return nil, errors.New("TlfID and TlfHandle disagree on TLF type")
	}

	var writers []keybase1.UserOrTeamID
	var wKeys TLFWriterKeyGenerationsV2
	var rKeys TLFReaderKeyGenerationsV2
	if tlfID.Type() == tlf.Private {
		wKeys = make(TLFWriterKeyGenerationsV2, 0, 1)
		rKeys = make(TLFReaderKeyGenerationsV2, 0, 1)
	} else {
		writers = make([]keybase1.UserOrTeamID, len(h.Writers))
		copy(writers, h.Writers)
	}

	var unresolvedWriters, unresolvedReaders []keybase1.SocialAssertion
	if len(h.UnresolvedWriters) > 0 {
		unresolvedWriters = make(
			[]keybase1.SocialAssertion, len(h.UnresolvedWriters))
		copy(unresolvedWriters, h.UnresolvedWriters)
	}

	if len(h.UnresolvedReaders) > 0 {
		unresolvedReaders = make(
			[]keybase1.SocialAssertion, len(h.UnresolvedReaders))
		copy(unresolvedReaders, h.UnresolvedReaders)
	}

	return &RootMetadataV2{
		WriterMetadataV2: WriterMetadataV2{
			Writers: writers,
			WKeys:   wKeys,
			ID:      tlfID,
			Extra: WriterMetadataExtraV2{
				UnresolvedWriters: unresolvedWriters,
			},
		},
		Revision:          RevisionInitial,
		RKeys:             rKeys,
		UnresolvedReaders: unresolvedReaders,
		// Normally an MD wouldn't start out with extensions, but this
		// is useful for tests.
		ConflictInfo:  h.ConflictInfo,
		FinalizedInfo: h.FinalizedInfo,
	}, nil
}
122210
func (md *RootMetadataV2) getTLFKeyBundles(keyGen KeyGen) (
	*TLFWriterKeyBundleV2, *TLFReaderKeyBundleV2, error) {
	if md.ID.Type() != tlf.Private {
		return nil, nil, InvalidNonPrivateTLFOperation{md.ID, "getTLFKeyBundles", md.Version()}
	}

	if keyGen < FirstValidKeyGen {
		return nil, nil, InvalidKeyGenerationError{md.ID, keyGen}
	}
	i := int(keyGen - FirstValidKeyGen)
	if i >= len(md.WKeys) || i >= len(md.RKeys) {
		return nil, nil, NewKeyGenerationError{md.ID, keyGen}
	}
	return &md.WKeys[i], &md.RKeys[i], nil
}
229954
func (b KeyBundleCacheMeasured) PutTLFReaderKeyBundle(
	bundleID kbfsmd.TLFReaderKeyBundleID, rkb kbfsmd.TLFReaderKeyBundleV3) {
	b.putReaderBundleTimer.Time(func() {
		b.delegate.PutTLFReaderKeyBundle(bundleID, rkb)
	})
}
1368773
func (md *RootMetadataV3) GetTLFCryptKeyParams(
	keyGen KeyGen, user keybase1.UID,
	key kbfscrypto.CryptPublicKey, extra ExtraMetadata) (
	kbfscrypto.TLFEphemeralPublicKey,
	kbfscrypto.EncryptedTLFCryptKeyClientHalf,
	kbfscrypto.TLFCryptKeyServerHalfID, bool, error) {
	if keyGen != md.LatestKeyGeneration() {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false,
			TLFCryptKeyNotPerDeviceEncrypted{md.TlfID(), keyGen}
	}
	wkb, rkb, err := md.getTLFKeyBundles(extra)
	if err != nil {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false, err
	}
	isWriter := true
	dkim := wkb.Keys[user]
	if dkim == nil {
		dkim = rkb.Keys[user]
		if dkim == nil {
			return kbfscrypto.TLFEphemeralPublicKey{},
				kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
				kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil
		}
		isWriter = false
	}
	info, ok := dkim[key]
	if !ok {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil
	}

	var publicKeys kbfscrypto.TLFEphemeralPublicKeys
	var keyType string
	if isWriter {
		publicKeys = wkb.TLFEphemeralPublicKeys
		keyType = "writer"
	} else {
		publicKeys = rkb.TLFEphemeralPublicKeys
		keyType = "reader"
	}
	keyCount := len(publicKeys)
	index := info.EPubKeyIndex
	if index >= keyCount {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false,
			errors.Errorf("Invalid %s key index %d >= %d",
				keyType, index, keyCount)
	}
	return publicKeys[index], info.ClientHalf, info.ServerHalfID, true, nil
}
794130
func (md *RootMetadataV2) GetTLFCryptKeyParams(
	keyGen KeyGen, user keybase1.UID, key kbfscrypto.CryptPublicKey,
	_ ExtraMetadata) (
	kbfscrypto.TLFEphemeralPublicKey, kbfscrypto.EncryptedTLFCryptKeyClientHalf,
	kbfscrypto.TLFCryptKeyServerHalfID, bool, error) {
	wkb, rkb, err := md.getTLFKeyBundles(keyGen)
	if err != nil {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false, err
	}

	dkim := wkb.WKeys[user]
	if dkim == nil {
		dkim = rkb.RKeys[user]
		if dkim == nil {
			return kbfscrypto.TLFEphemeralPublicKey{},
				kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
				kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil
		}
	}
	info, ok := dkim[key.KID()]
	if !ok {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false, nil
	}

	_, _, ePubKey, err := GetEphemeralPublicKeyInfoV2(info, *wkb, *rkb)
	if err != nil {
		return kbfscrypto.TLFEphemeralPublicKey{},
			kbfscrypto.EncryptedTLFCryptKeyClientHalf{},
			kbfscrypto.TLFCryptKeyServerHalfID{}, false, err
	}

	return ePubKey, info.ClientHalf, info.ServerHalfID, true, nil
}