github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/kbpki_client_test.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  	"reflect"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/golang/mock/gomock"
    13  	"github.com/keybase/client/go/kbfs/idutil"
    14  	"github.com/keybase/client/go/kbfs/kbfscodec"
    15  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    16  	"github.com/keybase/client/go/kbfs/kbfsmd"
    17  	kbname "github.com/keybase/client/go/kbun"
    18  	"github.com/keybase/client/go/logger"
    19  	"github.com/keybase/client/go/protocol/keybase1"
    20  	"github.com/pkg/errors"
    21  	"golang.org/x/net/context"
    22  )
    23  
    24  type keybaseServiceSelfOwner struct {
    25  	service KeybaseService
    26  }
    27  
    28  func (o keybaseServiceSelfOwner) KeybaseService() KeybaseService {
    29  	return o.service
    30  }
    31  
    32  func makeTestKBPKIClient(t *testing.T) (
    33  	client *KBPKIClient, currentUID keybase1.UID, users []idutil.LocalUser,
    34  	teams []idutil.TeamInfo) {
    35  	currentUID = keybase1.MakeTestUID(1)
    36  	names := []kbname.NormalizedUsername{"test_name1", "test_name2"}
    37  	users = idutil.MakeLocalUsers(names)
    38  	teamNames := []kbname.NormalizedUsername{"test_team1", "test_team2"}
    39  	teams = idutil.MakeLocalTeams(teamNames)
    40  	codec := kbfscodec.NewMsgpack()
    41  	daemon := NewKeybaseDaemonMemory(currentUID, users, teams, codec)
    42  	return NewKBPKIClient(keybaseServiceSelfOwner{daemon},
    43  		logger.NewTestLogger(t)), currentUID, users, teams
    44  }
    45  
    46  func makeTestKBPKIClientWithRevokedKey(t *testing.T, revokeTime time.Time) (
    47  	client *KBPKIClient, currentUID keybase1.UID, users []idutil.LocalUser) {
    48  	currentUID = keybase1.MakeTestUID(1)
    49  	names := []kbname.NormalizedUsername{"test_name1", "test_name2"}
    50  	users = idutil.MakeLocalUsers(names)
    51  	// Give each user a revoked key
    52  	for i, user := range users {
    53  		index := 99
    54  		keySalt := keySaltForUserDevice(user.Name, index)
    55  		newVerifyingKey := idutil.MakeLocalUserVerifyingKeyOrBust(keySalt)
    56  		user.RevokedVerifyingKeys =
    57  			map[kbfscrypto.VerifyingKey]idutil.RevokedKeyInfo{
    58  				newVerifyingKey: {Time: keybase1.ToTime(revokeTime)},
    59  			}
    60  		users[i] = user
    61  	}
    62  	codec := kbfscodec.NewMsgpack()
    63  	daemon := NewKeybaseDaemonMemory(currentUID, users, nil, codec)
    64  	return NewKBPKIClient(keybaseServiceSelfOwner{daemon},
    65  		logger.NewTestLogger(t)), currentUID, users
    66  }
    67  
    68  func TestKBPKIClientIdentify(t *testing.T) {
    69  	c, _, _, _ := makeTestKBPKIClient(t)
    70  
    71  	_, id, err := c.Identify(
    72  		context.Background(), "test_name1", "",
    73  		keybase1.OfflineAvailability_NONE)
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	if id == keybase1.UserOrTeamID("") {
    78  		t.Fatal("empty user")
    79  	}
    80  }
    81  
    82  func TestKBPKIClientGetNormalizedUsername(t *testing.T) {
    83  	c, _, _, _ := makeTestKBPKIClient(t)
    84  
    85  	name, err := c.GetNormalizedUsername(
    86  		context.Background(), keybase1.MakeTestUID(1).AsUserOrTeam(),
    87  		keybase1.OfflineAvailability_NONE)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	if name == kbname.NormalizedUsername("") {
    92  		t.Fatal("empty user")
    93  	}
    94  }
    95  
    96  func TestKBPKIClientHasVerifyingKey(t *testing.T) {
    97  	c, _, localUsers, _ := makeTestKBPKIClient(t)
    98  
    99  	err := c.HasVerifyingKey(
   100  		context.Background(), keybase1.MakeTestUID(1),
   101  		localUsers[0].VerifyingKeys[0], time.Now(),
   102  		keybase1.OfflineAvailability_NONE)
   103  	if err != nil {
   104  		t.Error(err)
   105  	}
   106  
   107  	err = c.HasVerifyingKey(
   108  		context.Background(), keybase1.MakeTestUID(1),
   109  		kbfscrypto.VerifyingKey{}, time.Now(),
   110  		keybase1.OfflineAvailability_NONE)
   111  	if err == nil {
   112  		t.Error("HasVerifyingKey unexpectedly succeeded")
   113  	}
   114  }
   115  
   116  func TestKBPKIClientHasRevokedVerifyingKey(t *testing.T) {
   117  	revokeTime := time.Now()
   118  	c, _, localUsers := makeTestKBPKIClientWithRevokedKey(t, revokeTime)
   119  
   120  	var revokedKey kbfscrypto.VerifyingKey
   121  	for k := range localUsers[0].RevokedVerifyingKeys {
   122  		revokedKey = k
   123  		break
   124  	}
   125  
   126  	// Something verified before the key was revoked
   127  	err := c.HasVerifyingKey(
   128  		context.Background(), keybase1.MakeTestUID(1),
   129  		revokedKey, revokeTime.Add(-10*time.Second),
   130  		keybase1.OfflineAvailability_NONE)
   131  	if _, ok := errors.Cause(err).(RevokedDeviceVerificationError); !ok {
   132  		t.Error(err)
   133  	}
   134  
   135  	// Something verified after the key was revoked
   136  	err = c.HasVerifyingKey(
   137  		context.Background(), keybase1.MakeTestUID(1), revokedKey,
   138  		revokeTime.Add(70*time.Second), keybase1.OfflineAvailability_NONE)
   139  	if err == nil {
   140  		t.Error("HasVerifyingKey unexpectedly succeeded")
   141  	}
   142  }
   143  
   144  // Test that KBPKI forces a cache flush one time if it can't find a
   145  // given verifying key.
   146  func TestKBPKIClientHasVerifyingKeyStaleCache(t *testing.T) {
   147  	ctr := NewSafeTestReporter(t)
   148  	mockCtrl := gomock.NewController(ctr)
   149  	config := NewConfigMock(mockCtrl, ctr)
   150  	c := NewKBPKIClient(config, config.MakeLogger(""))
   151  	config.SetKBPKI(c)
   152  	defer func() {
   153  		config.ctr.CheckForFailures()
   154  		mockCtrl.Finish()
   155  	}()
   156  
   157  	u := keybase1.MakeTestUID(1)
   158  	key1 := idutil.MakeLocalUserVerifyingKeyOrBust("u_1")
   159  	key2 := idutil.MakeLocalUserVerifyingKeyOrBust("u_2")
   160  	info1 := idutil.UserInfo{
   161  		VerifyingKeys: []kbfscrypto.VerifyingKey{key1},
   162  	}
   163  	config.mockKbs.EXPECT().LoadUserPlusKeys(
   164  		gomock.Any(), u, gomock.Any(), gomock.Any()).Return(info1, nil)
   165  
   166  	config.mockKbs.EXPECT().FlushUserFromLocalCache(gomock.Any(), u)
   167  	info2 := idutil.UserInfo{
   168  		VerifyingKeys: []kbfscrypto.VerifyingKey{key1, key2},
   169  	}
   170  	config.mockKbs.EXPECT().LoadUserPlusKeys(
   171  		gomock.Any(), u, key2.KID(), gomock.Any()).
   172  		Return(info2, nil)
   173  
   174  	err := c.HasVerifyingKey(
   175  		context.Background(), u, key2, time.Now(),
   176  		keybase1.OfflineAvailability_NONE)
   177  	if err != nil {
   178  		t.Error(err)
   179  	}
   180  }
   181  
   182  func TestKBPKIClientGetCryptPublicKeys(t *testing.T) {
   183  	c, _, localUsers, _ := makeTestKBPKIClient(t)
   184  
   185  	cryptPublicKeys, err := c.GetCryptPublicKeys(
   186  		context.Background(), keybase1.MakeTestUID(1),
   187  		keybase1.OfflineAvailability_NONE)
   188  	if err != nil {
   189  		t.Fatal(err)
   190  	}
   191  
   192  	if len(cryptPublicKeys) != 1 {
   193  		t.Fatalf("Expected 1 crypt public key, got %d", len(cryptPublicKeys))
   194  	}
   195  
   196  	key := cryptPublicKeys[0]
   197  	expectedKey := localUsers[0].CryptPublicKeys[0]
   198  	if key != expectedKey {
   199  		t.Errorf("Expected %s, got %s", expectedKey, key)
   200  	}
   201  }
   202  
   203  func TestKBPKIClientGetCurrentCryptPublicKey(t *testing.T) {
   204  	c, _, localUsers, _ := makeTestKBPKIClient(t)
   205  
   206  	session, err := c.GetCurrentSession(context.Background())
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	kid := session.CryptPublicKey.KID()
   212  	expectedKID := localUsers[0].GetCurrentCryptPublicKey().KID()
   213  	if kid != expectedKID {
   214  		t.Errorf("Expected %s, got %s", expectedKID, kid)
   215  	}
   216  }
   217  
   218  func TestKBPKIClientGetTeamTLFCryptKeys(t *testing.T) {
   219  	c, _, _, localTeams := makeTestKBPKIClient(t)
   220  
   221  	if len(localTeams) == 0 {
   222  		t.Error("No local teams were generated")
   223  	}
   224  
   225  	for _, team := range localTeams {
   226  		keys, keyGen, err := c.GetTeamTLFCryptKeys(
   227  			context.Background(), team.TID, kbfsmd.UnspecifiedKeyGen,
   228  			keybase1.OfflineAvailability_NONE)
   229  		if err != nil {
   230  			t.Error(err)
   231  		}
   232  		if !reflect.DeepEqual(team.CryptKeys, keys) {
   233  			t.Errorf("Team TLF crypt keys don't match: %v vs %v",
   234  				team.CryptKeys, keys)
   235  		}
   236  		if keyGen != kbfsmd.FirstValidKeyGen {
   237  			t.Errorf("Unexpected team key gen: %v", keyGen)
   238  		}
   239  	}
   240  }