github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/crypto_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  	"fmt"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/keybase/client/go/kbcrypto"
    13  	"github.com/keybase/client/go/kbfs/kbfscodec"
    14  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    15  	"github.com/keybase/client/go/libkb"
    16  	"github.com/keybase/client/go/logger"
    17  	"github.com/keybase/client/go/protocol/keybase1"
    18  	"github.com/keybase/go-framed-msgpack-rpc/rpc"
    19  	"github.com/pkg/errors"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  	"golang.org/x/crypto/nacl/box"
    23  	"golang.org/x/net/context"
    24  )
    25  
    26  type FakeCryptoClient struct {
    27  	Local     *CryptoLocal
    28  	readyChan chan<- struct{}
    29  	goChan    <-chan struct{}
    30  }
    31  
    32  func NewFakeCryptoClient(
    33  	codec kbfscodec.Codec, signingKey kbfscrypto.SigningKey,
    34  	cryptPrivateKey kbfscrypto.CryptPrivateKey, readyChan chan<- struct{},
    35  	goChan <-chan struct{}) *FakeCryptoClient {
    36  	return &FakeCryptoClient{
    37  		Local: NewCryptoLocal(
    38  			codec, signingKey, cryptPrivateKey, makeBlockCryptV1()),
    39  		readyChan: readyChan,
    40  		goChan:    goChan,
    41  	}
    42  }
    43  
    44  func (fc FakeCryptoClient) maybeWaitOnChannel(ctx context.Context) error {
    45  	if fc.readyChan == nil {
    46  		return nil
    47  	}
    48  
    49  	// say we're ready, and wait for a signal to proceed or a
    50  	// cancellation.
    51  	fc.readyChan <- struct{}{}
    52  	select {
    53  	case <-fc.goChan:
    54  		return nil
    55  	case <-ctx.Done():
    56  		return errors.WithStack(ctx.Err())
    57  	}
    58  }
    59  
    60  func (fc FakeCryptoClient) Call(ctx context.Context, s string, args interface{},
    61  	res interface{}, _ time.Duration) error {
    62  	return fc.call(ctx, s, args, res)
    63  }
    64  
    65  func (fc FakeCryptoClient) CallCompressed(ctx context.Context, s string, args interface{},
    66  	res interface{}, _ rpc.CompressionType, _ time.Duration) error {
    67  	return fc.call(ctx, s, args, res)
    68  }
    69  
    70  func (fc FakeCryptoClient) call(ctx context.Context, s string, args interface{}, res interface{}) error {
    71  	switch s {
    72  	case "keybase.1.crypto.signED25519":
    73  		if err := fc.maybeWaitOnChannel(ctx); err != nil {
    74  			return err
    75  		}
    76  		arg := args.([]interface{})[0].(keybase1.SignED25519Arg)
    77  		sigInfo, err := fc.Local.Sign(ctx, arg.Msg)
    78  		if err != nil {
    79  			return err
    80  		}
    81  		sigRes := res.(*keybase1.ED25519SignatureInfo)
    82  		// Normally, we'd have to validate all the parameters
    83  		// in sigInfo, but since this is used in tests only,
    84  		// there's no need.
    85  		var ed25519Signature keybase1.ED25519Signature
    86  		copy(ed25519Signature[:], sigInfo.Signature)
    87  		publicKey :=
    88  			kbcrypto.KIDToNaclSigningKeyPublic(sigInfo.VerifyingKey.KID().ToBytes())
    89  		*sigRes = keybase1.ED25519SignatureInfo{
    90  			Sig:       ed25519Signature,
    91  			PublicKey: keybase1.ED25519PublicKey(*publicKey),
    92  		}
    93  		return nil
    94  
    95  	case "keybase.1.crypto.unboxBytes32":
    96  		if err := fc.maybeWaitOnChannel(ctx); err != nil {
    97  			return err
    98  		}
    99  		arg := args.([]interface{})[0].(keybase1.UnboxBytes32Arg)
   100  		publicKey := kbfscrypto.MakeTLFEphemeralPublicKey(
   101  			arg.PeersPublicKey)
   102  		encryptedClientHalf := kbfscrypto.MakeEncryptedTLFCryptKeyClientHalfForTest(
   103  			kbfscrypto.EncryptionSecretbox, arg.EncryptedBytes32[:],
   104  			arg.Nonce[:])
   105  		clientHalf, err := fc.Local.DecryptTLFCryptKeyClientHalf(
   106  			ctx, publicKey, encryptedClientHalf)
   107  		if err != nil {
   108  			return err
   109  		}
   110  		res := res.(*keybase1.Bytes32)
   111  		*res = clientHalf.Data()
   112  		return nil
   113  
   114  	case "keybase.1.crypto.unboxBytes32Any":
   115  		if err := fc.maybeWaitOnChannel(ctx); err != nil {
   116  			return err
   117  		}
   118  		arg := args.([]interface{})[0].(keybase1.UnboxBytes32AnyArg)
   119  		keys := make([]EncryptedTLFCryptKeyClientAndEphemeral, 0, len(arg.Bundles))
   120  		for _, k := range arg.Bundles {
   121  			ePublicKey := kbfscrypto.MakeTLFEphemeralPublicKey(
   122  				k.PublicKey)
   123  			encryptedClientHalf := kbfscrypto.MakeEncryptedTLFCryptKeyClientHalfForTest(
   124  				kbfscrypto.EncryptionSecretbox,
   125  				k.Ciphertext[:],
   126  				k.Nonce[:])
   127  			keys = append(keys, EncryptedTLFCryptKeyClientAndEphemeral{
   128  				EPubKey:    ePublicKey,
   129  				ClientHalf: encryptedClientHalf,
   130  				PubKey:     kbfscrypto.MakeCryptPublicKey(k.Kid),
   131  			})
   132  		}
   133  		clientHalf, index, err := fc.Local.DecryptTLFCryptKeyClientHalfAny(
   134  			ctx, keys, arg.PromptPaper)
   135  		if err != nil {
   136  			return err
   137  		}
   138  		res := res.(*keybase1.UnboxAnyRes)
   139  		res.Plaintext = clientHalf.Data()
   140  		res.Index = index
   141  		res.Kid = keys[index].PubKey.KID()
   142  		return nil
   143  
   144  	default:
   145  		return errors.Errorf("Unknown call: %s %v %v", s, args, res)
   146  	}
   147  }
   148  
   149  func (fc FakeCryptoClient) Notify(_ context.Context, s string, args interface{}, _ time.Duration) error {
   150  	return errors.Errorf("Unknown notify: %s %v", s, args)
   151  }
   152  
   153  // Test that signing a message and then verifying it works.
   154  func TestCryptoClientSignAndVerify(t *testing.T) {
   155  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   156  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   157  	codec := kbfscodec.NewMsgpack()
   158  	log := logger.NewTestLogger(t)
   159  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   160  	c := newCryptoClientWithClient(codec, log, fc)
   161  
   162  	msg := []byte("message")
   163  	sigInfo, err := c.Sign(context.Background(), msg)
   164  	require.NoError(t, err)
   165  
   166  	err = kbfscrypto.Verify(msg, sigInfo)
   167  	require.NoError(t, err)
   168  }
   169  
   170  // Test that canceling a signing RPC returns the correct error
   171  func TestCryptoClientSignCanceled(t *testing.T) {
   172  	codec := kbfscodec.NewMsgpack()
   173  	log := logger.NewTestLogger(t)
   174  	serverConn, conn := rpc.MakeConnectionForTest(t)
   175  	c := newCryptoClientWithClient(codec, log, conn.GetClient())
   176  
   177  	f := func(ctx context.Context) error {
   178  		msg := []byte("message")
   179  		_, err := c.Sign(ctx, msg)
   180  		return err
   181  	}
   182  	testRPCWithCanceledContext(t, serverConn, f)
   183  }
   184  
   185  // Test that decrypting a TLF crypt key client half encrypted with
   186  // box.Seal works.
   187  func TestCryptoClientDecryptTLFCryptKeyClientHalfBoxSeal(t *testing.T) {
   188  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   189  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   190  	codec := kbfscodec.NewMsgpack()
   191  	log := logger.NewTestLogger(t)
   192  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   193  	c := newCryptoClientWithClient(codec, log, fc)
   194  
   195  	ephPublicKey, ephPrivateKey, err := c.MakeRandomTLFEphemeralKeys()
   196  	require.NoError(t, err)
   197  
   198  	cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   199  	require.NoError(t, err)
   200  
   201  	serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   202  	require.NoError(t, err)
   203  
   204  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   205  
   206  	var nonce [24]byte
   207  	err = kbfscrypto.RandRead(nonce[:])
   208  	require.NoError(t, err)
   209  
   210  	keypair, err := libkb.ImportKeypairFromKID(cryptPrivateKey.GetPublicKey().KID())
   211  	require.NoError(t, err)
   212  
   213  	dhKeyPair, ok := keypair.(libkb.NaclDHKeyPair)
   214  	require.True(t, ok)
   215  
   216  	clientHalfData := clientHalf.Data()
   217  	ephPrivateKeyData := ephPrivateKey.Data()
   218  	encryptedBytes := box.Seal(nil, clientHalfData[:], &nonce, (*[32]byte)(&dhKeyPair.Public), &ephPrivateKeyData)
   219  	encryptedClientHalf := kbfscrypto.MakeEncryptedTLFCryptKeyClientHalfForTest(
   220  		kbfscrypto.EncryptionSecretbox, encryptedBytes, nonce[:])
   221  
   222  	decryptedClientHalf, err := c.DecryptTLFCryptKeyClientHalf(
   223  		context.Background(), ephPublicKey, encryptedClientHalf)
   224  	require.NoError(t, err)
   225  	require.Equal(t, clientHalf, decryptedClientHalf)
   226  }
   227  
   228  // Test that decrypting a TLF crypt key client half encrypted with the
   229  // default method (currently nacl/box) works.
   230  func TestCryptoClientDecryptEncryptedTLFCryptKeyClientHalf(t *testing.T) {
   231  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   232  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   233  	codec := kbfscodec.NewMsgpack()
   234  	log := logger.NewTestLogger(t)
   235  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   236  	c := newCryptoClientWithClient(codec, log, fc)
   237  
   238  	ephPublicKey, ephPrivateKey, err := c.MakeRandomTLFEphemeralKeys()
   239  	require.NoError(t, err)
   240  
   241  	cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   242  	require.NoError(t, err)
   243  
   244  	serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   245  	require.NoError(t, err)
   246  
   247  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   248  
   249  	// See crypto_common_test.go for tests that this actually
   250  	// performs encryption.
   251  	encryptedClientHalf, err := kbfscrypto.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.GetPublicKey(), clientHalf)
   252  	require.NoError(t, err)
   253  	require.Equal(t, kbfscrypto.EncryptionSecretbox, encryptedClientHalf.Version)
   254  
   255  	decryptedClientHalf, err := c.DecryptTLFCryptKeyClientHalf(
   256  		context.Background(), ephPublicKey, encryptedClientHalf)
   257  	require.NoError(t, err)
   258  	require.Equal(t, clientHalf, decryptedClientHalf)
   259  }
   260  
   261  // Test that attempting to decrypt an empty set of client keys fails.
   262  func TestCryptoClientDecryptEmptyEncryptedTLFCryptKeyClientHalfAny(t *testing.T) {
   263  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   264  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   265  	codec := kbfscodec.NewMsgpack()
   266  	log := logger.NewTestLogger(t)
   267  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   268  	c := newCryptoClientWithClient(codec, log, fc)
   269  
   270  	keys := make([]EncryptedTLFCryptKeyClientAndEphemeral, 0)
   271  
   272  	_, _, err := c.DecryptTLFCryptKeyClientHalfAny(
   273  		context.Background(), keys, false)
   274  	require.IsType(t, NoKeysError{}, errors.Cause(err))
   275  }
   276  
   277  // Test that when decrypting set of client keys, the first working one
   278  // is used to decrypt.
   279  func TestCryptoClientDecryptEncryptedTLFCryptKeyClientHalfAny(t *testing.T) {
   280  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   281  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   282  	codec := kbfscodec.NewMsgpack()
   283  	log := logger.NewTestLogger(t)
   284  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   285  	c := newCryptoClientWithClient(codec, log, fc)
   286  
   287  	keys := make([]EncryptedTLFCryptKeyClientAndEphemeral, 0, 4)
   288  	clientHalves := make([]kbfscrypto.TLFCryptKeyClientHalf, 0, 4)
   289  	for i := 0; i < 4; i++ {
   290  		ephPublicKey, ephPrivateKey, err :=
   291  			c.MakeRandomTLFEphemeralKeys()
   292  		require.NoError(t, err)
   293  
   294  		cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   295  		require.NoError(t, err)
   296  
   297  		serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   298  		require.NoError(t, err)
   299  
   300  		clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   301  
   302  		// See crypto_common_test.go for tests that this actually
   303  		// performs encryption.
   304  		encryptedClientHalf, err := kbfscrypto.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.GetPublicKey(), clientHalf)
   305  		require.NoError(t, err)
   306  		require.Equal(t, kbfscrypto.EncryptionSecretbox,
   307  			encryptedClientHalf.Version)
   308  		keys = append(keys, EncryptedTLFCryptKeyClientAndEphemeral{
   309  			PubKey:     cryptPrivateKey.GetPublicKey(),
   310  			ClientHalf: encryptedClientHalf,
   311  			EPubKey:    ephPublicKey,
   312  		})
   313  		clientHalves = append(clientHalves, clientHalf)
   314  	}
   315  
   316  	decryptedClientHalf, index, err := c.DecryptTLFCryptKeyClientHalfAny(
   317  		context.Background(), keys, false)
   318  	require.NoError(t, err)
   319  	require.Equal(t, clientHalves[0], decryptedClientHalf)
   320  	require.Equal(t, 0, index)
   321  }
   322  
   323  // Test various failure cases for DecryptTLFCryptKeyClientHalfAny and that
   324  // if a working key is present, the decryption succeeds.
   325  func TestCryptoClientDecryptTLFCryptKeyClientHalfAnyFailures(t *testing.T) {
   326  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   327  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   328  	codec := kbfscodec.NewMsgpack()
   329  	log := logger.NewTestLogger(t)
   330  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   331  	c := newCryptoClientWithClient(codec, log, fc)
   332  
   333  	ephPublicKey, ephPrivateKey, err := c.MakeRandomTLFEphemeralKeys()
   334  	require.NoError(t, err)
   335  
   336  	cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   337  	require.NoError(t, err)
   338  
   339  	serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   340  	require.NoError(t, err)
   341  
   342  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   343  
   344  	encryptedClientHalf, err := kbfscrypto.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.GetPublicKey(), clientHalf)
   345  	require.NoError(t, err)
   346  
   347  	// Wrong version.
   348  	encryptedClientHalfWrongVersion := encryptedClientHalf
   349  	encryptedClientHalfWrongVersion.Version++
   350  
   351  	// Wrong sizes.
   352  	encryptedClientHalfWrongSize := encryptedClientHalf
   353  	encryptedClientHalfWrongSize.EncryptedData = encryptedClientHalfWrongSize.EncryptedData[:len(encryptedClientHalfWrongSize.EncryptedData)-1]
   354  
   355  	encryptedClientHalfWrongNonceSize := encryptedClientHalf
   356  	encryptedClientHalfWrongNonceSize.Nonce = encryptedClientHalfWrongNonceSize.Nonce[:len(encryptedClientHalfWrongNonceSize.Nonce)-1]
   357  
   358  	// Corrupt key.
   359  	ephPublicKeyCorruptData := ephPublicKey.Data()
   360  	ephPublicKeyCorruptData[0] = ^ephPublicKeyCorruptData[0]
   361  	ephPublicKeyCorrupt := kbfscrypto.MakeTLFEphemeralPublicKey(
   362  		ephPublicKeyCorruptData)
   363  
   364  	// Corrupt data.
   365  	encryptedClientHalfCorruptData := encryptedClientHalf
   366  	encryptedClientHalfCorruptData.EncryptedData = make([]byte, len(encryptedClientHalf.EncryptedData))
   367  	copy(encryptedClientHalfCorruptData.EncryptedData, encryptedClientHalf.EncryptedData)
   368  	encryptedClientHalfCorruptData.EncryptedData[0] = ^encryptedClientHalfCorruptData.EncryptedData[0]
   369  
   370  	keys := []EncryptedTLFCryptKeyClientAndEphemeral{
   371  		{
   372  			PubKey:     cryptPrivateKey.GetPublicKey(),
   373  			ClientHalf: encryptedClientHalfWrongVersion,
   374  			EPubKey:    ephPublicKey,
   375  		}, {
   376  			PubKey:     cryptPrivateKey.GetPublicKey(),
   377  			ClientHalf: encryptedClientHalfWrongSize,
   378  			EPubKey:    ephPublicKey,
   379  		}, {
   380  			PubKey:     cryptPrivateKey.GetPublicKey(),
   381  			ClientHalf: encryptedClientHalfWrongNonceSize,
   382  			EPubKey:    ephPublicKey,
   383  		}, {
   384  			PubKey:     cryptPrivateKey.GetPublicKey(),
   385  			ClientHalf: encryptedClientHalf,
   386  			EPubKey:    ephPublicKeyCorrupt,
   387  		}, {
   388  			PubKey:     cryptPrivateKey.GetPublicKey(),
   389  			ClientHalf: encryptedClientHalfCorruptData,
   390  			EPubKey:    ephPublicKey,
   391  		}, {
   392  			PubKey:     cryptPrivateKey.GetPublicKey(),
   393  			ClientHalf: encryptedClientHalf,
   394  			EPubKey:    ephPublicKey,
   395  		},
   396  	}
   397  
   398  	_, index, err := c.DecryptTLFCryptKeyClientHalfAny(
   399  		context.Background(), keys, false)
   400  	require.NoError(t, err)
   401  	require.Equal(t, len(keys)-1, index)
   402  }
   403  
   404  // Test various failure cases for DecryptTLFCryptKeyClientHalf.
   405  func TestCryptoClientDecryptTLFCryptKeyClientHalfFailures(t *testing.T) {
   406  	signingKey := kbfscrypto.MakeFakeSigningKeyOrBust("client sign")
   407  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   408  	codec := kbfscodec.NewMsgpack()
   409  	log := logger.NewTestLogger(t)
   410  	fc := NewFakeCryptoClient(codec, signingKey, cryptPrivateKey, nil, nil)
   411  	c := newCryptoClientWithClient(codec, log, fc)
   412  
   413  	ephPublicKey, ephPrivateKey, err := c.MakeRandomTLFEphemeralKeys()
   414  	require.NoError(t, err)
   415  
   416  	cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   417  	require.NoError(t, err)
   418  
   419  	serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   420  	require.NoError(t, err)
   421  
   422  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   423  
   424  	encryptedClientHalf, err := kbfscrypto.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.GetPublicKey(), clientHalf)
   425  	require.NoError(t, err)
   426  
   427  	// Wrong version.
   428  
   429  	encryptedClientHalfWrongVersion := encryptedClientHalf
   430  	encryptedClientHalfWrongVersion.Version++
   431  	ctx := context.Background()
   432  	_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey,
   433  		encryptedClientHalfWrongVersion)
   434  	assert.Equal(t,
   435  		kbfscrypto.UnknownEncryptionVer{
   436  			Ver: encryptedClientHalfWrongVersion.Version},
   437  		errors.Cause(err))
   438  
   439  	// Wrong sizes.
   440  
   441  	encryptedClientHalfWrongSize := encryptedClientHalf
   442  	encryptedClientHalfWrongSize.EncryptedData = encryptedClientHalfWrongSize.EncryptedData[:len(encryptedClientHalfWrongSize.EncryptedData)-1]
   443  	_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey,
   444  		encryptedClientHalfWrongSize)
   445  	assert.EqualError(t, errors.Cause(err),
   446  		fmt.Sprintf("Expected %d bytes, got %d",
   447  			len(encryptedClientHalf.EncryptedData),
   448  			len(encryptedClientHalfWrongSize.EncryptedData)))
   449  
   450  	encryptedClientHalfWrongNonceSize := encryptedClientHalf
   451  	encryptedClientHalfWrongNonceSize.Nonce = encryptedClientHalfWrongNonceSize.Nonce[:len(encryptedClientHalfWrongNonceSize.Nonce)-1]
   452  	_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey,
   453  		encryptedClientHalfWrongNonceSize)
   454  	assert.Equal(t,
   455  		kbfscrypto.InvalidNonceError{
   456  			Nonce: encryptedClientHalfWrongNonceSize.Nonce},
   457  		errors.Cause(err))
   458  
   459  	// Corrupt key.
   460  
   461  	ephPublicKeyCorruptData := ephPublicKey.Data()
   462  	ephPublicKeyCorruptData[0] = ^ephPublicKeyCorruptData[0]
   463  	ephPublicKeyCorrupt := kbfscrypto.MakeTLFEphemeralPublicKey(
   464  		ephPublicKeyCorruptData)
   465  	_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKeyCorrupt,
   466  		encryptedClientHalf)
   467  	assert.IsType(t, libkb.DecryptionError{}, errors.Cause(err))
   468  
   469  	// Corrupt data.
   470  
   471  	encryptedClientHalfCorruptData := encryptedClientHalf
   472  	encryptedClientHalfCorruptData.EncryptedData[0] = ^encryptedClientHalfCorruptData.EncryptedData[0]
   473  	_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey,
   474  		encryptedClientHalfCorruptData)
   475  	assert.IsType(t, libkb.DecryptionError{}, errors.Cause(err))
   476  }
   477  
   478  // Test that canceling a signing RPC returns the correct error
   479  func TestCryptoClientDecryptTLFCryptKeyClientHalfCanceled(t *testing.T) {
   480  	cryptPrivateKey := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("client crypt private")
   481  	codec := kbfscodec.NewMsgpack()
   482  	log := logger.NewTestLogger(t)
   483  	serverConn, conn := rpc.MakeConnectionForTest(t)
   484  	c := newCryptoClientWithClient(codec, log, conn.GetClient())
   485  
   486  	ephPublicKey, ephPrivateKey, err := c.MakeRandomTLFEphemeralKeys()
   487  	require.NoError(t, err)
   488  
   489  	cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey()
   490  	require.NoError(t, err)
   491  
   492  	serverHalf, err := kbfscrypto.MakeRandomTLFCryptKeyServerHalf()
   493  	require.NoError(t, err)
   494  
   495  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, cryptKey)
   496  
   497  	encryptedClientHalf, err := kbfscrypto.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.GetPublicKey(), clientHalf)
   498  	require.NoError(t, err)
   499  
   500  	f := func(ctx context.Context) error {
   501  		_, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey,
   502  			encryptedClientHalf)
   503  		return err
   504  	}
   505  	testRPCWithCanceledContext(t, serverConn, f)
   506  }