diff --git a/core/crypto/key.go b/core/crypto/key.go index cb8e77858..bc0026eb2 100644 --- a/core/crypto/key.go +++ b/core/crypto/key.go @@ -279,6 +279,12 @@ func UnmarshalPublicKey(data []byte) (PubKey, error) { return nil, err } + return PublicKeyFromProto(pmes) +} + +// PublicKeyFromProto converts an unserialized protobuf PublicKey message +// into its representative object. +func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) { um, ok := PubKeyUnmarshallers[pmes.GetType()] if !ok { return nil, ErrBadKeyType @@ -290,6 +296,17 @@ func UnmarshalPublicKey(data []byte) (PubKey, error) { // MarshalPublicKey converts a public key object into a protobuf serialized // public key func MarshalPublicKey(k PubKey) ([]byte, error) { + pbmes, err := PublicKeyToProto(k) + if err != nil { + return nil, err + } + + return proto.Marshal(pbmes) +} + +// PublicKeyToProto converts a public key object into an unserialized +// protobuf PublicKey message. +func PublicKeyToProto(k PubKey) (*pb.PublicKey, error) { pbmes := new(pb.PublicKey) pbmes.Type = k.Type() data, err := k.Raw() @@ -297,8 +314,7 @@ func MarshalPublicKey(k PubKey) ([]byte, error) { return nil, err } pbmes.Data = data - - return proto.Marshal(pbmes) + return pbmes, nil } // UnmarshalPrivateKey converts a protobuf serialized private key into its diff --git a/core/sec/insecure/insecure.go b/core/sec/insecure/insecure.go index 801569cb0..e3670c222 100644 --- a/core/sec/insecure/insecure.go +++ b/core/sec/insecure/insecure.go @@ -5,64 +5,207 @@ package insecure import ( "context" + "fmt" "net" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-msgio" ci "github.com/libp2p/go-libp2p-core/crypto" + pb "github.com/libp2p/go-libp2p-core/sec/insecure/pb" ) // ID is the multistream-select protocol ID that should be used when identifying // this security transport. -const ID = "/plaintext/1.0.0" +const ID = "/plaintext/2.0.0" // Transport is a no-op stream security transport. It provides no -// security and simply mocks the security and identity methods to -// return peer IDs known ahead of time. +// security and simply mocks the security methods. Identity methods +// return the local peer's ID and private key, and whatever the remote +// peer presents as their ID and public key. +// No authentication of the remote identity is performed. type Transport struct { - id peer.ID + id peer.ID + key ci.PrivKey } // New constructs a new insecure transport. +// Deprecated: use NewWithIdentity instead. func New(id peer.ID) *Transport { return &Transport{ id: id, } } -// LocalPeer returns the transports local peer ID. +// New constructs a new insecure transport. The provided private key +// is stored and returned from LocalPrivateKey to satisfy the +// SecureTransport interface, and the public key is sent to +// remote peers. No security is provided. +func NewWithIdentity(id peer.ID, key ci.PrivKey) *Transport { + return &Transport{ + id: id, + key: key, + } +} + +// LocalPeer returns the transport's local peer ID. func (t *Transport) LocalPeer() peer.ID { return t.id } -// LocalPrivateKey returns nil. This transport is not secure. +// LocalPrivateKey returns the local private key. +// This key is used only for identity generation and provides no security. func (t *Transport) LocalPrivateKey() ci.PrivKey { - return nil + return t.key } // SecureInbound *pretends to secure* an outbound connection to the given peer. +// It sends the local peer's ID and public key, and receives the same from the remote peer. +// No validation is performed as to the authenticity or ownership of the provided public key, +// and the key exchange provides no security. +// +// SecureInbound may fail if the remote peer sends an ID and public key that are inconsistent +// with each other, or if a network error occurs during the ID exchange. func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { - return &Conn{ - Conn: insecure, - local: t.id, - }, nil + conn := &Conn{ + Conn: insecure, + local: t.id, + localPrivKey: t.key, + } + + err := conn.runHandshakeSync() + if err != nil { + return nil, err + } + + return conn, nil } // SecureOutbound *pretends to secure* an outbound connection to the given peer. +// It sends the local peer's ID and public key, and receives the same from the remote peer. +// No validation is performed as to the authenticity or ownership of the provided public key, +// and the key exchange provides no security. +// +// SecureOutbound may fail if the remote peer sends an ID and public key that are inconsistent +// with each other, or if the ID sent by the remote peer does not match the one dialed. It may +// also fail if a network error occurs during the ID exchange. func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { - return &Conn{ - Conn: insecure, - local: t.id, - remote: p, - }, nil + conn := &Conn{ + Conn: insecure, + local: t.id, + localPrivKey: t.key, + } + + err := conn.runHandshakeSync() + if err != nil { + return nil, err + } + + if t.key != nil && p != conn.remote { + return nil, fmt.Errorf("remote peer sent unexpected peer ID. expected=%s received=%s", + p, conn.remote) + } + + return conn, nil } // Conn is the connection type returned by the insecure transport. type Conn struct { net.Conn + local peer.ID remote peer.ID + + localPrivKey ci.PrivKey + remotePubKey ci.PubKey +} + +func makeExchangeMessage(pubkey ci.PubKey) (*pb.Exchange, error) { + keyMsg, err := ci.PublicKeyToProto(pubkey) + if err != nil { + return nil, err + } + id, err := peer.IDFromPublicKey(pubkey) + if err != nil { + return nil, err + } + + return &pb.Exchange{ + Id: []byte(id), + Pubkey: keyMsg, + }, nil +} + +func (ic *Conn) runHandshakeSync() error { + // If we were initialized without keys, behave as in plaintext/1.0.0 (do nothing) + if ic.localPrivKey == nil { + return nil + } + + rw := msgio.NewReadWriter(ic.Conn) + // Generate an Exchange message + msg, err := makeExchangeMessage(ic.localPrivKey.GetPublic()) + if err != nil { + return err + } + + // Send our Exchange and read theirs + remoteMsg, err := readWriteMsg(rw, msg) + if err != nil { + return err + } + + // Pull remote ID and public key from message + remotePubkey, err := ci.PublicKeyFromProto(remoteMsg.Pubkey) + if err != nil { + return err + } + + remoteID, err := peer.IDFromPublicKey(remotePubkey) + if err != nil { + return err + } + + // Validate that ID matches public key + if !remoteID.MatchesPublicKey(remotePubkey) { + calculatedID, _ := peer.IDFromPublicKey(remotePubkey) + return fmt.Errorf("remote peer id does not match public key. id=%s calculated_id=%s", + remoteID, calculatedID) + } + + // Add remote ID and key to conn state + ic.remotePubKey = remotePubkey + ic.remote = remoteID + return nil +} + +// read and write a message at the same time. +func readWriteMsg(c msgio.ReadWriter, out *pb.Exchange) (*pb.Exchange, error) { + outBytes, err := out.Marshal() + if err != nil { + return nil, err + } + wresult := make(chan error) + go func() { + wresult <- c.WriteMsg(outBytes) + }() + + msg, err1 := c.ReadMsg() + + // Always wait for the read to finish. + err2 := <-wresult + + if err1 != nil { + return nil, err1 + } + if err2 != nil { + c.ReleaseMsg(msg) + return nil, err2 + } + inMsg := new(pb.Exchange) + err = inMsg.Unmarshal(msg) + return inMsg, err } // LocalPeer returns the local peer ID. @@ -76,14 +219,15 @@ func (ic *Conn) RemotePeer() peer.ID { return ic.remote } -// RemotePublicKey returns nil. This connection is not secure +// RemotePublicKey returns whatever public key was given by the remote peer. +// Note that no verification of ownership is done, as this connection is not secure. func (ic *Conn) RemotePublicKey() ci.PubKey { - return nil + return ic.remotePubKey } -// LocalPrivateKey returns nil. This connection is not secure. +// LocalPrivateKey returns the private key for the local peer. func (ic *Conn) LocalPrivateKey() ci.PrivKey { - return nil + return ic.localPrivKey } var _ sec.SecureTransport = (*Transport)(nil) diff --git a/core/sec/insecure/insecure_test.go b/core/sec/insecure/insecure_test.go new file mode 100644 index 000000000..a8b86f16c --- /dev/null +++ b/core/sec/insecure/insecure_test.go @@ -0,0 +1,157 @@ +package insecure + +import ( + "bytes" + "context" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" + "io" + "net" + "testing" + + ci "github.com/libp2p/go-libp2p-core/crypto" +) + +// Run a set of sessions through the session setup and verification. +func TestConnections(t *testing.T) { + clientTpt := newTestTransport(t, ci.RSA, 1024) + serverTpt := newTestTransport(t, ci.Ed25519, 1024) + + testConnection(t, clientTpt, serverTpt) +} + +func newTestTransport(t *testing.T, typ, bits int) *Transport { + priv, pub, err := ci.GenerateKeyPair(typ, bits) + if err != nil { + t.Fatal(err) + } + id, err := peer.IDFromPublicKey(pub) + if err != nil { + t.Fatal(err) + } + + return NewWithIdentity(id, priv) +} + +// Create a new pair of connected TCP sockets. +func newConnPair(t *testing.T) (net.Conn, net.Conn) { + lstnr, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatalf("Failed to listen: %v", err) + return nil, nil + } + + var clientErr error + var client net.Conn + addr := lstnr.Addr() + done := make(chan struct{}) + + go func() { + defer close(done) + client, clientErr = net.Dial(addr.Network(), addr.String()) + }() + + server, err := lstnr.Accept() + <-done + + lstnr.Close() + + if err != nil { + t.Fatalf("Failed to accept: %v", err) + } + + if clientErr != nil { + t.Fatalf("Failed to connect: %v", clientErr) + } + + return client, server +} + +// Create a new pair of connected sessions based off of the provided +// session generators. +func connect(t *testing.T, clientTpt, serverTpt *Transport) (sec.SecureConn, sec.SecureConn) { + client, server := newConnPair(t) + + // Connect the client and server sessions + done := make(chan struct{}) + + var clientConn sec.SecureConn + var clientErr error + go func() { + defer close(done) + clientConn, clientErr = clientTpt.SecureOutbound(context.TODO(), client, serverTpt.LocalPeer()) + }() + + serverConn, serverErr := serverTpt.SecureInbound(context.TODO(), server) + <-done + + if serverErr != nil { + t.Fatal(serverErr) + } + + if clientErr != nil { + t.Fatal(clientErr) + } + + return clientConn, serverConn +} + +// Check the peer IDs +func testIDs(t *testing.T, clientTpt, serverTpt *Transport, clientConn, serverConn sec.SecureConn) { + if clientConn.LocalPeer() != clientTpt.LocalPeer() { + t.Fatal("Client Local Peer ID mismatch.") + } + + if clientConn.RemotePeer() != serverTpt.LocalPeer() { + t.Fatal("Client Remote Peer ID mismatch.") + } + + if clientConn.LocalPeer() != serverConn.RemotePeer() { + t.Fatal("Server Local Peer ID mismatch.") + } +} + +// Check the keys +func testKeys(t *testing.T, clientTpt, serverTpt *Transport, clientConn, serverConn sec.SecureConn) { + sk := serverConn.LocalPrivateKey() + pk := sk.GetPublic() + + if !sk.Equals(serverTpt.LocalPrivateKey()) { + t.Error("Private key Mismatch.") + } + + if !pk.Equals(clientConn.RemotePublicKey()) { + t.Error("Public key mismatch.") + } +} + +// Check sending and receiving messages +func testReadWrite(t *testing.T, clientConn, serverConn sec.SecureConn) { + before := []byte("hello world") + _, err := clientConn.Write(before) + if err != nil { + t.Fatal(err) + } + + after := make([]byte, len(before)) + _, err = io.ReadFull(serverConn, after) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(before, after) { + t.Errorf("Message mismatch. %v != %v", before, after) + } +} + +// Setup a new session with a pair of locally connected sockets +func testConnection(t *testing.T, clientTpt, serverTpt *Transport) { + clientConn, serverConn := connect(t, clientTpt, serverTpt) + + testIDs(t, clientTpt, serverTpt, clientConn, serverConn) + testKeys(t, clientTpt, serverTpt, clientConn, serverConn) + testReadWrite(t, clientConn, serverConn) + + clientConn.Close() + serverConn.Close() +} diff --git a/core/sec/insecure/pb/Makefile b/core/sec/insecure/pb/Makefile new file mode 100644 index 000000000..4fb825a4b --- /dev/null +++ b/core/sec/insecure/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:../../../crypto/pb:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/core/sec/insecure/pb/plaintext.pb.go b/core/sec/insecure/pb/plaintext.pb.go new file mode 100644 index 000000000..68b12f0c8 --- /dev/null +++ b/core/sec/insecure/pb/plaintext.pb.go @@ -0,0 +1,404 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: plaintext.proto + +package plaintext_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + io "io" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Exchange struct { + Id []byte `protobuf:"bytes,1,opt,name=id" json:"id"` + Pubkey *pb.PublicKey `protobuf:"bytes,2,opt,name=pubkey" json:"pubkey,omitempty"` +} + +func (m *Exchange) Reset() { *m = Exchange{} } +func (m *Exchange) String() string { return proto.CompactTextString(m) } +func (*Exchange) ProtoMessage() {} +func (*Exchange) Descriptor() ([]byte, []int) { + return fileDescriptor_aba144f73931b711, []int{0} +} +func (m *Exchange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Exchange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Exchange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Exchange) XXX_Merge(src proto.Message) { + xxx_messageInfo_Exchange.Merge(m, src) +} +func (m *Exchange) XXX_Size() int { + return m.Size() +} +func (m *Exchange) XXX_DiscardUnknown() { + xxx_messageInfo_Exchange.DiscardUnknown(m) +} + +var xxx_messageInfo_Exchange proto.InternalMessageInfo + +func (m *Exchange) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Exchange) GetPubkey() *pb.PublicKey { + if m != nil { + return m.Pubkey + } + return nil +} + +func init() { + proto.RegisterType((*Exchange)(nil), "plaintext.pb.Exchange") +} + +func init() { proto.RegisterFile("plaintext.proto", fileDescriptor_aba144f73931b711) } + +var fileDescriptor_aba144f73931b711 = []byte{ + // 187 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc8, 0x49, 0xcc, + 0xcc, 0x2b, 0x49, 0xad, 0x28, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x12, 0x48, + 0x92, 0x32, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xc9, 0x4c, + 0x2a, 0x30, 0x2a, 0xd0, 0x4f, 0xcf, 0xd7, 0x85, 0xb0, 0x74, 0x93, 0xf3, 0x8b, 0x52, 0xf5, 0x93, + 0x8b, 0x2a, 0x0b, 0x4a, 0xf2, 0xf5, 0x0b, 0x92, 0xa0, 0x2c, 0x88, 0x31, 0x4a, 0x7e, 0x5c, 0x1c, + 0xae, 0x15, 0xc9, 0x19, 0x89, 0x79, 0xe9, 0xa9, 0x42, 0x22, 0x5c, 0x4c, 0x99, 0x29, 0x12, 0x8c, + 0x0a, 0x8c, 0x1a, 0x3c, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x31, 0x65, 0xa6, 0x08, 0xe9, + 0x70, 0xb1, 0x15, 0x94, 0x26, 0x65, 0xa7, 0x56, 0x4a, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x1b, 0x89, + 0xe8, 0xc1, 0x0c, 0x48, 0xd2, 0x0b, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xf6, 0x4e, 0xad, 0x0c, 0x82, + 0xaa, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, + 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x06, 0x40, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x40, 0xde, 0x90, 0x0b, 0xc2, 0x00, 0x00, 0x00, +} + +func (m *Exchange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Exchange) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPlaintext(dAtA, i, uint64(len(m.Id))) + i += copy(dAtA[i:], m.Id) + } + if m.Pubkey != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintPlaintext(dAtA, i, uint64(m.Pubkey.Size())) + n1, err := m.Pubkey.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + return i, nil +} + +func encodeVarintPlaintext(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Exchange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = len(m.Id) + n += 1 + l + sovPlaintext(uint64(l)) + } + if m.Pubkey != nil { + l = m.Pubkey.Size() + n += 1 + l + sovPlaintext(uint64(l)) + } + return n +} + +func sovPlaintext(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPlaintext(x uint64) (n int) { + return sovPlaintext(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Exchange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Exchange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Exchange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlaintext + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlaintext + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlaintext + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlaintext + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pubkey == nil { + m.Pubkey = &pb.PublicKey{} + } + if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlaintext(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPlaintext + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPlaintext + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPlaintext(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPlaintext + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthPlaintext + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipPlaintext(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthPlaintext + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthPlaintext = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPlaintext = fmt.Errorf("proto: integer overflow") +) diff --git a/core/sec/insecure/pb/plaintext.proto b/core/sec/insecure/pb/plaintext.proto new file mode 100644 index 000000000..1e299df58 --- /dev/null +++ b/core/sec/insecure/pb/plaintext.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package plaintext.pb; + +import "github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto"; + +message Exchange { + optional bytes id = 1; + optional crypto.pb.PublicKey pubkey = 2; +}