Skip to content
This repository was archived by the owner on Feb 27, 2023. It is now read-only.

Commit c758193

Browse files
committed
Merge branch 'cs/164590'
* cs/164590: Check for invalid ECDH keys in headers, JWKs Do not accept invalid public keys in DeriveECDHES function
2 parents b1b0f90 + 7f0dd80 commit c758193

File tree

5 files changed

+66
-3
lines changed

5 files changed

+66
-3
lines changed

asymmetric.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientI
370370
return nil, errors.New("square/go-jose: invalid epk header")
371371
}
372372

373+
if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
374+
return nil, errors.New("square/go-jose: invalid public key in epk header")
375+
}
376+
373377
apuData := headers.Apu.bytes()
374378
apvData := headers.Apv.bytes()
375379

asymmetric_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package jose
1818

1919
import (
2020
"bytes"
21+
"crypto/ecdsa"
22+
"crypto/elliptic"
2123
"crypto/rand"
2224
"crypto/rsa"
2325
"errors"
@@ -429,3 +431,31 @@ func TestInvalidEllipticCurve(t *testing.T) {
429431
t.Error("should not generate ES384 signature with P-521 key")
430432
}
431433
}
434+
435+
func TestInvalidECPublicKey(t *testing.T) {
436+
// Invalid key
437+
invalid := &ecdsa.PrivateKey{
438+
PublicKey: ecdsa.PublicKey{
439+
Curve: elliptic.P256(),
440+
X: fromBase64Int("MTEx"),
441+
Y: fromBase64Int("MTEx"),
442+
},
443+
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo="),
444+
}
445+
446+
headers := rawHeader{
447+
Alg: string(ECDH_ES),
448+
Epk: &JsonWebKey{
449+
Key: &invalid.PublicKey,
450+
},
451+
}
452+
453+
dec := ecDecrypterSigner{
454+
privateKey: ecTestKey256,
455+
}
456+
457+
_, err := dec.decryptKey(headers, nil, randomKeyGenerator{size: 16})
458+
if err == nil {
459+
t.Fatal("decrypter accepted JWS with invalid ECDH public key")
460+
}
461+
}

cipher/ecdh_es.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, p
3333
supPubInfo := make([]byte, 4)
3434
binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
3535

36+
if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
37+
panic("public key not on same curve as private key")
38+
}
39+
3640
z, _ := priv.PublicKey.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
3741
reader := NewConcatKDF(crypto.SHA256, z.Bytes(), algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
3842

cipher/ecdh_es_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,23 @@ func TestVectorECDHES(t *testing.T) {
6767
}
6868
}
6969

70+
func TestInvalidECPublicKey(t *testing.T) {
71+
defer func() { recover() }()
72+
73+
// Invalid key
74+
invalid := &ecdsa.PrivateKey{
75+
PublicKey: ecdsa.PublicKey{
76+
Curve: elliptic.P256(),
77+
X: fromBase64Int("MTEx"),
78+
Y: fromBase64Int("MTEx"),
79+
},
80+
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo="),
81+
}
82+
83+
DeriveECDHES("A128GCM", []byte{}, []byte{}, bobKey, &invalid.PublicKey, 16)
84+
t.Fatal("should panic if public key was invalid")
85+
}
86+
7087
func BenchmarkECDHES_128(b *testing.B) {
7188
apuData := []byte("APU")
7289
apvData := []byte("APV")

jwk.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"crypto/rsa"
2424
"crypto/x509"
2525
"encoding/base64"
26+
"errors"
2627
"fmt"
2728
"math/big"
2829
"reflect"
@@ -277,13 +278,20 @@ func (key rawJsonWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
277278
}
278279

279280
if key.X == nil || key.Y == nil {
280-
return nil, fmt.Errorf("square/go-jose: invalid EC key, missing x/y values")
281+
return nil, errors.New("square/go-jose: invalid EC key, missing x/y values")
282+
}
283+
284+
x := key.X.bigInt()
285+
y := key.Y.bigInt()
286+
287+
if !curve.IsOnCurve(x, y) {
288+
return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve")
281289
}
282290

283291
return &ecdsa.PublicKey{
284292
Curve: curve,
285-
X: key.X.bigInt(),
286-
Y: key.Y.bigInt(),
293+
X: x,
294+
Y: y,
287295
}, nil
288296
}
289297

0 commit comments

Comments
 (0)