github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/idutil/local.go (about)

     1  // Copyright 2019 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 idutil
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    12  	"github.com/keybase/client/go/kbfs/kbfsmd"
    13  	"github.com/keybase/client/go/kbfs/tlf"
    14  	kbname "github.com/keybase/client/go/kbun"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  )
    17  
    18  // LocalUser represents a fake KBFS user, useful for testing.
    19  type LocalUser struct {
    20  	UserInfo
    21  	Asserts []string
    22  	// Index into UserInfo.CryptPublicKeys.
    23  	CurrentCryptPublicKeyIndex int
    24  	// Index into UserInfo.VerifyingKeys.
    25  	CurrentVerifyingKeyIndex int
    26  	// Unverified keys.
    27  	UnverifiedKeys []keybase1.PublicKey
    28  }
    29  
    30  // GetCurrentCryptPublicKey returns this LocalUser's public encryption key.
    31  func (lu *LocalUser) GetCurrentCryptPublicKey() kbfscrypto.CryptPublicKey {
    32  	return lu.CryptPublicKeys[lu.CurrentCryptPublicKeyIndex]
    33  }
    34  
    35  // GetCurrentVerifyingKey returns this LocalUser's public signing key.
    36  func (lu *LocalUser) GetCurrentVerifyingKey() kbfscrypto.VerifyingKey {
    37  	return lu.VerifyingKeys[lu.CurrentVerifyingKeyIndex]
    38  }
    39  
    40  // MakeLocalUsers is a helper function to generate a list of
    41  // LocalUsers suitable to use with KeybaseDaemonLocal.
    42  func MakeLocalUsers(users []kbname.NormalizedUsername) []LocalUser {
    43  	localUsers := make([]LocalUser, len(users))
    44  	for i := 0; i < len(users); i++ {
    45  		verifyingKey := MakeLocalUserVerifyingKeyOrBust(users[i])
    46  		cryptPublicKey := MakeLocalUserCryptPublicKeyOrBust(users[i])
    47  		localUsers[i] = LocalUser{
    48  			UserInfo: UserInfo{
    49  				Name:            users[i],
    50  				UID:             keybase1.MakeTestUID(uint32(i + 1)),
    51  				VerifyingKeys:   []kbfscrypto.VerifyingKey{verifyingKey},
    52  				CryptPublicKeys: []kbfscrypto.CryptPublicKey{cryptPublicKey},
    53  				KIDNames: map[keybase1.KID]string{
    54  					verifyingKey.KID(): "dev1",
    55  				},
    56  			},
    57  			CurrentCryptPublicKeyIndex: 0,
    58  			CurrentVerifyingKeyIndex:   0,
    59  		}
    60  	}
    61  	return localUsers
    62  }
    63  
    64  func verifyingKeysToPublicKeys(
    65  	keys []kbfscrypto.VerifyingKey) []keybase1.PublicKey {
    66  	publicKeys := make([]keybase1.PublicKey, len(keys))
    67  	for i, key := range keys {
    68  		publicKeys[i] = keybase1.PublicKey{
    69  			KID:      key.KID(),
    70  			IsSibkey: true,
    71  		}
    72  	}
    73  	return publicKeys
    74  }
    75  
    76  func cryptPublicKeysToPublicKeys(
    77  	keys []kbfscrypto.CryptPublicKey) []keybase1.PublicKey {
    78  	publicKeys := make([]keybase1.PublicKey, len(keys))
    79  	for i, key := range keys {
    80  		publicKeys[i] = keybase1.PublicKey{
    81  			KID:      key.KID(),
    82  			IsSibkey: false,
    83  		}
    84  	}
    85  	return publicKeys
    86  }
    87  
    88  // GetPublicKeys returns all of this LocalUser's public encryption keys.
    89  func (lu *LocalUser) GetPublicKeys() []keybase1.PublicKey {
    90  	sibkeys := verifyingKeysToPublicKeys(lu.VerifyingKeys)
    91  	subkeys := cryptPublicKeysToPublicKeys(lu.CryptPublicKeys)
    92  	return append(sibkeys, subkeys...)
    93  }
    94  
    95  // DeepCopy returns a deep copy of this `LocalUser`.
    96  func (lu LocalUser) DeepCopy() LocalUser {
    97  	luCopy := lu
    98  
    99  	luCopy.VerifyingKeys = make(
   100  		[]kbfscrypto.VerifyingKey, len(lu.VerifyingKeys))
   101  	copy(luCopy.VerifyingKeys, lu.VerifyingKeys)
   102  
   103  	luCopy.CryptPublicKeys = make(
   104  		[]kbfscrypto.CryptPublicKey, len(lu.CryptPublicKeys))
   105  	copy(luCopy.CryptPublicKeys, lu.CryptPublicKeys)
   106  
   107  	luCopy.KIDNames = make(map[keybase1.KID]string, len(lu.KIDNames))
   108  	for k, v := range lu.KIDNames {
   109  		luCopy.KIDNames[k] = v
   110  	}
   111  
   112  	luCopy.RevokedVerifyingKeys = make(
   113  		map[kbfscrypto.VerifyingKey]RevokedKeyInfo,
   114  		len(lu.RevokedVerifyingKeys))
   115  	for k, v := range lu.RevokedVerifyingKeys {
   116  		luCopy.RevokedVerifyingKeys[k] = v
   117  	}
   118  
   119  	luCopy.RevokedCryptPublicKeys = make(
   120  		map[kbfscrypto.CryptPublicKey]RevokedKeyInfo,
   121  		len(lu.RevokedCryptPublicKeys))
   122  	for k, v := range lu.RevokedCryptPublicKeys {
   123  		luCopy.RevokedCryptPublicKeys[k] = v
   124  	}
   125  
   126  	luCopy.Asserts = make([]string, len(lu.Asserts))
   127  	copy(luCopy.Asserts, lu.Asserts)
   128  	luCopy.UnverifiedKeys = make([]keybase1.PublicKey, len(lu.UnverifiedKeys))
   129  	copy(luCopy.UnverifiedKeys, lu.UnverifiedKeys)
   130  
   131  	return luCopy
   132  }
   133  
   134  func makeLocalTeams(
   135  	teams []kbname.NormalizedUsername, startingIndex int, ty tlf.Type) (
   136  	localTeams []TeamInfo) {
   137  	localTeams = make([]TeamInfo, len(teams))
   138  	for index := 0; index < len(teams); index++ {
   139  		i := index + startingIndex
   140  		cryptKey := MakeLocalTLFCryptKeyOrBust(
   141  			tlf.SingleTeam.String()+"/"+string(teams[index]),
   142  			kbfsmd.FirstValidKeyGen)
   143  		localTeams[index] = TeamInfo{
   144  			Name: teams[index],
   145  			TID:  keybase1.MakeTestTeamID(uint32(i+1), ty == tlf.Public),
   146  			CryptKeys: map[kbfsmd.KeyGen]kbfscrypto.TLFCryptKey{
   147  				kbfsmd.FirstValidKeyGen: cryptKey,
   148  			},
   149  			LatestKeyGen: kbfsmd.FirstValidKeyGen,
   150  		}
   151  		// If this is a subteam, set the root ID.
   152  		if strings.Contains(string(teams[index]), ".") {
   153  			parts := strings.SplitN(string(teams[index]), ".", 2)
   154  			for j := 0; j < index; j++ {
   155  				if parts[0] == string(localTeams[j].Name) {
   156  					localTeams[index].RootID = localTeams[j].TID
   157  					break
   158  				}
   159  			}
   160  		}
   161  	}
   162  	return localTeams
   163  }
   164  
   165  // MakeLocalTeams is a helper function to generate a list of local
   166  // teams suitable to use with KeybaseDaemonLocal.  Any subteams must come
   167  // after their root team names in the `teams` slice.
   168  func MakeLocalTeams(teams []kbname.NormalizedUsername) []TeamInfo {
   169  	return makeLocalTeams(teams, 0, tlf.Private)
   170  }
   171  
   172  // Helper functions to get a various keys for a local user. Each
   173  // function will return the same key will always be returned for a
   174  // given user.
   175  
   176  // MakeLocalUserSigningKeyOrBust returns a unique signing key for this user.
   177  func MakeLocalUserSigningKeyOrBust(
   178  	name kbname.NormalizedUsername) kbfscrypto.SigningKey {
   179  	return kbfscrypto.MakeFakeSigningKeyOrBust(
   180  		string(name) + " signing key")
   181  }
   182  
   183  // MakeLocalUserCryptPublicKeyOrBust returns the public key
   184  // corresponding to the crypt private key for this user.
   185  func MakeLocalUserCryptPublicKeyOrBust(
   186  	name kbname.NormalizedUsername) kbfscrypto.CryptPublicKey {
   187  	return MakeLocalUserCryptPrivateKeyOrBust(name).GetPublicKey()
   188  }
   189  
   190  // MakeLocalUserVerifyingKeyOrBust makes a new verifying key
   191  // corresponding to the signing key for this user.
   192  func MakeLocalUserVerifyingKeyOrBust(
   193  	name kbname.NormalizedUsername) kbfscrypto.VerifyingKey {
   194  	return MakeLocalUserSigningKeyOrBust(name).GetVerifyingKey()
   195  }
   196  
   197  // MakeLocalUserCryptPrivateKeyOrBust returns a unique private
   198  // encryption key for this user.
   199  func MakeLocalUserCryptPrivateKeyOrBust(
   200  	name kbname.NormalizedUsername) kbfscrypto.CryptPrivateKey {
   201  	return kbfscrypto.MakeFakeCryptPrivateKeyOrBust(
   202  		string(name) + " crypt key")
   203  }
   204  
   205  // MakeLocalTLFCryptKeyOrBust returns a unique private symmetric key
   206  // for a TLF.
   207  func MakeLocalTLFCryptKeyOrBust(
   208  	name string, keyGen kbfsmd.KeyGen) kbfscrypto.TLFCryptKey {
   209  	// Put the key gen first to make it more likely to fit into the
   210  	// 32-character "random" seed.
   211  	return kbfscrypto.MakeFakeTLFCryptKeyOrBust(
   212  		name + " " + fmt.Sprint(keyGen) + " crypt key ")
   213  }