@cryptotaxi247 / kubo / commits / 5136c786e

Bugfix: "Malformed Public Key" Error

This commit fixed the notoriously annoying "Malformed Public Key" problem. The issue was that sometimes the byte representation of the points (x,y in big.Int) generated would be one less byte than expected. This is simply because (* big.Int) Write uses the least amount of bytes needed for the int. I instead changed the marshalling/unmarshalling to do exactly what stdlib crypto/tls does: use `ellipctic.Marshal` which marshals according to the ANSI X9.62 standard. http://golang.org/pkg/crypto/elliptic/#Marshal http://golang.org/src/pkg/crypto/tls/key_agreement.go#L214 ```Go // crypto/tls ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand()) ecdhePublic := elliptic.Marshal(ka.curve, x, y) // ipfs/crypto priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader) pubKey := elliptic.Marshal(curve, x, y) ``` ((Warning: we're using `rand.Reader` directly, which we shouldn't do, as it can be seeded. We should use a configured source, as crypto/tls. Flagged in #143)) This makes me think we should re-use a lot of their datastructures and functions directly (e.g. ecdheKeyAgreement) Fixed: #135 cc @bren2010 @whyrusleeping

Juan Batiz-Benet committed Oct 5, 2014 at 15:56 UTC 5136c786e51c7e95a6db6d55e5527dca53e2e945
2 files changed +8 -19
crypto/key.go
+6 -17
@@ -13,7 +13,6 @@ import (
13 "crypto/sha256"
14 "crypto/sha512"
15 "hash"
16 - "math/big"
16
17 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
18
@@ -97,26 +96,16 @@ func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
96 return nil, nil, err
97 }
98
100 - var pubKey bytes.Buffer
101 - pubKey.Write(x.Bytes())
102 - pubKey.Write(y.Bytes())
99 + pubKey := elliptic.Marshal(curve, x, y)
100 + u.PErr("GenerateEKeyPair %d\n", len(pubKey))
101
102 done := func(theirPub []byte) ([]byte, error) {
103 // Verify and unpack node's public key.
106 - curveSize := curve.Params().BitSize
107 -
108 - if len(theirPub) != (curveSize / 4) {
109 - u.PErr("Malformed public key: %v", theirPub)
110 - return nil, fmt.Errorf("Malformed public key: %v != %v", len(theirPub), (curveSize / 4))
104 + x, y := elliptic.Unmarshal(curve, theirPub)
105 + if x == nil {
106 + return nil, fmt.Errorf("Malformed public key: %d %v", len(theirPub), theirPub)
107 }
108
113 - bound := (curveSize / 8)
114 - x := big.NewInt(0)
115 - y := big.NewInt(0)
116 -
117 - x.SetBytes(theirPub[0:bound])
118 - y.SetBytes(theirPub[bound : bound*2])
119 -
109 if !curve.IsOnCurve(x, y) {
110 return nil, errors.New("Invalid public key.")
111 }
@@ -127,7 +116,7 @@ func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
116 return secret.Bytes(), nil
117 }
118
130 - return pubKey.Bytes(), done, nil
119 + return pubKey, done, nil
120 }
121
122 // Generates a set of keys for each party by stretching the shared key.
crypto/spipe/handshake.go
+2 -2
@@ -119,7 +119,7 @@ func (s *SecurePipe) handshake() error {
119 }
120
121 // u.POut("Selected %s %s %s\n", exchange, cipherType, hashType)
122 - epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
122 + epubkey, genSharedKey, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
123
124 var handshake bytes.Buffer // Gather corpus to sign.
125 handshake.Write(encoded)
@@ -173,7 +173,7 @@ func (s *SecurePipe) handshake() error {
173 return errors.New("Bad signature!")
174 }
175
176 - secret, err := done(exchangeResp.GetEpubkey())
176 + secret, err := genSharedKey(exchangeResp.GetEpubkey())
177 if err != nil {
178 return err
179 }