Skip to content

Commit 2fae465

Browse files
AGWAericchiang
authored andcommitted
Return an error if Ed25519ctx or Ed25519ph is used
Otherwise, an invalid signature will be returned. As far as I can tell, the YubiKey only supports straight Ed25519.
1 parent bc889e4 commit 2fae465

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

v2/piv/key.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -1295,9 +1295,9 @@ func (k *keyEd25519) Public() crypto.PublicKey {
12951295
return k.pub
12961296
}
12971297

1298-
func (k *keyEd25519) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
1298+
func (k *keyEd25519) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) ([]byte, error) {
12991299
return k.auth.do(k.yk, k.pp, func(tx *scTx) ([]byte, error) {
1300-
return ykSignEd25519(tx, k.slot, k.pub, digest)
1300+
return ykSignEd25519(tx, k.slot, k.pub, message, opts)
13011301
})
13021302
}
13031303

@@ -1400,7 +1400,14 @@ func ykECDHX25519(tx *scTx, slot Slot, pub *ecdh.PublicKey, peer *ecdh.PublicKey
14001400
return sharedSecret, nil
14011401
}
14021402

1403-
func ykSignEd25519(tx *scTx, slot Slot, pub ed25519.PublicKey, digest []byte) ([]byte, error) {
1403+
func ykSignEd25519(tx *scTx, slot Slot, pub ed25519.PublicKey, message []byte, opts crypto.SignerOpts) ([]byte, error) {
1404+
if opts.HashFunc() != crypto.Hash(0) {
1405+
return nil, fmt.Errorf("ed25519ph not supported")
1406+
}
1407+
if ed25519opts, ok := opts.(*ed25519.Options); ok && ed25519opts.Context != "" {
1408+
return nil, fmt.Errorf("ed25519ctx not supported")
1409+
}
1410+
14041411
// Adaptation of
14051412
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=118
14061413
cmd := apdu{
@@ -1409,7 +1416,7 @@ func ykSignEd25519(tx *scTx, slot Slot, pub ed25519.PublicKey, digest []byte) ([
14091416
param2: byte(slot.Key),
14101417
data: marshalASN1(0x7c,
14111418
append([]byte{0x82, 0x00},
1412-
marshalASN1(0x81, digest)...)),
1419+
marshalASN1(0x81, message)...)),
14131420
}
14141421
resp, err := tx.Transmit(cmd)
14151422
if err != nil {

v2/piv/key_test.go

+24-7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"crypto/rand"
2525
"crypto/rsa"
2626
"crypto/sha256"
27+
"crypto/sha512"
2728
"crypto/tls"
2829
"crypto/x509"
2930
"crypto/x509/pkix"
@@ -303,13 +304,29 @@ func TestYubiKeySignEd25519(t *testing.T) {
303304
if !ok {
304305
t.Fatalf("expected private key to implement crypto.Signer")
305306
}
306-
sig, err := s.Sign(rand.Reader, data, crypto.Hash(0))
307-
if err != nil {
308-
t.Fatalf("signing failed: %v", err)
309-
}
310-
if !ed25519.Verify(pub, data, sig) {
311-
t.Errorf("signature didn't match")
312-
}
307+
308+
t.Run("good", func(t *testing.T) {
309+
sig, err := s.Sign(rand.Reader, data, crypto.Hash(0))
310+
if err != nil {
311+
t.Fatalf("signing failed: %v", err)
312+
}
313+
if !ed25519.Verify(pub, data, sig) {
314+
t.Errorf("signature didn't match")
315+
}
316+
})
317+
t.Run("unsupported_ed25519ph", func(t *testing.T) {
318+
digest := sha512.Sum512(data)
319+
_, err := s.Sign(rand.Reader, digest[:], crypto.SHA512)
320+
if err == nil {
321+
t.Fatalf("expected signing with Ed25519ph to fail")
322+
}
323+
})
324+
t.Run("unsupported_ed25519ctx", func(t *testing.T) {
325+
_, err := s.Sign(rand.Reader, data, &ed25519.Options{Context: "test"})
326+
if err == nil {
327+
t.Fatalf("expected signing with Ed25519ctx to fail")
328+
}
329+
})
313330
}
314331

315332
func TestPINPrompt(t *testing.T) {

0 commit comments

Comments
 (0)