Documentation
¶
Overview ¶
Package stream is a Golang library that transforms any net.Conn or io.ReadWriter stream to an encrypted and/or authenticated stream.
1. The encrypted stream implements net.Conn and io.ReadWriter and can be used as drop-in replacement.
2. Works with any encryption, authentication, or authenticated encryption algorithm or even arbitrary transformation. Only a cipher that implements encrypt/decrypt needs to be provided. XSalsa20-Poly1305 and AES-GCM are provided as reference cipher.
3. The encrypted stream only adds a small constant memory overhead compared to the original stream.
Note: this library does not handle handshake or key exchange. Handshake should be done separately before using this library to compute a shared key.
Example ¶
package main
import (
"crypto/rand"
"net"
stream "github.com/EgeBalci/encrypted-stream"
)
func main() {
// We use a net.Conn as an example.
conn, err := net.Dial("tcp", "golang.org:80")
if err != nil {
panic(err)
}
// In this example we treat key as a prior knowledge. In actual usage you can
// do handshake here using the original stream and compute shared key before
// creating encrypted stream from it.
var key [32]byte
_, err = rand.Read(key[:])
if err != nil {
panic(err)
}
config := &stream.Config{
Cipher: stream.NewXSalsa20Poly1305Cipher(&key),
SequentialNonce: true, // only when key is unique for every stream
Initiator: true, // only on the dialer side
}
// Create an encrypted stream from a conn.
encryptedConn, err := stream.NewEncryptedStream(conn, config)
if err != nil {
panic(err)
}
// Now you can use encryptedConn just like a regular conn
_, err = encryptedConn.Write([]byte("hello world"))
if err != nil {
panic(err)
}
}
Index ¶
- Variables
- type Cipher
- type Config
- type CryptoAEADCipher
- type Decoder
- type Encoder
- type EncryptedStream
- func (es *EncryptedStream) Close() error
- func (es *EncryptedStream) IsClosed() bool
- func (es *EncryptedStream) LocalAddr() net.Addr
- func (es *EncryptedStream) Read(b []byte) (int, error)
- func (es *EncryptedStream) RemoteAddr() net.Addr
- func (es *EncryptedStream) SetDeadline(t time.Time) error
- func (es *EncryptedStream) SetReadDeadline(t time.Time) error
- func (es *EncryptedStream) SetWriteDeadline(t time.Time) error
- func (es *EncryptedStream) Write(b []byte) (int, error)
- type XSalsa20Poly1305Cipher
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMaxNonce indicates the max allowed nonce is reach. If this happends, a // new stream with different key should be created. ErrMaxNonce = errors.New("max nonce reached") // ErrWrongNonceInitiator indicates a nonce with the wrong party is received, // i.e. initiator receives a nonce from initiator, or responder receives a // nonce from responder. It is either a configuration error (e.g. both party // set initiator to the same value), or a middle man is performing reflection // attack. ErrWrongNonceInitiator = errors.New("wrong nonce direction") // ErrWrongNonceSequential indicates a nonce with the wrong value is received. // It is either a configuration error (e.g. one side set sequentialNonce to // true, the other side set to false), or a middle man is performing replay, // re-order or packet drop attack. ErrWrongNonceSequential = errors.New("wrong nonce value") )
Functions ¶
This section is empty.
Types ¶
type Cipher ¶
type Cipher interface {
// Encrypt encrypts a plaintext to ciphertext. Returns ciphertext slice
// whose length should be equal to ciphertext length. Input buffer ciphertext
// has enough length for encrypted plaintext, and the length satisfy:
// len(ciphertext) == MaxChunkSize + MaxOverheadSize
// len(plaintext) <= MaxChunkSize
Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error)
// Decrypt decrypts a ciphertext to plaintext. Returns plaintext slice
// whose length should be equal to plaintext length. Input buffer plaintext
// has enough length for decrypted ciphertext, and the length satisfy:
// len(plaintext) == MaxChunkSize
// len(ciphertext) <= MaxChunkSize + MaxOverheadSize
Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error)
// MaxOverhead is the max number of bytes overhead of ciphertext compared to
// plaintext. It is only used to determine internal buffer size, so
// overestimate is ok.
MaxOverhead() int
// NonceSize is the nonce size in bytes.
NonceSize() int
}
Cipher provides encrypt and decrypt function of a slice data.
type Config ¶
type Config struct {
// Cipher is used to encrypt and decrypt data.
Cipher Cipher
// MaxChunkSize is the max number of bytes that will be encrypted and write to
// underlying stream in a single chunk. If zero, default value (65535) will be
// used.
MaxChunkSize int
// Initiator indicates the direction of the stream (initiator or responder).
// Two sides of the stream should set this to different value (i.e. one stream
// initiator and one stream responder) unless DisableNonceVerification is
// true.
Initiator bool
// Use sequential nonce instead of random nonce to prevent replay, re-order
// and packet drop attack. For cipher with short nonce (e.g. AES-GCM),
// sequential nonce should be used to prevent nonce reuse if large amount of
// data is transmitted in the same stream. Both sides of the stream should set
// this to the same value unless DisableNonceVerification is true. IMPORTANT:
// Enable sequential nonce only when key is unique for every stream, otherwise
// key will be leaked.
SequentialNonce bool
// Disable nonce verification during decryption. Setting this to true will
// make the stream vulnerable to reflection, replay, re-order and packet drop
// attack. Do not set it to true unless you have a strong reason.
DisableNonceVerification bool
}
Config is the configuration for encrypted stream.
func MergeConfig ¶
MergeConfig merges a given config with the default config recursively. Any non zero value fields will override the default config.
type CryptoAEADCipher ¶
type CryptoAEADCipher struct {
// contains filtered or unexported fields
}
CryptoAEADCipher is a wrapper to crypto/cipher AEAD interface and implements Cipher interface.
func NewAESGCMCipher ¶
func NewAESGCMCipher(key []byte) (*CryptoAEADCipher, error)
NewAESGCMCipher creates a 128-bit (16 bytes key) or 256-bit (32 bytes key) AES block cipher wrapped in Galois Counter Mode with the standard nonce length. For best security, every stream should have a unique key.
func NewCryptoAEADCipher ¶
func NewCryptoAEADCipher(aead cipher.AEAD) *CryptoAEADCipher
NewCryptoAEADCipher converts a crypto/cipher AEAD to Cipher.
func (*CryptoAEADCipher) Decrypt ¶
func (c *CryptoAEADCipher) Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error)
Decrypt implements Cipher.
func (*CryptoAEADCipher) Encrypt ¶
func (c *CryptoAEADCipher) Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error)
Encrypt implements Cipher.
func (*CryptoAEADCipher) MaxOverhead ¶
func (c *CryptoAEADCipher) MaxOverhead() int
MaxOverhead implements Cipher.
func (*CryptoAEADCipher) NonceSize ¶
func (c *CryptoAEADCipher) NonceSize() int
NonceSize implements Cipher.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder provides decode function of a slice data.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder provides encode function of a slice data.
func NewEncoder ¶
NewEncoder creates a Encoder with given cipher and config.
type EncryptedStream ¶
type EncryptedStream struct {
// contains filtered or unexported fields
}
EncryptedStream is an encrypted stream. Data are encrypted before writing to underlying stream, and are decrypted after reading from underlying stream.
func NewEncryptedStream ¶
func NewEncryptedStream(stream io.ReadWriter, config *Config) (*EncryptedStream, error)
NewEncryptedStream creates an EncryptedStream with a given ReadWriter and config.
func (*EncryptedStream) Close ¶
func (es *EncryptedStream) Close() error
Close implements net.Conn and io.Closer. Will call underlying stream's Close() method if it has one.
func (*EncryptedStream) IsClosed ¶
func (es *EncryptedStream) IsClosed() bool
IsClosed returns whether the EncryptedStream is closed.
func (*EncryptedStream) LocalAddr ¶
func (es *EncryptedStream) LocalAddr() net.Addr
LocalAddr implements net.Conn. Will call underlying stream's LocalAddr() method if it has one, otherwise will return nil.
func (*EncryptedStream) Read ¶
func (es *EncryptedStream) Read(b []byte) (int, error)
Read implements net.Conn and io.Reader
func (*EncryptedStream) RemoteAddr ¶
func (es *EncryptedStream) RemoteAddr() net.Addr
RemoteAddr implements net.Conn. Will call underlying stream's RemoteAddr() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetDeadline ¶
func (es *EncryptedStream) SetDeadline(t time.Time) error
SetDeadline implements net.Conn. Will call underlying stream's SetDeadline() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetReadDeadline ¶
func (es *EncryptedStream) SetReadDeadline(t time.Time) error
SetReadDeadline implements net.Conn. Will call underlying stream's SetReadDeadline() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetWriteDeadline ¶
func (es *EncryptedStream) SetWriteDeadline(t time.Time) error
SetWriteDeadline implements net.Conn. Will call underlying stream's SetWriteDeadline() method if it has one, otherwise will return nil.
type XSalsa20Poly1305Cipher ¶
type XSalsa20Poly1305Cipher struct {
// contains filtered or unexported fields
}
XSalsa20Poly1305Cipher is an AEAD cipher that uses XSalsa20 and Poly1305 to encrypt and authenticate messages. The ciphertext it produces contains 24 bytes of random nonce, followed by n+16 bytes of authenticated encrypted data, where n is the plaintext size.
func NewXSalsa20Poly1305Cipher ¶
func NewXSalsa20Poly1305Cipher(key *[32]byte) *XSalsa20Poly1305Cipher
NewXSalsa20Poly1305Cipher creates a XSalsa20Poly1305Cipher with a given key. For best security, every stream should have a unique key.
func (*XSalsa20Poly1305Cipher) Decrypt ¶
func (c *XSalsa20Poly1305Cipher) Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error)
Decrypt implements Cipher.
func (*XSalsa20Poly1305Cipher) Encrypt ¶
func (c *XSalsa20Poly1305Cipher) Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error)
Encrypt implements Cipher.
func (*XSalsa20Poly1305Cipher) MaxOverhead ¶
func (c *XSalsa20Poly1305Cipher) MaxOverhead() int
MaxOverhead implements Cipher.
func (*XSalsa20Poly1305Cipher) NonceSize ¶
func (c *XSalsa20Poly1305Cipher) NonceSize() int
NonceSize implements Cipher.