//
// Aspia Project
// Copyright (C) 2016-2024 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

syntax = "proto3";

option optimize_for = LITE_RUNTIME;

import "common.proto";

package proto;

// 1. After the connection is established, the client sends message |ClientHello| to the server.
//    Field |methods| contains supported methods.
// 2. The server selects the preferred method and sends the message |ServerHello|.
//    Field |method| contains the selected method.
//
// Description of algorithms |ALGORITHM_SRP_*| (authentication and key exchange):
// 1. The client sends message |SrpIdentify| with field |username| containing the user name.
// 2. The server searches for a user who has the same username and sends a message
//    |SrpServerKeyExchange|.
//    Fields |number|, |generator|, |salt|, |B| contain the values stored in the user profile
//    (for more details see RFC 5054).
//    Field |iv| contains a random initialization vector specific to the encryption algorithm.
// 3. The client sends a message |SrpClientKeyExchange|.
//    Field |A| contains the calculated value.
//    Field |iv| contains a random initialization vector specific to the encryption algorithm.
//
//    Now the client and the server have encryption keys and initialization vectors. These keys
//    can be correct or incorrect. Authentication and key exchange are considered complete.
//    After the stage of authentication and exchange of keys, the authorization stage begins.
//
// Description of authorization:
// 1. The server sends the message |AuthorizationChallenge|. Field |session_types| contains the
//    allowed session types for the user. This message should be encrypted using the key and the
//    initialization vector received at the authentication stage.
// 2. The client decrypts the message from the server.
//    If the message can not be decrypted, then the user name and password entered are incorrect.
//    The client selects the session type from the offered by the server and sends the message
//    |AuthorizationResponse|. Field |session_type| contains the selected session type.
//

enum Identify
{
    IDENTIFY_SRP       = 0;
    IDENTIFY_ANONYMOUS = 1;
}

enum Encryption
{
    ENCRYPTION_UNKNOWN           = 0;
    ENCRYPTION_CHACHA20_POLY1305 = 1;
    ENCRYPTION_AES256_GCM        = 2;
}

// Client to server.
message ClientHello
{
    uint32 encryption = 1;
    Identify identify = 2;
    bytes public_key  = 3;
    bytes iv          = 4;
    Version version   = 5;
}

// Server to client.
message ServerHello
{
    Encryption encryption = 1;
    bytes iv              = 2;
    Version version       = 3;
}

// Client to server.
message SrpIdentify
{
    string username = 1;
}

// Server to client.
message SrpServerKeyExchange
{
    bytes number    = 1;
    bytes generator = 2;
    bytes salt      = 3;
    bytes B         = 4;
    bytes iv        = 5;
}

// Client to server.
message SrpClientKeyExchange
{
    bytes A  = 1;
    bytes iv = 2;
}

// Server to client.
message SessionChallenge
{
    Version version      = 1; // Deprecated since version 2.7.0. For backward compatibility only.
    uint32 session_types = 2;
    uint32 cpu_cores     = 3;
    string os_name       = 4;
    string computer_name = 5;
    string arch          = 6;
    string display_name  = 7;
}

// Client to server.
message SessionResponse
{
    Version version      = 1; // Deprecated since version 2.7.0. For backward compatibility only.
    uint32 session_type  = 2;
    uint32 cpu_cores     = 3;
    string os_name       = 4;
    string computer_name = 5;
    string arch          = 6;
    string display_name  = 7;
}
