Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Nomad
Commits
0c05b68e
Unverified
Commit
0c05b68e
authored
2 years ago
by
Tim Gross
Committed by
GitHub
2 years ago
Browse files
Options
Download
Email Patches
Plain Diff
keyring: split structs to its own file (#14378)
parent
e1e5bb1d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
nomad/structs/keyring.go
+239
-0
nomad/structs/keyring.go
nomad/structs/variables.go
+0
-237
nomad/structs/variables.go
with
239 additions
and
237 deletions
+239
-237
nomad/structs/keyring.go
0 → 100644
+
239
-
0
View file @
0c05b68e
package
structs
import
(
"fmt"
"time"
// note: this is aliased so that it's more noticeable if someone
// accidentally swaps it out for math/rand via running goimports
cryptorand
"crypto/rand"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/nomad/helper/uuid"
)
// RootKey is used to encrypt and decrypt variables. It is never stored in raft.
type
RootKey
struct
{
Meta
*
RootKeyMeta
Key
[]
byte
// serialized to keystore as base64 blob
}
// NewRootKey returns a new root key and its metadata.
func
NewRootKey
(
algorithm
EncryptionAlgorithm
)
(
*
RootKey
,
error
)
{
meta
:=
NewRootKeyMeta
()
meta
.
Algorithm
=
algorithm
rootKey
:=
&
RootKey
{
Meta
:
meta
,
}
switch
algorithm
{
case
EncryptionAlgorithmAES256GCM
:
const
keyBytes
=
32
key
:=
make
([]
byte
,
keyBytes
)
n
,
err
:=
cryptorand
.
Read
(
key
)
if
err
!=
nil
{
return
nil
,
err
}
if
n
<
keyBytes
{
return
nil
,
fmt
.
Errorf
(
"failed to generate key: entropy exhausted"
)
}
rootKey
.
Key
=
key
}
return
rootKey
,
nil
}
// RootKeyMeta is the metadata used to refer to a RootKey. It is
// stored in raft.
type
RootKeyMeta
struct
{
KeyID
string
// UUID
Algorithm
EncryptionAlgorithm
CreateTime
int64
CreateIndex
uint64
ModifyIndex
uint64
State
RootKeyState
}
// RootKeyState enum describes the lifecycle of a root key.
type
RootKeyState
string
const
(
RootKeyStateInactive
RootKeyState
=
"inactive"
RootKeyStateActive
=
"active"
RootKeyStateRekeying
=
"rekeying"
RootKeyStateDeprecated
=
"deprecated"
)
// NewRootKeyMeta returns a new RootKeyMeta with default values
func
NewRootKeyMeta
()
*
RootKeyMeta
{
now
:=
time
.
Now
()
.
UTC
()
.
UnixNano
()
return
&
RootKeyMeta
{
KeyID
:
uuid
.
Generate
(),
Algorithm
:
EncryptionAlgorithmAES256GCM
,
State
:
RootKeyStateInactive
,
CreateTime
:
now
,
}
}
// RootKeyMetaStub is for serializing root key metadata to the
// keystore, not for the List API. It excludes frequently-changing
// fields such as ModifyIndex so we don't have to sync them to the
// on-disk keystore when the fields are already in raft.
type
RootKeyMetaStub
struct
{
KeyID
string
Algorithm
EncryptionAlgorithm
CreateTime
int64
State
RootKeyState
}
// Active indicates his key is the one currently being used for
// crypto operations (at most one key can be Active)
func
(
rkm
*
RootKeyMeta
)
Active
()
bool
{
return
rkm
.
State
==
RootKeyStateActive
}
func
(
rkm
*
RootKeyMeta
)
SetActive
()
{
rkm
.
State
=
RootKeyStateActive
}
// Rekeying indicates that variables encrypted with this key should be
// rekeyed
func
(
rkm
*
RootKeyMeta
)
Rekeying
()
bool
{
return
rkm
.
State
==
RootKeyStateRekeying
}
func
(
rkm
*
RootKeyMeta
)
SetRekeying
()
{
rkm
.
State
=
RootKeyStateRekeying
}
func
(
rkm
*
RootKeyMeta
)
SetInactive
()
{
rkm
.
State
=
RootKeyStateInactive
}
// Deprecated indicates that variables encrypted with this key
// have been rekeyed
func
(
rkm
*
RootKeyMeta
)
Deprecated
()
bool
{
return
rkm
.
State
==
RootKeyStateDeprecated
}
func
(
rkm
*
RootKeyMeta
)
SetDeprecated
()
{
rkm
.
State
=
RootKeyStateDeprecated
}
func
(
rkm
*
RootKeyMeta
)
Stub
()
*
RootKeyMetaStub
{
if
rkm
==
nil
{
return
nil
}
return
&
RootKeyMetaStub
{
KeyID
:
rkm
.
KeyID
,
Algorithm
:
rkm
.
Algorithm
,
CreateTime
:
rkm
.
CreateTime
,
State
:
rkm
.
State
,
}
}
func
(
rkm
*
RootKeyMeta
)
Copy
()
*
RootKeyMeta
{
if
rkm
==
nil
{
return
nil
}
out
:=
*
rkm
return
&
out
}
func
(
rkm
*
RootKeyMeta
)
Validate
()
error
{
if
rkm
==
nil
{
return
fmt
.
Errorf
(
"root key metadata is required"
)
}
if
rkm
.
KeyID
==
""
||
!
helper
.
IsUUID
(
rkm
.
KeyID
)
{
return
fmt
.
Errorf
(
"root key UUID is required"
)
}
if
rkm
.
Algorithm
==
""
{
return
fmt
.
Errorf
(
"root key algorithm is required"
)
}
switch
rkm
.
State
{
case
RootKeyStateInactive
,
RootKeyStateActive
,
RootKeyStateRekeying
,
RootKeyStateDeprecated
:
default
:
return
fmt
.
Errorf
(
"root key state %q is invalid"
,
rkm
.
State
)
}
return
nil
}
// EncryptionAlgorithm chooses which algorithm is used for
// encrypting / decrypting entries with this key
type
EncryptionAlgorithm
string
const
(
EncryptionAlgorithmAES256GCM
EncryptionAlgorithm
=
"aes256-gcm"
)
type
KeyringRotateRootKeyRequest
struct
{
Algorithm
EncryptionAlgorithm
Full
bool
WriteRequest
}
// KeyringRotateRootKeyResponse returns the full key metadata
type
KeyringRotateRootKeyResponse
struct
{
Key
*
RootKeyMeta
WriteMeta
}
type
KeyringListRootKeyMetaRequest
struct
{
// TODO: do we need any fields here?
QueryOptions
}
type
KeyringListRootKeyMetaResponse
struct
{
Keys
[]
*
RootKeyMeta
QueryMeta
}
// KeyringUpdateRootKeyRequest is used internally for key replication
// only and for keyring restores. The RootKeyMeta will be extracted
// for applying to the FSM with the KeyringUpdateRootKeyMetaRequest
// (see below)
type
KeyringUpdateRootKeyRequest
struct
{
RootKey
*
RootKey
Rekey
bool
WriteRequest
}
type
KeyringUpdateRootKeyResponse
struct
{
WriteMeta
}
// KeyringGetRootKeyRequest is used internally for key replication
// only and for keyring restores.
type
KeyringGetRootKeyRequest
struct
{
KeyID
string
QueryOptions
}
type
KeyringGetRootKeyResponse
struct
{
Key
*
RootKey
QueryMeta
}
// KeyringUpdateRootKeyMetaRequest is used internally for key
// replication so that we have a request wrapper for writing the
// metadata to the FSM without including the key material
type
KeyringUpdateRootKeyMetaRequest
struct
{
RootKeyMeta
*
RootKeyMeta
Rekey
bool
WriteRequest
}
type
KeyringUpdateRootKeyMetaResponse
struct
{
WriteMeta
}
type
KeyringDeleteRootKeyRequest
struct
{
KeyID
string
WriteRequest
}
type
KeyringDeleteRootKeyResponse
struct
{
WriteMeta
}
This diff is collapsed.
Click to expand it.
nomad/structs/variables.go
+
0
-
237
View file @
0c05b68e
...
...
@@ -6,14 +6,6 @@ import (
"fmt"
"reflect"
"strings"
"time"
// note: this is aliased so that it's more noticeable if someone
// accidentally swaps it out for math/rand via running goimports
cryptorand
"crypto/rand"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/nomad/helper/uuid"
)
const
(
...
...
@@ -365,232 +357,3 @@ type VariablesReadResponse struct {
Data
*
VariableDecrypted
QueryMeta
}
// ---------------------------------------
// Keyring state and RPC objects
// RootKey is used to encrypt and decrypt variables. It is never stored in raft.
type
RootKey
struct
{
Meta
*
RootKeyMeta
Key
[]
byte
// serialized to keystore as base64 blob
}
// NewRootKey returns a new root key and its metadata.
func
NewRootKey
(
algorithm
EncryptionAlgorithm
)
(
*
RootKey
,
error
)
{
meta
:=
NewRootKeyMeta
()
meta
.
Algorithm
=
algorithm
rootKey
:=
&
RootKey
{
Meta
:
meta
,
}
switch
algorithm
{
case
EncryptionAlgorithmAES256GCM
:
const
keyBytes
=
32
key
:=
make
([]
byte
,
keyBytes
)
n
,
err
:=
cryptorand
.
Read
(
key
)
if
err
!=
nil
{
return
nil
,
err
}
if
n
<
keyBytes
{
return
nil
,
fmt
.
Errorf
(
"failed to generate key: entropy exhausted"
)
}
rootKey
.
Key
=
key
}
return
rootKey
,
nil
}
// RootKeyMeta is the metadata used to refer to a RootKey. It is
// stored in raft.
type
RootKeyMeta
struct
{
KeyID
string
// UUID
Algorithm
EncryptionAlgorithm
CreateTime
int64
CreateIndex
uint64
ModifyIndex
uint64
State
RootKeyState
}
// RootKeyState enum describes the lifecycle of a root key.
type
RootKeyState
string
const
(
RootKeyStateInactive
RootKeyState
=
"inactive"
RootKeyStateActive
=
"active"
RootKeyStateRekeying
=
"rekeying"
RootKeyStateDeprecated
=
"deprecated"
)
// NewRootKeyMeta returns a new RootKeyMeta with default values
func
NewRootKeyMeta
()
*
RootKeyMeta
{
now
:=
time
.
Now
()
.
UTC
()
.
UnixNano
()
return
&
RootKeyMeta
{
KeyID
:
uuid
.
Generate
(),
Algorithm
:
EncryptionAlgorithmAES256GCM
,
State
:
RootKeyStateInactive
,
CreateTime
:
now
,
}
}
// RootKeyMetaStub is for serializing root key metadata to the
// keystore, not for the List API. It excludes frequently-changing
// fields such as ModifyIndex so we don't have to sync them to the
// on-disk keystore when the fields are already in raft.
type
RootKeyMetaStub
struct
{
KeyID
string
Algorithm
EncryptionAlgorithm
CreateTime
int64
State
RootKeyState
}
// Active indicates his key is the one currently being used for
// crypto operations (at most one key can be Active)
func
(
rkm
*
RootKeyMeta
)
Active
()
bool
{
return
rkm
.
State
==
RootKeyStateActive
}
func
(
rkm
*
RootKeyMeta
)
SetActive
()
{
rkm
.
State
=
RootKeyStateActive
}
// Rekeying indicates that variables encrypted with this key should be
// rekeyed
func
(
rkm
*
RootKeyMeta
)
Rekeying
()
bool
{
return
rkm
.
State
==
RootKeyStateRekeying
}
func
(
rkm
*
RootKeyMeta
)
SetRekeying
()
{
rkm
.
State
=
RootKeyStateRekeying
}
func
(
rkm
*
RootKeyMeta
)
SetInactive
()
{
rkm
.
State
=
RootKeyStateInactive
}
// Deprecated indicates that variables encrypted with this key
// have been rekeyed
func
(
rkm
*
RootKeyMeta
)
Deprecated
()
bool
{
return
rkm
.
State
==
RootKeyStateDeprecated
}
func
(
rkm
*
RootKeyMeta
)
SetDeprecated
()
{
rkm
.
State
=
RootKeyStateDeprecated
}
func
(
rkm
*
RootKeyMeta
)
Stub
()
*
RootKeyMetaStub
{
if
rkm
==
nil
{
return
nil
}
return
&
RootKeyMetaStub
{
KeyID
:
rkm
.
KeyID
,
Algorithm
:
rkm
.
Algorithm
,
CreateTime
:
rkm
.
CreateTime
,
State
:
rkm
.
State
,
}
}
func
(
rkm
*
RootKeyMeta
)
Copy
()
*
RootKeyMeta
{
if
rkm
==
nil
{
return
nil
}
out
:=
*
rkm
return
&
out
}
func
(
rkm
*
RootKeyMeta
)
Validate
()
error
{
if
rkm
==
nil
{
return
fmt
.
Errorf
(
"root key metadata is required"
)
}
if
rkm
.
KeyID
==
""
||
!
helper
.
IsUUID
(
rkm
.
KeyID
)
{
return
fmt
.
Errorf
(
"root key UUID is required"
)
}
if
rkm
.
Algorithm
==
""
{
return
fmt
.
Errorf
(
"root key algorithm is required"
)
}
switch
rkm
.
State
{
case
RootKeyStateInactive
,
RootKeyStateActive
,
RootKeyStateRekeying
,
RootKeyStateDeprecated
:
default
:
return
fmt
.
Errorf
(
"root key state %q is invalid"
,
rkm
.
State
)
}
return
nil
}
// EncryptionAlgorithm chooses which algorithm is used for
// encrypting / decrypting entries with this key
type
EncryptionAlgorithm
string
const
(
EncryptionAlgorithmAES256GCM
EncryptionAlgorithm
=
"aes256-gcm"
)
type
KeyringRotateRootKeyRequest
struct
{
Algorithm
EncryptionAlgorithm
Full
bool
WriteRequest
}
// KeyringRotateRootKeyResponse returns the full key metadata
type
KeyringRotateRootKeyResponse
struct
{
Key
*
RootKeyMeta
WriteMeta
}
type
KeyringListRootKeyMetaRequest
struct
{
// TODO: do we need any fields here?
QueryOptions
}
type
KeyringListRootKeyMetaResponse
struct
{
Keys
[]
*
RootKeyMeta
QueryMeta
}
// KeyringUpdateRootKeyRequest is used internally for key replication
// only and for keyring restores. The RootKeyMeta will be extracted
// for applying to the FSM with the KeyringUpdateRootKeyMetaRequest
// (see below)
type
KeyringUpdateRootKeyRequest
struct
{
RootKey
*
RootKey
Rekey
bool
WriteRequest
}
type
KeyringUpdateRootKeyResponse
struct
{
WriteMeta
}
// KeyringGetRootKeyRequest is used internally for key replication
// only and for keyring restores.
type
KeyringGetRootKeyRequest
struct
{
KeyID
string
QueryOptions
}
type
KeyringGetRootKeyResponse
struct
{
Key
*
RootKey
QueryMeta
}
// KeyringUpdateRootKeyMetaRequest is used internally for key
// replication so that we have a request wrapper for writing the
// metadata to the FSM without including the key material
type
KeyringUpdateRootKeyMetaRequest
struct
{
RootKeyMeta
*
RootKeyMeta
Rekey
bool
WriteRequest
}
type
KeyringUpdateRootKeyMetaResponse
struct
{
WriteMeta
}
type
KeyringDeleteRootKeyRequest
struct
{
KeyID
string
WriteRequest
}
type
KeyringDeleteRootKeyResponse
struct
{
WriteMeta
}
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment