Unverified Commit 62b2c6c4 authored by Yusef Napora's avatar Yusef Napora Committed by GitHub

bring back plaintext 2.0.0 with new constructor (#42)

* bring back plaintext 2.0.0 with new constructor

* fix deprecation comment

* rm unused context argument

* only check remote id validity if we actually have keys

* bring back msgio & simultaneous read/write
parent be905198
......@@ -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
......
......@@ -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)
......
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()
}
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
// 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")
)
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;
}
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