← All compilation units

Flyology.Postgres.SCRAM

Description

PostgreSQL SCRAM-SHA-256 client/server message and verifier support. Strings are treated as exact octets; SASLprep is not performed.

Bare_From_Client_First

function Bare_From_Client_First (Message : String) return String

Validate a client-first message and remove its GS2 header.

Parameters
Message

Complete client-first message.

Return value

Bare client-first attribute sequence.

Raised exceptions
SCRAM_Error

Message is malformed or uses unsupported binding.

Base64_Decode

function Base64_Decode (Value : String) return Byte_Array

Decode canonical padded base64 text.

Parameters
Value

Base64 text to decode.

Return value

Decoded bytes.

Raised exceptions
SCRAM_Error

Value is not valid canonical base64.

Base64_Encode

function Base64_Encode (Value : Byte_Array) return String

Encode bytes using canonical padded base64.

Parameters
Value

Bytes to encode.

Return value

Base64 text.

Byte_Array

subtype Byte_Array is SCRAM_Core.Byte_Array;

Byte sequence used by SCRAM cryptographic operations.

Channel_Binding_From_Client_First

function Channel_Binding_From_Client_First
  (Message : String) return String

Derive the base64 channel-binding value for a client-first GS2 header.

Parameters
Message

Complete client-first message.

Return value

Value expected in the client-final c attribute.

Raised exceptions
SCRAM_Error

The GS2 header is invalid or unsupported.

Client_Final_Message

function Client_Final_Message
  (Password                  : String;
   Bare_Client_First         : String;
   Server_First              : String;
   Client_Nonce              : String;
   Expected_Server_Signature : out Digest) return String

Verify a server-first challenge and construct the client proof.

Parameters
Password

Exact password octets; no SASLprep is performed.

Bare_Client_First

Previously sent bare client-first attributes.

Server_First

Server challenge to validate.

Client_Nonce

Original nonce, which must prefix the combined one.

Expected_Server_Signature

Signature required in server-final.

Return value

Complete client-final message with proof.

Raised exceptions
SCRAM_Error

The challenge is malformed or inconsistent.

Client_First_Bare

function Client_First_Bare (User, Nonce : String) return String

Construct the bare client-first attributes.

Parameters
User

PostgreSQL role name, escaped according to SCRAM.

Nonce

Nonempty client nonce.

Return value

n=<user>,r=<nonce> attribute sequence.

Raised exceptions
SCRAM_Error

User or Nonce is invalid.

Client_First_Message

function Client_First_Message (User, Nonce : String) return String

Construct a complete client-first message using no channel binding.

Parameters
User

PostgreSQL role name.

Nonce

Nonempty client nonce.

Return value

GS2 header followed by the bare client-first attributes.

Digest

subtype Digest is SCRAM_Core.Digest;

SHA-256 digest used for keys, proofs, and signatures.

Make_Verifier_Raw

function Make_Verifier_Raw
  (Password   : String;
   Salt       : Byte_Array;
   Iterations : Positive := Minimum_Iterations) return String

Derive a PostgreSQL rolpassword verifier. Password is consumed as exact String octets; this operation deliberately does not perform SASLprep.

Parameters
Password

Raw password octets.

Salt

Nonempty random salt stored in the verifier.

Iterations

PBKDF2 work factor within the supported bounds.

Return value

PostgreSQL SCRAM-SHA-256 rolpassword text.

Raised exceptions
SCRAM_Error

An input is empty, invalid, or out of range.

Maximum_Iterations

Maximum_Iterations : constant := 1_000_000;

Largest verifier iteration count accepted, bounding authentication work.

Maximum_Message_Length

Maximum_Message_Length : constant := 4_096;

Largest SCRAM message or verifier string accepted by the parser.

Mechanism

Mechanism : constant String := "SCRAM-SHA-256";

SASL mechanism name advertised on the PostgreSQL wire.

Minimum_Iterations

Minimum_Iterations : constant := 4_096;

Smallest verifier iteration count accepted or generated.

Nonce_From_Client_First

function Nonce_From_Client_First (Message : String) return String

Extract the client nonce from a validated client-first message.

Parameters
Message

Complete client-first message.

Return value

Value of its r attribute.

Raised exceptions
SCRAM_Error

Message lacks a valid nonce.

Parse_Verifier

function Parse_Verifier (Value : String) return Verifier

Parse and validate a PostgreSQL SCRAM-SHA-256 rolpassword value.

Parameters
Value

Text in SCRAM-SHA-256$iterations:salt$StoredKey:ServerKey form.

Return value

Validated verifier ready for server authentication.

Raised exceptions
SCRAM_Error

Value is malformed or outside configured limits.

Random_Nonce

function Random_Nonce return String

Generate a cryptographically random printable SCRAM nonce.

Return value

Fresh nonce suitable for a client-first message.

SCRAM_Error

SCRAM_Error : exception;

Raised when a verifier, SCRAM attribute, proof, or signature is invalid.

Server_First_Message

function Server_First_Message
  (Credential     : Verifier;
   Combined_Nonce : String) return String

Construct the server-first challenge for a parsed credential.

Parameters
Credential

Verifier supplying salt and iteration count.

Combined_Nonce

Client nonce followed by fresh server entropy.

Return value

SCRAM server-first attribute sequence.

Raised exceptions
SCRAM_Error

Combined_Nonce is invalid.

To_Bytes

function To_Bytes (Value : String) return Byte_Array

Convert String character codes to identical byte values.

Parameters
Value

String interpreted as octets.

Return value

Byte array with the same length and values.

To_String

function To_String (Value : Byte_Array) return String

Convert byte values to characters without text transcoding.

Parameters
Value

Octets to convert.

Return value

String with the same length and values.

Verifier

type Verifier is private;

Parsed PostgreSQL rolpassword verifier containing no plaintext password.

Verify_Client_Final

procedure Verify_Client_Final
  (Credential        : Verifier;
   Bare_Client_First : String;
   Server_First      : String;
   Combined_Nonce    : String;
   Client_Final      : String;
   Server_Signature  : out Digest;
   Valid             : out Boolean;
   Channel_Binding   : String := "biws")

Validate a client's final proof and derive the server signature.

Parameters
Credential

Stored verifier for the startup role.

Bare_Client_First

Client's validated bare first message.

Server_First

Challenge previously sent by this server.

Combined_Nonce

Exact nonce included in Server_First.

Client_Final

Client proof message to authenticate.

Server_Signature

Signature returned only for an authentic client.

Valid

Set True only when the proof matches Credential.

Channel_Binding

Expected base64 GS2 channel-binding value.

Raised exceptions
SCRAM_Error

A message is malformed or inconsistent.

Verify_Server_Final

procedure Verify_Server_Final
  (Message : String; Expected_Server_Signature : Digest)

Authenticate a server-final message against the locally derived value.

Parameters
Message

Server-final attributes containing v or e.

Expected_Server_Signature

Signature derived by the client.

Raised exceptions
SCRAM_Error

The server reports an error or signatures differ.