mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 17:03:58 +08:00
Merge branch 'crypto' of github.com:Bren2010/go-ipfs into crypto
Conflicts: crypto/key.go
This commit is contained in:
157
crypto/key.go
157
crypto/key.go
@ -1,10 +1,18 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
"math/big"
|
||||
|
||||
"code.google.com/p/goprotobuf/proto"
|
||||
)
|
||||
@ -19,10 +27,7 @@ type PrivKey interface {
|
||||
// Cryptographically sign the given bytes
|
||||
Sign([]byte) ([]byte, error)
|
||||
|
||||
// Decrypt a message encrypted with this keys public key
|
||||
Decrypt([]byte) ([]byte, error)
|
||||
|
||||
// Return the public key paired with this private key
|
||||
// Return a public key paired with this private key
|
||||
GetPublic() PubKey
|
||||
|
||||
// Generate a secret string of bytes
|
||||
@ -36,13 +41,13 @@ type PubKey interface {
|
||||
// Verify that 'sig' is the signed hash of 'data'
|
||||
Verify(data []byte, sig []byte) (bool, error)
|
||||
|
||||
// Encrypt the given data with the public key
|
||||
Encrypt([]byte) ([]byte, error)
|
||||
|
||||
// Bytes returns a serialized, storeable representation of this key
|
||||
Bytes() ([]byte, error)
|
||||
}
|
||||
|
||||
// Given a public key, generates the shared key.
|
||||
type GenSharedKey func([]byte) ([]byte, error)
|
||||
|
||||
func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
|
||||
switch typ {
|
||||
case RSA:
|
||||
@ -57,6 +62,144 @@ func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Generates an ephemeral public key and returns a function that will compute
|
||||
// the shared secret key. Used in the identify module.
|
||||
//
|
||||
// Focuses only on ECDH now, but can be made more general in the future.
|
||||
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
|
||||
var curve elliptic.Curve
|
||||
|
||||
switch curveName {
|
||||
case "P-224":
|
||||
curve = elliptic.P224()
|
||||
case "P-256":
|
||||
curve = elliptic.P256()
|
||||
case "P-384":
|
||||
curve = elliptic.P384()
|
||||
case "P-521":
|
||||
curve = elliptic.P521()
|
||||
}
|
||||
|
||||
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pubKey bytes.Buffer
|
||||
pubKey.Write(x.Bytes())
|
||||
pubKey.Write(y.Bytes())
|
||||
|
||||
done := func(theirPub []byte) ([]byte, error) {
|
||||
// Verify and unpack node's public key.
|
||||
curveSize := curve.Params().BitSize
|
||||
|
||||
if len(theirPub) != (curveSize / 4) {
|
||||
return nil, errors.New("Malformed public key.")
|
||||
}
|
||||
|
||||
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.")
|
||||
}
|
||||
|
||||
// Generate shared secret.
|
||||
secret, _ := curve.ScalarMult(x, y, priv)
|
||||
|
||||
return secret.Bytes(), nil
|
||||
}
|
||||
|
||||
return pubKey.Bytes(), done, nil
|
||||
}
|
||||
|
||||
// Generates a set of keys for each party by stretching the shared key.
|
||||
// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
|
||||
func KeyStretcher(cmp int, cipherType string, hashType string, secret []byte) ([]byte, []byte, []byte, []byte, []byte, []byte) {
|
||||
var cipherKeySize int
|
||||
switch cipherType {
|
||||
case "AES-128":
|
||||
cipherKeySize = 16
|
||||
case "AES-256":
|
||||
cipherKeySize = 32
|
||||
}
|
||||
|
||||
ivSize := 16
|
||||
hmacKeySize := 20
|
||||
|
||||
seed := []byte("key expansion")
|
||||
|
||||
result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize))
|
||||
|
||||
var h func() hash.Hash
|
||||
|
||||
switch hashType {
|
||||
case "SHA1":
|
||||
h = sha1.New
|
||||
case "SHA256":
|
||||
h = sha256.New
|
||||
case "SHA512":
|
||||
h = sha512.New
|
||||
}
|
||||
|
||||
m := hmac.New(h, secret)
|
||||
m.Write(seed)
|
||||
|
||||
a := m.Sum(nil)
|
||||
|
||||
j := 0
|
||||
for j < len(result) {
|
||||
m.Reset()
|
||||
m.Write(a)
|
||||
m.Write(seed)
|
||||
b := m.Sum(nil)
|
||||
|
||||
todo := len(b)
|
||||
|
||||
if j+todo > len(result) {
|
||||
todo = len(result) - j
|
||||
}
|
||||
|
||||
copy(result[j:j+todo], b)
|
||||
|
||||
j += todo
|
||||
|
||||
m.Reset()
|
||||
m.Write(a)
|
||||
a = m.Sum(nil)
|
||||
}
|
||||
|
||||
myResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
|
||||
theirResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
|
||||
|
||||
half := len(result) / 2
|
||||
|
||||
if cmp == 1 {
|
||||
copy(myResult, result[:half])
|
||||
copy(theirResult, result[half:])
|
||||
} else if cmp == -1 {
|
||||
copy(myResult, result[half:])
|
||||
copy(theirResult, result[:half])
|
||||
} else { // Shouldn't happen, but oh well.
|
||||
copy(myResult, result[half:])
|
||||
copy(theirResult, result[half:])
|
||||
}
|
||||
|
||||
myIV := myResult[0:ivSize]
|
||||
myCKey := myResult[ivSize : ivSize+cipherKeySize]
|
||||
myMKey := myResult[ivSize+cipherKeySize:]
|
||||
|
||||
theirIV := theirResult[0:ivSize]
|
||||
theirCKey := theirResult[ivSize : ivSize+cipherKeySize]
|
||||
theirMKey := theirResult[ivSize+cipherKeySize:]
|
||||
|
||||
return myIV, theirIV, myCKey, theirCKey, myMKey, theirMKey
|
||||
}
|
||||
|
||||
func UnmarshalPublicKey(data []byte) (PubKey, error) {
|
||||
pmes := new(PBPublicKey)
|
||||
err := proto.Unmarshal(data, pmes)
|
||||
|
@ -28,10 +28,6 @@ func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (pk *RsaPublicKey) Encrypt(message []byte) ([]byte, error) {
|
||||
return rsa.EncryptPKCS1v15(rand.Reader, pk.k, message)
|
||||
}
|
||||
|
||||
func (pk *RsaPublicKey) Bytes() ([]byte, error) {
|
||||
b, err := x509.MarshalPKIXPublicKey(pk.k)
|
||||
if err != nil {
|
||||
@ -56,10 +52,6 @@ func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) {
|
||||
return rsa.SignPKCS1v15(rand.Reader, sk.k, crypto.SHA256, hashed[:])
|
||||
}
|
||||
|
||||
func (sk *RsaPrivateKey) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||
return rsa.DecryptPKCS1v15(rand.Reader, sk.k, ciphertext)
|
||||
}
|
||||
|
||||
func (sk *RsaPrivateKey) GetPublic() PubKey {
|
||||
return &RsaPublicKey{&sk.k.PublicKey}
|
||||
}
|
||||
|
@ -5,6 +5,16 @@ package identify
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
|
||||
proto "code.google.com/p/goprotobuf/proto"
|
||||
ci "github.com/jbenet/go-ipfs/crypto"
|
||||
@ -12,94 +22,221 @@ import (
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// List of supported protocols--each section in order of preference.
|
||||
// Takes the form: ECDH curves : Ciphers : Hashes
|
||||
var SupportedExchanges = "P-256,P-224,P-384,P-521"
|
||||
var SupportedCiphers = "AES-256,AES-128"
|
||||
var SupportedHashes = "SHA256,SHA512,SHA1"
|
||||
|
||||
// ErrUnsupportedKeyType is returned when a private key cast/type switch fails.
|
||||
var ErrUnsupportedKeyType = errors.New("unsupported key type")
|
||||
|
||||
// Perform initial communication with this peer to share node ID's and
|
||||
// initiate communication
|
||||
func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
|
||||
encoded, err := buildHandshake(self)
|
||||
// initiate communication. (secureIn, secureOut, error)
|
||||
func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan []byte, error) {
|
||||
// Generate and send Hello packet.
|
||||
// Hello = (rand, PublicKey, Supported)
|
||||
nonce := make([]byte, 16)
|
||||
rand.Read(nonce)
|
||||
|
||||
hello := new(Hello)
|
||||
|
||||
myPubKey, err := self.PubKey.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
hello.Rand = nonce
|
||||
hello.Pubkey = myPubKey
|
||||
hello.Exchanges = &SupportedExchanges
|
||||
hello.Ciphers = &SupportedCiphers
|
||||
hello.Hashes = &SupportedHashes
|
||||
|
||||
encoded, err := proto.Marshal(hello)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
out <- encoded
|
||||
|
||||
// Parse their Hello packet and generate an Exchange packet.
|
||||
// Exchange = (EphemeralPubKey, Signature)
|
||||
resp := <-in
|
||||
|
||||
pbresp := new(Identify)
|
||||
err = proto.Unmarshal(resp, pbresp)
|
||||
helloResp := new(Hello)
|
||||
err = proto.Unmarshal(resp, helloResp)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Verify that the given ID matches their given public key
|
||||
if verifyErr := verifyID(peer.ID(pbresp.GetId()), pbresp.GetPubkey()); verifyErr != nil {
|
||||
return verifyErr
|
||||
}
|
||||
|
||||
pubkey, err := ci.UnmarshalPublicKey(pbresp.GetPubkey())
|
||||
remote.PubKey, err = ci.UnmarshalPublicKey(helloResp.GetPubkey())
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Challenge peer to ensure they own the given pubkey
|
||||
secret := self.PrivKey.GenSecret()
|
||||
encrypted, err := pubkey.Encrypt(secret)
|
||||
remote.ID, err = IdFromPubKey(remote.PubKey)
|
||||
if err != nil {
|
||||
//... this is odd
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
out <- encrypted
|
||||
challenge := <-in
|
||||
|
||||
// Decrypt challenge and send plaintext to partner
|
||||
plain, err := self.PrivKey.Decrypt(challenge)
|
||||
exchange, err := selectBest(SupportedExchanges, helloResp.GetExchanges())
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
out <- plain
|
||||
chalResp := <-in
|
||||
if !bytes.Equal(chalResp, secret) {
|
||||
return errors.New("Recieved incorrect challenge response!")
|
||||
cipherType, err := selectBest(SupportedCiphers, helloResp.GetCiphers())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
hashType, err := selectBest(SupportedHashes, helloResp.GetHashes())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
|
||||
|
||||
var handshake bytes.Buffer // Gather corpus to sign.
|
||||
handshake.Write(encoded)
|
||||
handshake.Write(resp)
|
||||
handshake.Write(epubkey)
|
||||
|
||||
exPacket := new(Exchange)
|
||||
|
||||
exPacket.Epubkey = epubkey
|
||||
exPacket.Signature, err = self.PrivKey.Sign(handshake.Bytes())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
exEncoded, err := proto.Marshal(exPacket)
|
||||
|
||||
out <- exEncoded
|
||||
|
||||
// Parse their Exchange packet and generate a Finish packet.
|
||||
// Finish = E('Finish')
|
||||
resp1 := <-in
|
||||
|
||||
exchangeResp := new(Exchange)
|
||||
err = proto.Unmarshal(resp1, exchangeResp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var theirHandshake bytes.Buffer
|
||||
theirHandshake.Write(resp)
|
||||
theirHandshake.Write(encoded)
|
||||
theirHandshake.Write(exchangeResp.GetEpubkey())
|
||||
|
||||
ok, err := remote.PubKey.Verify(theirHandshake.Bytes(), exchangeResp.GetSignature())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return nil, nil, errors.New("Bad signature!")
|
||||
}
|
||||
|
||||
secret, err := done(exchangeResp.GetEpubkey())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cmp := bytes.Compare(myPubKey, helloResp.GetPubkey())
|
||||
mIV, tIV, mCKey, tCKey, mMKey, tMKey := ci.KeyStretcher(cmp, cipherType, hashType, secret)
|
||||
|
||||
secureIn := make(chan []byte)
|
||||
secureOut := make(chan []byte)
|
||||
|
||||
go secureInProxy(in, secureIn, hashType, tIV, tCKey, tMKey)
|
||||
go secureOutProxy(out, secureOut, hashType, mIV, mCKey, mMKey)
|
||||
|
||||
finished := []byte("Finished")
|
||||
|
||||
secureOut <- finished
|
||||
resp2 := <-secureIn
|
||||
|
||||
if bytes.Compare(resp2, finished) != 0 {
|
||||
return nil, nil, errors.New("Negotiation failed.")
|
||||
}
|
||||
|
||||
remote.ID = peer.ID(pbresp.GetId())
|
||||
remote.PubKey = pubkey
|
||||
u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
|
||||
|
||||
return nil
|
||||
return secureIn, secureOut, nil
|
||||
}
|
||||
|
||||
func buildHandshake(self *peer.Peer) ([]byte, error) {
|
||||
pkb, err := self.PubKey.Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func makeMac(hashType string, key []byte) (hash.Hash, int) {
|
||||
switch hashType {
|
||||
case "SHA1":
|
||||
return hmac.New(sha1.New, key), sha1.Size
|
||||
case "SHA512":
|
||||
return hmac.New(sha512.New, key), sha512.Size
|
||||
default:
|
||||
return hmac.New(sha256.New, key), sha256.Size
|
||||
}
|
||||
|
||||
pmes := new(Identify)
|
||||
pmes.Id = []byte(self.ID)
|
||||
pmes.Pubkey = pkb
|
||||
|
||||
encoded, err := proto.Marshal(pmes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
func verifyID(id peer.ID, pubkey []byte) error {
|
||||
hash, err := u.Hash(pubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func secureInProxy(in, secureIn chan []byte, hashType string, tIV, tCKey, tMKey []byte) {
|
||||
theirBlock, _ := aes.NewCipher(tCKey)
|
||||
theirCipher := cipher.NewCTR(theirBlock, tIV)
|
||||
|
||||
if id.Equal(peer.ID(hash)) {
|
||||
return nil
|
||||
}
|
||||
theirMac, macSize := makeMac(hashType, tMKey)
|
||||
|
||||
return errors.New("ID did not match public key!")
|
||||
for {
|
||||
data, ok := <-in
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) <= macSize {
|
||||
continue
|
||||
}
|
||||
|
||||
mark := len(data) - macSize
|
||||
buff := make([]byte, mark)
|
||||
|
||||
theirCipher.XORKeyStream(buff, data[0:mark])
|
||||
|
||||
theirMac.Write(data[0:mark])
|
||||
expected := theirMac.Sum(nil)
|
||||
theirMac.Reset()
|
||||
|
||||
hmacOk := hmac.Equal(data[mark:], expected)
|
||||
|
||||
if hmacOk {
|
||||
secureIn <- buff
|
||||
} else {
|
||||
secureIn <- nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func secureOutProxy(out, secureOut chan []byte, hashType string, mIV, mCKey, mMKey []byte) {
|
||||
myBlock, _ := aes.NewCipher(mCKey)
|
||||
myCipher := cipher.NewCTR(myBlock, mIV)
|
||||
|
||||
myMac, macSize := makeMac(hashType, mMKey)
|
||||
|
||||
for {
|
||||
data, ok := <-secureOut
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
buff := make([]byte, len(data)+macSize)
|
||||
|
||||
myCipher.XORKeyStream(buff, data)
|
||||
|
||||
myMac.Write(buff[0:len(data)])
|
||||
copy(buff[len(data):], myMac.Sum(nil))
|
||||
myMac.Reset()
|
||||
|
||||
out <- buff
|
||||
}
|
||||
}
|
||||
|
||||
func IdFromPubKey(pk ci.PubKey) (peer.ID, error) {
|
||||
@ -113,3 +250,41 @@ func IdFromPubKey(pk ci.PubKey) (peer.ID, error) {
|
||||
}
|
||||
return peer.ID(hash), nil
|
||||
}
|
||||
|
||||
// Determines which algorithm to use. Note: f(a, b) = f(b, a)
|
||||
func selectBest(myPrefs, theirPrefs string) (string, error) {
|
||||
// Person with greatest hash gets first choice.
|
||||
myHash, err := u.Hash([]byte(myPrefs))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
theirHash, err := u.Hash([]byte(theirPrefs))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cmp := bytes.Compare(myHash, theirHash)
|
||||
var firstChoiceArr, secChoiceArr []string
|
||||
|
||||
if cmp == -1 {
|
||||
firstChoiceArr = strings.Split(theirPrefs, ",")
|
||||
secChoiceArr = strings.Split(myPrefs, ",")
|
||||
} else if cmp == 1 {
|
||||
firstChoiceArr = strings.Split(myPrefs, ",")
|
||||
secChoiceArr = strings.Split(theirPrefs, ",")
|
||||
} else { // Exact same preferences.
|
||||
myPrefsArr := strings.Split(myPrefs, ",")
|
||||
return myPrefsArr[0], nil
|
||||
}
|
||||
|
||||
for _, secChoice := range secChoiceArr {
|
||||
for _, firstChoice := range firstChoiceArr {
|
||||
if firstChoice == secChoice {
|
||||
return firstChoice, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("No algorithms in common!")
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ func TestHandshake(t *testing.T) {
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := Handshake(pa, pb, cha, chb)
|
||||
_, _, err := Handshake(pa, pb, cha, chb)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = Handshake(pb, pa, chb, cha)
|
||||
_, _, err = Handshake(pb, pa, chb, cha)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ It is generated from these files:
|
||||
message.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Identify
|
||||
Hello
|
||||
Exchange
|
||||
*/
|
||||
package identify
|
||||
|
||||
@ -20,29 +21,77 @@ import math "math"
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type Identify struct {
|
||||
Id []byte `protobuf:"bytes,1,req,name=id" json:"id,omitempty"`
|
||||
Pubkey []byte `protobuf:"bytes,2,req,name=pubkey" json:"pubkey,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
type Hello struct {
|
||||
Rand []byte `protobuf:"bytes,1,req,name=rand" json:"rand,omitempty"`
|
||||
Pubkey []byte `protobuf:"bytes,2,req,name=pubkey" json:"pubkey,omitempty"`
|
||||
Exchanges *string `protobuf:"bytes,3,req,name=exchanges" json:"exchanges,omitempty"`
|
||||
Ciphers *string `protobuf:"bytes,4,req,name=ciphers" json:"ciphers,omitempty"`
|
||||
Hashes *string `protobuf:"bytes,5,req,name=hashes" json:"hashes,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Identify) Reset() { *m = Identify{} }
|
||||
func (m *Identify) String() string { return proto.CompactTextString(m) }
|
||||
func (*Identify) ProtoMessage() {}
|
||||
func (m *Hello) Reset() { *m = Hello{} }
|
||||
func (m *Hello) String() string { return proto.CompactTextString(m) }
|
||||
func (*Hello) ProtoMessage() {}
|
||||
|
||||
func (m *Identify) GetId() []byte {
|
||||
func (m *Hello) GetRand() []byte {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
return m.Rand
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Identify) GetPubkey() []byte {
|
||||
func (m *Hello) GetPubkey() []byte {
|
||||
if m != nil {
|
||||
return m.Pubkey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Hello) GetExchanges() string {
|
||||
if m != nil && m.Exchanges != nil {
|
||||
return *m.Exchanges
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Hello) GetCiphers() string {
|
||||
if m != nil && m.Ciphers != nil {
|
||||
return *m.Ciphers
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Hello) GetHashes() string {
|
||||
if m != nil && m.Hashes != nil {
|
||||
return *m.Hashes
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Exchange struct {
|
||||
Epubkey []byte `protobuf:"bytes,1,req,name=epubkey" json:"epubkey,omitempty"`
|
||||
Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Exchange) Reset() { *m = Exchange{} }
|
||||
func (m *Exchange) String() string { return proto.CompactTextString(m) }
|
||||
func (*Exchange) ProtoMessage() {}
|
||||
|
||||
func (m *Exchange) GetEpubkey() []byte {
|
||||
if m != nil {
|
||||
return m.Epubkey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Exchange) GetSignature() []byte {
|
||||
if m != nil {
|
||||
return m.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
package identify;
|
||||
|
||||
message Identify {
|
||||
required bytes id = 1;
|
||||
message Hello {
|
||||
required bytes rand = 1;
|
||||
required bytes pubkey = 2;
|
||||
required string exchanges = 3;
|
||||
required string ciphers = 4;
|
||||
required string hashes = 5;
|
||||
}
|
||||
|
||||
message Exchange {
|
||||
required bytes epubkey = 1;
|
||||
required bytes signature = 2;
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ func (s *Swarm) handleNewConn(nconn net.Conn) {
|
||||
}
|
||||
newConnChans(conn)
|
||||
|
||||
err := ident.Handshake(s.local, p, conn.Incoming.MsgChan, conn.Outgoing.MsgChan)
|
||||
_, _, err := ident.Handshake(s.local, p, conn.Incoming.MsgChan, conn.Outgoing.MsgChan)
|
||||
if err != nil {
|
||||
u.PErr("%v\n", err.Error())
|
||||
conn.Close()
|
||||
@ -420,7 +420,7 @@ func (s *Swarm) GetConnection(id peer.ID, addr *ma.Multiaddr) (*peer.Peer, error
|
||||
|
||||
// Handle performing a handshake on a new connection and ensuring proper forward communication
|
||||
func (s *Swarm) handleDialedCon(conn *Conn) error {
|
||||
err := ident.Handshake(s.local, conn.Peer, conn.Incoming.MsgChan, conn.Outgoing.MsgChan)
|
||||
_, _, err := ident.Handshake(s.local, conn.Peer, conn.Incoming.MsgChan, conn.Outgoing.MsgChan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Reference in New Issue
Block a user