deks.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package manager
  2. import (
  3. "crypto/subtle"
  4. "encoding/base64"
  5. "fmt"
  6. "github.com/docker/swarmkit/ca"
  7. "github.com/docker/swarmkit/manager/encryption"
  8. "github.com/docker/swarmkit/manager/state/raft"
  9. )
  10. const (
  11. // the raft DEK (data encryption key) is stored in the TLS key as a header
  12. // these are the header values
  13. pemHeaderRaftDEK = "raft-dek"
  14. pemHeaderRaftPendingDEK = "raft-dek-pending"
  15. pemHeaderRaftDEKNeedsRotation = "raft-dek-needs-rotation"
  16. )
  17. // RaftDEKData contains all the data stored in TLS pem headers
  18. type RaftDEKData struct {
  19. raft.EncryptionKeys
  20. NeedsRotation bool
  21. }
  22. // UnmarshalHeaders loads the state of the DEK manager given the current TLS headers
  23. func (r RaftDEKData) UnmarshalHeaders(headers map[string]string, kekData ca.KEKData) (ca.PEMKeyHeaders, error) {
  24. var (
  25. currentDEK, pendingDEK []byte
  26. err error
  27. )
  28. if currentDEKStr, ok := headers[pemHeaderRaftDEK]; ok {
  29. currentDEK, err = decodePEMHeaderValue(currentDEKStr, kekData.KEK)
  30. if err != nil {
  31. return nil, err
  32. }
  33. }
  34. if pendingDEKStr, ok := headers[pemHeaderRaftPendingDEK]; ok {
  35. pendingDEK, err = decodePEMHeaderValue(pendingDEKStr, kekData.KEK)
  36. if err != nil {
  37. return nil, err
  38. }
  39. }
  40. if pendingDEK != nil && currentDEK == nil {
  41. return nil, fmt.Errorf("there is a pending DEK, but no current DEK")
  42. }
  43. _, ok := headers[pemHeaderRaftDEKNeedsRotation]
  44. return RaftDEKData{
  45. NeedsRotation: ok,
  46. EncryptionKeys: raft.EncryptionKeys{
  47. CurrentDEK: currentDEK,
  48. PendingDEK: pendingDEK,
  49. },
  50. }, nil
  51. }
  52. // MarshalHeaders returns new headers given the current KEK
  53. func (r RaftDEKData) MarshalHeaders(kekData ca.KEKData) (map[string]string, error) {
  54. headers := make(map[string]string)
  55. for headerKey, contents := range map[string][]byte{
  56. pemHeaderRaftDEK: r.CurrentDEK,
  57. pemHeaderRaftPendingDEK: r.PendingDEK,
  58. } {
  59. if contents != nil {
  60. dekStr, err := encodePEMHeaderValue(contents, kekData.KEK)
  61. if err != nil {
  62. return nil, err
  63. }
  64. headers[headerKey] = dekStr
  65. }
  66. }
  67. if r.NeedsRotation {
  68. headers[pemHeaderRaftDEKNeedsRotation] = "true"
  69. }
  70. // return a function that updates the dek data on write success
  71. return headers, nil
  72. }
  73. // UpdateKEK optionally sets NeedRotation to true if we go from unlocked to locked
  74. func (r RaftDEKData) UpdateKEK(oldKEK, candidateKEK ca.KEKData) ca.PEMKeyHeaders {
  75. if _, unlockedToLocked, err := compareKEKs(oldKEK, candidateKEK); err == nil && unlockedToLocked {
  76. return RaftDEKData{
  77. EncryptionKeys: r.EncryptionKeys,
  78. NeedsRotation: true,
  79. }
  80. }
  81. return r
  82. }
  83. // Returns whether the old KEK should be replaced with the new KEK, whether we went from
  84. // unlocked to locked, and whether there was an error (the versions are the same, but the
  85. // keks are different)
  86. func compareKEKs(oldKEK, candidateKEK ca.KEKData) (bool, bool, error) {
  87. keksEqual := subtle.ConstantTimeCompare(oldKEK.KEK, candidateKEK.KEK) == 1
  88. switch {
  89. case oldKEK.Version == candidateKEK.Version && !keksEqual:
  90. return false, false, fmt.Errorf("candidate KEK has the same version as the current KEK, but a different KEK value")
  91. case oldKEK.Version >= candidateKEK.Version || keksEqual:
  92. return false, false, nil
  93. default:
  94. return true, oldKEK.KEK == nil, nil
  95. }
  96. }
  97. // RaftDEKManager manages the raft DEK keys using TLS headers
  98. type RaftDEKManager struct {
  99. kw ca.KeyWriter
  100. rotationCh chan struct{}
  101. }
  102. var errNoUpdateNeeded = fmt.Errorf("don't need to rotate or update")
  103. // this error is returned if the KeyReadWriter's PEMKeyHeaders object is no longer a RaftDEKData object -
  104. // this can happen if the node is no longer a manager, for example
  105. var errNotUsingRaftDEKData = fmt.Errorf("RaftDEKManager can no longer store and manage TLS key headers")
  106. // NewRaftDEKManager returns a RaftDEKManager that uses the current key writer
  107. // and header manager
  108. func NewRaftDEKManager(kw ca.KeyWriter) (*RaftDEKManager, error) {
  109. // If there is no current DEK, generate one and write it to disk
  110. err := kw.ViewAndUpdateHeaders(func(h ca.PEMKeyHeaders) (ca.PEMKeyHeaders, error) {
  111. dekData, ok := h.(RaftDEKData)
  112. // it wasn't a raft DEK manager before - just replace it
  113. if !ok || dekData.CurrentDEK == nil {
  114. return RaftDEKData{
  115. EncryptionKeys: raft.EncryptionKeys{
  116. CurrentDEK: encryption.GenerateSecretKey(),
  117. },
  118. }, nil
  119. }
  120. return nil, errNoUpdateNeeded
  121. })
  122. if err != nil && err != errNoUpdateNeeded {
  123. return nil, err
  124. }
  125. return &RaftDEKManager{
  126. kw: kw,
  127. rotationCh: make(chan struct{}, 1),
  128. }, nil
  129. }
  130. // NeedsRotation returns a boolean about whether we should do a rotation
  131. func (r *RaftDEKManager) NeedsRotation() bool {
  132. h, _ := r.kw.GetCurrentState()
  133. data, ok := h.(RaftDEKData)
  134. if !ok {
  135. return false
  136. }
  137. return data.NeedsRotation || data.EncryptionKeys.PendingDEK != nil
  138. }
  139. // GetKeys returns the current set of DEKs. If NeedsRotation is true, and there
  140. // is no existing PendingDEK, it will try to create one. If there are any errors
  141. // doing so, just return the original.
  142. func (r *RaftDEKManager) GetKeys() raft.EncryptionKeys {
  143. var newKeys, originalKeys raft.EncryptionKeys
  144. err := r.kw.ViewAndUpdateHeaders(func(h ca.PEMKeyHeaders) (ca.PEMKeyHeaders, error) {
  145. data, ok := h.(RaftDEKData)
  146. if !ok {
  147. return nil, errNotUsingRaftDEKData
  148. }
  149. originalKeys = data.EncryptionKeys
  150. if !data.NeedsRotation || data.PendingDEK != nil {
  151. return nil, errNoUpdateNeeded
  152. }
  153. newKeys = raft.EncryptionKeys{
  154. CurrentDEK: data.CurrentDEK,
  155. PendingDEK: encryption.GenerateSecretKey(),
  156. }
  157. return RaftDEKData{EncryptionKeys: newKeys}, nil
  158. })
  159. if err != nil {
  160. return originalKeys
  161. }
  162. return newKeys
  163. }
  164. // RotationNotify the channel used to notify subscribers as to whether there
  165. // should be a rotation done
  166. func (r *RaftDEKManager) RotationNotify() chan struct{} {
  167. return r.rotationCh
  168. }
  169. // UpdateKeys will set the updated encryption keys in the headers. This finishes
  170. // a rotation, and is expected to set the CurrentDEK to the previous PendingDEK.
  171. func (r *RaftDEKManager) UpdateKeys(newKeys raft.EncryptionKeys) error {
  172. return r.kw.ViewAndUpdateHeaders(func(h ca.PEMKeyHeaders) (ca.PEMKeyHeaders, error) {
  173. data, ok := h.(RaftDEKData)
  174. if !ok {
  175. return nil, errNotUsingRaftDEKData
  176. }
  177. // If there is no current DEK, we are basically wiping out all DEKs (no header object)
  178. if newKeys.CurrentDEK == nil {
  179. return nil, nil
  180. }
  181. return RaftDEKData{
  182. EncryptionKeys: newKeys,
  183. NeedsRotation: data.NeedsRotation,
  184. }, nil
  185. })
  186. }
  187. // MaybeUpdateKEK does a KEK rotation if one is required. Returns whether
  188. // the kek was updated, whether it went from unlocked to locked, and any errors.
  189. func (r *RaftDEKManager) MaybeUpdateKEK(candidateKEK ca.KEKData) (bool, bool, error) {
  190. var updated, unlockedToLocked bool
  191. err := r.kw.ViewAndRotateKEK(func(currentKEK ca.KEKData, h ca.PEMKeyHeaders) (ca.KEKData, ca.PEMKeyHeaders, error) {
  192. var err error
  193. updated, unlockedToLocked, err = compareKEKs(currentKEK, candidateKEK)
  194. if err == nil && !updated { // if we don't need to rotate the KEK, don't bother updating
  195. err = errNoUpdateNeeded
  196. }
  197. if err != nil {
  198. return ca.KEKData{}, nil, err
  199. }
  200. data, ok := h.(RaftDEKData)
  201. if !ok {
  202. return ca.KEKData{}, nil, errNotUsingRaftDEKData
  203. }
  204. if unlockedToLocked {
  205. data.NeedsRotation = true
  206. }
  207. return candidateKEK, data, nil
  208. })
  209. if err == errNoUpdateNeeded {
  210. err = nil
  211. }
  212. if err == nil && unlockedToLocked {
  213. r.rotationCh <- struct{}{}
  214. }
  215. return updated, unlockedToLocked, err
  216. }
  217. func decodePEMHeaderValue(headerValue string, kek []byte) ([]byte, error) {
  218. var decrypter encryption.Decrypter = encryption.NoopCrypter
  219. if kek != nil {
  220. _, decrypter = encryption.Defaults(kek)
  221. }
  222. valueBytes, err := base64.StdEncoding.DecodeString(headerValue)
  223. if err != nil {
  224. return nil, err
  225. }
  226. result, err := encryption.Decrypt(valueBytes, decrypter)
  227. if err != nil {
  228. return nil, ca.ErrInvalidKEK{Wrapped: err}
  229. }
  230. return result, nil
  231. }
  232. func encodePEMHeaderValue(headerValue []byte, kek []byte) (string, error) {
  233. var encrypter encryption.Encrypter = encryption.NoopCrypter
  234. if kek != nil {
  235. encrypter, _ = encryption.Defaults(kek)
  236. }
  237. encrypted, err := encryption.Encrypt(headerValue, encrypter)
  238. if err != nil {
  239. return "", err
  240. }
  241. return base64.StdEncoding.EncodeToString(encrypted), nil
  242. }