srp

package
v0.0.0-...-ee2271c Latest Latest
Warning

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

Go to latest
Published: Jan 21, 2017 License: AGPL-3.0, MIT Imports: 7 Imported by: 0

README

Secure Remote Password protocol

This is a library implementing the SRP protocol as defined in RFC 2945 (partially) and in the RFC 5054 for the TLS integration.

Usage

  1. Initialization phase

The server has to register all username and password that it is expected to server. The password are not stored directly, but the hash with salt. The example here use an implemented local memory store.

// enter the creds
db := NewMapLookup()
// password never stored in clear (hashed with salt)
db.Add("Serge","Karamazov",Group4096)

server := NewServerInstance(db)
  1. Exchange

server:

// give the username to the server
mat,err := server.KeyExchange("Serge",nil)
if err != nil {
    panic(err)
}

client:

// give the material to the client
// password is not kept in memory, it's directly hashed with salt.
client,err := NewClient("Serge","Karamazov"
if err != nil {
    panic(err)
}
keyC,A,err := client.KeyExchange(mat)
if err != nil {
    panic(err)
}
// keyC is the actual KEY derived :)

server:

keyS,err := server.Key(A)
if err != nil {
    panic(err)
}

// keyS is the actual KEY derived :)

Differences with the RFC 5054

  • The hash function used here is SHA256 instead of SHA-1
  • The number of groups allowed is reduced (1024 and 2048 bit size are dropped)

Open questions

  • field elements size ? a & b. Set to RandSize = 64

License

MIT License. See LICENSE file.

Documentation

Index

Constants

View Source
const MaxUserSize = 255

MaxUserSize is the maximum size an username can be, inclusive.

View Source
const MinUserSize = 3

MinUserSize is the minimum size an username must be, inclusive.

View Source
const RandSize = 32

RandSize is the size of the random numbers generated by the client and server Taken from tlslite implementation.

View Source
const SaltSize = 16

SaltSize is the size of the salt to generate in bytes. Taken from tlslite implementation.

Variables

View Source
var ErrInvalidGroup = errors.New("srp: invalid group parameters")
View Source
var ErrUnknownGroup = errors.New("srp: unknown group parameters")
View Source
var ErrUnknownUser = errors.New("username provided is not known")
View Source
var HashFunc = sha256.New

The hashing function used for the SRP protocol. NOTE: It might be adding an extra security layer to convert it to Argon2 for example later.

View Source
var Rand io.Reader

Rand is the reader used to generate randomness for the salt and the points in the exchange. By default, it is set to `crypto/rand.Reader`.

Functions

This section is empty.

Types

type Client

type Client struct {
	A *big.Int
	// contains filtered or unexported fields
}

func NewClient

func NewClient(username, password string, allowedGroups *Groups) (*Client, error)

NewClient returns a client that is able to proceed on the SRP protocol. It consumes the password into a hash function so there's no storage of it.

func (*Client) Key

func (c *Client) Key() []byte

Key returns a copy of the key

func (*Client) KeyExchange

func (c *Client) KeyExchange(m *ServerMaterial) (key, A []byte, err error)

Material uses the server materials to generate the random component A from the client as in 2.6 https://tools.ietf.org/html/rfc5054#page-8 It returns the shared key, the public part A to send to server, or an error otherwise. It can return ErrInvalidGroup is the group parameters are invalid.

func (*Client) Username

func (c *Client) Username() string

type Group

type Group struct {
	// modulo
	N *big.Int
	// base
	G *big.Int
}

Group structure holding the base generator point and the prime number

var (
	//Group1024 Group
	//Group1536 Group
	//Group2048 Group
	Group3072 Group
	Group4096 Group
	Group6144 Group
	Group8192 Group
)

SRP groups defined in RFC 5054.

func CreateGroup

func CreateGroup(N, G []byte) Group

func (*Group) Equal

func (g *Group) Equal(g2 Group) bool

Equal returns true if g2 is equal to g

func (*Group) Len

func (g *Group) Len() int

Len returns the length in bytes of the prime. It's to be used to pad any number of this group before hashing.

type Groups

type Groups []Group
var RFCGroups Groups

func (Groups) Contains

func (gs Groups) Contains(t Group) bool

Contains return true if t is contained in the list of groups, false otherwise. If gs is nil, RFCGroups is used.

type Lookup

type Lookup interface {
	Fetch(username string) (*UserInfo, bool)
}

type MapLookup

type MapLookup map[string]*UserInfo

func NewMapLookup

func NewMapLookup() *MapLookup

func (*MapLookup) Add

func (m *MapLookup) Add(uname, password string, group Group) error

Add an user to the database with the

func (*MapLookup) Fetch

func (m *MapLookup) Fetch(username string) (*UserInfo, bool)

type ServerInstance

type ServerInstance struct {
	B *big.Int
	// contains filtered or unexported fields
}

ServerInstance is a struct following the protocol FOR ONE USER

func NewServerInstance

func NewServerInstance(lookup Lookup) *ServerInstance

func (*ServerInstance) Key

func (s *ServerInstance) Key(A []byte) ([]byte, error)

Key returns the shared key given the A public client's information or an error if A is wrong or suspicious.

func (*ServerInstance) KeyExchange

func (s *ServerInstance) KeyExchange(username string, fakeSalt []byte) (*ServerMaterial, error)

KeyExchange proceeds to the key exchange part from the server's point of view. It computes B = k * v + g^b % N and returns the information needed by the Client to pursue. fakseSalt is used when the username is invalid: in that case, the server will simulate computation as usual in order to avoid timing attacks. If fakeSalt is nil, it directly returns and do NO DO this fake computations. In any cases, if the username is invalid, it returns ErrUnknownUser.

type ServerMaterial

type ServerMaterial struct {
	Salt  []byte
	B     []byte
	Group Group
}

type UserInfo

type UserInfo struct {
	Verifier *Verifier
	Group    Group
}

type Verifier

type Verifier struct {
	// the actual group element. Encoded as big.Int which by default uses
	// big endianness format.
	Hash []byte
	// Salt
	Salt []byte
}

Verifier contains H(salt || (username:password)). It is suitable for writing/reader from most of encoding schemes (json).

func NewVerifier

func NewVerifier(username, password string, group Group) (*Verifier, error)

NewVerifier returns a new verifier out of the username and the related password. The password can be discarded after as there is no need to store it. http://tools.ietf.org/html/rfc5054#section-2.4

Jump to

Keyboard shortcuts

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