Distinguish ED25519 for signing and X25519 for key exchange and encryption
This commit is contained in:
parent
2680bc40d6
commit
46e8b3c8e8
5 changed files with 76 additions and 34 deletions
|
@ -7,15 +7,17 @@
|
|||
|
||||
#define TIME_SIZE sizeof(time_t)
|
||||
#define SIGN_SIZE crypto_sign_BYTES
|
||||
#define PK_RAW_SIZE crypto_kx_PUBLICKEYBYTES
|
||||
#define SK_RAW_SIZE crypto_sign_SECRETKEYBYTES
|
||||
#define PK_DATA_SIZE PK_RAW_SIZE + MAX_NAME + TIME_SIZE
|
||||
#define PK_ED25519_SIZE crypto_sign_PUBLICKEYBYTES /* 32, size for signature keys */
|
||||
#define SK_ED25519_SIZE crypto_sign_SECRETKEYBYTES /* 64 */
|
||||
#define PK_X25519_SIZE crypto_kx_PUBLICKEYBYTES /* 32, size for key exchange keys */
|
||||
#define SK_X25519_SIZE crypto_kx_PUBLICKEYBYTES /* same with public key */
|
||||
#define PK_DATA_SIZE PK_ED25519_SIZE + MAX_NAME + TIME_SIZE
|
||||
#define PK_SIZE PK_DATA_SIZE + SIGN_SIZE /* Size with signature */
|
||||
#define SK_SIZE SK_RAW_SIZE
|
||||
#define SK_SIZE SK_ED25519_SIZE
|
||||
#define SHARED_KEY_SIZE crypto_kx_SESSIONKEYBYTES
|
||||
|
||||
typedef struct public_key {
|
||||
uint8_t raw[PK_RAW_SIZE];
|
||||
uint8_t raw[PK_ED25519_SIZE];
|
||||
uint8_t username[MAX_NAME];
|
||||
time_t creation;
|
||||
uint8_t signature[SIGN_SIZE];
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
keypair_t *create_keypair(char *username)
|
||||
{
|
||||
uint8_t pk_raw[PK_RAW_SIZE], sk[SK_SIZE], pk_data[PK_DATA_SIZE],
|
||||
uint8_t pk_raw[PK_ED25519_SIZE], sk[SK_SIZE], pk_data[PK_DATA_SIZE],
|
||||
username_padded[MAX_NAME], pk_hash[HASH_SIZE], pk_sign[SIGN_SIZE],
|
||||
pk[PK_SIZE];
|
||||
|
||||
|
@ -22,9 +22,9 @@ keypair_t *create_keypair(char *username)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(pk_data, pk_raw, PK_RAW_SIZE);
|
||||
memcpy(pk_data + PK_RAW_SIZE, username_padded, MAX_NAME);
|
||||
memcpy(pk_data + PK_RAW_SIZE + MAX_NAME, ¤t_time, TIME_SIZE);
|
||||
memcpy(pk_data, pk_raw, PK_ED25519_SIZE);
|
||||
memcpy(pk_data + PK_ED25519_SIZE, username_padded, MAX_NAME);
|
||||
memcpy(pk_data + PK_ED25519_SIZE + MAX_NAME, ¤t_time, TIME_SIZE);
|
||||
|
||||
crypto_generichash(pk_hash, HASH_SIZE, pk_data, PK_DATA_SIZE, NULL, 0);
|
||||
crypto_sign_detached(pk_sign, NULL, pk_hash, HASH_SIZE, sk);
|
||||
|
@ -53,7 +53,7 @@ keypair_t *create_keypair(char *username)
|
|||
fclose(keyf);
|
||||
|
||||
keypair_t *kp = memalloc(sizeof(keypair_t));
|
||||
memcpy(kp->pk.raw, pk_raw, PK_RAW_SIZE);
|
||||
memcpy(kp->pk.raw, pk_raw, PK_ED25519_SIZE);
|
||||
memcpy(kp->pk.username, username_padded, MAX_NAME);
|
||||
kp->pk.creation = current_time;
|
||||
memcpy(kp->pk.signature, pk_sign, SIGN_SIZE);
|
||||
|
@ -92,10 +92,10 @@ keypair_t *get_keypair(char *username)
|
|||
|
||||
keypair_t *kp = memalloc(sizeof(keypair_t));
|
||||
|
||||
memcpy(kp->pk.raw, pk, PK_RAW_SIZE);
|
||||
memcpy(kp->pk.username, pk + PK_RAW_SIZE, MAX_NAME);
|
||||
memcpy(&kp->pk.creation, pk + PK_RAW_SIZE + MAX_NAME, TIME_SIZE);
|
||||
memcpy(kp->pk.signature, pk + PK_RAW_SIZE + MAX_NAME + TIME_SIZE, SIGN_SIZE);
|
||||
memcpy(kp->pk.raw, pk, PK_ED25519_SIZE);
|
||||
memcpy(kp->pk.username, pk + PK_ED25519_SIZE, MAX_NAME);
|
||||
memcpy(&kp->pk.creation, pk + PK_ED25519_SIZE + MAX_NAME, TIME_SIZE);
|
||||
memcpy(kp->pk.signature, pk + PK_DATA_SIZE, SIGN_SIZE);
|
||||
memcpy(kp->pk.full, pk, PK_SIZE);
|
||||
|
||||
memcpy(kp->sk, sk, SK_SIZE);
|
||||
|
@ -108,14 +108,14 @@ keypair_t *get_keypair(char *username)
|
|||
*/
|
||||
uint8_t *get_pk_from_ks(char *username)
|
||||
{
|
||||
size_t bin_len = PK_RAW_SIZE;
|
||||
size_t bin_len = PK_ED25519_SIZE;
|
||||
unsigned char *bin = memalloc(bin_len);
|
||||
/* TEMPORARY */
|
||||
if (strcmp(username, "night") == 0) {
|
||||
sodium_hex2bin(bin, bin_len, "e2f0287d9c23aed8404dd8ba407e7dff8abe40fa98f0b9adf74904978a5fcd50", PK_RAW_SIZE * 2, NULL, NULL, NULL);
|
||||
sodium_hex2bin(bin, bin_len, "e2f0287d9c23aed8404dd8ba407e7dff8abe40fa98f0b9adf74904978a5fcd50", PK_ED25519_SIZE * 2, NULL, NULL, NULL);
|
||||
return bin;
|
||||
} else if (strcmp(username, "palanix") == 0) {
|
||||
sodium_hex2bin(bin, bin_len, "932aee08aa338108e49f65a5c4f0eb0a08a15bf717fdf8c0ff60eefd0ea014ae", PK_RAW_SIZE * 2, NULL, NULL, NULL);
|
||||
sodium_hex2bin(bin, bin_len, "932aee08aa338108e49f65a5c4f0eb0a08a15bf717fdf8c0ff60eefd0ea014ae", PK_ED25519_SIZE * 2, NULL, NULL, NULL);
|
||||
return bin;
|
||||
}
|
||||
return NULL;
|
||||
|
|
41
src/zen/ui.c
41
src/zen/ui.c
|
@ -521,15 +521,30 @@ void send_message()
|
|||
uint8_t *recipient = users->items[current_user].name;
|
||||
|
||||
keypair_t *kp_from = get_keypair(USERNAME);
|
||||
keypair_t *kp_to = get_keypair(recipient);
|
||||
uint8_t *pk_to = get_pk_from_ks(recipient); /* ed25519 */
|
||||
|
||||
int status = ZSM_STA_SUCCESS;
|
||||
|
||||
uint8_t shared_key[SHARED_KEY_SIZE];
|
||||
if (crypto_kx_client_session_keys(shared_key, NULL, kp_from->pk.raw,
|
||||
kp_from->sk, kp_to->pk.raw) != 0) {
|
||||
/* Recipient public key is suspicious */
|
||||
write_log(LOG_ERROR, "Error performing key exchange with %s", recipient);
|
||||
uint8_t *shared_key = get_sharedkey(recipient);
|
||||
if (shared_key == NULL) {
|
||||
uint8_t shared_key[SHARED_KEY_SIZE];
|
||||
|
||||
/* Key exchange need to be done with x25519 public and secret keys */
|
||||
uint8_t from_pk[PK_X25519_SIZE];
|
||||
uint8_t to_pk[PK_X25519_SIZE];
|
||||
uint8_t from_sk[SK_X25519_SIZE];
|
||||
crypto_sign_ed25519_pk_to_curve25519(from_pk, kp_from->pk.raw);
|
||||
crypto_sign_ed25519_pk_to_curve25519(to_pk, pk_to);
|
||||
crypto_sign_ed25519_sk_to_curve25519(from_sk, kp_from->sk);
|
||||
|
||||
|
||||
if (crypto_kx_client_session_keys(shared_key, NULL, from_pk, from_sk,
|
||||
to_pk) != 0) {
|
||||
deinit();
|
||||
/* Recipient public key is suspicious */
|
||||
error(1, "Error performing key exchange with %s", recipient);
|
||||
}
|
||||
save_sharedkey(recipient, shared_key);
|
||||
}
|
||||
|
||||
size_t content_len = strlen(content);
|
||||
|
@ -548,9 +563,20 @@ void send_message()
|
|||
size_t data_len = MAX_NAME * 2 + NONCE_SIZE + cipher_len;
|
||||
uint8_t *data = memalloc(data_len);
|
||||
|
||||
uint8_t recipient_padded[MAX_NAME];
|
||||
strcpy(recipient_padded, recipient);
|
||||
size_t length = strlen(recipient);
|
||||
if (length < MAX_NAME) {
|
||||
/* Pad with null characters up to max length */
|
||||
memset(recipient_padded + length, 0, MAX_NAME - length);
|
||||
} else {
|
||||
deinit();
|
||||
error(1, "Recipient username must be shorter than MAX_NAME");
|
||||
}
|
||||
|
||||
/* Construct data */
|
||||
memcpy(data, kp_from->pk.username, MAX_NAME);
|
||||
memcpy(data + MAX_NAME, kp_to->pk.username, MAX_NAME);
|
||||
memcpy(data + MAX_NAME, recipient, MAX_NAME);
|
||||
memcpy(data + MAX_NAME * 2, nonce, NONCE_SIZE);
|
||||
memcpy(data + MAX_NAME * 2 + NONCE_SIZE, encrypted, cipher_len);
|
||||
|
||||
|
@ -583,6 +609,7 @@ void ui(int *fd)
|
|||
users = arraylist_init(LINES);
|
||||
marked = arraylist_init(100);
|
||||
sqlite_init();
|
||||
get_users();
|
||||
draw_users();
|
||||
refresh();
|
||||
while (1) {
|
||||
|
|
|
@ -89,14 +89,27 @@ void *receive_worker(void *arg)
|
|||
memcpy(nonce, pkt.data + MAX_NAME * 2, NONCE_SIZE);
|
||||
memcpy(encrypted, pkt.data + MAX_NAME * 2 + NONCE_SIZE, cipher_len);
|
||||
|
||||
keypair_t *kp_from = get_keypair(from);
|
||||
uint8_t *pk_from = get_pk_from_ks(from); /* ed25519 */
|
||||
keypair_t *kp_to = get_keypair(to);
|
||||
|
||||
uint8_t shared_key[SHARED_KEY_SIZE];
|
||||
if (crypto_kx_client_session_keys(shared_key, NULL, kp_from->pk.raw,
|
||||
kp_from->sk, kp_to->pk.raw) != 0) {
|
||||
/* Suspicious server public key, bail out */
|
||||
write_log(LOG_ERROR, "Error performing key exchange with %s", from);
|
||||
|
||||
uint8_t *shared_key = get_sharedkey(from);
|
||||
if (shared_key == NULL) {
|
||||
uint8_t shared_key[SHARED_KEY_SIZE];
|
||||
|
||||
/* Key exchange need to be done with x25519 public and secret keys */
|
||||
uint8_t to_pk[PK_X25519_SIZE];
|
||||
uint8_t from_pk[PK_X25519_SIZE];
|
||||
uint8_t to_sk[SK_X25519_SIZE];
|
||||
crypto_sign_ed25519_pk_to_curve25519(to_pk, kp_to->pk.raw);
|
||||
crypto_sign_ed25519_pk_to_curve25519(from_pk, pk_from);
|
||||
crypto_sign_ed25519_sk_to_curve25519(to_sk, kp_to->sk);
|
||||
|
||||
if (crypto_kx_server_session_keys(shared_key, NULL, to_pk,
|
||||
to_sk, from_pk) != 0) {
|
||||
/* Author public key is suspicious */
|
||||
write_log(LOG_ERROR, "Error performing key exchange with %s", from);
|
||||
}
|
||||
save_sharedkey(from, shared_key);
|
||||
}
|
||||
|
||||
/* We don't need it anymore */
|
||||
|
|
|
@ -36,9 +36,9 @@ int authenticate_client(int clientfd, uint8_t *username)
|
|||
goto failure;
|
||||
}
|
||||
|
||||
uint8_t pk_bin[PK_RAW_SIZE], pk_username[MAX_NAME];
|
||||
memcpy(pk_bin, pkt->data, PK_RAW_SIZE);
|
||||
memcpy(pk_username, pkt->data + PK_RAW_SIZE, MAX_NAME);
|
||||
uint8_t pk_bin[PK_ED25519_SIZE], pk_username[MAX_NAME];
|
||||
memcpy(pk_bin, pkt->data, PK_ED25519_SIZE);
|
||||
memcpy(pk_username, pkt->data + PK_ED25519_SIZE, MAX_NAME);
|
||||
|
||||
if (crypto_sign_verify_detached(pkt->signature, challenge, CHALLENGE_SIZE,
|
||||
pk_bin) != 0) {
|
||||
|
|
Loading…
Reference in a new issue