Skip to content

Commit 8aa9c33

Browse files
authored
Merge pull request moby#2586 from cyli/fips-in-raft
[fips] Propagate the FIPS boolean to the manager, raft storage layer, and raft DEK management
2 parents bf83f94 + ba11e51 commit 8aa9c33

8 files changed

Lines changed: 469 additions & 329 deletions

File tree

integration/integration_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,9 +888,15 @@ func TestMixedFIPSClusterNonMandatoryFIPS(t *testing.T) {
888888

889889
pollClusterReady(t, cl, 2, 3)
890890

891-
// swap which nodes are fips and which are not - all should start up just fine
891+
// switch which worker nodes are fips and which are not - all should start up just fine
892+
// on managers, if we enable fips on a previously non-fips node, it won't be able to read
893+
// non-fernet raft logs
892894
for nodeID, n := range cl.nodes {
893-
n.config.FIPS = !n.config.FIPS
895+
if n.IsManager() {
896+
n.config.FIPS = false
897+
} else {
898+
n.config.FIPS = !n.config.FIPS
899+
}
894900
require.NoError(t, n.Pause(false))
895901
require.NoError(t, cl.StartNode(nodeID))
896902
}

manager/deks.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ const (
2222
type RaftDEKData struct {
2323
raft.EncryptionKeys
2424
NeedsRotation bool
25+
26+
// The FIPS boolean is not serialized, but is internal state which indicates how
27+
// the raft DEK headers should be encrypted (e.g. using FIPS compliant algorithms)
28+
FIPS bool
2529
}
2630

2731
// UnmarshalHeaders loads the state of the DEK manager given the current TLS headers
@@ -32,13 +36,13 @@ func (r RaftDEKData) UnmarshalHeaders(headers map[string]string, kekData ca.KEKD
3236
)
3337

3438
if currentDEKStr, ok := headers[pemHeaderRaftDEK]; ok {
35-
currentDEK, err = decodePEMHeaderValue(currentDEKStr, kekData.KEK)
39+
currentDEK, err = decodePEMHeaderValue(currentDEKStr, kekData.KEK, r.FIPS)
3640
if err != nil {
3741
return nil, err
3842
}
3943
}
4044
if pendingDEKStr, ok := headers[pemHeaderRaftPendingDEK]; ok {
41-
pendingDEK, err = decodePEMHeaderValue(pendingDEKStr, kekData.KEK)
45+
pendingDEK, err = decodePEMHeaderValue(pendingDEKStr, kekData.KEK, r.FIPS)
4246
if err != nil {
4347
return nil, err
4448
}
@@ -55,6 +59,7 @@ func (r RaftDEKData) UnmarshalHeaders(headers map[string]string, kekData ca.KEKD
5559
CurrentDEK: currentDEK,
5660
PendingDEK: pendingDEK,
5761
},
62+
FIPS: r.FIPS,
5863
}, nil
5964
}
6065

@@ -66,7 +71,7 @@ func (r RaftDEKData) MarshalHeaders(kekData ca.KEKData) (map[string]string, erro
6671
pemHeaderRaftPendingDEK: r.PendingDEK,
6772
} {
6873
if contents != nil {
69-
dekStr, err := encodePEMHeaderValue(contents, kekData.KEK)
74+
dekStr, err := encodePEMHeaderValue(contents, kekData.KEK, r.FIPS)
7075
if err != nil {
7176
return nil, err
7277
}
@@ -88,6 +93,7 @@ func (r RaftDEKData) UpdateKEK(oldKEK, candidateKEK ca.KEKData) ca.PEMKeyHeaders
8893
return RaftDEKData{
8994
EncryptionKeys: r.EncryptionKeys,
9095
NeedsRotation: true,
96+
FIPS: r.FIPS,
9197
}
9298
}
9399
return r
@@ -112,6 +118,7 @@ func compareKEKs(oldKEK, candidateKEK ca.KEKData) (bool, bool, error) {
112118
type RaftDEKManager struct {
113119
kw ca.KeyWriter
114120
rotationCh chan struct{}
121+
FIPS bool
115122
}
116123

117124
var errNoUpdateNeeded = fmt.Errorf("don't need to rotate or update")
@@ -122,7 +129,7 @@ var errNotUsingRaftDEKData = fmt.Errorf("RaftDEKManager can no longer store and
122129

123130
// NewRaftDEKManager returns a RaftDEKManager that uses the current key writer
124131
// and header manager
125-
func NewRaftDEKManager(kw ca.KeyWriter) (*RaftDEKManager, error) {
132+
func NewRaftDEKManager(kw ca.KeyWriter, fips bool) (*RaftDEKManager, error) {
126133
// If there is no current DEK, generate one and write it to disk
127134
err := kw.ViewAndUpdateHeaders(func(h ca.PEMKeyHeaders) (ca.PEMKeyHeaders, error) {
128135
dekData, ok := h.(RaftDEKData)
@@ -132,6 +139,7 @@ func NewRaftDEKManager(kw ca.KeyWriter) (*RaftDEKManager, error) {
132139
EncryptionKeys: raft.EncryptionKeys{
133140
CurrentDEK: encryption.GenerateSecretKey(),
134141
},
142+
FIPS: fips,
135143
}, nil
136144
}
137145
return nil, errNoUpdateNeeded
@@ -141,6 +149,7 @@ func NewRaftDEKManager(kw ca.KeyWriter) (*RaftDEKManager, error) {
141149
}
142150
return &RaftDEKManager{
143151
kw: kw,
152+
FIPS: fips,
144153
rotationCh: make(chan struct{}, 1),
145154
}, nil
146155
}
@@ -156,8 +165,9 @@ func (r *RaftDEKManager) NeedsRotation() bool {
156165
}
157166

158167
// GetKeys returns the current set of DEKs. If NeedsRotation is true, and there
159-
// is no existing PendingDEK, it will try to create one. If there are any errors
160-
// doing so, just return the original.
168+
// is no existing PendingDEK, it will try to create one. If it successfully creates
169+
// and writes a PendingDEK, it sets NeedRotation to false. If there are any errors
170+
// doing so, just return the original set of keys.
161171
func (r *RaftDEKManager) GetKeys() raft.EncryptionKeys {
162172
var newKeys, originalKeys raft.EncryptionKeys
163173
err := r.kw.ViewAndUpdateHeaders(func(h ca.PEMKeyHeaders) (ca.PEMKeyHeaders, error) {
@@ -173,7 +183,10 @@ func (r *RaftDEKManager) GetKeys() raft.EncryptionKeys {
173183
CurrentDEK: data.CurrentDEK,
174184
PendingDEK: encryption.GenerateSecretKey(),
175185
}
176-
return RaftDEKData{EncryptionKeys: newKeys}, nil
186+
return RaftDEKData{
187+
EncryptionKeys: newKeys,
188+
FIPS: data.FIPS,
189+
}, nil
177190
})
178191
if err != nil {
179192
return originalKeys
@@ -202,6 +215,7 @@ func (r *RaftDEKManager) UpdateKeys(newKeys raft.EncryptionKeys) error {
202215
return RaftDEKData{
203216
EncryptionKeys: newKeys,
204217
NeedsRotation: data.NeedsRotation,
218+
FIPS: data.FIPS,
205219
}, nil
206220
})
207221
}
@@ -240,10 +254,10 @@ func (r *RaftDEKManager) MaybeUpdateKEK(candidateKEK ca.KEKData) (bool, bool, er
240254
return updated, unlockedToLocked, err
241255
}
242256

243-
func decodePEMHeaderValue(headerValue string, kek []byte) ([]byte, error) {
257+
func decodePEMHeaderValue(headerValue string, kek []byte, fips bool) ([]byte, error) {
244258
var decrypter encryption.Decrypter = encryption.NoopCrypter
245259
if kek != nil {
246-
_, decrypter = encryption.Defaults(kek, false)
260+
_, decrypter = encryption.Defaults(kek, fips)
247261
}
248262
valueBytes, err := base64.StdEncoding.DecodeString(headerValue)
249263
if err != nil {
@@ -256,10 +270,10 @@ func decodePEMHeaderValue(headerValue string, kek []byte) ([]byte, error) {
256270
return result, nil
257271
}
258272

259-
func encodePEMHeaderValue(headerValue []byte, kek []byte) (string, error) {
273+
func encodePEMHeaderValue(headerValue []byte, kek []byte, fips bool) (string, error) {
260274
var encrypter encryption.Encrypter = encryption.NoopCrypter
261275
if kek != nil {
262-
encrypter, _ = encryption.Defaults(kek, false)
276+
encrypter, _ = encryption.Defaults(kek, fips)
263277
}
264278
encrypted, err := encryption.Encrypt(headerValue, encrypter)
265279
if err != nil {

0 commit comments

Comments
 (0)