github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/encryption/encryption_test.go (about)

     1  package encryption
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestEncryptDecrypt(t *testing.T) {
    11  	// not providing an encrypter will fail
    12  	msg := []byte("hello again swarmkit")
    13  	_, err := Encrypt(msg, nil)
    14  	require.Error(t, err)
    15  	require.Contains(t, err.Error(), "no encrypter")
    16  
    17  	// noop encrypter can encrypt
    18  	encrypted, err := Encrypt(msg, NoopCrypter)
    19  	require.NoError(t, err)
    20  
    21  	// not providing a decrypter will fail
    22  	_, err = Decrypt(encrypted, nil)
    23  	require.Error(t, err)
    24  	require.Contains(t, err.Error(), "no decrypter")
    25  
    26  	// noop decrypter can decrypt
    27  	decrypted, err := Decrypt(encrypted, NoopCrypter)
    28  	require.NoError(t, err)
    29  	require.Equal(t, msg, decrypted)
    30  
    31  	// the default encrypter can produce something the default decrypter can read
    32  	encrypter, decrypter := Defaults([]byte("key"), false)
    33  	encrypted, err = Encrypt(msg, encrypter)
    34  	require.NoError(t, err)
    35  	decrypted, err = Decrypt(encrypted, decrypter)
    36  	require.NoError(t, err)
    37  	require.Equal(t, msg, decrypted)
    38  
    39  	// mismatched encrypters and decrypters can't read the content produced by each
    40  	encrypted, err = Encrypt(msg, NoopCrypter)
    41  	require.NoError(t, err)
    42  	_, err = Decrypt(encrypted, decrypter)
    43  	require.Error(t, err)
    44  	require.IsType(t, ErrCannotDecrypt{}, err)
    45  
    46  	encrypted, err = Encrypt(msg, encrypter)
    47  	require.NoError(t, err)
    48  	_, err = Decrypt(encrypted, NoopCrypter)
    49  	require.Error(t, err)
    50  	require.IsType(t, ErrCannotDecrypt{}, err)
    51  }
    52  
    53  func TestHumanReadable(t *testing.T) {
    54  	// we can produce human readable strings that can then be re-parsed
    55  	key := GenerateSecretKey()
    56  	keyString := HumanReadableKey(key)
    57  	parsedKey, err := ParseHumanReadableKey(keyString)
    58  	require.NoError(t, err)
    59  	require.Equal(t, parsedKey, key)
    60  
    61  	// if the prefix is wrong, we can't parse the key
    62  	_, err = ParseHumanReadableKey("A" + keyString)
    63  	require.Error(t, err)
    64  
    65  	// With the right prefix, we can't parse if the key isn't base64 encoded
    66  	_, err = ParseHumanReadableKey(humanReadablePrefix + "aaa*aa/")
    67  	require.Error(t, err)
    68  
    69  	// Extra padding also fails
    70  	_, err = ParseHumanReadableKey(keyString + "=")
    71  	require.Error(t, err)
    72  }
    73  
    74  type bothCrypter interface {
    75  	Decrypter
    76  	Encrypter
    77  }
    78  
    79  func TestMultiDecryptor(t *testing.T) {
    80  	crypters := []bothCrypter{
    81  		noopCrypter{},
    82  		NewNACLSecretbox([]byte("key1")),
    83  		NewNACLSecretbox([]byte("key2")),
    84  		NewNACLSecretbox([]byte("key3")),
    85  		NewFernet([]byte("key1")),
    86  		NewFernet([]byte("key2")),
    87  	}
    88  	m := NewMultiDecrypter(
    89  		crypters[0], crypters[1], crypters[2], crypters[4],
    90  		NewMultiDecrypter(crypters[3], crypters[5]),
    91  	)
    92  
    93  	for i, c := range crypters {
    94  		plaintext := []byte(fmt.Sprintf("message %d", i))
    95  		ciphertext, err := Encrypt(plaintext, c)
    96  		require.NoError(t, err)
    97  		decrypted, err := Decrypt(ciphertext, m)
    98  		require.NoError(t, err)
    99  		require.Equal(t, plaintext, decrypted)
   100  
   101  		// for sanity, make sure the other crypters can't decrypt
   102  		for j, o := range crypters {
   103  			if j == i {
   104  				continue
   105  			}
   106  			_, err := Decrypt(ciphertext, o)
   107  			require.IsType(t, ErrCannotDecrypt{}, err)
   108  		}
   109  	}
   110  
   111  	// Test multidecryptor where it does not have a decryptor with the right key
   112  	for _, d := range []MultiDecrypter{m, NewMultiDecrypter()} {
   113  		plaintext := []byte("message")
   114  		ciphertext, err := Encrypt(plaintext, NewNACLSecretbox([]byte("other")))
   115  		require.NoError(t, err)
   116  		_, err = Decrypt(ciphertext, d)
   117  		require.IsType(t, ErrCannotDecrypt{}, err)
   118  	}
   119  }
   120  
   121  // The default encrypter/decrypter, if FIPS is not enabled, is NACLSecretBox.
   122  // However, it can decrypt using all other supported algorithms.  If FIPS is
   123  // enabled, the encrypter/decrypter is Fernet only, because FIPS only permits
   124  // (given the algorithms swarmkit supports) AES-128-CBC
   125  func TestDefaults(t *testing.T) {
   126  	plaintext := []byte("my message")
   127  
   128  	// encrypt something without FIPS enabled
   129  	c, d := Defaults([]byte("key"), false)
   130  	ciphertext, err := Encrypt(plaintext, c)
   131  	require.NoError(t, err)
   132  	decrypted, err := Decrypt(ciphertext, d)
   133  	require.NoError(t, err)
   134  	require.Equal(t, plaintext, decrypted)
   135  
   136  	// with fips enabled, defaults should return a fernet encrypter
   137  	// and a decrypter that can't decrypt nacl
   138  	c, d = Defaults([]byte("key"), true)
   139  	_, err = Decrypt(ciphertext, d)
   140  	require.Error(t, err)
   141  	ciphertext, err = Encrypt(plaintext, c)
   142  	require.NoError(t, err)
   143  	decrypted, err = Decrypt(ciphertext, d)
   144  	require.NoError(t, err)
   145  	require.Equal(t, plaintext, decrypted)
   146  
   147  	// without FIPS, and ensure we can decrypt the previous ciphertext
   148  	// (encrypted with fernet) with the decrypter returned by defaults
   149  	_, d = Defaults([]byte("key"), false)
   150  	decrypted, err = Decrypt(ciphertext, d)
   151  	require.NoError(t, err)
   152  	require.Equal(t, plaintext, decrypted)
   153  }