Implement RSA-AES
parent
ff5ca722b1
commit
727fd785c6
|
@ -46,6 +46,10 @@ enum nvnc_client_state {
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CRYPTO
|
#ifdef HAVE_CRYPTO
|
||||||
VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE,
|
VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE,
|
||||||
|
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_PUBLIC_KEY,
|
||||||
|
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CHALLENGE,
|
||||||
|
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CLIENT_HASH,
|
||||||
|
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CREDENTIALS,
|
||||||
#endif
|
#endif
|
||||||
VNC_CLIENT_STATE_WAITING_FOR_INIT,
|
VNC_CLIENT_STATE_WAITING_FOR_INIT,
|
||||||
VNC_CLIENT_STATE_READY,
|
VNC_CLIENT_STATE_READY,
|
||||||
|
@ -57,6 +61,8 @@ struct aml_handler;
|
||||||
struct aml_idle;
|
struct aml_idle;
|
||||||
struct nvnc_display;
|
struct nvnc_display;
|
||||||
struct crypto_key;
|
struct crypto_key;
|
||||||
|
struct crypto_rsa_pub_key;
|
||||||
|
struct crypto_rsa_priv_key;
|
||||||
|
|
||||||
struct nvnc_common {
|
struct nvnc_common {
|
||||||
void* userdata;
|
void* userdata;
|
||||||
|
@ -100,6 +106,11 @@ struct nvnc_client {
|
||||||
|
|
||||||
#ifdef HAVE_CRYPTO
|
#ifdef HAVE_CRYPTO
|
||||||
struct crypto_key* apple_dh_secret;
|
struct crypto_key* apple_dh_secret;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct crypto_rsa_pub_key *pub;
|
||||||
|
uint8_t challenge[16];
|
||||||
|
} rsa;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,6 +151,11 @@ struct nvnc {
|
||||||
void* auth_ud;
|
void* auth_ud;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CRYPTO
|
||||||
|
struct crypto_rsa_pub_key* rsa_pub;
|
||||||
|
struct crypto_rsa_priv_key* rsa_priv;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t n_damage_clients;
|
uint32_t n_damage_clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ enum rfb_security_type {
|
||||||
RFB_SECURITY_TYPE_INVALID = 0,
|
RFB_SECURITY_TYPE_INVALID = 0,
|
||||||
RFB_SECURITY_TYPE_NONE = 1,
|
RFB_SECURITY_TYPE_NONE = 1,
|
||||||
RFB_SECURITY_TYPE_VNC_AUTH = 2,
|
RFB_SECURITY_TYPE_VNC_AUTH = 2,
|
||||||
|
RFB_SECURITY_TYPE_RSA_AES = 5,
|
||||||
|
RFB_SECURITY_TYPE_RSA_AES_UNENCRYPTED = 6,
|
||||||
RFB_SECURITY_TYPE_TIGHT = 16,
|
RFB_SECURITY_TYPE_TIGHT = 16,
|
||||||
RFB_SECURITY_TYPE_VENCRYPT = 19,
|
RFB_SECURITY_TYPE_VENCRYPT = 19,
|
||||||
RFB_SECURITY_TYPE_APPLE_DH = 30,
|
RFB_SECURITY_TYPE_APPLE_DH = 30,
|
||||||
|
@ -107,6 +109,11 @@ enum rfb_resize_status {
|
||||||
RFB_RESIZE_STATUS_REQUEST_FORWARDED = 4,
|
RFB_RESIZE_STATUS_REQUEST_FORWARDED = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum rfb_rsa_aes_cred_subtype {
|
||||||
|
RFB_RSA_AES_CRED_SUBTYPE_USER_AND_PASS = 1,
|
||||||
|
RFB_RSA_AES_CRED_SUBTYPE_ONLY_PASS = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct rfb_security_types_msg {
|
struct rfb_security_types_msg {
|
||||||
uint8_t n;
|
uint8_t n;
|
||||||
uint8_t types[0];
|
uint8_t types[0];
|
||||||
|
@ -249,3 +256,13 @@ struct rfb_apple_dh_client_msg {
|
||||||
uint8_t encrypted_credentials[128];
|
uint8_t encrypted_credentials[128];
|
||||||
uint8_t public_key[0];
|
uint8_t public_key[0];
|
||||||
} RFB_PACKED;
|
} RFB_PACKED;
|
||||||
|
|
||||||
|
struct rfb_rsa_aes_pub_key_msg {
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t modulus_and_exponent[0];
|
||||||
|
} RFB_PACKED;
|
||||||
|
|
||||||
|
struct rfb_rsa_aes_challenge_msg {
|
||||||
|
uint16_t length;
|
||||||
|
uint8_t challenge[0];
|
||||||
|
} RFB_PACKED;
|
||||||
|
|
293
src/server.c
293
src/server.c
|
@ -69,6 +69,8 @@
|
||||||
#define DEFAULT_NAME "Neat VNC"
|
#define DEFAULT_NAME "Neat VNC"
|
||||||
#define SECURITY_TYPES_MAX 3
|
#define SECURITY_TYPES_MAX 3
|
||||||
|
|
||||||
|
#define UDIV_UP(a, b) (((a) + (b) - 1) / (b))
|
||||||
|
|
||||||
#define EXPORT __attribute__((visibility("default")))
|
#define EXPORT __attribute__((visibility("default")))
|
||||||
|
|
||||||
static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb);
|
static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb);
|
||||||
|
@ -227,6 +229,7 @@ static int on_version_message(struct nvnc_client* client)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CRYPTO
|
#ifdef HAVE_CRYPTO
|
||||||
|
security->types[security->n++] = RFB_SECURITY_TYPE_RSA_AES;
|
||||||
security->types[security->n++] = RFB_SECURITY_TYPE_APPLE_DH;
|
security->types[security->n++] = RFB_SECURITY_TYPE_APPLE_DH;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -480,6 +483,283 @@ static int on_apple_dh_response(struct nvnc_client* client)
|
||||||
|
|
||||||
return sizeof(*msg) + key_len;
|
return sizeof(*msg) + key_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rsa_aes_send_public_key(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
struct nvnc* server = client->server;
|
||||||
|
|
||||||
|
// TODO: The key should be loaded if it exists; otherwise generated and
|
||||||
|
// saved.
|
||||||
|
if (!server->rsa_priv) {
|
||||||
|
assert(!server->rsa_pub);
|
||||||
|
|
||||||
|
server->rsa_priv = crypto_rsa_priv_key_new();
|
||||||
|
server->rsa_pub = crypto_rsa_pub_key_new();
|
||||||
|
|
||||||
|
crypto_rsa_keygen(server->rsa_pub, server->rsa_priv);
|
||||||
|
}
|
||||||
|
assert(server->rsa_pub && server->rsa_priv);
|
||||||
|
|
||||||
|
char buffer[sizeof(struct rfb_rsa_aes_pub_key_msg) + 512] = {};
|
||||||
|
struct rfb_rsa_aes_pub_key_msg* msg =
|
||||||
|
(struct rfb_rsa_aes_pub_key_msg*)buffer;
|
||||||
|
|
||||||
|
uint8_t* modulus = msg->modulus_and_exponent;
|
||||||
|
uint8_t* exponent = msg->modulus_and_exponent + 256;
|
||||||
|
|
||||||
|
msg->length = htonl(2048);
|
||||||
|
crypto_rsa_pub_key_modulus(server->rsa_pub, modulus, 256);
|
||||||
|
crypto_rsa_pub_key_exponent(server->rsa_pub, exponent, 256);
|
||||||
|
|
||||||
|
crypto_dump_base16("Sending public key modulus", modulus, 256);
|
||||||
|
crypto_dump_base16("Sending public key exponent", exponent, 256);
|
||||||
|
|
||||||
|
stream_write(client->net_stream, buffer, sizeof(buffer), NULL, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsa_aes_send_challenge(struct nvnc_client* client,
|
||||||
|
struct crypto_rsa_pub_key* pub)
|
||||||
|
{
|
||||||
|
crypto_random(client->rsa.challenge, sizeof(client->rsa.challenge));
|
||||||
|
|
||||||
|
uint8_t buffer[1024];
|
||||||
|
struct rfb_rsa_aes_challenge_msg *msg =
|
||||||
|
(struct rfb_rsa_aes_challenge_msg*)buffer;
|
||||||
|
|
||||||
|
ssize_t len = crypto_rsa_encrypt(pub, msg->challenge, 256,
|
||||||
|
client->rsa.challenge, sizeof(client->rsa.challenge));
|
||||||
|
msg->length = htons(len);
|
||||||
|
|
||||||
|
nvnc_trace("Challenge length is %zd", len);
|
||||||
|
|
||||||
|
stream_write(client->net_stream, buffer, sizeof(*msg) + len, NULL, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_rsa_aes_public_key(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
struct rfb_rsa_aes_pub_key_msg* msg =
|
||||||
|
(void*)(client->msg_buffer + client->buffer_index);
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index < sizeof(*msg))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint32_t bit_length = ntohl(msg->length);
|
||||||
|
size_t byte_length = UDIV_UP(bit_length, 8);
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index <
|
||||||
|
sizeof(*msg) + byte_length * 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nvnc_trace("Got public key with bit size %d", bit_length);
|
||||||
|
|
||||||
|
const uint8_t* modulus = msg->modulus_and_exponent;
|
||||||
|
const uint8_t* exponent = msg->modulus_and_exponent + byte_length;
|
||||||
|
|
||||||
|
crypto_dump_base16("Got public key modulus", modulus, byte_length);
|
||||||
|
crypto_dump_base16("Got public key exponent", exponent, byte_length);
|
||||||
|
|
||||||
|
client->rsa.pub =
|
||||||
|
crypto_rsa_pub_key_import(modulus, exponent, byte_length);
|
||||||
|
assert(client->rsa.pub);
|
||||||
|
|
||||||
|
uint8_t foo[256];
|
||||||
|
crypto_rsa_pub_key_exponent(client->rsa.pub, foo, 256);
|
||||||
|
crypto_dump_base16("Got public key exponent check", foo, 256);
|
||||||
|
|
||||||
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CHALLENGE;
|
||||||
|
rsa_aes_send_challenge(client, client->rsa.pub);
|
||||||
|
|
||||||
|
return sizeof(*msg) + byte_length * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_rsa_aes_challenge(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
struct rfb_rsa_aes_challenge_msg* msg =
|
||||||
|
(void*)(client->msg_buffer + client->buffer_index);
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index < sizeof(*msg))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint16_t length = ntohs(msg->length);
|
||||||
|
if (client->buffer_len - client->buffer_index < sizeof(*msg) + length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
crypto_dump_base16("client buffer", client->msg_buffer +
|
||||||
|
client->buffer_index, client->buffer_len -
|
||||||
|
client->buffer_index);
|
||||||
|
|
||||||
|
struct nvnc* server = client->server;
|
||||||
|
|
||||||
|
nvnc_trace("Encrypted challenge has length: %d", length);
|
||||||
|
|
||||||
|
uint8_t client_random[16] = {};
|
||||||
|
ssize_t len = crypto_rsa_decrypt(server->rsa_priv, client_random,
|
||||||
|
sizeof(client_random), msg->challenge, length);
|
||||||
|
if (len < 0) {
|
||||||
|
nvnc_log(NVNC_LOG_ERROR, "Failed to decrypt client's challenge");
|
||||||
|
client->state = VNC_CLIENT_STATE_ERROR;
|
||||||
|
nvnc_client_close(client);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvnc_trace("Decrypted challenge has length: %zd", len);
|
||||||
|
crypto_dump_base16("Got challenge", client_random, 16);
|
||||||
|
|
||||||
|
uint8_t client_session_key[16];
|
||||||
|
uint8_t server_session_key[16];
|
||||||
|
|
||||||
|
struct crypto_hash* hasher = crypto_hash_new(CRYPTO_HASH_SHA1);
|
||||||
|
// ClientSessionKey = the first 16 bytes of SHA1(ServerRandom || ClientRandom)
|
||||||
|
crypto_hash_append(hasher, client->rsa.challenge, 16);
|
||||||
|
crypto_hash_append(hasher, client_random, 16);
|
||||||
|
crypto_hash_digest(hasher, client_session_key, 16);
|
||||||
|
|
||||||
|
// ServerSessionKey = the first 16 bytes of SHA1(ClientRandom || ServerRandom)
|
||||||
|
crypto_hash_append(hasher, client_random, 16);
|
||||||
|
crypto_hash_append(hasher, client->rsa.challenge, 16);
|
||||||
|
crypto_hash_digest(hasher, server_session_key, 16);
|
||||||
|
|
||||||
|
crypto_dump_base64("Client session key", client_session_key,
|
||||||
|
sizeof(client_session_key));
|
||||||
|
crypto_dump_base64("Server session key", server_session_key,
|
||||||
|
sizeof(server_session_key));
|
||||||
|
|
||||||
|
struct crypto_cipher* cipher = crypto_cipher_new(server_session_key,
|
||||||
|
client_session_key, CRYPTO_CIPHER_AES_EAX);
|
||||||
|
assert(cipher);
|
||||||
|
stream_install_cipher(client->net_stream, cipher);
|
||||||
|
|
||||||
|
uint8_t server_modulus[256];
|
||||||
|
uint8_t server_exponent[256];
|
||||||
|
crypto_rsa_pub_key_modulus(server->rsa_pub, server_modulus, 256);
|
||||||
|
crypto_rsa_pub_key_exponent(server->rsa_pub, server_exponent, 256);
|
||||||
|
|
||||||
|
size_t client_key_len = crypto_rsa_pub_key_length(client->rsa.pub);
|
||||||
|
uint8_t* client_modulus = malloc(client_key_len * 2);
|
||||||
|
uint8_t* client_exponent = client_modulus + client_key_len;
|
||||||
|
|
||||||
|
crypto_rsa_pub_key_modulus(client->rsa.pub, client_modulus,
|
||||||
|
client_key_len);
|
||||||
|
crypto_rsa_pub_key_exponent(client->rsa.pub, client_exponent,
|
||||||
|
client_key_len);
|
||||||
|
|
||||||
|
uint32_t server_key_len_be = htonl(256 * 8);
|
||||||
|
uint32_t client_key_len_be = htonl(client_key_len * 8);
|
||||||
|
|
||||||
|
uint8_t server_hash[20] = {};
|
||||||
|
crypto_hash_append(hasher, (uint8_t*)&server_key_len_be, 4);
|
||||||
|
crypto_hash_append(hasher, server_modulus, 256);
|
||||||
|
crypto_hash_append(hasher, server_exponent, 256);
|
||||||
|
crypto_hash_append(hasher, (uint8_t*)&client_key_len_be, 4);
|
||||||
|
crypto_hash_append(hasher, client_modulus, client_key_len);
|
||||||
|
crypto_hash_append(hasher, client_exponent, client_key_len);
|
||||||
|
crypto_hash_digest(hasher, server_hash, 20);
|
||||||
|
|
||||||
|
free(client_modulus);
|
||||||
|
crypto_hash_del(hasher);
|
||||||
|
|
||||||
|
crypto_dump_base16("Server hash", server_hash, 20);
|
||||||
|
|
||||||
|
stream_write(client->net_stream, server_hash, 20, NULL, NULL);
|
||||||
|
|
||||||
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CLIENT_HASH;
|
||||||
|
done:
|
||||||
|
return sizeof(*msg) + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_rsa_aes_client_hash(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
const char* msg = (void*)(client->msg_buffer + client->buffer_index);
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index < 20)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct nvnc* server = client->server;
|
||||||
|
|
||||||
|
struct crypto_hash* hasher = crypto_hash_new(CRYPTO_HASH_SHA1);
|
||||||
|
uint8_t server_modulus[256];
|
||||||
|
uint8_t server_exponent[256];
|
||||||
|
crypto_rsa_pub_key_modulus(server->rsa_pub, server_modulus, 256);
|
||||||
|
crypto_rsa_pub_key_exponent(server->rsa_pub, server_exponent, 256);
|
||||||
|
|
||||||
|
size_t client_key_len = crypto_rsa_pub_key_length(client->rsa.pub);
|
||||||
|
uint8_t* client_modulus = malloc(client_key_len * 2);
|
||||||
|
uint8_t* client_exponent = client_modulus + client_key_len;
|
||||||
|
|
||||||
|
crypto_rsa_pub_key_modulus(client->rsa.pub, client_modulus,
|
||||||
|
client_key_len);
|
||||||
|
crypto_rsa_pub_key_exponent(client->rsa.pub, client_exponent,
|
||||||
|
client_key_len);
|
||||||
|
|
||||||
|
uint32_t server_key_len_be = htonl(256 * 8);
|
||||||
|
uint32_t client_key_len_be = htonl(client_key_len * 8);
|
||||||
|
|
||||||
|
uint8_t client_hash[20] = {};
|
||||||
|
crypto_hash_append(hasher, (uint8_t*)&client_key_len_be, 4);
|
||||||
|
crypto_hash_append(hasher, client_modulus, client_key_len);
|
||||||
|
crypto_hash_append(hasher, client_exponent, client_key_len);
|
||||||
|
crypto_hash_append(hasher, (uint8_t*)&server_key_len_be, 4);
|
||||||
|
crypto_hash_append(hasher, server_modulus, 256);
|
||||||
|
crypto_hash_append(hasher, server_exponent, 256);
|
||||||
|
crypto_hash_digest(hasher, client_hash, 20);
|
||||||
|
|
||||||
|
free(client_modulus);
|
||||||
|
crypto_hash_del(hasher);
|
||||||
|
|
||||||
|
crypto_dump_base16("Client hash", client_hash, 20);
|
||||||
|
|
||||||
|
if (memcmp(msg, client_hash, 20) != 0) {
|
||||||
|
nvnc_log(NVNC_LOG_INFO, "Client hash mismatch");
|
||||||
|
// TODO: Close the connection or something
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Read this from config
|
||||||
|
uint8_t subtype = RFB_RSA_AES_CRED_SUBTYPE_USER_AND_PASS;
|
||||||
|
stream_write(client->net_stream, &subtype, 1, NULL, NULL);
|
||||||
|
|
||||||
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CREDENTIALS;
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_rsa_aes_credentials(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
const uint8_t* msg = (void*)(client->msg_buffer + client->buffer_index);
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size_t username_len = msg[0];
|
||||||
|
if (client->buffer_len - client->buffer_index < 2 + username_len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size_t password_len = msg[1 + username_len];
|
||||||
|
if (client->buffer_len - client->buffer_index < 2 + username_len +
|
||||||
|
password_len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct nvnc* server = client->server;
|
||||||
|
|
||||||
|
char username[256];
|
||||||
|
char password[256];
|
||||||
|
|
||||||
|
strlcpy(username, (const char*)(msg + 1), username_len + 1);
|
||||||
|
strlcpy(password, (const char*)(msg + 2 + username_len),
|
||||||
|
password_len + 1);
|
||||||
|
|
||||||
|
if (server->auth_fn(username, password, server->auth_ud)) {
|
||||||
|
nvnc_log(NVNC_LOG_INFO, "User \"%s\" authenticated", username);
|
||||||
|
security_handshake_ok(client);
|
||||||
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT;
|
||||||
|
} else {
|
||||||
|
nvnc_log(NVNC_LOG_INFO, "User \"%s\" rejected", username);
|
||||||
|
security_handshake_failed(client, "Invalid username or password");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 + username_len + password_len;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // HAVE_CRYPTO
|
#endif // HAVE_CRYPTO
|
||||||
|
|
||||||
static int on_security_message(struct nvnc_client* client)
|
static int on_security_message(struct nvnc_client* client)
|
||||||
|
@ -488,6 +768,7 @@ static int on_security_message(struct nvnc_client* client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint8_t type = client->msg_buffer[client->buffer_index];
|
uint8_t type = client->msg_buffer[client->buffer_index];
|
||||||
|
nvnc_log(NVNC_LOG_DEBUG, "Client chose security type: %d", type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RFB_SECURITY_TYPE_NONE:
|
case RFB_SECURITY_TYPE_NONE:
|
||||||
|
@ -505,6 +786,10 @@ static int on_security_message(struct nvnc_client* client)
|
||||||
apple_dh_send_public_key(client);
|
apple_dh_send_public_key(client);
|
||||||
client->state = VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE;
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE;
|
||||||
break;
|
break;
|
||||||
|
case RFB_SECURITY_TYPE_RSA_AES:
|
||||||
|
rsa_aes_send_public_key(client);
|
||||||
|
client->state = VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_PUBLIC_KEY;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
security_handshake_failed(client, "Unsupported security type");
|
security_handshake_failed(client, "Unsupported security type");
|
||||||
|
@ -1289,6 +1574,14 @@ static int try_read_client_message(struct nvnc_client* client)
|
||||||
#ifdef HAVE_CRYPTO
|
#ifdef HAVE_CRYPTO
|
||||||
case VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE:
|
case VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE:
|
||||||
return on_apple_dh_response(client);
|
return on_apple_dh_response(client);
|
||||||
|
case VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_PUBLIC_KEY:
|
||||||
|
return on_rsa_aes_public_key(client);
|
||||||
|
case VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CHALLENGE:
|
||||||
|
return on_rsa_aes_challenge(client);
|
||||||
|
case VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CLIENT_HASH:
|
||||||
|
return on_rsa_aes_client_hash(client);
|
||||||
|
case VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CREDENTIALS:
|
||||||
|
return on_rsa_aes_credentials(client);
|
||||||
#endif
|
#endif
|
||||||
case VNC_CLIENT_STATE_READY:
|
case VNC_CLIENT_STATE_READY:
|
||||||
return on_client_message(client);
|
return on_client_message(client);
|
||||||
|
|
Loading…
Reference in New Issue