Merge pull request #16174 from twz123/jwt-ed25519-support

auth: Support for EdDSA JWT algorithm
This commit is contained in:
Benjamin Wang 2023-07-05 12:29:04 +01:00 committed by GitHub
commit 89bbba8fb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 0 deletions

View File

@ -17,6 +17,7 @@ package auth
import (
"context"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"errors"
"time"
@ -54,6 +55,8 @@ func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInf
return &k.PublicKey, nil
case *ecdsa.PrivateKey:
return &k.PublicKey, nil
case ed25519.PrivateKey:
return k.Public(), nil
default:
return t.key, nil
}
@ -161,6 +164,10 @@ func newTokenProviderJWT(lg *zap.Logger, optMap map[string]string) (*tokenJWT, e
if _, ok := t.key.(*ecdsa.PublicKey); ok {
t.verifyOnly = true
}
case *jwt.SigningMethodEd25519:
if _, ok := t.key.(ed25519.PublicKey); ok {
t.verifyOnly = true
}
case *jwt.SigningMethodRSA, *jwt.SigningMethodRSAPSS:
if _, ok := t.key.(*rsa.PublicKey); ok {
t.verifyOnly = true

View File

@ -31,6 +31,9 @@ const (
jwtECPubKey = "../../tests/fixtures/server-ecdsa.crt"
jwtECPrivKey = "../../tests/fixtures/server-ecdsa.key.insecure"
jwtEdPubKey = "../../tests/fixtures/ed25519-public-key.pem"
jwtEdPrivKey = "../../tests/fixtures/ed25519-private-key.pem"
)
func TestJWTInfo(t *testing.T) {
@ -63,6 +66,15 @@ func TestJWTInfo(t *testing.T) {
"priv-key": jwtECPrivKey,
"sign-method": "ES256",
},
"Ed25519-priv": {
"priv-key": jwtEdPrivKey,
"sign-method": "EdDSA",
},
"Ed25519": {
"pub-key": jwtEdPubKey,
"priv-key": jwtEdPrivKey,
"sign-method": "EdDSA",
},
"HMAC": {
"priv-key": jwtECPrivKey, // any file, raw bytes used as shared secret
"sign-method": "HS256",

View File

@ -15,7 +15,9 @@
package auth
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"fmt"
"os"
@ -100,6 +102,8 @@ func (opts *jwtOptions) Key() (interface{}, error) {
return opts.rsaKey()
case *jwt.SigningMethodECDSA:
return opts.ecKey()
case *jwt.SigningMethodEd25519:
return opts.edKey()
case *jwt.SigningMethodHMAC:
return opts.hmacKey()
default:
@ -189,3 +193,45 @@ func (opts *jwtOptions) ecKey() (interface{}, error) {
return priv, nil
}
func (opts *jwtOptions) edKey() (interface{}, error) {
var (
priv ed25519.PrivateKey
pub ed25519.PublicKey
err error
)
if len(opts.PrivateKey) > 0 {
var privKey crypto.PrivateKey
privKey, err = jwt.ParseEdPrivateKeyFromPEM(opts.PrivateKey)
if err != nil {
return nil, err
}
priv = privKey.(ed25519.PrivateKey)
}
if len(opts.PublicKey) > 0 {
var pubKey crypto.PublicKey
pubKey, err = jwt.ParseEdPublicKeyFromPEM(opts.PublicKey)
if err != nil {
return nil, err
}
pub = pubKey.(ed25519.PublicKey)
}
if priv == nil {
if pub == nil {
// Neither key given
return nil, ErrMissingKey
}
// Public key only, can verify tokens
return pub, nil
}
// both keys provided, make sure they match
if pub != nil && !pub.Equal(priv.Public()) {
return nil, ErrKeyMismatch
}
return priv, nil
}

View File

@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIAtiwQ7KeS1I0otY9gw1Ox4av/zQ+wvs/8AIaTkawQ73
-----END PRIVATE KEY-----

3
tests/fixtures/ed25519-public-key.pem vendored Normal file
View File

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAuOUxC8Bbn1KqYctlim/MHaP5JrtmeK5xcs+9w506btA=
-----END PUBLIC KEY-----