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

     1  package manager
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/pem"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/docker/swarmkit/ca"
    12  	cautils "github.com/docker/swarmkit/ca/testutils"
    13  	"github.com/docker/swarmkit/manager/state/raft"
    14  	"github.com/pkg/errors"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  // Tests updating a kek on a raftDEK object.
    19  func TestRaftDEKUpdateKEK(t *testing.T) {
    20  	for _, fips := range []bool{true, false} {
    21  		startData := RaftDEKData{
    22  			EncryptionKeys: raft.EncryptionKeys{CurrentDEK: []byte("first dek")},
    23  			FIPS:           fips,
    24  		}
    25  		startKEK := ca.KEKData{}
    26  
    27  		// because UpdateKEK returns a PEMKeyHeaders interface, we need to cast to check
    28  		// values
    29  		updateDEKAndCast := func(dekdata RaftDEKData, oldKEK ca.KEKData, newKEK ca.KEKData) RaftDEKData {
    30  			result := dekdata.UpdateKEK(oldKEK, newKEK)
    31  			raftDekObj, ok := result.(RaftDEKData)
    32  			require.True(t, ok)
    33  			return raftDekObj
    34  		}
    35  
    36  		// nothing changes if we are updating a kek and they're both nil
    37  		result := updateDEKAndCast(startData, startKEK, ca.KEKData{Version: 2})
    38  		require.Equal(t, result, startData)
    39  		require.Equal(t, startData.FIPS, result.FIPS) // fips value should not have changed
    40  
    41  		// when moving from unlocked to locked, a "needs rotation" header is generated but no
    42  		// pending header is generated
    43  		updatedKEK := ca.KEKData{KEK: []byte("something"), Version: 1}
    44  		result = updateDEKAndCast(startData, startKEK, updatedKEK)
    45  		require.NotEqual(t, startData, result)
    46  		require.True(t, result.NeedsRotation)
    47  		require.Equal(t, startData.CurrentDEK, result.CurrentDEK)
    48  		require.Nil(t, result.PendingDEK)
    49  		require.Equal(t, startData.FIPS, result.FIPS) // fips value should not have changed
    50  
    51  		// this is whether or not pending exists
    52  		startData.PendingDEK = []byte("pending")
    53  		result = updateDEKAndCast(startData, startKEK, updatedKEK)
    54  		require.NotEqual(t, startData, result)
    55  		require.True(t, result.NeedsRotation)
    56  		require.Equal(t, startData.CurrentDEK, result.CurrentDEK)
    57  		require.Equal(t, startData.PendingDEK, result.PendingDEK)
    58  		require.Equal(t, startData.FIPS, result.FIPS) // fips value should not have changed
    59  
    60  		// if we are going from locked to unlocked, nothing happens
    61  		result = updateDEKAndCast(startData, updatedKEK, startKEK)
    62  		require.Equal(t, startData, result)
    63  		require.False(t, result.NeedsRotation)
    64  		require.Equal(t, startData.FIPS, result.FIPS) // fips value should not have changed
    65  
    66  		// if we are going to locked to another locked, nothing happens
    67  		result = updateDEKAndCast(startData, updatedKEK, ca.KEKData{KEK: []byte("other"), Version: 4})
    68  		require.Equal(t, startData, result)
    69  		require.False(t, result.NeedsRotation)
    70  		require.Equal(t, startData.FIPS, result.FIPS) // fips value should not have changed
    71  	}
    72  }
    73  
    74  func TestRaftDEKMarshalUnmarshal(t *testing.T) {
    75  	for _, fips := range []bool{true, false} {
    76  		startData := RaftDEKData{
    77  			EncryptionKeys: raft.EncryptionKeys{CurrentDEK: []byte("first dek")},
    78  			FIPS:           fips,
    79  		}
    80  		kek := ca.KEKData{}
    81  
    82  		headers, err := startData.MarshalHeaders(kek)
    83  		require.NoError(t, err)
    84  		require.Len(t, headers, 1)
    85  
    86  		// can't unmarshal with the wrong kek
    87  		_, err = RaftDEKData{FIPS: fips}.UnmarshalHeaders(headers, ca.KEKData{KEK: []byte("something")})
    88  		require.Error(t, err)
    89  
    90  		// we can unmarshal what was marshalled with the right kek
    91  		toData, err := RaftDEKData{FIPS: fips}.UnmarshalHeaders(headers, kek)
    92  		require.NoError(t, err)
    93  		require.Equal(t, startData, toData)
    94  		casted, ok := toData.(RaftDEKData)
    95  		require.True(t, ok)
    96  		require.Equal(t, fips, casted.FIPS) // fips value should not have changed
    97  
    98  		// try the other headers as well
    99  		startData.PendingDEK = []byte("Hello")
   100  		headers, err = startData.MarshalHeaders(kek)
   101  		require.NoError(t, err)
   102  		require.Len(t, headers, 2)
   103  
   104  		// we can unmarshal what was marshalled
   105  		toData, err = RaftDEKData{FIPS: fips}.UnmarshalHeaders(headers, kek)
   106  		require.NoError(t, err)
   107  		require.Equal(t, startData, toData)
   108  		casted, ok = toData.(RaftDEKData)
   109  		require.True(t, ok)
   110  		require.Equal(t, fips, casted.FIPS) // fips value should not have changed
   111  
   112  		// try the other headers as well
   113  		startData.NeedsRotation = true
   114  		startData.PendingDEK = nil
   115  		headers, err = startData.MarshalHeaders(kek)
   116  		require.NoError(t, err)
   117  		require.Len(t, headers, 2)
   118  
   119  		// we can unmarshal what was marshalled
   120  		toData, err = RaftDEKData{FIPS: fips}.UnmarshalHeaders(headers, kek)
   121  		require.NoError(t, err)
   122  		require.Equal(t, startData, toData)
   123  		casted, ok = toData.(RaftDEKData)
   124  		require.True(t, ok)
   125  		require.Equal(t, fips, casted.FIPS) // fips value should not have changed
   126  
   127  		// If there is a pending header, but no current header, set will fail
   128  		headers = map[string]string{
   129  			pemHeaderRaftPendingDEK: headers[pemHeaderRaftDEK],
   130  		}
   131  		_, err = RaftDEKData{FIPS: fips}.UnmarshalHeaders(headers, kek)
   132  		require.Error(t, err)
   133  		require.Contains(t, err.Error(), "pending DEK, but no current DEK")
   134  	}
   135  }
   136  
   137  // NewRaftDEKManager creates a key if one doesn't exist
   138  func TestNewRaftDEKManager(t *testing.T) {
   139  	tempDir, err := ioutil.TempDir("", "manager-new-dek-manager-")
   140  	require.NoError(t, err)
   141  	defer os.RemoveAll(tempDir)
   142  
   143  	paths := ca.NewConfigPaths(tempDir)
   144  	cert, key, err := cautils.CreateRootCertAndKey("cn")
   145  	require.NoError(t, err)
   146  
   147  	for _, fips := range []bool{true, false} {
   148  		krw := ca.NewKeyReadWriter(paths.Node, nil, nil)
   149  		require.NoError(t, krw.Write(cert, key, nil))
   150  
   151  		keyBytes, err := ioutil.ReadFile(paths.Node.Key)
   152  		require.NoError(t, err)
   153  		require.NotContains(t, string(keyBytes), pemHeaderRaftDEK) // headers are not written
   154  
   155  		dekManager, err := NewRaftDEKManager(krw, fips) // this should create a new DEK and write it to the file
   156  		require.NoError(t, err)
   157  
   158  		keyBytes, err = ioutil.ReadFile(paths.Node.Key)
   159  		require.NoError(t, err)
   160  		require.Contains(t, string(keyBytes), pemHeaderRaftDEK) // header is written now
   161  
   162  		// ensure that the created raft DEK uses FIPS
   163  		h, _ := krw.GetCurrentState()
   164  		casted, ok := h.(RaftDEKData)
   165  		require.True(t, ok)
   166  		require.Equal(t, fips, casted.FIPS)
   167  
   168  		keys := dekManager.GetKeys()
   169  		require.NotNil(t, keys.CurrentDEK)
   170  		require.Nil(t, keys.PendingDEK)
   171  		require.False(t, dekManager.NeedsRotation())
   172  
   173  		// If one exists, nothing is updated
   174  		dekManager, err = NewRaftDEKManager(krw, fips) // this should not have created a new dek
   175  		require.NoError(t, err)
   176  
   177  		keyBytes2, err := ioutil.ReadFile(paths.Node.Key)
   178  		require.NoError(t, err)
   179  		require.Equal(t, keyBytes, keyBytes2)
   180  
   181  		require.Equal(t, keys, dekManager.GetKeys())
   182  		require.False(t, dekManager.NeedsRotation())
   183  	}
   184  }
   185  
   186  // NeedsRotate returns true if there is a PendingDEK or a NeedsRotation flag.  GetKeys() evaluates
   187  // whether a PendingDEK is there, and if there's no pending DEK but there is a NeedsRotation flag,
   188  // it creates a PendingDEK and removes the NeedsRotation flag.  If both the PendingDEK and
   189  // NeedsRotation flag are there, it does not remove the NeedsRotation flag, because that indicates
   190  // that we basically need to do 2 rotations.
   191  func TestRaftDEKManagerNeedsRotateGetKeys(t *testing.T) {
   192  	tempDir, err := ioutil.TempDir("", "manager-maybe-get-data-")
   193  	require.NoError(t, err)
   194  	defer os.RemoveAll(tempDir)
   195  
   196  	paths := ca.NewConfigPaths(tempDir)
   197  
   198  	for _, fips := range []bool{true, false} {
   199  		for _, testcase := range []struct {
   200  			description             string
   201  			dekData                 RaftDEKData
   202  			managerNeedsRotation    bool
   203  			newDEKDataNeedsRotation bool
   204  			keyOnDisk               bool
   205  		}{
   206  			{
   207  				description: "if there is no PendingDEK, and no NeedsRotation flag:  NeedsRotation()->false, DEKData.NeedsRotation->false",
   208  				keyOnDisk:   true,
   209  				dekData: RaftDEKData{
   210  					EncryptionKeys: raft.EncryptionKeys{CurrentDEK: []byte("hello")},
   211  					NeedsRotation:  false,
   212  				},
   213  				managerNeedsRotation:    false,
   214  				newDEKDataNeedsRotation: false,
   215  			},
   216  			{
   217  				description: "if there is a PendingDEK, and no NeedsRotation flag:  NeedsRotation()->true, DEKData.NeedsRotation->false",
   218  				keyOnDisk:   true,
   219  				dekData: RaftDEKData{
   220  					EncryptionKeys: raft.EncryptionKeys{
   221  						CurrentDEK: []byte("hello"),
   222  						PendingDEK: []byte("another"),
   223  					},
   224  					NeedsRotation: false,
   225  				},
   226  				managerNeedsRotation:    true,
   227  				newDEKDataNeedsRotation: false,
   228  			},
   229  			{
   230  				description: "if there is a PendingDEK, and a NeedsRotation flag:  NeedsRotation()->true, DEKData.NeedsRotation->true",
   231  				keyOnDisk:   true,
   232  				dekData: RaftDEKData{
   233  					EncryptionKeys: raft.EncryptionKeys{
   234  						CurrentDEK: []byte("hello"),
   235  						PendingDEK: []byte("another"),
   236  					},
   237  					NeedsRotation: true,
   238  				},
   239  				managerNeedsRotation:    true,
   240  				newDEKDataNeedsRotation: true,
   241  			},
   242  			// These in these two cases, the original keys did not have pending keys.  GetKeys
   243  			// should create them, but only if it can write the new pending key to the disk.
   244  			{
   245  				description: `
   246  					if there no PendingDEK, and a NeedsRotation flag: NeedsRotation()->true and
   247  					GetKeys attempts to create a pending key and write it to disk. However, writing
   248  					will error (because there is no key on disk atm), and then the original keys will
   249  					be returned.  So DEKData.NeedsRotation->true.`,
   250  				keyOnDisk: false,
   251  				dekData: RaftDEKData{
   252  					EncryptionKeys: raft.EncryptionKeys{CurrentDEK: []byte("hello")},
   253  					NeedsRotation:  true,
   254  				},
   255  				managerNeedsRotation:    true,
   256  				newDEKDataNeedsRotation: true,
   257  			},
   258  			{
   259  				description: `
   260  					if there no PendingDEK, and there is a NeedsRotation flag:  NeedsRotation()->true and
   261  					GetKeys attempts to create a pending key and write it to disk. Once a pending key is
   262  					created, the NeedsRotation flag can be set to false.  So DEKData.NeedsRotation->false`,
   263  				keyOnDisk: true,
   264  				dekData: RaftDEKData{
   265  					EncryptionKeys: raft.EncryptionKeys{CurrentDEK: []byte("hello")},
   266  					NeedsRotation:  true,
   267  				},
   268  				managerNeedsRotation:    true,
   269  				newDEKDataNeedsRotation: false,
   270  			},
   271  		} {
   272  			// clear the directory
   273  			require.NoError(t, os.RemoveAll(tempDir))
   274  			os.Mkdir(tempDir, 0777)
   275  			testcase.dekData.FIPS = fips
   276  			krw := ca.NewKeyReadWriter(paths.Node, nil, testcase.dekData)
   277  			if testcase.keyOnDisk {
   278  				cert, key, err := cautils.CreateRootCertAndKey("cn")
   279  				require.NoError(t, err)
   280  				require.NoError(t, krw.Write(cert, key, nil))
   281  			}
   282  			dekManager, err := NewRaftDEKManager(krw, fips)
   283  			require.NoError(t, err)
   284  
   285  			require.Equal(t, testcase.managerNeedsRotation, dekManager.NeedsRotation(), testcase.description)
   286  
   287  			gotKeys := dekManager.GetKeys()
   288  			if testcase.dekData.NeedsRotation && testcase.dekData.EncryptionKeys.PendingDEK == nil && testcase.keyOnDisk {
   289  				require.Equal(t, testcase.dekData.EncryptionKeys.CurrentDEK, gotKeys.CurrentDEK, testcase.description)
   290  				require.NotNil(t, gotKeys.PendingDEK, testcase.description)
   291  			} else {
   292  				require.Equal(t, testcase.dekData.EncryptionKeys, gotKeys, testcase.description)
   293  			}
   294  
   295  			h, _ := krw.GetCurrentState()
   296  			dekData, ok := h.(RaftDEKData)
   297  			require.True(t, ok)
   298  			require.Equal(t, testcase.newDEKDataNeedsRotation, dekData.NeedsRotation,
   299  				"(FIPS: %v) %s", fips, testcase.description)
   300  		}
   301  	}
   302  }
   303  
   304  func TestRaftDEKManagerUpdateKeys(t *testing.T) {
   305  	tempDir, err := ioutil.TempDir("", "manager-update-keys-")
   306  	require.NoError(t, err)
   307  	defer os.RemoveAll(tempDir)
   308  
   309  	paths := ca.NewConfigPaths(tempDir)
   310  	cert, key, err := cautils.CreateRootCertAndKey("cn")
   311  	require.NoError(t, err)
   312  
   313  	keys := raft.EncryptionKeys{
   314  		CurrentDEK: []byte("key1"),
   315  		PendingDEK: []byte("key2"),
   316  	}
   317  	for _, fips := range []bool{true, false} {
   318  		krw := ca.NewKeyReadWriter(paths.Node, nil, RaftDEKData{
   319  			EncryptionKeys: keys,
   320  			NeedsRotation:  true,
   321  			FIPS:           fips,
   322  		})
   323  		require.NoError(t, krw.Write(cert, key, nil))
   324  
   325  		dekManager, err := NewRaftDEKManager(krw, fips)
   326  		require.NoError(t, err)
   327  
   328  		newKeys := raft.EncryptionKeys{
   329  			CurrentDEK: []byte("new current"),
   330  		}
   331  		require.NoError(t, dekManager.UpdateKeys(newKeys))
   332  		// don't run GetKeys, because NeedsRotation is true and it'd just generate a new one
   333  
   334  		h, _ := krw.GetCurrentState()
   335  		dekData, ok := h.(RaftDEKData)
   336  		require.True(t, ok)
   337  		require.True(t, dekData.NeedsRotation)
   338  		require.Equal(t, fips, dekData.FIPS)
   339  
   340  		// UpdateKeys so there is no CurrentDEK: all the headers should be wiped out
   341  		require.NoError(t, dekManager.UpdateKeys(raft.EncryptionKeys{}))
   342  		require.Equal(t, raft.EncryptionKeys{}, dekManager.GetKeys())
   343  		require.False(t, dekManager.NeedsRotation())
   344  
   345  		h, _ = krw.GetCurrentState()
   346  		require.Nil(t, h)
   347  
   348  		keyBytes, err := ioutil.ReadFile(paths.Node.Key)
   349  		require.NoError(t, err)
   350  		keyBlock, _ := pem.Decode(keyBytes)
   351  		require.NotNil(t, keyBlock)
   352  
   353  		// the only header remaining should be the kek version
   354  		require.Len(t, keyBlock.Headers, 1)
   355  		require.Contains(t, keyBlock.Headers, "kek-version")
   356  	}
   357  }
   358  
   359  func TestRaftDEKManagerMaybeUpdateKEK(t *testing.T) {
   360  	tempDir, err := ioutil.TempDir("", "manager-maybe-update-kek-")
   361  	require.NoError(t, err)
   362  	defer os.RemoveAll(tempDir)
   363  
   364  	paths := ca.NewConfigPaths(tempDir)
   365  	cert, key, err := cautils.CreateRootCertAndKey("cn")
   366  	require.NoError(t, err)
   367  
   368  	keys := raft.EncryptionKeys{CurrentDEK: []byte("current dek")}
   369  
   370  	for _, fips := range []bool{true, false} {
   371  		// trying to update a KEK will error if the version is the same but the kek is different
   372  		krw := ca.NewKeyReadWriter(paths.Node, nil, RaftDEKData{
   373  			EncryptionKeys: keys,
   374  			FIPS:           fips,
   375  		})
   376  		require.NoError(t, krw.Write(cert, key, nil))
   377  		dekManager, err := NewRaftDEKManager(krw, fips)
   378  		require.NoError(t, err)
   379  
   380  		keyBytes, err := ioutil.ReadFile(paths.Node.Key)
   381  		require.NoError(t, err)
   382  
   383  		_, _, err = dekManager.MaybeUpdateKEK(ca.KEKData{KEK: []byte("locked now")})
   384  		require.Error(t, err)
   385  		require.False(t, dekManager.NeedsRotation())
   386  
   387  		keyBytes2, err := ioutil.ReadFile(paths.Node.Key)
   388  		require.NoError(t, err)
   389  		require.Equal(t, keyBytes, keyBytes2)
   390  
   391  		// trying to update a KEK from unlocked to lock will set NeedsRotation to true, as well as encrypt the TLS key
   392  		updated, unlockedToLocked, err := dekManager.MaybeUpdateKEK(ca.KEKData{KEK: []byte("locked now"), Version: 1})
   393  		require.NoError(t, err)
   394  		require.True(t, updated)
   395  		require.True(t, unlockedToLocked)
   396  		// don't run GetKeys, because NeedsRotation is true and it'd just generate a new one
   397  		h, _ := krw.GetCurrentState()
   398  		dekData, ok := h.(RaftDEKData)
   399  		require.True(t, ok)
   400  		require.Equal(t, keys, dekData.EncryptionKeys)
   401  		require.True(t, dekData.NeedsRotation)
   402  		require.Equal(t, fips, dekData.FIPS)
   403  		require.NotNil(t, <-dekManager.RotationNotify()) // we are notified of a new pending key
   404  
   405  		keyBytes2, err = ioutil.ReadFile(paths.Node.Key)
   406  		require.NoError(t, err)
   407  		require.NotEqual(t, keyBytes, keyBytes2)
   408  		keyBytes = keyBytes2
   409  
   410  		readKRW := ca.NewKeyReadWriter(paths.Node, []byte("locked now"), RaftDEKData{FIPS: fips})
   411  		_, _, err = readKRW.Read()
   412  		require.NoError(t, err)
   413  
   414  		// trying to update a KEK of a lower version will not update anything, but will not error
   415  		updated, unlockedToLocked, err = dekManager.MaybeUpdateKEK(ca.KEKData{})
   416  		require.NoError(t, err)
   417  		require.False(t, unlockedToLocked)
   418  		require.False(t, updated)
   419  		// don't run GetKeys, because NeedsRotation is true and it'd just generate a new one
   420  		h, _ = krw.GetCurrentState()
   421  		dekData, ok = h.(RaftDEKData)
   422  		require.True(t, ok)
   423  		require.Equal(t, keys, dekData.EncryptionKeys)
   424  		require.True(t, dekData.NeedsRotation)
   425  		require.Equal(t, fips, dekData.FIPS)
   426  
   427  		keyBytes2, err = ioutil.ReadFile(paths.Node.Key)
   428  		require.NoError(t, err)
   429  		require.Equal(t, keyBytes, keyBytes2, string(keyBytes), string(keyBytes2))
   430  
   431  		// updating a kek to a higher version, but with the same kek, will also neither update anything nor error
   432  		updated, unlockedToLocked, err = dekManager.MaybeUpdateKEK(ca.KEKData{KEK: []byte("locked now"), Version: 100})
   433  		require.NoError(t, err)
   434  		require.False(t, unlockedToLocked)
   435  		require.False(t, updated)
   436  		// don't run GetKeys, because NeedsRotation is true and it'd just generate a new one
   437  		h, _ = krw.GetCurrentState()
   438  		dekData, ok = h.(RaftDEKData)
   439  		require.True(t, ok)
   440  		require.Equal(t, keys, dekData.EncryptionKeys)
   441  		require.True(t, dekData.NeedsRotation)
   442  		require.Equal(t, fips, dekData.FIPS)
   443  
   444  		keyBytes2, err = ioutil.ReadFile(paths.Node.Key)
   445  		require.NoError(t, err)
   446  		require.Equal(t, keyBytes, keyBytes2)
   447  
   448  		// going from locked to unlock does not result in the NeedsRotation flag, but does result in
   449  		// the key being decrypted
   450  		krw = ca.NewKeyReadWriter(paths.Node, []byte("kek"), RaftDEKData{
   451  			EncryptionKeys: keys,
   452  			FIPS:           fips,
   453  		})
   454  		require.NoError(t, krw.Write(cert, key, nil))
   455  		dekManager, err = NewRaftDEKManager(krw, fips)
   456  		require.NoError(t, err)
   457  
   458  		keyBytes, err = ioutil.ReadFile(paths.Node.Key)
   459  		require.NoError(t, err)
   460  
   461  		updated, unlockedToLocked, err = dekManager.MaybeUpdateKEK(ca.KEKData{Version: 2})
   462  		require.NoError(t, err)
   463  		require.False(t, unlockedToLocked)
   464  		require.True(t, updated)
   465  		require.Equal(t, keys, dekManager.GetKeys())
   466  		require.False(t, dekManager.NeedsRotation())
   467  
   468  		keyBytes2, err = ioutil.ReadFile(paths.Node.Key)
   469  		require.NoError(t, err)
   470  		require.NotEqual(t, keyBytes, keyBytes2)
   471  
   472  		readKRW = ca.NewKeyReadWriter(paths.Node, nil, RaftDEKData{FIPS: fips})
   473  		_, _, err = readKRW.Read()
   474  		require.NoError(t, err)
   475  	}
   476  }
   477  
   478  // The TLS KEK and the KEK for the headers should be in sync, and so failing
   479  // to decrypt the TLS key should be mean we won't be able to decrypt the headers.
   480  // However, the TLS Key encryption uses AES-256-CBC (golang as of 1.7.x does not seem
   481  // to support GCM, so no cipher modes with digests) so sometimes decrypting with
   482  // the wrong passphrase will not result in an error.  This means we will ultimately
   483  // have to rely on the header encryption mechanism, which does include a digest, to
   484  // determine if the KEK is valid.
   485  func TestDecryptTLSKeyFalsePositive(t *testing.T) {
   486  	badKey := []byte(`
   487  -----BEGIN ENCRYPTED PRIVATE KEY-----
   488  kek-version: 392
   489  raft-dek: CAESMBrzZ0gNVPe3FRs42743q8RtkUBrK1ICQpHWX2vdQ8iqSKt1WoKdFDFD2r28LYAVLxoYQguwHbijMx9k+BALUNBAI3s199S5tvnr
   490  
   491  MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQge1soOUock01aIHDn
   492  QGz2uSNlS0fFdTIYmqKkzjefLNWgCgYIKoZIzj0DAQehRANCAARjorw9uRP83LqU
   493  RUHSjimzx0vTMeyZVIZVp5dIkdCuVYVSFF41B7ffBrl+oA47OMlMxCkhsWD7EmJZ
   494  xvc0Km0E
   495  -----END ENCRYPTED PRIVATE KEY-----
   496  `)
   497  
   498  	// not actually a real swarm cert - generated a cert corresponding to the key that expires in 20 years
   499  	matchingCert := []byte(`
   500  -----BEGIN CERTIFICATE-----
   501  MIIB9jCCAZygAwIBAgIRAIdzF3Z9VT2OXbRvEw5cR68wCgYIKoZIzj0EAwIwYDEi
   502  MCAGA1UEChMZbWRwMXU5Z3FoOTV1NXN2MmNodDRrcDB1cTEWMBQGA1UECxMNc3dh
   503  cm0tbWFuYWdlcjEiMCAGA1UEAxMZcXJzYmwza2FqOWhiZWprM2R5aWFlc3FiYTAg
   504  GA8wMDAxMDEwMTAwMDAwMFoXDTM2MTEwODA2MjMwMlowYDEiMCAGA1UEChMZbWRw
   505  MXU5Z3FoOTV1NXN2MmNodDRrcDB1cTEWMBQGA1UECxMNc3dhcm0tbWFuYWdlcjEi
   506  MCAGA1UEAxMZcXJzYmwza2FqOWhiZWprM2R5aWFlc3FiYTBZMBMGByqGSM49AgEG
   507  CCqGSM49AwEHA0IABGOivD25E/zcupRFQdKOKbPHS9Mx7JlUhlWnl0iR0K5VhVIU
   508  XjUHt98GuX6gDjs4yUzEKSGxYPsSYlnG9zQqbQSjNTAzMA4GA1UdDwEB/wQEAwIF
   509  oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMC
   510  A0gAMEUCIQDWtjg1ITGznQILipaEe70G/NgZAOtFfuPXTVkUl3el+wIgSVOVKB/Q
   511  O0T3aXuZGYNyh//KqAoA3erCmh6HauMz84Y=
   512  -----END CERTIFICATE-----
   513  	`)
   514  
   515  	var wrongKEK []byte // empty passphrase doesn't decrypt without errors
   516  	falsePositiveKEK, err := base64.RawStdEncoding.DecodeString("bIQgLAAMoGCrHdjMLVhEVqnYTAM7ZNF2xWMiwtw7AiQ")
   517  	require.NoError(t, err)
   518  	realKEK, err := base64.RawStdEncoding.DecodeString("fDg9YejLnMjU+FpulWR62oJLzVpkD2j7VQuP5xiK9QA")
   519  	require.NoError(t, err)
   520  
   521  	tempdir, err := ioutil.TempDir("", "KeyReadWriter-false-positive-decryption")
   522  	require.NoError(t, err)
   523  	defer os.RemoveAll(tempdir)
   524  
   525  	path := ca.NewConfigPaths(tempdir)
   526  	require.NoError(t, ioutil.WriteFile(path.Node.Key, badKey, 0600))
   527  	require.NoError(t, ioutil.WriteFile(path.Node.Cert, matchingCert, 0644))
   528  
   529  	krw := ca.NewKeyReadWriter(path.Node, wrongKEK, RaftDEKData{})
   530  	_, _, err = krw.Read()
   531  	require.IsType(t, ca.ErrInvalidKEK{}, errors.Cause(err))
   532  
   533  	krw = ca.NewKeyReadWriter(path.Node, falsePositiveKEK, RaftDEKData{})
   534  	_, _, err = krw.Read()
   535  	require.Error(t, err)
   536  	require.IsType(t, ca.ErrInvalidKEK{}, errors.Cause(err))
   537  
   538  	krw = ca.NewKeyReadWriter(path.Node, realKEK, RaftDEKData{})
   539  	_, _, err = krw.Read()
   540  	require.NoError(t, err)
   541  }
   542  
   543  // If FIPS is enabled, the raft DEK will be encrypted using fernet, and not NACL secretbox.
   544  func TestRaftDEKsFIPSEnabledUsesFernet(t *testing.T) {
   545  	tempDir, err := ioutil.TempDir("", "manager-dek-fips")
   546  	require.NoError(t, err)
   547  	defer os.RemoveAll(tempDir)
   548  
   549  	paths := ca.NewConfigPaths(tempDir)
   550  	cert, key, err := cautils.CreateRootCertAndKey("cn")
   551  	require.NoError(t, err)
   552  
   553  	// no particular reason not to use FIPS in the key writer to write the TLS key itself,
   554  	// except to demonstrate that these two functionalities are decoupled
   555  	keys := raft.EncryptionKeys{CurrentDEK: []byte("current dek")}
   556  	krw := ca.NewKeyReadWriter(paths.Node, nil, RaftDEKData{EncryptionKeys: keys, FIPS: true})
   557  	require.NoError(t, krw.Write(cert, key, nil))
   558  
   559  	dekManager, err := NewRaftDEKManager(krw, true) // this should be able to read the dek data
   560  	require.NoError(t, err)
   561  	require.Equal(t, keys, dekManager.GetKeys())
   562  
   563  	// if we do not use FIPS to write the header in the first place, a FIPS DEK manager can't read it
   564  	// because it's NACL secretbox
   565  	keys = raft.EncryptionKeys{CurrentDEK: []byte("current dek")}
   566  	krw = ca.NewKeyReadWriter(paths.Node, nil, RaftDEKData{EncryptionKeys: keys})
   567  	require.NoError(t, krw.Write(cert, key, nil))
   568  
   569  	dekManager, err = NewRaftDEKManager(krw, true) // this should be able to read the dek data
   570  	require.NoError(t, err)
   571  	fmt.Println(err)
   572  }