Skip to content

Commit efc9cd7

Browse files
committed
Error if public parts missing on PrivateKey creation
RFC8152 allows public parts to be omitted from private keys, as they could be derived (though it recommends that they are present). crypto.PrivateKey implementations require for them to be present. Signed-off-by: setrofim <[email protected]>
1 parent 58b2935 commit efc9cd7

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ var (
1818
ErrNotPrivKey = errors.New("not a private key")
1919
ErrSignOpNotSupported = errors.New("sign key_op not supported by key")
2020
ErrVerifyOpNotSupported = errors.New("verify key_op not supported by key")
21+
ErrEC2NoPub = errors.New("cannot create PrivateKey from EC2 key: missing X or Y")
22+
ErrOKPNoPub = errors.New("cannot create PrivateKey from OKP key: missing X")
2123
)

key.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,13 @@ func (k *Key) PrivateKey() (crypto.PrivateKey, error) {
639639

640640
switch alg {
641641
case AlgorithmES256, AlgorithmES384, AlgorithmES512:
642+
// RFC8152 allows omitting X and Y from private keys;
643+
// crypto.PrivateKey assumes they are available.
644+
// see https://www.rfc-editor.org/rfc/rfc8152#section-13.1.1
645+
if len(k.X) == 0 || len(k.Y) == 0 {
646+
return nil, ErrEC2NoPub
647+
}
648+
642649
var curve elliptic.Curve
643650

644651
switch alg {
@@ -660,6 +667,13 @@ func (k *Key) PrivateKey() (crypto.PrivateKey, error) {
660667

661668
return priv, nil
662669
case AlgorithmEd25519:
670+
// RFC8152 allows omitting X from private keys;
671+
// crypto.PrivateKey assumes it is available.
672+
// see https://www.rfc-editor.org/rfc/rfc8152#section-13.2
673+
if len(k.X) == 0 {
674+
return nil, ErrOKPNoPub
675+
}
676+
663677
buf := make([]byte, ed25519.PrivateKeySize)
664678

665679
copy(buf, k.D)

key_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,4 +650,19 @@ func Test_Key_crypto_keys(t *testing.T) {
650650
assertEqualError(t, err, "unsupported curve \"X448\" for key type OKP")
651651
_, err = k.PrivateKey()
652652
assertEqualError(t, err, "unsupported curve \"X448\" for key type OKP")
653+
654+
k = Key{
655+
KeyType: KeyTypeOKP,
656+
Curve: CurveEd25519,
657+
D: []byte{0xde, 0xad, 0xbe, 0xef},
658+
}
659+
660+
_, err = k.PrivateKey()
661+
assertEqualError(t, err, ErrOKPNoPub.Error())
662+
663+
k.KeyType = KeyTypeEC2
664+
k.Curve = CurveP256
665+
666+
_, err = k.PrivateKey()
667+
assertEqualError(t, err, ErrEC2NoPub.Error())
653668
}

0 commit comments

Comments
 (0)