noise

package module
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2020 License: BSD-3-Clause Imports: 20 Imported by: 0

README

noise GoDoc Build Status

This is a Go package that implements the Noise Protocol Framework. See the documentation for usage information.

Documentation

Overview

The concept of identities allows you to amend the static public key (as defined in noiseprotocol) with additional metadata, effectively creating a certificate (if the combination if metadata and public is signed by trusted party). The downside of this approach is, that the private key, which the static public key is derived from needs to reside in memory (at least for now), because we will perform DH operations on it. So if you want to use certificates with private keys stored in TPMs, TEEs etc. this approach is not for you (for now).

Package noise implements the Noise Protocol Framework.

Noise is a low-level framework for building crypto protocols. Noise protocols support mutual and optional authentication, identity hiding, forward secrecy, zero round-trip encryption, and other advanced features. For more details, visit https://noiseprotocol.org.

Index

Constants

View Source
const MaxMsgLen = 65535

MaxMsgLen is the maximum number of bytes that can be sent in a single Noise message.

Variables

View Source
var ErrShortMessage = errors.New("noise: message is too short")

ErrShortMessage is returned by ReadMessage if a message is not as long as it should be.

View Source
var HandshakeK = HandshakePattern{
	Name:                 "K",
	InitiatorPreMessages: []MessagePattern{MessagePatternS},
	ResponderPreMessages: []MessagePattern{MessagePatternS},
	Messages: [][]MessagePattern{
		{MessagePatternE, MessagePatternDHES, MessagePatternDHSS},
	},
}
View Source
var HandshakeKN = HandshakePattern{
	Name:                 "KN",
	InitiatorPreMessages: []MessagePattern{MessagePatternS},
	Messages: [][]MessagePattern{
		{MessagePatternE},
		{MessagePatternE, MessagePatternDHEE, MessagePatternDHSE},
	},
}
View Source
var HandshakeN = HandshakePattern{
	Name:                 "N",
	ResponderPreMessages: []MessagePattern{MessagePatternS},
	Messages: [][]MessagePattern{
		{MessagePatternE, MessagePatternDHES},
	},
}
View Source
var HandshakeNK = HandshakePattern{
	Name:                 "NK",
	ResponderPreMessages: []MessagePattern{MessagePatternS},
	Messages: [][]MessagePattern{
		{MessagePatternE, MessagePatternDHES},
		{MessagePatternE, MessagePatternDHEE},
	},
}
View Source
var HandshakeNN = HandshakePattern{
	Name: "NN",
	Messages: [][]MessagePattern{
		{MessagePatternE},
		{MessagePatternE, MessagePatternDHEE},
	},
}
View Source
var HandshakeX = HandshakePattern{
	Name:                 "X",
	ResponderPreMessages: []MessagePattern{MessagePatternS},
	Messages: [][]MessagePattern{
		{MessagePatternE, MessagePatternDHES, MessagePatternS, MessagePatternDHSS},
	},
}
View Source
var HandshakeXXfallback = HandshakePattern{
	Name:                 "XXfallback",
	ResponderPreMessages: []MessagePattern{MessagePatternE},
	Messages: [][]MessagePattern{
		{MessagePatternE, MessagePatternDHEE, MessagePatternS, MessagePatternDHSE},
		{MessagePatternS, MessagePatternDHES},
	},
}

Functions

This section is empty.

Types

type Cipher

type Cipher interface {
	// Encrypt encrypts the provided plaintext with a nonce and then appends the
	// ciphertext to out along with an authentication tag over the ciphertext
	// and optional authenticated data.
	Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte

	// Decrypt authenticates the ciphertext and optional authenticated data and
	// then decrypts the provided ciphertext using the provided nonce and
	// appends it to out.
	Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error)
}

A Cipher is a AEAD cipher that has been initialized with a key.

type CipherFunc

type CipherFunc interface {
	// Cipher initializes the algorithm with the provided key and returns a Cipher.
	Cipher(k [32]byte) Cipher

	// CipherName is the name of the cipher.
	CipherName() string
}

A CipherFunc implements an AEAD symmetric cipher.

var CipherAESGCM CipherFunc = cipherFn{cipherAESGCM, "AESGCM"}

CipherAESGCM is the AES256-GCM AEAD cipher.

var CipherChaChaPoly CipherFunc = cipherFn{cipherChaChaPoly, "ChaChaPoly"}

CipherChaChaPoly is the ChaCha20-Poly1305 AEAD cipher construction.

type CipherState

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

A CipherState provides symmetric encryption and decryption after a successful handshake.

func (*CipherState) Cipher

func (s *CipherState) Cipher() Cipher

Cipher returns the low-level symmetric encryption primitive. It should only be used if nonces need to be managed manually, for example with a network protocol that can deliver out-of-order messages. This is dangerous, users must ensure that they are incrementing a nonce after every encrypt operation. After calling this method, it is an error to call Encrypt/Decrypt on the CipherState.

func (*CipherState) Decrypt

func (s *CipherState) Decrypt(out, ad, ciphertext []byte) ([]byte, error)

Decrypt checks the authenticity of the ciphertext and authenticated data and then decrypts and appends the plaintext to out. This method automatically increments the nonce after every call, messages must be provided in the same order that they were encrypted with no missing messages.

func (*CipherState) Encrypt

func (s *CipherState) Encrypt(out, ad, plaintext []byte) []byte

Encrypt encrypts the plaintext and then appends the ciphertext and an authentication tag across the ciphertext and optional authenticated data to out. This method automatically increments the nonce after every call, so messages must be decrypted in the same order.

func (*CipherState) Rekey

func (s *CipherState) Rekey()

type CipherSuite

type CipherSuite interface {
	DHFunc
	CipherFunc
	HashFunc
	Name() []byte
}

A CipherSuite is a set of cryptographic primitives used in a Noise protocol. It should be constructed with NewCipherSuite.

func NewCipherSuite

func NewCipherSuite(dh DHFunc, c CipherFunc, h HashFunc) CipherSuite

NewCipherSuite returns a CipherSuite constructed from the specified primitives.

type Config

type Config struct {
	// CipherSuite is the set of cryptographic primitives that will be used.
	CipherSuite CipherSuite

	// Random is the source for cryptographically appropriate random bytes. If
	// zero, it is automatically configured.
	Random io.Reader

	// Pattern is the pattern for the handshake.
	Pattern HandshakePattern

	// Initiator must be true if the first message in the handshake will be sent
	// by this peer.
	Initiator bool

	// Prologue is an optional message that has already be communicated and must
	// be identical on both sides for the handshake to succeed.
	Prologue []byte

	// PresharedKey is the optional preshared key for the handshake.
	PresharedKey []byte

	// PresharedKeyPlacement specifies the placement position of the PSK token
	// when PresharedKey is specified
	PresharedKeyPlacement int

	// StaticKeypair is this peer's static keypair, required if part of the
	// handshake.
	StaticKeypair PrivateIdentity

	// EphemeralKeypair is this peer's ephemeral keypair that was provided as
	// a pre-message in the handshake.
	EphemeralKeypair DHKey

	// PeerStatic is the static public key of the remote peer that was provided
	// as a pre-message in the handshake.
	PeerStatic Identity

	// PeerEphemeral is the ephemeral public key of the remote peer that was
	// provided as a pre-message in the handshake.
	PeerEphemeral []byte

	// IdMarshaller allows you to use more complex IDs than plain public keys, i.e. certificates.
	// This parameter is optional.
	IDMarshaler IdentityMarshaler

	// IDVerifier can optionally be set to verify the remote identity.
	IDVerifier IdentityVerifier
}

A Config provides the details necessary to process a Noise handshake. It is never modified by this package, and can be reused.

type DHFunc

type DHFunc interface {
	// GenerateKeypair generates a new keypair using random as a source of
	// entropy.
	GenerateKeypair(random io.Reader) (DHKey, error)

	// DH performs a Diffie-Hellman calculation between the provided private and
	// public keys and returns the result.
	DH(privkey, pubkey []byte) []byte

	// DHLen is the number of bytes returned by DH.
	DHLen() int

	// DHName is the name of the DH function.
	DHName() string
}

A DHFunc implements Diffie-Hellman key agreement.

var DH25519 DHFunc = dh25519{}

DH25519 is the Curve25519 ECDH function.

type DHKey

type DHKey struct {
	Private []byte
	Public  []byte
}

A DHKey is a keypair used for Diffie-Hellman key agreement.

func (DHKey) PrivateKey

func (d DHKey) PrivateKey() []byte

PrivateKey returns the private key part of DHKey

func (DHKey) PublicKey

func (d DHKey) PublicKey() []byte

PublicKey gives you the static public key of DHKey which is used as PrivateIdentity here

type HandshakePattern

type HandshakePattern struct {
	Name                 string
	InitiatorPreMessages []MessagePattern
	ResponderPreMessages []MessagePattern
	Messages             [][]MessagePattern
}

A HandshakePattern is a list of messages and operations that are used to perform a specific Noise handshake.

type HandshakeState

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

A HandshakeState tracks the state of a Noise handshake. It may be discarded after the handshake is complete.

func NewHandshakeState

func NewHandshakeState(c Config) (*HandshakeState, error)

NewHandshakeState starts a new handshake using the provided configuration.

func NewSmolHandshakeState added in v0.1.5

func NewSmolHandshakeState(c Config, rootCerts ...*smolcert.Certificate) (*HandshakeState, error)

func (*HandshakeState) ChannelBinding

func (s *HandshakeState) ChannelBinding() []byte

ChannelBinding provides a value that uniquely identifies the session and can be used as a channel binding. It is an error to call this method before the handshake is complete.

func (*HandshakeState) LocalEphemeral

func (s *HandshakeState) LocalEphemeral() DHKey

LocalEphemeral returns the local ephemeral key pair generated during a handshake.

func (*HandshakeState) MessageIndex

func (s *HandshakeState) MessageIndex() int

MessageIndex returns the current handshake message id

func (*HandshakeState) PeerEphemeral

func (s *HandshakeState) PeerEphemeral() []byte

PeerEphemeral returns the ephemeral key provided by the remote peer during a handshake. It is an error to call this method if a handshake message containing a static key has not been read.

func (*HandshakeState) PeerIdentity

func (s *HandshakeState) PeerIdentity() Identity

PeerIdentity returns the static identity provided by the remote peer during a handshake. It is an error to call this method if a handshake message containing the static identity has not been read.

func (*HandshakeState) ReadMessage

func (s *HandshakeState) ReadMessage(out []byte, message ReadableHandshakeMessage) ([]byte, *CipherState, *CipherState, error)

ReadMessage processes a received handshake message and appends the payload, if any to out. If the handshake is completed by the call, two CipherStates will be returned, one is used for encryption of messages to the remote peer, the other is used for decryption of messages from the remote peer. It is an error to call this method out of sync with the handshake pattern.

func (*HandshakeState) WriteMessage

func (s *HandshakeState) WriteMessage(out WriteableHandshakeMessage, payload []byte) (*CipherState, *CipherState, error)

WriteMessage appends a handshake message to out. The message will include the optional payload if provided. If the handshake is completed by the call, two CipherStates will be returned, one is used for encryption of messages to the remote peer, the other is used for decryption of messages from the remote peer. It is an error to call this method out of sync with the handshake pattern.

type HashFunc

type HashFunc interface {
	// Hash returns a hash state.
	Hash() hash.Hash

	// HashName is the name of the hash function.
	HashName() string
}

A HashFunc implements a cryptographic hash function.

var HashBLAKE2b HashFunc = hashFn{blake2bNew, "BLAKE2b"}

HashBLAKE2b is the BLAKE2b hash function.

var HashBLAKE2s HashFunc = hashFn{blake2sNew, "BLAKE2s"}

HashBLAKE2s is the BLAKE2s hash function.

var HashSHA256 HashFunc = hashFn{sha256.New, "SHA256"}

HashSHA256 is the SHA-256 hash function.

var HashSHA512 HashFunc = hashFn{sha512.New, "SHA512"}

HashSHA512 is the SHA-512 hash function.

type Identity

type Identity interface {
	PublicKey() []byte
}

Identity is an interface which provides the public key of a static identity to the HandshakeState

type IdentityMarshaler

type IdentityMarshaler interface {
	UnmarshalIdentity(identityBytes []byte) (Identity, error)

	MarshalIdentity(identity Identity) ([]byte, error)
}

IdentityMarshaler provides the HandshakeState with the ability to marshal und unmarshal identities from byte slices, enabling the use of certificates instead of plain public keys

type IdentityVerifier

type IdentityVerifier interface {
	VerifyIdentity(id Identity) error
}

IdentityVerifier can be used by a HandshakeState to verify the remote identity fulfills certain criteria (i.e. signed by common authority etc.)

type MessagePattern

type MessagePattern int

A MessagePattern is a single message or operation used in a Noise handshake.

const (
	// MessagePatternS Appends EncryptAndHash(s.public_key) to the buffer.
	//
	// Sets temp to the next DHLEN + 16 bytes of the message if HasKey() == True, or to the next DHLEN bytes otherwise. Sets rs (which must be empty) to DecryptAndHash(temp).
	MessagePatternS MessagePattern = iota
	// MessagePatternE Sets e (which must be empty) to GENERATE_KEYPAIR().
	// Appends e.public_key to the buffer. Calls MixHash(e.public_key)
	//
	// Sets re (which must be empty) to the next DHLEN bytes from the message. Calls MixHash(re.public_key).
	MessagePatternE
	// MessagePatternDHEE Calls MixKey(DH(e, re)).
	//
	// Calls MixKey(DH(e, re)).
	MessagePatternDHEE
	// MessagePatternDHES Calls MixKey(DH(e, rs)) if initiator, MixKey(DH(s, re)) if responder.
	//
	// Calls MixKey(DH(e, rs)) if initiator, MixKey(DH(s, re)) if responder.
	MessagePatternDHES
	// MessagePatternDHSE Calls MixKey(DH(s, re)) if initiator, MixKey(DH(e, rs)) if responder.
	//
	// Calls MixKey(DH(s, re)) if initiator, MixKey(DH(e, rs)) if responder.
	MessagePatternDHSE
	// MessagePatternDHSS Calls MixKey(DH(s, rs)).
	//
	// Calls MixKey(DH(s, rs)).
	MessagePatternDHSS
	// MessagePatternPSK for PresharedKey
	MessagePatternPSK
)

type PrivateIdentity

type PrivateIdentity interface {
	Identity
	PrivateKey() []byte
}

PrivateIdentity is an Identity with access to the private key

type PrivateSmolIdentity added in v0.1.5

type PrivateSmolIdentity struct {
	SmolIdentity
	// contains filtered or unexported fields
}

PrivateSmolIdentity wraps a SmolIdentity and an ed25519 private key

func NewPrivateSmolIdentity added in v0.1.5

func NewPrivateSmolIdentity(cert *smolcert.Certificate, privKey ed25519.PrivateKey) *PrivateSmolIdentity

NewPrivateSmolIdentity creates a new PrivateSmolIdentity which contains the smolcert with the private key. This might be needed for cryptographic operations like eDH or eDSA etc.

func (*PrivateSmolIdentity) PrivateKey added in v0.1.5

func (p *PrivateSmolIdentity) PrivateKey() []byte

PrivateKey returns a curve25519 representation of the private key

type ReadableHandshakeMessage

type ReadableHandshakeMessage interface {
	ReadEPublic() ([]byte, error)
	ReadEncryptedIdentity() ([]byte, error)
	ReadPayload() ([]byte, error)
	Length() int
}

ReadableHandshakeMessage provides the HandshakeState the possibility to digest handshake messages in other formats than simple concatenated byte slices

type SimpleIdentity

type SimpleIdentity struct {
	// PubKey is the static public key
	PubKey []byte
}

SimpleIdentity gives the possibility to simply use plain public keys as identity, similar to the original behavior

func (*SimpleIdentity) PublicKey

func (s *SimpleIdentity) PublicKey() []byte

PublicKey gives you the static public key of this identity

type SimpleMessage

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

SimpleMessage is mostly used for testing, but can also be used to emulate the previous behavior of simply concatenating bytes together

func (*SimpleMessage) Length

func (s *SimpleMessage) Length() int

Length gives you the total length of this message

func (*SimpleMessage) ReadEPublic

func (s *SimpleMessage) ReadEPublic() ([]byte, error)

ReadEPublic gives you the ephemeral remote public key from this payload

func (*SimpleMessage) ReadEncryptedIdentity

func (s *SimpleMessage) ReadEncryptedIdentity() ([]byte, error)

ReadEncryptedIdentity gives you the bytes of the encrypted static remote identity (key)

func (*SimpleMessage) ReadPayload

func (s *SimpleMessage) ReadPayload() ([]byte, error)

ReadPayload gives you the encrypted bytes of the additional optional payload

func (*SimpleMessage) Reset

func (s *SimpleMessage) Reset()

Reset sets the fields to empty values, used in testing

func (*SimpleMessage) Serialize

func (s *SimpleMessage) Serialize() []byte

Serialize simply concatenates all fields in an expected order

func (*SimpleMessage) WriteEPublic

func (s *SimpleMessage) WriteEPublic(e []byte)

WriteEPublic writes the ephemeral public key to the payload

func (*SimpleMessage) WriteEncryptedIdentity

func (s *SimpleMessage) WriteEncryptedIdentity(sr []byte)

WriteEncryptedIdentity writes the encrypted static identity (public key) to this payload

func (*SimpleMessage) WriteEncryptedPayload

func (s *SimpleMessage) WriteEncryptedPayload(p []byte)

WriteEncryptedPayload adds the encrypted payload

type SmolIdentity added in v0.1.5

type SmolIdentity struct {
	smolcert.Certificate
}

SmolIdentity wraps a smolcert based certificate and provides the public key as curve25519 representation instead of ed25519

func (*SmolIdentity) Cert added in v0.1.5

func (s *SmolIdentity) Cert() *smolcert.Certificate

Cert returns the plain smolcert certificate

func (*SmolIdentity) PublicKey added in v0.1.5

func (s *SmolIdentity) PublicKey() []byte

PublicKey returns the curve25519 representation of the ed25519 public key of this certificate

type SmolIdentityMarshaler added in v0.1.5

type SmolIdentityMarshaler struct{}

func (SmolIdentityMarshaler) MarshalIdentity added in v0.1.5

func (s SmolIdentityMarshaler) MarshalIdentity(identity Identity) ([]byte, error)

func (SmolIdentityMarshaler) UnmarshalIdentity added in v0.1.5

func (s SmolIdentityMarshaler) UnmarshalIdentity(identityBytes []byte) (Identity, error)

type SmolIdentityVerifier added in v0.1.5

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

SmolIdentityVerifier verifies certificates against a set of root certificates

func NewSmolIdentityVerifier added in v0.1.5

func NewSmolIdentityVerifier(rootCerts ...*smolcert.Certificate) *SmolIdentityVerifier

func (*SmolIdentityVerifier) VerifyIdentity added in v0.1.5

func (s *SmolIdentityVerifier) VerifyIdentity(id Identity) error

type WriteableHandshakeMessage

type WriteableHandshakeMessage interface {
	WriteEPublic(e []byte)
	WriteEncryptedIdentity(s []byte)
	WriteEncryptedPayload(p []byte)
}

WriteableHandshakeMessage takes data from the HandshakeState to marshal it to a custom format.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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