
//////////////////////////////////////////////////////////////////////////////
//
//   FlatBuffers schema for WAMP v2 messages
//   Copyright (c) typedef int GmbH and contributors
//   Licensed under the MIT License (MIT)
//
//////////////////////////////////////////////////////////////////////////////

include "types.fbs";
include "roles.fbs";

namespace wamp.proto;


/// WAMP authentication method (see: WAMP protocol spec, "13. Authentication Methods").
enum AuthMethod: uint8
{
    /// Not set / not authenticated: `anonymous`.
    NULL = 0,

    /// WAMP Ticket authentication: `ticket` (see: WAMP protocol spec, "13.1. Ticket-based Authentication").
    TICKET = 1,

    /// WAMP Challenge-Response authentication: `wampcra` (see: WAMP protocol spec, "13.2. Challenge Response Authentication").
    CRA = 2,

    /// WAMP Salted Challenge Response authentication: `wamp-scram` (see: WAMP protocol spec, "13.3. Salted Challenge Response Authentication").
    SCRAM = 3,

    /// WAMP Cryptosign authentication: `cryptosign` (see: WAMP protocol spec, "13.4. Cryptosign-based Authentication").
    CRYPTOSIGN = 4
}


/// TLS channel binding type (see: RFC5929 https://www.rfc-editor.org/rfc/rfc5929 and RFC9266 https://www.rfc-editor.org/rfc/rfc9266).
enum TLSChannelBinding: uint8
{
    /// Not set / no channel binding.
    NULL = 0,

    // RFC 5929 `tls-unique`. Available for TLS connections; historically used as the default for many SASL/SCRAM uses over TLS ≤ 1.2. Care needed with renegotiation and with TLS versions where the triple-handshake / EMS issues apply (see RFCs).
    TLS_UNIQUE = 1,

    /// RFC 5929 `tls-unique-for-telnet`. Only relevant to TELNET / TELNET AUTH usage. See RFC 5929 for details and applicability guidance.
    TLS_UNIQUE_TELNET = 2,

    /// RFC 5929 `tls-server-end-point`. Only available when a server certificate is used (i.e., cipher suites that include the Certificate handshake message / PKIX). Not applicable to OpenPGP server certificates. Recommended for situations where server-side proxies must interoperate without changes.
    TLS_SERVER_ENDPOINT = 3,

    /// RFC 9266 `tls-exporter`. Defined to address TLS 1.3 (where the older tls-unique semantics are not reliably available). RFC 9266 updates defaults for TLS ≥ 1.3: when channel bindings are used for TLS 1.3, tls-exporter is the mandatory/expected mechanism. Not defined for connections where TLS renegotiation is enabled.
    TLS_EXPORTER = 4
}


/// Key Derivation Functions, e.g. WAMP SCRAM uses a password-based key derivation function (KDF) to hash user passwords. WAMP-SCRAM supports both Argon2 and PBKDF2 as the KDF (see: WAMP protocol specification, "SCRAM Algorithms").
enum KDF: uint8
{
    /// Not set / no TLS channel binding.
    NULL = 0,

    /// Argon2id variant of Argon2, version 1.3 - `argon2id13`.
    ARGON2ID13 = 1,

    /// PBKDF2 - `pbkdf2`.
    PBKDF2 = 2
}



//
// WAMP-Ticket Authentication
//

table AuthTicketRequest
{
}

table AuthTicketChallenge
{
}

table AuthTicketWelcome
{
}


//
// WAMP-CRA Authentication
//

table AuthCraRequest
{
    // nothing here
}

table AuthCraChallenge
{
    // The challenge sent by the router.
    challenge: string (required);

    // If using PBKDF2 password salting with WAMP-CRA, the user salt.
    salt: string;

    // If using PBKDF2 password salting, the iterations in the salting.
    iterations: uint32 = 1000;

    // If using PBKDF2 password salting, the keylen in the salting.
    keylen: uint8 = 32;
}

table AuthCraWelcome
{
    // nothing here
}


//
// WAMP-SCRAM Authentication
//

table AuthScramRequest
{
    // A base64-encoded sequence of random octets, generated by the client.
    nonce: string (required, base64);

    // Optional requested channel binding type.
    channel_binding: TLSChannelBinding;
}

table AuthScramChallenge
{
    // A server-generatated nonce that is appended to the client-generated
    // nonce sent in the previous HELLO message.
    nonce: string (required, base64);

    // The base64-encoded salt for this user, to be passed to the key
    // derivation function. This value is stored with each user record in
    // the authentication database.
    salt: string (required, base64);

    // The key derivation function (KDF) used to hash the password. This
    // value is stored with each user record in the authentication database.
    kdf: KDF = ARGON2ID13;

    // The execution time cost factor to use for generating the
    // SaltedPassword hash. This value is stored with each user record in
    // the authentication database.
    iterations: uint32;

    // The memory cost factor to use for generating the SaltedPassword hash.
    // This is only used by the Argon2 key derivation function, where it is
    // stored with each user record in the authentication database.
    memory: uint32;

    // Channel binding type, if channel binding was requested and is actually used.
    channel_binding: TLSChannelBinding;
}

table AuthScramWelcome
{
    // The base64-encoded ServerSignature, computed as described in the
    // SCRAM Algorithms section.
    verifier: string;
}


//
// WAMP-Cryptosign Authentication
//

table AuthCryptosignRequest
{
    pubkey: string (required, hex);

    // Optional requested channel binding type.
    channel_binding: TLSChannelBinding;
}


table AuthCryptosignChallenge
{
    // Channel binding type, if channel binding was requested and is actually used.
    channel_binding: TLSChannelBinding;
}

table AuthCryptosignWelcome
{
}


// Any authentication factor usable in HELLO.
union AuthFactor
{
    AuthTicketRequest,
    AuthCraRequest,
    AuthScramRequest,
    AuthCryptosignRequest
}


// When more than one authentication factor slot in the HELLO message
// is filled, determines how the factor are to be combined. With FIRST,
// the client hints the router to choose the first authentication factor
// from the list that is acceptable. With MULTIFACTOR, the router will
// challenge the client for _all_ authentication factors filled.
enum AuthMode: uint8
{
    // Let router choose first (filled) acceptable authentication factor.
    FIRST = 0,

    // Router will challenge for multi-factor authentication for all
    // factors, and sequentially using multiple CHALLENGE and AUTHENTICATE
    // message roundtrips.
    MULTIFACTOR = 1,
}


table HelloNew
{
    // Supported client roles and features.
    roles: ClientRoles (required);

    // Realm requested to join.
    realm: string (uri);

    // Client authentication ID requested.
    authid: string (principal);

    // Client authentication role requested.
    authrole: string (principal);

    // Requested authentication level.
    authmode: AuthMode;

    // First authentication factor.
    authfactor1: AuthFactor;

    // Second authentication factor.
    authfactor2: AuthFactor;

    // Third authentication factor.
    authfactor3: AuthFactor;

    // Whether the client wants this to be a session that can be
    // later resumed (HELLO.Details.resumable).
    resumable: bool;

    // The session the client would like to resume (HELLO.Details.resume_session).
    resume_session: uint64;

    // The secure authorisation token to resume the session (HELLO.Details.resume_token).
    resume_token: string;
}


