Sovite.SASL.Password (sovite v0.2.0)

Copy Markdown View Source

Stored password hashes: creating them and checking passwords against them.

Formats, compatible with Dovecot and crypt(3):

  • {SCRAM-SHA-256}iterations,salt,stored_key,server_key (parts in base64) - the default. Works with PLAIN, LOGIN, and SCRAM-SHA-256.
  • $6$[rounds=N$]salt$hash (SHA512-CRYPT), also with a {SHA512-CRYPT} prefix.
  • $5$[rounds=N$]salt$hash (SHA256-CRYPT), also with a {SHA256-CRYPT} prefix.
  • {PLAIN}password - the password itself. Not recommended.

Crypt hashes only work with PLAIN and LOGIN, since SCRAM-SHA-256 needs values derived from the password in its own way.

Summary

Types

Values a server needs for SCRAM-SHA-256, see Sovite.SASL.ScramSHA256.

Functions

Spends about as long as verify/2 on a typical hash, then fails. Use it for unknown users, so response times do not reveal which users exist.

Derives SCRAM-SHA-256 values from a password (RFC 5802 §3). The password is prepared with Sovite.SASL.saslprep/1 when possible.

Returns SCRAM-SHA-256 values from a stored hash, if it has them: {SCRAM-SHA-256} hashes, and {PLAIN} ones (derived with a salt fixed per password, so the exchange is repeatable).

Returns whether hash is in a known format.

Checks password against a stored hash. Returns {:error, :unsupported} for a format this module does not know.

Types

scram()

@type scram() :: %{
  salt: binary(),
  iterations: pos_integer(),
  stored_key: binary(),
  server_key: binary()
}

Values a server needs for SCRAM-SHA-256, see Sovite.SASL.ScramSHA256.

Functions

dummy_verify(password)

@spec dummy_verify(String.t()) :: {:error, :mismatch}

Spends about as long as verify/2 on a typical hash, then fails. Use it for unknown users, so response times do not reveal which users exist.

hash(password, scheme \\ :scram_sha256, opts \\ [])

@spec hash(String.t(), :scram_sha256 | :sha512_crypt | :sha256_crypt, keyword()) ::
  String.t()

Hashes password for storage.

Schemes: :scram_sha256 (default; option :iterations, default 4096), :sha512_crypt, and :sha256_crypt (option :rounds, default 5000).

scram(password, salt, iterations)

@spec scram(String.t(), binary(), pos_integer()) :: scram()

Derives SCRAM-SHA-256 values from a password (RFC 5802 §3). The password is prepared with Sovite.SASL.saslprep/1 when possible.

scram_credentials(hash)

@spec scram_credentials(String.t()) :: {:ok, scram()} | :error

Returns SCRAM-SHA-256 values from a stored hash, if it has them: {SCRAM-SHA-256} hashes, and {PLAIN} ones (derived with a salt fixed per password, so the exchange is repeatable).

supported?(hash)

@spec supported?(String.t()) :: boolean()

Returns whether hash is in a known format.

verify(hash, password)

@spec verify(String.t(), String.t()) :: :ok | {:error, :mismatch | :unsupported}

Checks password against a stored hash. Returns {:error, :unsupported} for a format this module does not know.