Commit 5136c786 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

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
parent d7d3af3f
......@@ -13,7 +13,6 @@ import (
"crypto/sha256"
"crypto/sha512"
"hash"
"math/big"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
......@@ -97,26 +96,16 @@ func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
return nil, nil, err
}
var pubKey bytes.Buffer
pubKey.Write(x.Bytes())
pubKey.Write(y.Bytes())
pubKey := elliptic.Marshal(curve, x, y)
u.PErr("GenerateEKeyPair %d\n", len(pubKey))
done := func(theirPub []byte) ([]byte, error) {
// Verify and unpack node's public key.
curveSize := curve.Params().BitSize
if len(theirPub) != (curveSize / 4) {
u.PErr("Malformed public key: %v", theirPub)
return nil, fmt.Errorf("Malformed public key: %v != %v", len(theirPub), (curveSize / 4))
x, y := elliptic.Unmarshal(curve, theirPub)
if x == nil {
return nil, fmt.Errorf("Malformed public key: %d %v", len(theirPub), theirPub)
}
bound := (curveSize / 8)
x := big.NewInt(0)
y := big.NewInt(0)
x.SetBytes(theirPub[0:bound])
y.SetBytes(theirPub[bound : bound*2])
if !curve.IsOnCurve(x, y) {
return nil, errors.New("Invalid public key.")
}
......@@ -127,7 +116,7 @@ func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
return secret.Bytes(), nil
}
return pubKey.Bytes(), done, nil
return pubKey, done, nil
}
// Generates a set of keys for each party by stretching the shared key.
......
......@@ -119,7 +119,7 @@ func (s *SecurePipe) handshake() error {
}
// u.POut("Selected %s %s %s\n", exchange, cipherType, hashType)
epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
epubkey, genSharedKey, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
var handshake bytes.Buffer // Gather corpus to sign.
handshake.Write(encoded)
......@@ -173,7 +173,7 @@ func (s *SecurePipe) handshake() error {
return errors.New("Bad signature!")
}
secret, err := done(exchangeResp.GetEpubkey())
secret, err := genSharedKey(exchangeResp.GetEpubkey())
if err != nil {
return err
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment