Skip to content

Commit

Permalink
Introduce routability and protocol events; cache unmarshalled RSA keys (
Browse files Browse the repository at this point in the history
#105)

* event: Add autonat events (#25)

* add events for identify (#26)

* implement caching for rsaKey.Bytes()

* store marshalled protobuf in cache for RsaPublicKey.Bytes()

* fix(crypto): fix build when openssl is enabled

* add godocs to routability events.

Co-authored-by: Łukasz Magiera <magik6k@users.noreply.github.com>
Co-authored-by: Whyrusleeping <why@ipfs.io>
Co-authored-by: Adin Schmahmann <adin.schmahmann@gmail.com>
Co-authored-by: Steven Allen <steven@stebalien.com>
  • Loading branch information
5 people committed Jan 16, 2020
1 parent ca6e701 commit 628240f
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 12 deletions.
14 changes: 13 additions & 1 deletion core/crypto/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,19 @@ func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) {
return nil, ErrBadKeyType
}

return um(pmes.GetData())
data := pmes.GetData()

pk, err := um(data)
if err != nil {
return nil, err
}

switch tpk := pk.(type) {
case *RsaPublicKey:
tpk.cached, _ = pmes.Marshal()
}

return pk, nil
}

// MarshalPublicKey converts a public key object into a protobuf serialized
Expand Down
2 changes: 1 addition & 1 deletion core/crypto/key_not_openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {

switch p := priv.(type) {
case *rsa.PrivateKey:
return &RsaPrivateKey{*p}, &RsaPublicKey{p.PublicKey}, nil
return &RsaPrivateKey{*p}, &RsaPublicKey{k: p.PublicKey}, nil

case *ecdsa.PrivateKey:
return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil
Expand Down
2 changes: 1 addition & 1 deletion core/crypto/key_openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
return nil, nil, err
}

return &opensslPrivateKey{pk}, &opensslPublicKey{pk}, nil
return &opensslPrivateKey{pk}, &opensslPublicKey{key: pk}, nil

case *ecdsa.PrivateKey:
return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil
Expand Down
17 changes: 14 additions & 3 deletions core/crypto/openssl_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package crypto

import (
"sync"

pb "github.com/libp2p/go-libp2p-core/crypto/pb"

openssl "github.com/libp2p/go-openssl"
Expand All @@ -13,6 +15,9 @@ import (

type opensslPublicKey struct {
key openssl.PublicKey

cacheLk sync.Mutex
cached []byte
}

type opensslPrivateKey struct {
Expand All @@ -32,7 +37,7 @@ func unmarshalOpensslPublicKey(b []byte) (opensslPublicKey, error) {
if err != nil {
return opensslPublicKey{}, err
}
return opensslPublicKey{sk}, nil
return opensslPublicKey{key: sk, cached: b}, nil
}

// Verify compares a signature against input data
Expand All @@ -52,7 +57,13 @@ func (pk *opensslPublicKey) Type() pb.KeyType {

// Bytes returns protobuf bytes of a public key
func (pk *opensslPublicKey) Bytes() ([]byte, error) {
return MarshalPublicKey(pk)
pk.cacheLk.Lock()
var err error
if pk.cached == nil {
pk.cached, err = MarshalPublicKey(pk)
}
pk.cacheLk.Unlock()
return pk.cached, err
}

func (pk *opensslPublicKey) Raw() ([]byte, error) {
Expand All @@ -76,7 +87,7 @@ func (sk *opensslPrivateKey) Sign(message []byte) ([]byte, error) {

// GetPublic returns a public key
func (sk *opensslPrivateKey) GetPublic() PubKey {
return &opensslPublicKey{sk.key}
return &opensslPublicKey{key: sk.key}
}

func (sk *opensslPrivateKey) Type() pb.KeyType {
Expand Down
19 changes: 15 additions & 4 deletions core/crypto/rsa_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"crypto/x509"
"errors"
"io"
"sync"

pb "github.com/libp2p/go-libp2p-core/crypto/pb"

Expand All @@ -23,6 +24,9 @@ type RsaPrivateKey struct {
// RsaPublicKey is an rsa public key
type RsaPublicKey struct {
k rsa.PublicKey

cacheLk sync.Mutex
cached []byte
}

// GenerateRSAKeyPair generates a new rsa private and public key
Expand All @@ -35,7 +39,7 @@ func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
return nil, nil, err
}
pk := priv.PublicKey
return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{pk}, nil
return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{k: pk}, nil
}

// Verify compares a signature against input data
Expand All @@ -54,7 +58,13 @@ func (pk *RsaPublicKey) Type() pb.KeyType {

// Bytes returns protobuf bytes of a public key
func (pk *RsaPublicKey) Bytes() ([]byte, error) {
return MarshalPublicKey(pk)
pk.cacheLk.Lock()
var err error
if pk.cached == nil {
pk.cached, err = MarshalPublicKey(pk)
}
pk.cacheLk.Unlock()
return pk.cached, err
}

func (pk *RsaPublicKey) Raw() ([]byte, error) {
Expand All @@ -80,7 +90,7 @@ func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) {

// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
return &RsaPublicKey{sk.sk.PublicKey}
return &RsaPublicKey{k: sk.sk.PublicKey}
}

func (sk *RsaPrivateKey) Type() pb.KeyType {
Expand Down Expand Up @@ -137,5 +147,6 @@ func UnmarshalRsaPublicKey(b []byte) (PubKey, error) {
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
return &RsaPublicKey{*pk}, nil

return &RsaPublicKey{k: *pk}, nil
}
4 changes: 2 additions & 2 deletions core/crypto/rsa_openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ func GenerateRSAKeyPair(bits int, _ io.Reader) (PrivKey, PubKey, error) {
if err != nil {
return nil, nil, err
}
return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key}}, nil
return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key: key}}, nil
}

// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
return &RsaPublicKey{opensslPublicKey{sk.opensslPrivateKey.key}}
return &RsaPublicKey{opensslPublicKey{key: sk.opensslPrivateKey.key}}
}

// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
Expand Down
17 changes: 17 additions & 0 deletions core/event/identify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package event

import "github.com/libp2p/go-libp2p-core/peer"

// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
type EvtPeerIdentificationCompleted struct {
// Peer is the ID of the peer whose identification succeeded.
Peer peer.ID
}

// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
type EvtPeerIdentificationFailed struct {
// Peer is the ID of the peer whose identification failed.
Peer peer.ID
// Reason is the reason why identification failed.
Reason error
}
21 changes: 21 additions & 0 deletions core/event/routability.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package event

// EvtLocalRoutabilityPrivate is an event struct to be emitted with the local's
// node routability changes to PRIVATE (i.e. not routable from the Internet).
//
// This event is usually emitted by the AutoNAT subsystem.
type EvtLocalRoutabilityPrivate struct{}

// EvtLocalRoutabilityPublic is an event struct to be emitted with the local's
// node routability changes to PUBLIC (i.e. appear to routable from the
// Internet).
//
// This event is usually emitted by the AutoNAT subsystem.
type EvtLocalRoutabilityPublic struct{}

// EvtLocalRoutabilityUnknown is an event struct to be emitted with the local's
// node routability changes to UNKNOWN (i.e. we were unable to make a
// determination about our NAT status with enough confidence).
//
// This event is usually emitted by the AutoNAT subsystem.
type EvtLocalRoutabilityUnknown struct{}

0 comments on commit 628240f

Please sign in to comment.