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

Commit 8fd82ff

Browse files
authored
Merge pull request #267 from square/cs/v2
Version 2 cherry-picks
2 parents 1e80868 + fe1ef12 commit 8fd82ff

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

cipher/ecdh_es.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package josecipher
1818

1919
import (
20+
"bytes"
2021
"crypto"
2122
"crypto/ecdsa"
23+
"crypto/elliptic"
2224
"encoding/binary"
2325
)
2426

@@ -44,16 +46,38 @@ func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, p
4446
panic("public key not on same curve as private key")
4547
}
4648

47-
z, _ := priv.PublicKey.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
48-
reader := NewConcatKDF(crypto.SHA256, z.Bytes(), algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
49+
z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
50+
zBytes := z.Bytes()
4951

52+
// Note that calling z.Bytes() on a big.Int may strip leading zero bytes from
53+
// the returned byte array. This can lead to a problem where zBytes will be
54+
// shorter than expected which breaks the key derivation. Therefore we must pad
55+
// to the full length of the expected coordinate here before calling the KDF.
56+
octSize := dSize(priv.Curve)
57+
if len(zBytes) != octSize {
58+
zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...)
59+
}
60+
61+
reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
5062
key := make([]byte, size)
5163

5264
// Read on the KDF will never fail
5365
_, _ = reader.Read(key)
66+
5467
return key
5568
}
5669

70+
// dSize returns the size in octets for a coordinate on a elliptic curve.
71+
func dSize(curve elliptic.Curve) int {
72+
order := curve.Params().P
73+
bitLen := order.BitLen()
74+
size := bitLen / 8
75+
if bitLen%8 != 0 {
76+
size++
77+
}
78+
return size
79+
}
80+
5781
func lengthPrefixed(data []byte) []byte {
5882
out := make([]byte, len(data)+4)
5983
binary.BigEndian.PutUint32(out, uint32(len(data)))

jwe_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,41 @@ func TestSampleJose4jJWEMessagesECDH(t *testing.T) {
550550
}
551551
}
552552

553+
func TestPrecomputedECDHMessagesFromJose4j(t *testing.T) {
554+
data := []struct{ key, message string }{
555+
{
556+
`{"kty":"EC","x":"fXx-DfOsmecjKh3VrLZFsF98Z1nutsL4UdFTdgA8S7Y","y":"LGzyJY99aqKk52UIExcNFSTs0S7HnNzQ-DRWBTHDad4","crv":"P-256","d":"OeVCWbXuFuJ9U16q7bhLNoKPLLnK-yTx95grzfvQ2l4"}`,
557+
`eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiRUNESC1FUyIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJ3ZlRHNVFHZkItNHUxanVUUEN1aTNESXhFTV82ZUs5ZEk5TXNZckpxWDRnIiwieSI6Ik8yanlRbHQ2TXFGTGtqMWFCWW1aNXZJWHFVRHh6Ulk3dER0WmdZUUVNa0kiLCJjcnYiOiJQLTI1NiJ9fQ..mk4wQzGSSeZ8uSgEYTIetA.fCw3-TosL4p0D5fEXw0bEA.9mPsdmGTVoVexXqEOdN5VUKk-ZNtfOtUfbdjVHoko_o`,
558+
},
559+
{
560+
`{"kty":"EC","x":"nBr92fh2JsEjIF1LR5PKICBeHNIBe0xb7nlBrrU3WoWgfJYfXve1jxC-5VT5EPLt","y":"sUAxL3L5lJdzFUSR9EHLniuBhEbvXfPa_3OiR6Du0_GOlFXXIi4UmbNpk10_Thfq","crv":"P-384","d":"0f0NnWg__Qgqjj3fl2gAlsID4Ni41FR88cmZPVgb6ch-ZShuVJRjoxymCuzVP7Gi"}`,
561+
`eyJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiRUNESC1FUyIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJsX3hXdzIyb1NfOWZGbV96amNzYkstd3R3d0RHSlRQLUxnNFVBWDI3WWF1b1YwNml2emwtcm1ra2h6ci11SDBmIiwieSI6IloyYmVnbzBqeE9nY0YtNVp4SFNBOU5jZDVCOW8wUE1pSVlRbm9sWkNQTHA3YndPd1RLUEZaaFZVUlFPSjdoeUciLCJjcnYiOiJQLTM4NCJ9fQ..jSWP7pfa4KcpqKWZ1x8awg.osb-5641Ej1Uon_f3U8bNw.KUQWwb35Gxq3YQ34_AVkebugx4rxq1lO`,
562+
},
563+
{
564+
`{"kty":"EC","x":"AH3rqSYjKue50ThW0qq_qQ76cNtqWrc7hU6kZR6akxy8iTf8ugcpqnbgbi98AgSwIqgJZDBMCk-8eoiGaf3R_kDD","y":"AeafPdJjHLf6pK5V7iyMsL3-6MShpHS6jXQ8m-Bcbp06yxAMn6TJbdkacvj45dy_pdh1s6XZwoxRxNETg_gj-hq9","crv":"P-521","d":"AB2tm9vgGe2BaxZmJQ016GY-U7NV_EWhrPsLDC5l9tAM9DGEwI2cT2HcO20Z6CQndw0ZhqLZ6MEvS8siL-SCxIl2"}`,
565+
`eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiRUNESC1FUyIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJBQ1RLMlVPSjJ6SVk3U1U4T0xkaG1QQmE4ZUVpd2JrX09UMXE0MHBsRlRwQmJKUXg3YWdqWG9LYml2NS1OTXB6eXZySm1rblM3SjNRUWlUeFgwWmtjemhEIiwieSI6IkFXeTZCR1dkZld2ekVNeGIxQklCQnZmRDJ4bEh6Rjk2YzVVRVQ4SFBUS0RSeUJyMnQ4T2dTX1J2MnNoUmxGbXlqUWpyX25uQk94akcxVTZNWDNlZ2VETzciLCJjcnYiOiJQLTUyMSJ9fQ..EWqSGntxbO_Y_6JRjFkCgg.DGjDNjAYdsnYTpUFJi1gEI4YtNd7gBPMjD3CDH047RAwZKTme6Ah_ztzxSfVg5kG.yGm5jn2LtbFXaK_yf0b0932sI2O77j2gwmL1Y09YC_Y`,
566+
},
567+
}
568+
569+
for i, vector := range data {
570+
var jwk JSONWebKey
571+
err := jwk.UnmarshalJSON([]byte(vector.key))
572+
if err != nil {
573+
t.Fatal(i, err)
574+
}
575+
576+
parsed, err := ParseEncrypted(vector.message)
577+
if err != nil {
578+
t.Fatal(i, err)
579+
}
580+
581+
_, err = parsed.Decrypt(jwk)
582+
if err != nil {
583+
t.Fatal(i, err)
584+
}
585+
}
586+
}
587+
553588
func TestSampleAESCBCHMACMessagesFromNodeJose(t *testing.T) {
554589
samples := []struct {
555590
key []byte

jwk.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,11 @@ func (key rawJSONWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
357357
// the curve specified in the "crv" parameter.
358358
// https://tools.ietf.org/html/rfc7518#section-6.2.1.2
359359
if curveSize(curve) != len(key.X.data) {
360-
return nil, fmt.Errorf("square/go-jose: invalid EC private key, wrong length for x")
360+
return nil, fmt.Errorf("square/go-jose: invalid EC public key, wrong length for x")
361361
}
362362

363363
if curveSize(curve) != len(key.Y.data) {
364-
return nil, fmt.Errorf("square/go-jose: invalid EC private key, wrong length for y")
364+
return nil, fmt.Errorf("square/go-jose: invalid EC public key, wrong length for y")
365365
}
366366

367367
x := key.X.bigInt()

0 commit comments

Comments
 (0)