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