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

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package libkb
     5  
     6  import (
     7  	"bytes"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/keybase/saltpack"
    12  	saltpackBasic "github.com/keybase/saltpack/basic"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/keybase/client/go/saltpackkeystest"
    16  )
    17  
    18  type outputBuffer struct {
    19  	bytes.Buffer
    20  }
    21  
    22  func (ob outputBuffer) Close() error {
    23  	return nil
    24  }
    25  
    26  // Encrypt a message, and make sure recipients can decode it, and
    27  // non-recipients can't decode it.
    28  func TestSaltpackEncDec(t *testing.T) {
    29  	tc := SetupTest(t, "TestSaltpackEncDec", 1)
    30  	defer tc.Cleanup()
    31  
    32  	m := NewMetaContextForTest(tc)
    33  
    34  	senderKP, err := GenerateNaclDHKeyPair()
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  
    39  	senderSigningKP, err := GenerateNaclSigningKeyPair()
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  
    44  	var receiverKPs []NaclDHKeyPair
    45  	var receiverPKs []NaclDHKeyPublic
    46  	for i := 0; i < 12; i++ {
    47  		kp, err := GenerateNaclDHKeyPair()
    48  		if err != nil {
    49  			t.Fatal(err)
    50  		}
    51  		receiverKPs = append(receiverKPs, kp)
    52  		receiverPKs = append(receiverPKs, kp.Public)
    53  	}
    54  
    55  	nonReceiverKP, err := GenerateNaclDHKeyPair()
    56  	if err != nil {
    57  		t.Fatal(err)
    58  	}
    59  
    60  	message := "The Magic Words are Squeamish Ossifrage"
    61  
    62  	var buf outputBuffer
    63  
    64  	arg := SaltpackEncryptArg{
    65  		Source:        strings.NewReader(message),
    66  		Sink:          &buf,
    67  		Receivers:     receiverPKs,
    68  		Sender:        senderKP,
    69  		SenderSigning: senderSigningKP,
    70  	}
    71  	if err := SaltpackEncrypt(m, &arg); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	ciphertext := buf.String()
    76  	if !strings.HasPrefix(ciphertext, saltpack.MakeArmorHeader(saltpack.MessageTypeEncryption, KeybaseSaltpackBrand)) {
    77  		t.Errorf("ciphertext doesn't have header: %s", ciphertext)
    78  	}
    79  
    80  	if !strings.HasSuffix(ciphertext, saltpack.MakeArmorFooter(saltpack.MessageTypeEncryption, KeybaseSaltpackBrand)+".\n") {
    81  		t.Errorf("ciphertext doesn't have footer: %s", ciphertext)
    82  	}
    83  
    84  	for _, key := range receiverKPs {
    85  		buf.Reset()
    86  
    87  		// Create a keyring with only one key
    88  		keyring := saltpackBasic.NewKeyring()
    89  		keyring.ImportBoxKey((*[NaclDHKeysize]byte)(&key.Public), (*[NaclDHKeysize]byte)(key.Private))
    90  
    91  		_, err = SaltpackDecrypt(m,
    92  			strings.NewReader(ciphertext),
    93  			&buf, keyring, nil, nil, saltpackkeystest.NewMockPseudonymResolver(t))
    94  		if err != nil {
    95  			t.Fatal(err)
    96  		}
    97  
    98  		plaintext := buf.String()
    99  		if plaintext != message {
   100  			t.Errorf("expected %s, got %s",
   101  				message, plaintext)
   102  		}
   103  	}
   104  
   105  	// Sender is a non-recipient, too.
   106  	nonReceiverKPs := []NaclDHKeyPair{nonReceiverKP, senderKP}
   107  
   108  	for _, key := range nonReceiverKPs {
   109  		buf.Reset()
   110  
   111  		// Create a keyring with only one key
   112  		keyring := saltpackBasic.NewKeyring()
   113  		keyring.ImportBoxKey((*[NaclDHKeysize]byte)(&key.Public), (*[NaclDHKeysize]byte)(key.Private))
   114  
   115  		_, err = SaltpackDecrypt(m,
   116  			strings.NewReader(ciphertext), &buf, keyring, nil, nil, saltpackkeystest.NewMockPseudonymResolver(t))
   117  		// An unauthorized receiver trying to decrypt should receive an error
   118  		decError := err.(DecryptionError)
   119  		require.Equal(t, decError.Cause.Err, saltpack.ErrNoDecryptionKey)
   120  	}
   121  }