boxconn

package
v0.0.0-...-c6f3048 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2015 License: MIT Imports: 9 Imported by: 0

README

boxconn GoDoc

boxconn adds encryption and authentication to a network connection. It uses the NaCL box library to encrypt messages.

Overview

I wanted something simpler than TLS, but still assymetric. Key distribution is entirely manual: every client / server should have their own set of keys, and their public keys should be added to their corresponding counterpart. For example a server will look like this:

listener, _ := boxconn.Listen("tcp",":5000", serverPrivateKey, serverPublicKey, clientPublicKey)

for {
	conn, _ := listener.Accept()

	...
}

And the client will look like this:

conn, _ := boxconn.Dial("tcp", ":5000", clientPrivateKey, clientPublicKey, serverPublicKey)

If you already have a connection you can use Handshake:

bc, _ := boxconn.Handshake(conn, clientPrivateKey, clientPublicKey, serverPublicKey)

To generate keys use code.google.com/p/go.crypto/nacl/box:

// these are *[32]byte not [32]byte so you'll need to do
//   *clientPrivateKey, *clientPublicKey, *serverPublicKey
publicKey, privateKey, err := box.GenerateKey()

Keys are pretty small and are just byte arrays so you can store / marshal them however you want.

Caveats

  • Although this library is very simple and is built on top of a pretty solid foundation, I'm not entirely sure it's secure. You're probably better off using TLS. But its a bit of a chore to setup everything. You'll need to create a root CA certificate, then sign all your private keys, and enforce verification using TLS config.

  • Then again TLS hasn't had the best track record lately. Major vulnerabilites seem to be discovered about twice a year or so. 1, 2, 3, 4, 4, 5, 6

  • The library encrypts every Write as a separate message. You should probably use buffering on top of the connection (not a terrible idea anyway), or just be careful about not writing super small messages. It will work, and it's still secure, it's just inefficient.

Documentation

Overview

Package boxconn encrypts an underlying network connection using NaCL's box public-key encryption. See https://github.com/badgerodon/net/boxconn for more details.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a secure connection over an underlying net.Conn

func Dial

func Dial(network, address string, privateKey, publicKey [keySize]byte, allowedKeys ...[keySize]byte) (*Conn, error)

Dial connects to the address on the named network. See net.Dial for more details

func Handshake

func Handshake(conn net.Conn, privateKey, publicKey [keySize]byte, allowedKeys ...[keySize]byte) (*Conn, error)

Handshake establishes a session between two parties. Keys can be generated using box.GenerateKeys. allowedKeys is a list of keys which are allowed for the session.

Example
sPub, sPriv, _ := box.GenerateKey(rand.Reader)
cPub, cPriv, _ := box.GenerateKey(rand.Reader)

// server
l, _ := net.Listen("tcp", "127.0.0.1:0")
defer l.Close()
go func() {
	c, _ := l.Accept()
	defer c.Close()

	bc, _ := Handshake(c, *sPriv, *sPub, *cPub)
	msg := make([]byte, 1024)
	n, _ := bc.Read(msg)
	fmt.Println("SERVER:", string(msg[:n]))
	bc.Write([]byte("pong"))
}()

// client
c, _ := net.Dial("tcp", l.Addr().String())
defer c.Close()

bc, _ := Handshake(c, *cPriv, *cPub, *sPub)
bc.Write([]byte("ping"))
msg := make([]byte, 1024)
n, _ := bc.Read(msg)
fmt.Println("CLIENT:", string(msg[:n]))
Output:

SERVER: ping
CLIENT: pong

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection. Any blocked Read or Write operations will be unblocked and return errors.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr returns the local network address.

func (*Conn) Read

func (c *Conn) Read(b []byte) (n int, err error)

Read reads data from the connection. Read can be made to time out and return a Error with Timeout() == true after a fixed time limit; see SetDeadline and SetReadDeadline.

func (*Conn) ReadMessage

func (c *Conn) ReadMessage() (Message, error)

ReadMessage reads a message (nonce, data) from the connection

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr returns the remote network address.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadlines associated with the connection. It is equivalent to calling both SetReadDeadline and SetWriteDeadline.

A deadline is an absolute time after which I/O operations fail with a timeout (see type Error) instead of blocking. The deadline applies to all future I/O, not just the immediately following call to Read or Write.

An idle timeout can be implemented by repeatedly extending the deadline after successful Read or Write calls.

A zero value for t means I/O operations will not time out.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the deadline for future Read calls. A zero value for t means Read will not time out.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the deadline for future Write calls. Even if write times out, it may return n > 0, indicating that some of the data was successfully written. A zero value for t means Write will not time out.

func (*Conn) Write

func (c *Conn) Write(b []byte) (n int, err error)

Write writes data to the connection. Write can be made to time out and return a Error with Timeout() == true after a fixed time limit; see SetDeadline and SetWriteDeadline.

func (*Conn) WriteMessage

func (c *Conn) WriteMessage(msg Message) error

WriteMessage writes a message (nonce, data) to the connection

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

func Listen

func Listen(network, laddr string, privateKey, publicKey [32]byte, allowedKeys ...[32]byte) (*Listener, error)

Listen starts a listener and wraps it in a secure connection. (See net.Listener for details on network and laddr).

func (*Listener) Accept

func (l *Listener) Accept() (net.Conn, error)

Accept waits for and returns the next connection to the listener.

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns the listener's network address.

func (*Listener) Close

func (l *Listener) Close() error

Close closes the listener. Any blocked Accept operations will be unblocked and return errors.

type Message

type Message struct {
	Nonce [nonceSize]byte
	Data  []byte
}

type Protocol

type Protocol struct {
	// contains filtered or unexported fields
}

func NewProtocol

func NewProtocol(r Reader, w Writer) *Protocol

func (*Protocol) Handshake

func (p *Protocol) Handshake(privateKey, publicKey [keySize]byte, allowedKeys ...[keySize]byte) error

Handshake establishes a session between two parties. Keys can be generated using box.GenerateKeys. allowedKeys is a list of keys which are allowed for the session.

func (*Protocol) Read

func (p *Protocol) Read() ([]byte, error)

Read reads a raw message from the reader, then decrypts it

func (*Protocol) ReadRaw

func (p *Protocol) ReadRaw() ([]byte, error)

ReadRaw reads a message from the reader, checks its nonce

value, but does not decrypt it

func (*Protocol) Write

func (p *Protocol) Write(unsealed []byte) error

Write writes the data (sealed) to the writer and increments the nonce

func (*Protocol) WriteRaw

func (p *Protocol) WriteRaw(data []byte) error

WriteRaw writes the data (unsealed) to the writer and increments the nonce

type Reader

type Reader interface {
	ReadMessage() (Message, error)
}

type ReaderFunc

type ReaderFunc func() (Message, error)

func (ReaderFunc) ReadMessage

func (rf ReaderFunc) ReadMessage() (Message, error)

type Writer

type Writer interface {
	WriteMessage(Message) error
}

type WriterFunc

type WriterFunc func(Message) error

func (WriterFunc) WriteMessage

func (wf WriterFunc) WriteMessage(msg Message) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL