Skip to content

Commit

Permalink
only skip deprecated keys and test listpublic rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
schmichael committed Jul 26, 2023
1 parent 027c6b2 commit 3f252d1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
4 changes: 2 additions & 2 deletions nomad/keyring_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ func (k *Keyring) ListPublic(args *structs.GenericRequest, reply *structs.Keyrin
}

keyMeta := raw.(*structs.RootKeyMeta)
if keyMeta.Inactive() {
// Skip inactive keys
if keyMeta.State == structs.RootKeyStateDeprecated {
// Only include valid keys
continue
}

Expand Down
57 changes: 57 additions & 0 deletions nomad/keyring_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/shoenig/test/must"
"github.com/stretchr/testify/require"

"github.com/hashicorp/nomad/ci"
Expand Down Expand Up @@ -295,3 +296,59 @@ func TestKeyringEndpoint_Rotate(t *testing.T) {
gotKey := getResp.Key
require.Len(t, gotKey.Key, 32)
}

// TestKeyringEndpoint_ListPublic asserts the Keyring.ListPublic RPC returns
// all keys which may be in use for active crytpographic material (variables,
// valid JWTs).
func TestKeyringEndpoint_ListPublic(t *testing.T) {

ci.Parallel(t)
srv, rootToken, shutdown := TestACLServer(t, func(c *Config) {
c.NumSchedulers = 0 // Prevent automatic dequeue
})
defer shutdown()
testutil.WaitForLeader(t, srv.RPC)
codec := rpcClient(t, srv)

// Assert 1 key exists and normal fields are set
req := structs.GenericRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
AuthToken: "ignored!",
},
}
var resp structs.KeyringListPublicResponse
must.NoError(t, msgpackrpc.CallWithCodec(codec, "Keyring.ListPublic", &req, &resp))
must.Eq(t, srv.config.RootKeyRotationThreshold, resp.RotationThreshold)
must.Len(t, 1, resp.PublicKeys)
must.NonZero(t, resp.Index)

// Rotate keys and assert there are now 2 keys
rotateReq := &structs.KeyringRotateRootKeyRequest{
WriteRequest: structs.WriteRequest{
Region: "global",
AuthToken: rootToken.SecretID,
},
}
var rotateResp structs.KeyringRotateRootKeyResponse
must.NoError(t, msgpackrpc.CallWithCodec(codec, "Keyring.Rotate", rotateReq, &rotateResp))
must.NotEq(t, resp.Index, rotateResp.Index)

// Verify we have a new key and the old one is inactive
var resp2 structs.KeyringListPublicResponse
must.NoError(t, msgpackrpc.CallWithCodec(codec, "Keyring.ListPublic", &req, &resp2))
must.Eq(t, srv.config.RootKeyRotationThreshold, resp2.RotationThreshold)
must.Len(t, 2, resp2.PublicKeys)
must.NonZero(t, resp2.Index)

found := false
for _, pk := range resp2.PublicKeys {
if pk.KeyID == resp.PublicKeys[0].KeyID {
must.False(t, found, must.Sprint("found the original public key twice"))
found = true
must.Eq(t, resp.PublicKeys[0], pk)
break
}
}
must.True(t, found, must.Sprint("original public key missing after rotation"))
}

0 comments on commit 3f252d1

Please sign in to comment.