opaque

package
v0.0.0-...-b26be1d Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2021 License: BSD-3-Clause Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ProtocolMessageTypeToStringMap = map[ProtocolMessageType]string{
	ProtocolMessageTypeRegistrationRequest:  "OPAQUE Registration Request",
	ProtocolMessageTypeRegistrationResponse: "OPAQUE Registration Response",
	ProtocolMessageTypeRegistrationUpload:   "OPAQUE Registration Upload",
	ProtocolMessageTypeCredentialRequest:    "OPAQUE Credential Request",
	ProtocolMessageTypeCredentialResponse:   "OPAQUE Credential Response",
}

ProtocolMessageTypeToStringMap maps the Protocol Message Type to its string equivalent.

Functions

func RunLocalOPRF

func RunLocalOPRF(s *Server, username, password string) ([]byte, error)

RunLocalOPRF returns the randomized password for the given server, username and password. It runs the OPRF protocol locally with a dummy client. Only for testing - in a real setting the server does not know the password.

func TestMarshalUnmarshal

func TestMarshalUnmarshal(data, empty common.MarshalUnmarshaler) error

TestMarshalUnmarshal is a test helper that errors if Marshal/Unmarshal for the type of data and empty is not working. data should be filled in and empty should be empty.

Types

type AuthenticatedOneTimePad

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

AuthenticatedOneTimePad is a cipher for encrypting/decrypting OPAQUE credentials. It is specialized and should likely not be used elsewhere.

func NewAuthenticatedOneTimePad

func NewAuthenticatedOneTimePad(key, nonce []byte, l int) (*AuthenticatedOneTimePad, error)

NewAuthenticatedOneTimePad returns a new AOTP cipher initialized with the given key and nonce. It calculates: pseudorandom_pad = HKDF-Expand(rwdU, concat(nonce, "Pad"), len(pt)) auth_key = HKDF-Expand(rwdU, concat(nonce, "AuthKey"), Nh) export_key = HKDF-Expand(rwdU, concat(nonce, "ExportKey"), Nh)

func (*AuthenticatedOneTimePad) Open

func (otp *AuthenticatedOneTimePad) Open(ciphertext, authData, tag []byte) ([]byte, error)

Open decrypts the ciphertext and verifies the HMAC Errors if decryption or verification fails. It uses HmacKey to validate the received value 'authData', and errors if verification fails.

func (*AuthenticatedOneTimePad) Seal

func (otp *AuthenticatedOneTimePad) Seal(plaintext, authData []byte) (ciphertext, tag []byte, err error)

Seal encrypts and HMACs the given plaintext. MUST only be called once (it is a one-time pad after all). It calculates: Set Ct = SecEnv XOR Pad Set E = Nonce | Ct | authData Set T = HMAC(HmacKey, E)

type Client

type Client struct {
	UserID   []byte
	ServerID []byte
	// contains filtered or unexported fields
}

Client holds state for the client role in OPAQUE.

func NewClient

func NewClient(userID, serverID string, suite oprf.SuiteID, signerKey crypto.Signer) (*Client, error)

NewClient returns a new OPAQUE client.

func (*Client) CreateCredentialRequest

func (c *Client) CreateCredentialRequest(password []byte) (*CredentialRequest, error)

CreateCredentialRequest is called by the client on a password to initiate the online OPAQUE protocol. Returns a credential request, which will be sent to the server.

func (*Client) CreateRegistrationRequest

func (c *Client) CreateRegistrationRequest(password string) (*RegistrationRequest, error)

CreateRegistrationRequest is called by the client for registration. This function creates the first OPAQUE registration message. Errors if the OPRF message cannot be created.

func (*Client) FinalizeRegistrationRequest

func (c *Client) FinalizeRegistrationRequest(msg *RegistrationResponse) (*RegistrationUpload, []byte, error)

FinalizeRegistrationRequest is called by the client to respond to the server's response to its registration request (registration response). Returns a registration upload message and an exporter key. Errors if the OPRF cannot be completed or there is a problem encrypting the envelope.

func (*Client) RecoverCredentials

func (c *Client) RecoverCredentials(response *CredentialResponse) (*Credentials, error)

RecoverCredentials is called by the client on receiving an OPAQUE credential response from the server. Returns the credentials that the client uploaded during the registration phase.

type CredentialEncodingPolicy

type CredentialEncodingPolicy struct {
	SecretTypes    []CredentialType
	CleartextTypes []CredentialType
}

CredentialEncodingPolicy indicates which user credentials are stored, and whether they are held encrypted or in cleartext.

type CredentialExtension

type CredentialExtension struct {
	CredentialType CredentialType
	CredentialData []byte `tls:"head=2"`
}

A CredentialExtension is a piece of data that may be included in client Credentials.

 struct {
	 CredentialType type;
	 CredentialData data<0..2^16-1>;
 } CredentialExtension;

     1            2

| credType | credDataLen | credData |.

func (*CredentialExtension) Marshal

func (ce *CredentialExtension) Marshal() ([]byte, error)

Marshal returns the raw form of the struct.

func (*CredentialExtension) Unmarshal

func (ce *CredentialExtension) Unmarshal(data []byte) (int, error)

Unmarshal puts raw data into fields of a struct.

type CredentialExtensionList

type CredentialExtensionList []*CredentialExtension

CredentialExtensionList is a list of credential extensions. Used to package secret and cleartext credentials separately.

func (CredentialExtensionList) Find

func (cel CredentialExtensionList) Find(t CredentialType) (interface{}, bool)

Find returns the value of credential type t in this CredentialExtensionList, or false if not present.

func (CredentialExtensionList) Marshal

func (cel CredentialExtensionList) Marshal() ([]byte, error)

Marshal encodes the Credential Extension List.

type CredentialRequest

type CredentialRequest struct {
	UserID   []byte `tls:"head=2"`       // client account info, if present
	OprfData []byte `tls:"head=2,min=1"` // an encoded element in the OPRF group
}

A CredentialRequest is the first message sent by the client to initiate OPAQUE. Implements ProtocolMessageBody.

struct {
	opaque id<0..2^16-1>;
	opaque data<1..2^16-1>;
} CredentialRequest;
2                    2

| userIDLen | userID | oprfDataLen | oprfData |

func UnmarshalCredentialRequestJSON

func UnmarshalCredentialRequestJSON(b []byte) (*CredentialRequest, error)

UnmarshalCredentialRequestJSON decodes to a CredentialRequest.

func (*CredentialRequest) Marshal

func (cr *CredentialRequest) Marshal() ([]byte, error)

Marshal returns the raw form of the struct.

func (*CredentialRequest) MarshalJSON

func (cr *CredentialRequest) MarshalJSON() ([]byte, error)

MarshalJSON encodes the CredentialRequest.

func (*CredentialRequest) Type

Type returns the type of this struct.

func (*CredentialRequest) Unmarshal

func (cr *CredentialRequest) Unmarshal(data []byte) (int, error)

Unmarshal puts raw data into fields of a struct.

type CredentialResponse

type CredentialResponse struct {
	OprfData []byte    // an encoded element in the OPRF group
	Envelope *Envelope // an authenticated encoding of a Credentials structure
	// contains filtered or unexported fields
}

A CredentialResponse is the message sent by the server in response to the Client's initial OPAQUE message. Implements ProtocolMessageBody.

struct {
	opaque data<1..2^16-1>;
	opaque envelope<1..2^16-1>;
	opaque pkS<0..2^16-1;
} CredentialResponse;
2                                2

| oprfDataLen | oprfData | envelope | pkSLen | pkS |

func UnmarshalCredentialResponseJSON

func UnmarshalCredentialResponseJSON(b []byte) (*CredentialResponse, error)

UnmarshalCredentialResponseJSON decodes to a CredentialResponse.

func (*CredentialResponse) Marshal

func (cr *CredentialResponse) Marshal() ([]byte, error)

Marshal encodes a Credential Response.

func (*CredentialResponse) MarshalJSON

func (cr *CredentialResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the CredentialResponse.

func (*CredentialResponse) Type

Type returns the type of this struct.

func (*CredentialResponse) Unmarshal

func (cr *CredentialResponse) Unmarshal(data []byte) (int, error)

Unmarshal decodes a Credential Response.

type CredentialType

type CredentialType byte

CredentialType indicates the type of an OPAQUE credential extension struct.

enum {
	skU(1),
	pkU(2),
	pkS(3),
	idU(4),
	idS(5),
	(255)
  } CredentialType;
const (
	CredentialTypeUserPrivateKey CredentialType = 1 + iota
	CredentialTypeUserPublicKey
	CredentialTypeServerPublicKey
	CredentialTypeUserIdentity
	CredentialTypeServerIdentity
)

Credential types.

func (CredentialType) MarshalText

func (ct CredentialType) MarshalText() ([]byte, error)

MarshalText encodes the Credential Type.

func (CredentialType) String

func (ct CredentialType) String() string

String returns the string equivalent of the Credential Type.

type Credentials

type Credentials struct {
	SecretCredentials    CredentialExtensionList `tls:"head=2,min=1"`
	CleartextCredentials CredentialExtensionList `tls:"head=2"`
}

Credentials holds the decrypted user-specific envelope contents.

struct {
	CredentialExtension secret_credentials<1..2^16-1>;
	CredentialExtension cleartext_credentials<0..2^16-1>;
} Credentials;
           2                              2
| secretCredsLen | secretCreds | cleartextCredsLen | cleartextCreds |

SecretCredentials MUST contain the skU. It can contain the pkS. CleartextCredentials MUST contain the pkS

func DecryptCredentials

func DecryptCredentials(rwd []byte, envelope *Envelope) (*Credentials, error)

DecryptCredentials decrypts the encrypted envelope. Returns the decrypted Credentials struct, or an error if decryption fails.

func (*Credentials) Find

func (creds *Credentials) Find(t CredentialType) (interface{}, bool)

Find returns the value of credential type t in this Credentials struct, or false if not present.

func (*Credentials) Marshal

func (creds *Credentials) Marshal() ([]byte, error)

Marshal returns the raw form of the struct.

func (*Credentials) MarshalSplit

func (creds *Credentials) MarshalSplit() (secret, cleartext []byte, err error)

MarshalSplit encodes the Credential into its secret and clear parts.

func (*Credentials) Unmarshal

func (creds *Credentials) Unmarshal(data []byte) (int, error)

Unmarshal puts raw data into fields of a struct.

func (*Credentials) UnmarshalSplit

func (creds *Credentials) UnmarshalSplit(secret, cleartext []byte) (int, error)

UnmarshalSplit decodes the Credential into its secret and clear parts.

type Envelope

type Envelope struct {
	Nonce              []byte `tls:"head=1"`       // unique value, which must be 32 byte long.
	EncryptedCreds     []byte `tls:"head=2,min=1"` // raw encrypted and authenticated credential extensions list.
	AuthenticatedCreds []byte `tls:"head=2"`       // raw authenticated credential extensions list.
	AuthTag            []byte `tls:"head=2,min=1"` // tag authenticating the envelope contents.
}

Envelope is the data encrypted under the randomized password which is stored encrypted and sent to to the user.

struct {
	opaque nonce[Nn];
	opaque ct<1..2^16-1>;
	opaque auth_data<0..2^16-1>;
	opaque auth_tag<1..2^16-1>;
} Envelope;
1                   2                         2                         2

| nonceLen | nonce | encCredsLen | encCreds | authCredsLen | authCreds | authTagLen | authTag |.

func EncryptCredentials

func EncryptCredentials(rwd []byte, creds *Credentials) (*Envelope, []byte, error)

EncryptCredentials encrypts the given Credentials under a key derived from rwd, the randomized password.

func (*Envelope) Marshal

func (e *Envelope) Marshal() ([]byte, error)

Marshal returns the raw form of the struct.

func (*Envelope) Unmarshal

func (e *Envelope) Unmarshal(data []byte) (int, error)

Unmarshal puts raw data into fields of a struct.

type InMemoryUserRecordTable

type InMemoryUserRecordTable map[string]*UserRecord

InMemoryUserRecordTable is a map from usernames to user records to mimic a database. Implements UserRecordTable.

func NewInMemoryUserRecordTable

func NewInMemoryUserRecordTable() *InMemoryUserRecordTable

NewInMemoryUserRecordTable returns a new empty in-memory user record table.

func (InMemoryUserRecordTable) BulkAdd

func (t InMemoryUserRecordTable) BulkAdd(records []*UserRecord) error

BulkAdd adds the given records to the in-memory user record table.

func (InMemoryUserRecordTable) InsertUserRecord

func (t InMemoryUserRecordTable) InsertUserRecord(username string, record *UserRecord) error

InsertUserRecord adds a record to the in-memory user record table. Username must be unique. The UserID in the record must be nil or match the given username.

func (InMemoryUserRecordTable) LookupUserRecord

func (t InMemoryUserRecordTable) LookupUserRecord(username string) (*UserRecord, error)

LookupUserRecord returns the user record associated with the given username in the user record, or an error if the username is not registered.

type ProtocolMessage

type ProtocolMessage struct {
	MessageType    ProtocolMessageType
	MessageBodyRaw []byte `tls:"head=3"`
}

A ProtocolMessage is a bundle containing all OPAQUE data sent in a flow between parties (during registration or login).

struct {
	ProtocolMessageType msg_type;    /* protocol message type */
	uint24 length;                   /* remaining bytes in message */
	select (ProtocolMessage.msg_type) {
		case registration_request: RegistrationRequest;
		case registration_response: RegistrationResponse;
		case registration_upload: RegistrationUpload;
		case credential_request: CredentialRequest;
		case credential_response: CredentialResponse;
	};
} ProtocolMessage;
1               3

| messageType | messageBodyLen | messageBody |

func ProtocolMessageFromBody

func ProtocolMessageFromBody(body ProtocolMessageBody) (*ProtocolMessage, error)

ProtocolMessageFromBody reconstructs a ProtocolMessage from its body.

func (*ProtocolMessage) Marshal

func (msg *ProtocolMessage) Marshal() ([]byte, error)

Marshal encodes a ProtocolMessage.

func (*ProtocolMessage) ToBody

func (msg *ProtocolMessage) ToBody() (ProtocolMessageBody, error)

ToBody assigns the message type.

func (*ProtocolMessage) Unmarshal

func (msg *ProtocolMessage) Unmarshal(data []byte) (int, error)

Unmarshal decodes a ProtocolMessage.

type ProtocolMessageBody

type ProtocolMessageBody interface {
	Marshal() ([]byte, error)
	Unmarshal([]byte) (int, error)
	Type() ProtocolMessageType
}

ProtocolMessageBody is an interface implemented by all protocol messages. Represents the "inner" part of the message, not including metadata.

type ProtocolMessageType

type ProtocolMessageType byte

ProtocolMessageType indicates the OPAQUE protocol message type

enum {
	registration_request(1),
	registration_response(2),
	registration_upload(3),
	credential_request(4),
	credential_response(5),
	(255)
} ProtocolMessageType;.
const (
	ProtocolMessageTypeRegistrationRequest ProtocolMessageType = 1 + iota
	ProtocolMessageTypeRegistrationResponse
	ProtocolMessageTypeRegistrationUpload
	ProtocolMessageTypeCredentialRequest
	ProtocolMessageTypeCredentialResponse
)

OPAQUE protocol message types.

func (ProtocolMessageType) String

func (pmt ProtocolMessageType) String() string

type RegistrationRequest

type RegistrationRequest struct {
	UserID   []byte `tls:"head=2"`
	OprfData []byte `tls:"head=2, min=1"`
}

RegistrationRequest is the first message sent by the client to register a new OPAQUE identity with that server

struct {
	opaque id<0..2^16-1>;
	opaque data<1..2^16-1>;
} RegistrationRequest;
2                     2

| userIDLen | userID | oprfDataLen | oprfData |.

func UnmarshalRegistrationRequestJSON

func UnmarshalRegistrationRequestJSON(b []byte) (*RegistrationRequest, error)

UnmarshalRegistrationRequestJSON decodes to a RegistrationRequest.

func (*RegistrationRequest) Marshal

func (rr *RegistrationRequest) Marshal() ([]byte, error)

Marshal returns the raw form of the Registration Request.

func (*RegistrationRequest) MarshalJSON

func (rr *RegistrationRequest) MarshalJSON() ([]byte, error)

MarshalJSON encodes the RegistrationRequest.

func (*RegistrationRequest) Type

Type returns the type of this struct: RegistrationRequest.

func (*RegistrationRequest) Unmarshal

func (rr *RegistrationRequest) Unmarshal(data []byte) (int, error)

Unmarshal converts the raw data of a RegistrationRequest into a struct and returns the number of bytes read.

type RegistrationResponse

type RegistrationResponse struct {
	OprfData                 []byte
	ServerPublicKey          crypto.PublicKey
	CredentialEncodingPolicy *CredentialEncodingPolicy
}

RegistrationResponse is the first message sent by the Server in response to the client's registration request.

struct {
	opaque data<0..2^16-1>;
	opaque pkS<0..2^16-1>;
	CredentialType secret_types<1..254>;
	CredentialType cleartext_types<0..254>;
} RegistrationResponse;
2                       2                 1                                1

| oprfDataLen | oprfData | pkSLen | pkS | secretTypesLen | secretTypes | cleartextTypesLen | cleartextTypes |.

func UnmarshalRegistrationResponseJSON

func UnmarshalRegistrationResponseJSON(b []byte) (*RegistrationResponse, error)

UnmarshalRegistrationResponseJSON decodes to a RegistrationResponse.

func (*RegistrationResponse) Marshal

func (rr *RegistrationResponse) Marshal() ([]byte, error)

Marshal returns the raw form of a RegistrationResponse.

func (*RegistrationResponse) MarshalJSON

func (rr *RegistrationResponse) MarshalJSON() ([]byte, error)

MarshalJSON encodes the RegistrationResponse.

func (*RegistrationResponse) Type

Type returns the type of this struct: RegistrationResponse.

func (*RegistrationResponse) Unmarshal

func (rr *RegistrationResponse) Unmarshal(data []byte) (int, error)

Unmarshal converts the raw data into a RegistrationResponse and returns the number of bytes read.

type RegistrationUpload

type RegistrationUpload struct {
	Envelope        *Envelope
	ClientPublicKey crypto.PublicKey
}

RegistrationUpload is the second and final message sent by the client to register a new identity with a server.

struct {
	Envelope envelope;
	opaque pkU<0..2^16-1>;
} RegistrationUpload;
2

| envelope | pubKeyLen | pubKey.

func UnmarshalRegistrationUploadJSON

func UnmarshalRegistrationUploadJSON(b []byte) (*RegistrationUpload, error)

UnmarshalRegistrationUploadJSON decodes to a RegistrationRequest.

func (*RegistrationUpload) Marshal

func (ru *RegistrationUpload) Marshal() ([]byte, error)

Marshal returns the raw form of a RegistrationUpload.

func (*RegistrationUpload) MarshalJSON

func (rr *RegistrationUpload) MarshalJSON() ([]byte, error)

MarshalJSON encodes the RegistrationUpload.

func (*RegistrationUpload) Type

Type returns the type of this struct: RegistrationUpload.

func (*RegistrationUpload) Unmarshal

func (ru *RegistrationUpload) Unmarshal(data []byte) (int, error)

Unmarshal converts the raw data into a RegistrationUpload and returns the number of bytes read.

type Server

type Server struct {
	Config     *ServerConfig
	UserRecord *UserRecord
}

Server holds state for an instance of the server role in OPAQUE.

func NewServer

func NewServer(cfg *ServerConfig) (*Server, error)

NewServer returns a new OPAQUE server with the RECOMMENDED credential encoding policy.

func (*Server) CreateCredentialResponse

func (s *Server) CreateCredentialResponse(request *CredentialRequest) (*CredentialResponse, error)

CreateCredentialResponse is called by the server on receiving a credential request from the client. Returns a credential response, which will be sent to the server.

func (*Server) CreateRegistrationResponse

func (s *Server) CreateRegistrationResponse(msg *RegistrationRequest) (*RegistrationResponse, error)

CreateRegistrationResponse is called by the server to respond to a client's registration request. It fails is an OPRF message cannot be created or if a user is already registered.

func (*Server) GetUserRecordFromUsername

func (s *Server) GetUserRecordFromUsername(username []byte) (*UserRecord, error)

GetUserRecordFromUsername looks up the user record associated with the given username, and uses it to set the server's user record. Errors if no user record can be found, or there is no LookupUserRecord set.

func (*Server) InsertNewUserRecord

func (s *Server) InsertNewUserRecord(userPublicKey crypto.PublicKey, envelope *Envelope) (*UserRecord, error)

InsertNewUserRecord updates the server's user record struct with the given data, registers the record using the InsertUserRecord, and returns the created record.

func (*Server) SetUserID

func (s *Server) SetUserID(username []byte) error

SetUserID sets the User ID for the Server's User Record.

func (*Server) StoreUserRecord

func (s *Server) StoreUserRecord(msg *RegistrationUpload) error

StoreUserRecord is called by the Server to add the new client identity to it's records, ending the registration process. Errors if the record cannot be added, e.g. because the username has already been registered.

type ServerConfig

type ServerConfig struct {
	ServerID                 string
	Signer                   crypto.Signer
	RecordTable              UserRecordTable
	Suite                    oprf.SuiteID
	CredentialEncodingPolicy *CredentialEncodingPolicy
}

ServerConfig holds long term state for the server.

func NewServerConfig

func NewServerConfig(domain string, suite oprf.SuiteID) (cfg *ServerConfig, err error)

NewServerConfig returns a ServerConfig struct containing a fresh signing key and an empty lookup table

func NewTestServerConfig

func NewTestServerConfig(domain string, suite oprf.SuiteID) (cfg *ServerConfig, err error)

NewTestServerConfig returns a ServerConfig struct containing a test record table of the desired size, with dummy usernames and user records, and a function to get a user record from a username. Credentials are (user1, password1)...(userN,passwordN). It should be used for testing.

type UserRecord

type UserRecord struct {
	UserID        []byte
	UserPublicKey crypto.PublicKey
	OprfServer    *oprf.Server
	Envelope      *Envelope
}

UserRecord holds the data stored by the server about the user. The values UserPublicKey and OprfState should be kept secret.

func GetTestUserRecord

func GetTestUserRecord(s *Server, username, password string) (*UserRecord, error)

GetTestUserRecord returns a new test user record for the given domain, username and password. It should be used for testing.

func GetTestUserRecords

func GetTestUserRecords(serverSigner crypto.Signer, numRecords int, domain string, suite oprf.SuiteID) (records []*UserRecord, err error)

GetTestUserRecords returns numRecords dummy user records with unique usernames and passwords: (user1, password1),...,(userN,...,passwordN). It should be used for testing.

type UserRecordTable

type UserRecordTable interface {
	InsertUserRecord(string, *UserRecord) error
	LookupUserRecord(string) (*UserRecord, error)
}

UserRecordTable is an interface for password storage and lookup.

Jump to

Keyboard shortcuts

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