github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/secret_store_darwin_test.go (about) 1 //go:build darwin 2 // +build darwin 3 4 package libkb 5 6 import ( 7 "encoding/base64" 8 "testing" 9 10 keychain "github.com/keybase/go-keychain" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestSecretStoreDarwin(t *testing.T) { 15 tc := SetupTest(t, "secret store darwin", 1) 16 defer tc.Cleanup() 17 18 mctx := NewMetaContextForTest(tc) 19 secretStore := KeychainSecretStore{} 20 nu := NormalizedUsername("username") 21 22 defer func() { 23 err := secretStore.ClearSecret(mctx, nu) 24 require.NoError(tc.T, err) 25 }() 26 27 serviceName := secretStore.serviceName(mctx) 28 accessGroup := secretStore.accessGroup(mctx) 29 30 expectedSecret1 := []byte("test secret 1test secret 1test s") 31 expectedSecret2 := []byte("test secret 2test secret 2test s") 32 encodedSecret1 := base64.StdEncoding.EncodeToString(expectedSecret1) 33 encodedSecret2 := base64.StdEncoding.EncodeToString(expectedSecret2) 34 lkSec1, err := newLKSecFullSecretFromBytes(expectedSecret1) 35 require.NoError(t, err) 36 37 err = secretStore.StoreSecret(mctx, nu, lkSec1) 38 require.NoError(t, err) 39 40 secret, err := secretStore.RetrieveSecret(mctx, nu) 41 require.NoError(t, err) 42 require.Equal(t, string(expectedSecret1), string(secret.Bytes())) 43 44 t.Logf("Corrupt keychain, add new secret") 45 // corrupt the secret in the keychain by writing into a new slot 46 // forcing us to use a new keychain slot when writing the new item 47 account := newKeychainSlottedAccount(nu, 1) 48 item := keychain.NewGenericPassword(serviceName, account.String(), 49 "", []byte(encodedSecret2), accessGroup) 50 err = keychain.AddItem(item) 51 require.NoError(t, err) 52 53 // We now readout expectedSecret2 since it is the latest entry. 54 secret, err = secretStore.RetrieveSecret(mctx, nu) 55 require.NoError(t, err) 56 require.Equal(t, string(expectedSecret2), string(secret.Bytes())) 57 58 // Now write expectedSecret1 back into the store, which will overwrite secret2 59 err = secretStore.StoreSecret(mctx, nu, lkSec1) 60 require.NoError(t, err) 61 62 secret, err = secretStore.RetrieveSecret(mctx, nu) 63 require.NoError(t, err) 64 require.Equal(t, string(expectedSecret1), string(secret.Bytes())) 65 66 // verify our keychain state 67 for i := 0; i < 2; i++ { 68 account := newKeychainSlottedAccount(nu, i) 69 query := keychain.NewItem() 70 query.SetSecClass(keychain.SecClassGenericPassword) 71 query.SetService(serviceName) 72 query.SetAccount(account.String()) 73 query.SetAccessGroup(accessGroup) 74 query.SetReturnData(true) 75 query.SetReturnAttributes(true) 76 results, err := keychain.QueryItem(query) 77 require.NoError(t, err) 78 require.Len(t, results, 1) 79 res := results[0] 80 81 require.Equal(t, secretStore.serviceName(mctx), res.Service) 82 require.Equal(t, account.String(), res.Account) 83 require.Equal(t, secretStore.accessGroup(mctx), res.AccessGroup) 84 require.Equal(t, "", res.Description) 85 require.Equal(t, encodedSecret1, string(res.Data)) 86 } 87 88 // Although we have 3 keychain items, we technically only have one user in 89 // the store. 90 users, err := secretStore.GetUsersWithStoredSecrets(mctx) 91 require.NoError(t, err) 92 require.Len(t, users, 1) 93 94 err = secretStore.ClearSecret(mctx, nu) 95 require.NoError(t, err) 96 97 for i := 0; i < 2; i++ { 98 account := newKeychainSlottedAccount(nu, i) 99 query := keychain.NewItem() 100 query.SetSecClass(keychain.SecClassGenericPassword) 101 query.SetService(serviceName) 102 query.SetAccount(account.String()) 103 query.SetAccessGroup(accessGroup) 104 query.SetReturnData(true) 105 query.SetReturnAttributes(true) 106 results, err := keychain.QueryItem(query) 107 require.NoError(t, err) 108 require.Nil(t, results) 109 } 110 111 users, err = secretStore.GetUsersWithStoredSecrets(mctx) 112 require.NoError(t, err) 113 require.Len(t, users, 0) 114 } 115 116 func TestPrimeSecretStoreDarwin(t *testing.T) { 117 tc := SetupTest(t, "secret_store_darwin", 1) 118 defer tc.Cleanup() 119 tc.G.Env.Test.SecretStorePrimingDisabled = false 120 121 mctx := NewMetaContextForTest(tc) 122 secretStore := KeychainSecretStore{} 123 err := PrimeSecretStore(mctx, secretStore) 124 require.NoError(t, err) 125 }