
//////////////////////////////////////////////////////////////////////////////
//
//   FlatBuffers schema for WAMP v2 messages
//   Copyright (c) Crossbar.io Technologies GmbH and contributors
//   Licensed under the MIT License (MIT)
//
//////////////////////////////////////////////////////////////////////////////

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

namespace wamp.proto;


// WAMP authentication method.
enum AuthMethod: uint8
{
    // Pseudo anonymous authentication.
    ANONYMOUS = 0,

    // Trnasport level authentication based on HTTP header cookie set.
    COOKIE = 1,

    // Transport level authentication based on TLS client certificate presented.
    TLS = 2,

    // Authentication using WAMP-Ticket, a flexible one time token/password scheme..
    TICKET = 3,

    // Authentication using WAMP-CRA, a simple challenge-response scheme.
    CRA = 4,

    // Authentication using WAMP-SCRAM, a sophisticated challenge-response scheme.
    SCRAM = 5,

    // Authentication using WAMP-Cryptosign, a highly secure public-private-key scheme.
    CRYPTOSIGN = 6
}


enum ChannelBinding: uint8
{
    NONE = 0,
    TLS_UNIQUE = 1,
}


enum Kdf: uint8
{
    NONE = 0,

    PBKDF2 = 1,

    // Argon2id variant of Argon2, version 1.3 (`argon2id13`).
    ARGON2 = 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: ChannelBinding;
}

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 = ARGON2;

    // 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: ChannelBinding;
}

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: ChannelBinding;
}


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

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;
}


