github.com/keybase/client/go@v0.0.0-20240520164431-4f512a4c85a3/teams/oracle_test.go (about)

     1  package teams
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/keybase/client/go/kbtest"
     8  	"github.com/keybase/client/go/libkb"
     9  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    10  	"github.com/stretchr/testify/require"
    11  	"golang.org/x/crypto/nacl/box"
    12  )
    13  
    14  func encryptWithTeamKey(t *testing.T, team *Team, data []byte, nonce [24]byte,
    15  	gen keybase1.PerTeamKeyGeneration) (ciphertext []byte, pubkey libkb.NaclDHKeyPublic) {
    16  	kp, err := team.encryptionKeyAtGen(context.Background(), gen)
    17  	require.NoError(t, err)
    18  	ciphertext = box.Seal(nil, data, &nonce, (*[32]byte)(&kp.Public), (*[32]byte)(kp.Private))
    19  	pubkey = kp.Public
    20  	return ciphertext, pubkey
    21  }
    22  
    23  func TestTeamUnboxOracle(t *testing.T) {
    24  	tc := SetupTest(t, "team", 1)
    25  	defer tc.Cleanup()
    26  
    27  	_, err := kbtest.CreateAndSignupFakeUser("team", tc.G)
    28  	require.NoError(t, err)
    29  
    30  	teamname := createTeam(tc)
    31  	t.Logf("Created team %s", teamname)
    32  
    33  	team, err := Load(context.Background(), tc.G, keybase1.LoadTeamArg{
    34  		Name:        teamname,
    35  		ForceRepoll: true,
    36  	})
    37  	require.NoError(t, err)
    38  
    39  	require.NoError(t, RotateKeyVisible(context.Background(), tc.G, team.ID))
    40  	require.NoError(t, RotateKeyVisible(context.Background(), tc.G, team.ID))
    41  
    42  	team, err = Load(context.Background(), tc.G, keybase1.LoadTeamArg{
    43  		Name:        teamname,
    44  		ForceRepoll: true,
    45  	})
    46  	require.NoError(t, err)
    47  
    48  	mctx := libkb.NewMetaContextBackground(tc.G)
    49  
    50  	clearText := []byte{0, 1, 2, 3, 4, 5}
    51  	nonce := [24]byte{6, 7, 8, 9, 10}
    52  	buf, pub := encryptWithTeamKey(t, team, clearText, nonce, keybase1.PerTeamKeyGeneration(2))
    53  	arg := keybase1.TryDecryptWithTeamKeyArg{
    54  		TeamID:         team.ID,
    55  		EncryptedData:  buf,
    56  		Nonce:          nonce,
    57  		PeersPublicKey: (keybase1.BoxPublicKey)(pub),
    58  	}
    59  	ret, err := TryDecryptWithTeamKey(mctx, arg)
    60  	require.NoError(t, err)
    61  	require.ElementsMatch(t, ret, clearText)
    62  
    63  	// Try again with MinGeneration argument.
    64  	arg.MinGeneration = keybase1.PerTeamKeyGeneration(2)
    65  	ret, err = TryDecryptWithTeamKey(mctx, arg)
    66  	require.NoError(t, err)
    67  	require.ElementsMatch(t, ret, clearText)
    68  
    69  	// Do same encryption scheme but with generation 1.
    70  	buf, pub = encryptWithTeamKey(t, team, clearText, nonce, keybase1.PerTeamKeyGeneration(1))
    71  	arg.EncryptedData = buf
    72  	arg.MinGeneration = keybase1.PerTeamKeyGeneration(0) // default
    73  	arg.PeersPublicKey = (keybase1.BoxPublicKey)(pub)
    74  	ret, err = TryDecryptWithTeamKey(mctx, arg)
    75  	require.NoError(t, err)
    76  	require.ElementsMatch(t, ret, clearText)
    77  }
    78  
    79  func TestTeamOracleRepolling(t *testing.T) {
    80  	fus, tcs, cleanup := setupNTests(t, 2)
    81  	defer cleanup()
    82  
    83  	teamName, teamID := createTeam2(*tcs[0])
    84  	t.Logf("Created team %s", teamName)
    85  
    86  	_, err := AddMember(context.Background(), tcs[0].G, teamName.String(), fus[1].Username, keybase1.TeamRole_ADMIN, nil)
    87  	require.NoError(t, err)
    88  
    89  	// Issue a team load as user 1 to get this version of the team to cache.
    90  	_, err = Load(context.Background(), tcs[1].G, keybase1.LoadTeamArg{
    91  		Name:        teamName.String(),
    92  		ForceRepoll: true,
    93  	})
    94  	require.NoError(t, err)
    95  
    96  	// Rotate team as user 0 and encrypt with key 2.
    97  	require.NoError(t, RotateKeyVisible(context.Background(), tcs[0].G, teamID))
    98  	team, err := Load(context.Background(), tcs[0].G, keybase1.LoadTeamArg{
    99  		Name:        teamName.String(),
   100  		ForceRepoll: true,
   101  	})
   102  	require.NoError(t, err)
   103  
   104  	clearText := []byte{0, 1, 2, 3, 4, 5}
   105  	nonce := [24]byte{6, 7, 8, 9, 10}
   106  	buf, pub := encryptWithTeamKey(t, team, clearText, nonce, keybase1.PerTeamKeyGeneration(2))
   107  
   108  	// Try to decrypt as user 1. User 1 does not have team with gen=2
   109  	// in cache, so `TryDecryptWithTeamKey` will have to take slower
   110  	// repoll path.
   111  	arg := keybase1.TryDecryptWithTeamKeyArg{
   112  		TeamID:         teamID,
   113  		EncryptedData:  buf,
   114  		Nonce:          nonce,
   115  		PeersPublicKey: (keybase1.BoxPublicKey)(pub),
   116  	}
   117  	ret, err := TryDecryptWithTeamKey(libkb.NewMetaContextBackground(tcs[1].G), arg)
   118  	require.NoError(t, err)
   119  	require.ElementsMatch(t, ret, clearText)
   120  }