github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/secret_store_secretservice_test.go (about)

     1  // Copyright 2019 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  //go:build linux && !skipkeyringtests
     5  // +build linux,!skipkeyringtests
     6  
     7  // nolint:unused
     8  package libkb
     9  
    10  import (
    11  	"fmt"
    12  	"os"
    13  	"testing"
    14  
    15  	secsrv "github.com/keybase/go-keychain/secretservice"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func secret() LKSecFullSecret {
    20  	sec, err := newLKSecFullSecretFromBytes([]byte("YELLOW_SUBMARINEYELLOW_SUBMARINE"))
    21  	if err != nil {
    22  		panic(err)
    23  	}
    24  	return sec
    25  }
    26  
    27  func requireError(t *testing.T, err error, msg string) {
    28  	require.Error(t, err)
    29  	require.Contains(t, err.Error(), msg)
    30  }
    31  
    32  var alice = NewNormalizedUsername("alice")
    33  var bob = NewNormalizedUsername("bob")
    34  var charlie = NewNormalizedUsername("charlie")
    35  
    36  func TestSSSSBasic(t *testing.T) {
    37  	t.Skip("Skipping secret service test while Linux CI AMI is being upgraded to include keyring")
    38  
    39  	tc := SetupTest(t, "secret_store_secretservice", 0)
    40  	defer tc.Cleanup()
    41  	mctx := NewMetaContextForTest(tc)
    42  
    43  	sec := secret()
    44  
    45  	s := NewSecretStoreRevokableSecretService()
    46  	err := s.StoreSecret(mctx, alice, sec)
    47  	require.NoError(t, err)
    48  
    49  	gotSec, err := s.RetrieveSecret(mctx, alice)
    50  	require.NoError(t, err)
    51  	require.Equal(t, sec, gotSec)
    52  
    53  	err = s.ClearSecret(mctx, alice)
    54  	require.NoError(t, err)
    55  
    56  	_, err = s.RetrieveSecret(mctx, alice)
    57  	requireError(t, err.(UnboxError), "no such file")
    58  
    59  	err = s.StoreSecret(mctx, alice, sec)
    60  	require.NoError(t, err)
    61  	err = s.StoreSecret(mctx, bob, sec)
    62  	require.NoError(t, err)
    63  	err = s.StoreSecret(mctx, charlie, sec)
    64  	require.NoError(t, err)
    65  	gotSec, err = s.RetrieveSecret(mctx, charlie)
    66  	require.NoError(t, err)
    67  	require.Equal(t, sec, gotSec)
    68  
    69  	users, err := s.GetUsersWithStoredSecrets(mctx)
    70  	require.NoError(t, err)
    71  	require.Equal(t, []string{"alice", "bob", "charlie"}, users)
    72  
    73  	err = s.ClearSecret(mctx, alice)
    74  	require.NoError(t, err)
    75  	err = s.ClearSecret(mctx, bob)
    76  	require.NoError(t, err)
    77  	err = s.ClearSecret(mctx, charlie)
    78  	require.NoError(t, err)
    79  }
    80  
    81  func TestSSSSCorruptKeystore(t *testing.T) {
    82  	t.Skip("Skipping secret service test while Linux CI AMI is being upgraded to include keyring")
    83  
    84  	tc := SetupTest(t, "secret_store_secretservice", 0)
    85  	defer tc.Cleanup()
    86  	mctx := NewMetaContextForTest(tc)
    87  
    88  	s := NewSecretStoreRevokableSecretService()
    89  	err := s.StoreSecret(mctx, alice, secret())
    90  	require.NoError(t, err)
    91  
    92  	keystore := s.keystore(mctx, "alice", nil)
    93  	keypath := keystore.(*FileErasableKVStore).filepath(s.keystoreKey())
    94  	file, err := os.OpenFile(keypath, os.O_RDWR, 0755)
    95  	defer func() {
    96  		err := file.Close()
    97  		require.NoError(t, err)
    98  	}()
    99  	require.NoError(t, err)
   100  	_, err = file.Write([]byte("YELLOW_SUBMARINE"))
   101  	require.NoError(t, err)
   102  
   103  	_, err = s.RetrieveSecret(mctx, alice)
   104  	require.Error(t, err)
   105  	requireError(t, err.(UnboxError), "msgpack decode error")
   106  
   107  	err = s.ClearSecret(mctx, alice)
   108  	require.NoError(t, err)
   109  }
   110  
   111  func TestSSSSCorruptNoise(t *testing.T) {
   112  	t.Skip("Skipping secret service test while Linux CI AMI is being upgraded to include keyring")
   113  
   114  	tc := SetupTest(t, "secret_store_secretservice", 0)
   115  	defer tc.Cleanup()
   116  	mctx := NewMetaContextForTest(tc)
   117  
   118  	s := NewSecretStoreRevokableSecretService()
   119  	err := s.StoreSecret(mctx, alice, secret())
   120  	require.NoError(t, err)
   121  
   122  	keystore := s.keystore(mctx, "alice", nil)
   123  	fileKeystore := keystore.(*FileErasableKVStore)
   124  	keypath := fileKeystore.filepath(fileKeystore.noiseKey(s.keystoreKey()))
   125  	file, err := os.OpenFile(keypath, os.O_RDWR, 0755)
   126  	defer func() {
   127  		err := file.Close()
   128  		require.NoError(t, err)
   129  	}()
   130  	require.NoError(t, err)
   131  	_, err = file.Write([]byte("YELLOW_SUBMARINE"))
   132  	require.NoError(t, err)
   133  
   134  	_, err = s.RetrieveSecret(mctx, alice)
   135  	require.Error(t, err)
   136  	require.Equal(t, err.(UnboxError).Info(), "noise hashes do not match")
   137  
   138  	err = s.ClearSecret(mctx, alice)
   139  	require.NoError(t, err)
   140  }
   141  
   142  func TestSSSSCorruptKeyring(t *testing.T) {
   143  	t.Skip("Skipping secret service test while Linux CI AMI is being upgraded to include keyring")
   144  
   145  	tc := SetupTest(t, "secret_store_secretservice", 0)
   146  	defer tc.Cleanup()
   147  	mctx := NewMetaContextForTest(tc)
   148  
   149  	s := NewSecretStoreRevokableSecretService()
   150  
   151  	err := s.StoreSecret(mctx, alice, secret())
   152  	require.NoError(t, err)
   153  
   154  	srv, err := secsrv.NewService()
   155  	require.NoError(t, err)
   156  	session, err := srv.OpenSession(secsrv.AuthenticationDHAES)
   157  	require.NoError(t, err)
   158  	defer srv.CloseSession(session)
   159  	identifierKeystore := s.identifierKeystore(mctx)
   160  	var instanceIdentifier []byte
   161  	err = identifierKeystore.Get(mctx, s.identifierKeystoreKey("alice"), &instanceIdentifier)
   162  	require.NoError(t, err)
   163  	label := fmt.Sprintf("%s@%s", "alice", mctx.G().Env.GetStoredSecretServiceName())
   164  	properties := secsrv.NewSecretProperties(label, s.makeAttributes(mctx, "alice", instanceIdentifier))
   165  	srvSecret, err := session.NewSecret([]byte("NOT_THE_REAL_SECRET"))
   166  	require.NoError(t, err)
   167  	_, err = srv.CreateItem(secsrv.DefaultCollection, properties, srvSecret, secsrv.ReplaceBehaviorReplace)
   168  	require.NoError(t, err)
   169  
   170  	_, err = s.RetrieveSecret(mctx, alice)
   171  	require.Error(t, err)
   172  	require.Equal(t, err.(UnboxError).Info(), "noise hashes match")
   173  	// (i.e., issue is something else - likely a MAC mismatch, but secretbox.Open doesn't give a more specific error)
   174  
   175  	err = s.ClearSecret(mctx, alice)
   176  	require.NoError(t, err)
   177  }