|
| 1 | +// +build go1.13 |
| 2 | + |
| 3 | +package jwt |
| 4 | + |
| 5 | +import ( |
| 6 | + "crypto/ed25519" |
| 7 | + "errors" |
| 8 | + |
| 9 | + "github.com/gbrlsnchs/jwt/v3/internal" |
| 10 | +) |
| 11 | + |
| 12 | +var ( |
| 13 | + // ErrEd25519PrivKey is the error for trying to sign a JWT with a nil private key. |
| 14 | + ErrEd25519PrivKey = errors.New("jwt: Ed25519 private key is nil") |
| 15 | + // ErrEd25519PubKey is the error for trying to verify a JWT with a nil public key. |
| 16 | + ErrEd25519PubKey = errors.New("jwt: Ed25519 public key is nil") |
| 17 | + // ErrEd25519Verification is the error for when verification with Ed25519 fails. |
| 18 | + ErrEd25519Verification = errors.New("jwt: Ed25519 verification failed") |
| 19 | + |
| 20 | + _ Algorithm = new(Ed25519) |
| 21 | +) |
| 22 | + |
| 23 | +// Ed25519PrivateKey is an option to set a private key to the Ed25519 algorithm. |
| 24 | +func Ed25519PrivateKey(priv ed25519.PrivateKey) func(*Ed25519) { |
| 25 | + return func(ed *Ed25519) { |
| 26 | + ed.priv = priv |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +// Ed25519PublicKey is an option to set a public key to the Ed25519 algorithm. |
| 31 | +func Ed25519PublicKey(pub ed25519.PublicKey) func(*Ed25519) { |
| 32 | + return func(ed *Ed25519) { |
| 33 | + ed.pub = pub |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +// Ed25519 is an algorithm that uses EdDSA to sign SHA-512 hashes. |
| 38 | +type Ed25519 struct { |
| 39 | + priv ed25519.PrivateKey |
| 40 | + pub ed25519.PublicKey |
| 41 | +} |
| 42 | + |
| 43 | +// NewEd25519 creates a new algorithm using EdDSA and SHA-512. |
| 44 | +func NewEd25519(opts ...func(*Ed25519)) *Ed25519 { |
| 45 | + var ed Ed25519 |
| 46 | + for _, opt := range opts { |
| 47 | + opt(&ed) |
| 48 | + } |
| 49 | + if ed.pub == nil { |
| 50 | + ed.pub = ed.priv.Public().(ed25519.PublicKey) |
| 51 | + } |
| 52 | + return &ed |
| 53 | +} |
| 54 | + |
| 55 | +// Name returns the algorithm's name. |
| 56 | +func (*Ed25519) Name() string { |
| 57 | + return "Ed25519" |
| 58 | +} |
| 59 | + |
| 60 | +// Sign signs headerPayload using the Ed25519 algorithm. |
| 61 | +func (ed *Ed25519) Sign(headerPayload []byte) ([]byte, error) { |
| 62 | + if ed.priv == nil { |
| 63 | + return nil, ErrEd25519PrivKey |
| 64 | + } |
| 65 | + return ed25519.Sign(ed.priv, headerPayload), nil |
| 66 | +} |
| 67 | + |
| 68 | +// Size returns the signature byte size. |
| 69 | +func (*Ed25519) Size() int { |
| 70 | + return ed25519.SignatureSize |
| 71 | +} |
| 72 | + |
| 73 | +// Verify verifies a payload and a signature. |
| 74 | +func (ed *Ed25519) Verify(payload, sig []byte) (err error) { |
| 75 | + if ed.pub == nil { |
| 76 | + return ErrEd25519PubKey |
| 77 | + } |
| 78 | + if sig, err = internal.DecodeToBytes(sig); err != nil { |
| 79 | + return err |
| 80 | + } |
| 81 | + if !ed25519.Verify(ed.pub, payload, sig) { |
| 82 | + return ErrEd25519Verification |
| 83 | + } |
| 84 | + return nil |
| 85 | +} |
0 commit comments