tls

package module
v0.0.0-...-ec94fe1 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2014 License: BSD-3-Clause Imports: 20 Imported by: 3

README

go-tls-srp is an implementation of TLS-SRP, https://tools.ietf.org/html/rfc5054

TLS-SRP lets a client make a secure, authenticated TLS (SSL)
connection to a server with only a username and password. No
certificates are needed. No certificate authorities have to be
trusted.

This implementation is based on a stripped down version of Go's
crypto/tls package.  It only implements the non-certificate ciphers
from RFC5054 (because it was simpler, and not needing certificates
is the whole point of TLS-SRP), in order of preference:
- SRP-SHA1 with AES-256-CBC,SHA1
- SRP-SHA1 with AES-128-CBC,SHA1
- SRP-SHA1 with 3DES-CBC,SHA1

Supported TLS extensions:
- SNI, server name indication
- Ticket sessions
- SRP (obviously)

Other extensions from crypto/tls are not relevant for SRP, or will
be deprecated.

go-tls-srp is based on crypto/tls from the 1.2.1 Go release branch.
The plan is to keep it updated with later release branches, and
maybe more.

Both the client and server implementation have been tested against
the client and server implementations of GnuTLS and OpenSSL.

This library should not yet be considered ready for use. Another
security review would be nice, and more experience using it.


# Documentation

See http://godoc.org/bitbucket.org/mjl/go-tls-srp for documentation.

See ex/ for simple, working examples of clients and servers.


# Contact

For feedback, questions, changes etc, contact me at mechiel@ueber.net.


# Todo

- test that username/passwords that are not valid utf-8 do work
- redo current test cases and include the exact commands that were used to generate them
- write test case for two authentication attempts to server with invalid username, ensure that we get the same salt twice (so attacker cannot probe for (in)valid accounts)
- write test cases so all N,g groups are covered
- figure out why disappearing servers do not cause read errors for clients (and probably vice versa).

Maybe:

- integrate srp support back into go's crypto/tls.  but perhaps not, the api/interface might become ugly, the use case for srp vs "normal" certificated-based tls is quite different. also, the code will be more complicated, because some messages take on an other form under srp.
- implement srp's certificate-related ciphers.
- different interface for clients to pass in username & password (though it's nice and simple like it is now, and since this library only has srp ciphers, you know you will need a password before starting the connection, to there is not much use delaying reading a password)
- try to clear memory with sensitive data in it (like passwords).  not sure if this is possible in go.  how do you overwrite a string?
- be more strict in handling usernames: always use []byte form, never string


# License

Since this code is based on Go's crypto/tls package, the same license
applies (see LICENSE). My changes are released under the same
conditions.

Documentation

Overview

Package tls partially implements TLS-SRP as specified in RFC 5054.

TLS-SRP lets a client make a secure, authenticated TLS (SSL) connection to a server with only a username and password. No certificates are needed. No certificate authorities have to be trusted.

This implementation is based on a stripped down version of Go's crypto/tls package. Only the non-certificate ciphers from RFC 5054 are supported, in order of preference:

  • SRP-SHA1 with AES-256-CBC,SHA1
  • SRP-SHA1 with AES-128-CBC,SHA1
  • SRP-SHA1 with 3DES-CBC,SHA1

Supported TLS extensions:

  • SNI, server name indication
  • Ticket sessions
  • SRP (obviously)

Usage is very similar to crypto/tls. However, you must always pass the Conn-functions a valid Config. For server configs, you must set SRPLookup, SRPSaltKey and SRPSaltSize. For client configs, you must set SRPUser and SRPPassword.

For a minimal example of a client and server, see ex/srpdial.go and ex/srplisten.go. For a more complete example, see ex/srpexserver.go, ex/srpexadmin.go and ex/srpexclient.go.

Index

Constants

View Source
const (
	TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc01a
	TLS_SRP_SHA_WITH_AES_128_CBC_SHA  uint16 = 0xc01d
	TLS_SRP_SHA_WITH_AES_256_CBC_SHA  uint16 = 0xc020
)

A list of the supported cipher suite ids from the SRP RFC.

View Source
const (
	VersionSSL30 = 0x0300
	VersionTLS10 = 0x0301
	VersionTLS11 = 0x0302
	VersionTLS12 = 0x0303
)

Variables

This section is empty.

Functions

func Listen

func Listen(network, laddr string, config *Config) (net.Listener, error)

Listen creates a TLS listener accepting connections on the given network address using net.Listen. The configuration config must be non-nil and must have SRPLookup, SRPSaltKey and SRPSaltSize set.

func NewListener

func NewListener(inner net.Listener, config *Config) net.Listener

NewListener creates a Listener which accepts connections from an inner Listener and wraps each connection with Server. The configuration config must be non-nil and must have SRPLookup, SRPSaltKey and SRPSaltSize set.

func SRPVerifier

func SRPVerifier(user, password string, salt []byte, grp SRPGroup) []byte

SRPVerifier calculates the SRP verifier "v" as specified in http://tools.ietf.org/html/rfc5054#section-2.4

Types

type Config

type Config struct {
	// Rand provides the source of entropy for nonces and RSA blinding.
	// If Rand is nil, TLS uses the cryptographic random reader in package
	// crypto/rand.
	Rand io.Reader

	// Time returns the current time as the number of seconds since the epoch.
	// If Time is nil, TLS uses time.Now.
	Time func() time.Time

	// ServerName is included in the client's handshake to support virtual
	// hosting.
	ServerName string

	// CipherSuites is a list of supported cipher suites. If CipherSuites
	// is nil, TLS uses a list of suites supported by the implementation.
	CipherSuites []uint16

	// PreferServerCipherSuites controls whether the server selects the
	// client's most preferred ciphersuite, or the server's most preferred
	// ciphersuite. If true then the server's preference, as expressed in
	// the order of elements in CipherSuites, is used.
	PreferServerCipherSuites bool

	// SessionTicketsDisabled may be set to true to disable session ticket
	// (resumption) support.
	SessionTicketsDisabled bool

	// SessionTicketKey is used by TLS servers to provide session
	// resumption. See RFC 5077. If zero, it will be filled with
	// random data before the first server handshake.
	//
	// If multiple servers are terminating connections for the same host
	// they should all have the same SessionTicketKey. If the
	// SessionTicketKey leaks, previously recorded and future TLS
	// connections using that key are compromised.
	SessionTicketKey [32]byte

	// MinVersion contains the minimum SSL/TLS version that is acceptable.
	// If zero, then SSLv3 is taken as the minimum.
	MinVersion uint16

	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
	// If zero, then the maximum version supported by this package is used,
	// which is currently TLS 1.2.
	MaxVersion uint16

	// For SRP servers:
	SRPLookup   Lookuper // for looking up salt, verifier & srp group for a username
	SRPSaltKey  string   // used in hmac for generating fake salts, for hiding existence of account
	SRPSaltSize int      // size of fake salts (<= 64), should match what is used for valid accounts

	// For SRP clients:
	SRPUser     string
	SRPPassword string
	SRPGroups   []*SRPGroup // Groups allowed from server.  If nil, all groups from RFC 5054 are allowed.
	// contains filtered or unexported fields
}

A Config structure is used to configure a TLS client or server. After one has been passed to a TLS function it must not be modified.

type Conn

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

A Conn represents a secured connection. It implements the net.Conn interface.

func Client

func Client(conn net.Conn, config *Config) *Conn

Client returns a new TLS client side connection using conn as the underlying transport. The configuration config must be non-nil and should have SRPUser and SRPPassword set.

func Dial

func Dial(network, addr string, config *Config) (*Conn, error)

Dial connects to the given network address using net.Dial and then initiates a TLS handshake, returning the resulting TLS connection. Configuration config must be non-nil and should have SRPUser and SRPPassword set.

func Server

func Server(conn net.Conn, config *Config) *Conn

Server returns a new TLS server side connection using conn as the underlying transport. The configuration config must be non-nil and must have SRPLookup, SRPSaltKey and SRPSaltSize set.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection.

func (*Conn) ConnectionState

func (c *Conn) ConnectionState() ConnectionState

ConnectionState returns basic TLS details about the connection.

func (*Conn) Handshake

func (c *Conn) Handshake() error

Handshake runs the client or server handshake protocol if it has not yet been run. Most uses of this package need not call Handshake explicitly: the first Read or Write will call it automatically.

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 can be made to time out and return a net.Error with Timeout() == true after a fixed time limit; see SetDeadline and SetReadDeadline.

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. A zero value for t means Read and Write will not time out. After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.

func (*Conn) SetReadDeadline

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

SetReadDeadline sets the read deadline on the underlying connection. 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 write deadline on the underlying conneciton. A zero value for t means Write will not time out. After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.

func (*Conn) Write

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

Write writes data to the connection.

type ConnectionState

type ConnectionState struct {
	HandshakeComplete bool   // TLS handshake is complete
	CipherSuite       uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
	ServerName        string // server name requested by client, if any (server side only)
	SRPUser           string // authenticated SRP user
}

ConnectionState records basic TLS details about the connection.

type Lookuper

type Lookuper interface {
	// Lookup looks up the user and returns the verifier (v),
	// and salt (s) and group (grp) used to create the verifier.
	// If the user is absent, Lookup should return a nil v and
	// nil s but a valid grp. In this case, grp is used to generate a
	// verifier, in order to make it harder for attackers to enumerate
	// valid accounts.
	Lookup(user string) (v, s []byte, grp SRPGroup, err error)
}

Lookuper is an interface for looking up SRP account information.

type SRPGroup

type SRPGroup struct {
	N *big.Int
	G *big.Int
}

Group with prime N and generator G.

var (
	SRPGroup1024 SRPGroup
	SRPGroup1536 SRPGroup
	SRPGroup2048 SRPGroup
	SRPGroup3072 SRPGroup
	SRPGroup4096 SRPGroup
	SRPGroup6144 SRPGroup
	SRPGroup8192 SRPGroup
)

SRP groups defined in RFC 5054.

Jump to

Keyboard shortcuts

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