Minimal, sync SCRAM-SHA-256 state machine (RFC 5802 / RFC 7677) for server and client
roles. No I/O, no async — consumers supply the framing (SMTP/IMAP SASL, PostgreSQL
AuthenticationSASLContinue envelopes, whatever else).
Server-side credentials follow RFC 5802 §3: (salt, iterations, StoredKey, ServerKey). No
plaintext password ever held.
use tinyscram::{Credential, ServerSession, peek_authcid};
let authcid = peek_authcid(client_first_bytes)?;
let credential: Credential = lookup_credential(authcid).await?;
let mut session = ServerSession::new(credential);
let server_first = session.handle_client_first(client_first_bytes)?;
// send server_first, receive client_final
let server_final = session.handle_client_final(client_final_bytes)?;
// send server_final, authentication completeuse tinyscram::ClientSession;
let mut session = ClientSession::new("alice", "secret");
let client_first = session.client_first();
// send client_first, receive server_first
let client_final = session.handle_server_first(server_first_bytes)?;
// send client_final, receive server_final
session.handle_server_final(server_final_bytes)?;use tinyscram::crypto::DerivedKeys;
let salt: [u8; 16] = rand::random();
let keys = DerivedKeys::from_password("user-password", &salt, 4096);
// Store (salt, 4096, keys.stored_key, keys.server_key); discard keys.client_key.The GS2 parser recognises n / y / p=<type>, but ServerSession currently rejects p=
(non-PLUS only). The Gs2Header API is exposed so SCRAM-SHA-256-PLUS can be added without
breaking changes.
Apache-2.0.