From 03e805d6e4f07b8bd386301ab1589150ff7be2c2 Mon Sep 17 00:00:00 2001 From: Daniel Shuy Date: Sat, 30 Oct 2021 00:17:31 +0800 Subject: [PATCH] feat: Support ES256 for Create JWT --- cmd/keys_create.go | 2 +- docs/docs/.static/api.json | 2 +- .../version-v1.10/.static/api.json | 2 +- .../version-v1.10/cli/hydra-keys-create.md | 2 +- driver/registry_base.go | 1 + jwk/doc.go | 2 +- jwk/manager_test_helpers.go | 38 +++++++++---------- persistence/sql/persister_test.go | 33 ++++++++-------- spec/api.json | 2 +- 9 files changed, 43 insertions(+), 41 deletions(-) diff --git a/cmd/keys_create.go b/cmd/keys_create.go index fa97ca92d8e..e9080bc72f2 100644 --- a/cmd/keys_create.go +++ b/cmd/keys_create.go @@ -33,7 +33,7 @@ func NewKeysCreateCmd() *cobra.Command { Short: "Create a new JSON Web Key Set", Run: cli.NewHandler().Keys.CreateKeys, } - cmd.Flags().StringP("alg", "a", "RS256", "The algorithm to be used to generated they key. Supports: RS256, ES512, HS256, EdDSA") + cmd.Flags().StringP("alg", "a", "RS256", "The algorithm to be used to generated they key. Supports: RS256, ES256, ES512, HS256, EdDSA") cmd.Flags().StringP("use", "u", "sig", "The intended use of this key") return cmd } diff --git a/docs/docs/.static/api.json b/docs/docs/.static/api.json index e01f23b6a3c..126e82894db 100755 --- a/docs/docs/.static/api.json +++ b/docs/docs/.static/api.json @@ -2392,7 +2392,7 @@ "required": ["alg", "use", "kid"], "properties": { "alg": { - "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES512\", \"HS512\", and \"HS256\"", + "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES256\", \"ES512\", \"HS512\", and \"HS256\"", "type": "string" }, "kid": { diff --git a/docs/versioned_docs/version-v1.10/.static/api.json b/docs/versioned_docs/version-v1.10/.static/api.json index 051d1023734..fcaa33f6496 100755 --- a/docs/versioned_docs/version-v1.10/.static/api.json +++ b/docs/versioned_docs/version-v1.10/.static/api.json @@ -2750,7 +2750,7 @@ ], "properties": { "alg": { - "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES512\", \"HS512\", and \"HS256\"", + "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES256\", \"ES512\", \"HS512\", and \"HS256\"", "type": "string" }, "kid": { diff --git a/docs/versioned_docs/version-v1.10/cli/hydra-keys-create.md b/docs/versioned_docs/version-v1.10/cli/hydra-keys-create.md index ad4ede69ef6..07a0b6c6cea 100644 --- a/docs/versioned_docs/version-v1.10/cli/hydra-keys-create.md +++ b/docs/versioned_docs/version-v1.10/cli/hydra-keys-create.md @@ -21,7 +21,7 @@ hydra keys create <set> <key> [flags] ### Options ``` - -a, --alg string The algorithm to be used to generated they key. Supports: RS256, ES512, HS256 (default "RS256") + -a, --alg string The algorithm to be used to generated they key. Supports: RS256, ES256, ES512, HS256 (default "RS256") -h, --help help for create -u, --use string The intended use of this key (default "sig") ``` diff --git a/driver/registry_base.go b/driver/registry_base.go index cae0ff88863..0928dc0a993 100644 --- a/driver/registry_base.go +++ b/driver/registry_base.go @@ -224,6 +224,7 @@ func (m *RegistryBase) KeyGenerators() map[string]jwk.KeyGenerator { if m.kg == nil { m.kg = map[string]jwk.KeyGenerator{ "RS256": &jwk.RS256Generator{}, + "ES256": &jwk.ECDSA256Generator{}, "ES512": &jwk.ECDSA512Generator{}, "HS256": &jwk.HS256Generator{}, "HS512": &jwk.HS512Generator{}, diff --git a/jwk/doc.go b/jwk/doc.go index 20f912e03e9..f1bc504a295 100644 --- a/jwk/doc.go +++ b/jwk/doc.go @@ -30,7 +30,7 @@ import "github.com/ory/hydra/x" // swagger:model jsonWebKeySetGeneratorRequest type createRequest struct { - // The algorithm to be used for creating the key. Supports "RS256", "ES512", "HS512", and "HS256" + // The algorithm to be used for creating the key. Supports "RS256", "ES256", "ES512", "HS512", and "HS256" // required: true Algorithm string `json:"alg"` diff --git a/jwk/manager_test_helpers.go b/jwk/manager_test_helpers.go index d963a81c16d..3d50a57321e 100644 --- a/jwk/manager_test_helpers.go +++ b/jwk/manager_test_helpers.go @@ -55,29 +55,29 @@ func canonicalizeThumbprints(js []jose.JSONWebKey) []jose.JSONWebKey { return js } -func TestHelperManagerKey(m Manager, keys *jose.JSONWebKeySet, suffix string) func(t *testing.T) { +func TestHelperManagerKey(m Manager, algo string, keys *jose.JSONWebKeySet, suffix string) func(t *testing.T) { pub := canonicalizeThumbprints(keys.Key("public:" + suffix)) priv := canonicalizeThumbprints(keys.Key("private:" + suffix)) return func(t *testing.T) { - _, err := m.GetKey(context.TODO(), "faz", "baz") + _, err := m.GetKey(context.TODO(), algo+"faz", "baz") assert.NotNil(t, err) - err = m.AddKey(context.TODO(), "faz", First(priv)) + err = m.AddKey(context.TODO(), algo+"faz", First(priv)) require.NoError(t, err) - got, err := m.GetKey(context.TODO(), "faz", "private:"+suffix) + got, err := m.GetKey(context.TODO(), algo+"faz", "private:"+suffix) require.NoError(t, err) assert.Equal(t, priv, canonicalizeThumbprints(got.Keys)) - err = m.AddKey(context.TODO(), "faz", First(pub)) + err = m.AddKey(context.TODO(), algo+"faz", First(pub)) require.NoError(t, err) - got, err = m.GetKey(context.TODO(), "faz", "private:"+suffix) + got, err = m.GetKey(context.TODO(), algo+"faz", "private:"+suffix) require.NoError(t, err) assert.Equal(t, priv, canonicalizeThumbprints(got.Keys)) - got, err = m.GetKey(context.TODO(), "faz", "public:"+suffix) + got, err = m.GetKey(context.TODO(), algo+"faz", "public:"+suffix) require.NoError(t, err) assert.Equal(t, pub, canonicalizeThumbprints(got.Keys)) @@ -85,46 +85,46 @@ func TestHelperManagerKey(m Manager, keys *jose.JSONWebKeySet, suffix string) fu time.Sleep(time.Second * 2) First(pub).KeyID = "new-key-id:" + suffix - err = m.AddKey(context.TODO(), "faz", First(pub)) + err = m.AddKey(context.TODO(), algo+"faz", First(pub)) require.NoError(t, err) - _, err = m.GetKey(context.TODO(), "faz", "new-key-id:"+suffix) + _, err = m.GetKey(context.TODO(), algo+"faz", "new-key-id:"+suffix) require.NoError(t, err) - keys, err = m.GetKeySet(context.TODO(), "faz") + keys, err = m.GetKeySet(context.TODO(), algo+"faz") require.NoError(t, err) assert.EqualValues(t, "new-key-id:"+suffix, First(keys.Keys).KeyID) beforeDeleteKeysCount := len(keys.Keys) - err = m.DeleteKey(context.TODO(), "faz", "public:"+suffix) + err = m.DeleteKey(context.TODO(), algo+"faz", "public:"+suffix) require.NoError(t, err) - _, err = m.GetKey(context.TODO(), "faz", "public:"+suffix) + _, err = m.GetKey(context.TODO(), algo+"faz", "public:"+suffix) require.Error(t, err) - keys, err = m.GetKeySet(context.TODO(), "faz") + keys, err = m.GetKeySet(context.TODO(), algo+"faz") require.NoError(t, err) assert.EqualValues(t, beforeDeleteKeysCount-1, len(keys.Keys)) } } -func TestHelperManagerKeySet(m Manager, keys *jose.JSONWebKeySet, suffix string) func(t *testing.T) { +func TestHelperManagerKeySet(m Manager, algo string, keys *jose.JSONWebKeySet, suffix string) func(t *testing.T) { return func(t *testing.T) { - _, err := m.GetKeySet(context.TODO(), "foo") + _, err := m.GetKeySet(context.TODO(), algo+"foo") require.Error(t, err) - err = m.AddKeySet(context.TODO(), "bar", keys) + err = m.AddKeySet(context.TODO(), algo+"bar", keys) require.NoError(t, err) - got, err := m.GetKeySet(context.TODO(), "bar") + got, err := m.GetKeySet(context.TODO(), algo+"bar") require.NoError(t, err) assert.Equal(t, canonicalizeThumbprints(keys.Key("public:"+suffix)), canonicalizeThumbprints(got.Key("public:"+suffix))) assert.Equal(t, canonicalizeThumbprints(keys.Key("private:"+suffix)), canonicalizeThumbprints(got.Key("private:"+suffix))) - err = m.DeleteKeySet(context.TODO(), "bar") + err = m.DeleteKeySet(context.TODO(), algo+"bar") require.NoError(t, err) - _, err = m.GetKeySet(context.TODO(), "bar") + _, err = m.GetKeySet(context.TODO(), algo+"bar") require.Error(t, err) } } diff --git a/persistence/sql/persister_test.go b/persistence/sql/persister_test.go index 0c0c53780b5..74c72e219c0 100644 --- a/persistence/sql/persister_test.go +++ b/persistence/sql/persister_test.go @@ -42,22 +42,23 @@ func TestManagers(t *testing.T) { t.Run("package=consent/janitor="+k, testhelpers.JanitorTests(m.Config(), m.ConsentManager(), m.ClientManager(), m.OAuth2Storage())) t.Run("package=jwk/manager="+k, func(t *testing.T) { - var testGenerator = &jwk.RS256Generator{} - - t.Run("TestManagerKey", func(t *testing.T) { - ks, err := testGenerator.Generate("TestManagerKey", "sig") - require.NoError(t, err) - - jwk.TestHelperManagerKey(m.KeyManager(), ks, uuid.New()) - }) - - t.Run("TestManagerKeySet", func(t *testing.T) { - ks, err := testGenerator.Generate("TestManagerKeySet", "sig") - require.NoError(t, err) - ks.Key("private") - - jwk.TestHelperManagerKeySet(m.KeyManager(), ks, uuid.New()) - }) + testGenerators := new(driver.RegistryBase).KeyGenerators() + for algo, testGenerator := range testGenerators { + t.Run("TestManagerKey", func(t *testing.T) { + ks, err := testGenerator.Generate("TestManagerKey", "sig") + require.NoError(t, err) + + jwk.TestHelperManagerKey(m.KeyManager(), algo, ks, uuid.New()) + }) + + t.Run("TestManagerKeySet", func(t *testing.T) { + ks, err := testGenerator.Generate("TestManagerKeySet", "sig") + require.NoError(t, err) + ks.Key("private") + + jwk.TestHelperManagerKeySet(m.KeyManager(), algo, ks, uuid.New()) + }) + } }) } } diff --git a/spec/api.json b/spec/api.json index 30ab1aa7f44..65bb566ada6 100755 --- a/spec/api.json +++ b/spec/api.json @@ -2760,7 +2760,7 @@ ], "properties": { "alg": { - "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES512\", \"HS512\", and \"HS256\"", + "description": "The algorithm to be used for creating the key. Supports \"RS256\", \"ES256\", \"ES512\", \"HS512\", and \"HS256\"", "type": "string" }, "kid": {