diff --git a/src/crypt.c b/src/crypt.c new file mode 100644 index 0000000..cddf8bc --- /dev/null +++ b/src/crypt.c @@ -0,0 +1,79 @@ +#include "crypt.h" + +#include + +int crypt_key_gen(crypt_key_t *k) { + if (crypto_kx_keypair(k->kxPub, k->kxSec) < 0) { + return -1; + } + + if (crypto_sign_keypair(k->signPub, k->signSec) < 0) { + return -1; + } + + k->hasSecKey = true; + + return 0; +} + +int crypt_key_from_hex(crypt_key_t *k, char phex[CRYPT_PUBKEY_HEXSIZE], char shex[CRYPT_SECKEY_HEXSIZE]) { + int res = 0; + res = sodium_hex2bin(k->kxPub, crypto_kx_PUBLICKEYBYTES, phex, crypto_kx_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + res = sodium_hex2bin(k->kxSec, crypto_kx_SECRETKEYBYTES, shex, crypto_kx_SECRETKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + res = sodium_hex2bin(k->signPub, crypto_sign_PUBLICKEYBYTES, phex+(crypto_kx_PUBLICKEYBYTES * 2), crypto_sign_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + res = sodium_hex2bin(k->signSec, crypto_sign_SECRETKEYBYTES, shex+(crypto_kx_SECRETKEYBYTES * 2), crypto_sign_SECRETKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + + k->hasSecKey = true; + + return 0; +} + +int crypt_key_from_hex_public(crypt_key_t *k, char phex[CRYPT_PUBKEY_HEXSIZE]) { + int res = 0; + res = sodium_hex2bin(k->kxPub, crypto_kx_PUBLICKEYBYTES, phex, crypto_kx_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + res = sodium_hex2bin(k->signPub, crypto_sign_PUBLICKEYBYTES, phex+(crypto_kx_PUBLICKEYBYTES * 2), crypto_sign_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (res < 0) + return -1; + + k->hasSecKey = false; + + return 0; +} + +void crypt_key_export_public(crypt_key_t *k, char hex[CRYPT_PUBKEY_HEXSIZE]) { + sodium_bin2hex(hex, crypto_kx_PUBLICKEYBYTES * 2 + 1, k->kxPub, crypto_kx_PUBLICKEYBYTES); + sodium_bin2hex(hex+(crypto_kx_PUBLICKEYBYTES * 2), crypto_sign_PUBLICKEYBYTES * 2 + 1, k->signPub, crypto_sign_PUBLICKEYBYTES); +} + +void crypt_key_export_secret(crypt_key_t *k, char hex[CRYPT_SECKEY_HEXSIZE]) { + sodium_bin2hex(hex, crypto_kx_SECRETKEYBYTES * 2 + 1, k->kxSec, crypto_kx_SECRETKEYBYTES); + sodium_bin2hex(hex+(crypto_kx_SECRETKEYBYTES * 2), crypto_sign_SECRETKEYBYTES * 2 + 1, k->signSec, crypto_sign_SECRETKEYBYTES); +} + +int crypt_session_init(crypt_session_t *s, crypt_key_t *own, crypt_key_t *remote, bool dirClient) { + if (dirClient) { + if (crypto_kx_client_session_keys(s->rx, s->tx, own->kxPub, own->kxSec, remote->kxPub) != 0) { + fprintf(stderr, "Failed to instantiate a client session.\n"); + return -1; + } + } else { + if (crypto_kx_server_session_keys(s->rx, s->tx, own->kxPub, own->kxSec, remote->kxPub) != 0) { + fprintf(stderr, "Failed to instantiate a server session.\n"); + return -1; + } + } + + s->remoteKey = remote; + + return 0; +} \ No newline at end of file diff --git a/src/crypt.h b/src/crypt.h new file mode 100644 index 0000000..aa585c0 --- /dev/null +++ b/src/crypt.h @@ -0,0 +1,34 @@ +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +#include + +#include + +#define CRYPT_PUBKEY_HEXSIZE (crypto_kx_PUBLICKEYBYTES + crypto_sign_PUBLICKEYBYTES) * 2 + 1 +#define CRYPT_SECKEY_HEXSIZE (crypto_kx_SECRETKEYBYTES + crypto_sign_SECRETKEYBYTES) * 2 + 1 + +typedef struct crypt_key_t { + unsigned char kxPub[crypto_kx_PUBLICKEYBYTES]; + unsigned char kxSec[crypto_kx_SECRETKEYBYTES]; + unsigned char signPub[crypto_sign_PUBLICKEYBYTES]; + unsigned char signSec[crypto_sign_SECRETKEYBYTES]; + bool hasSecKey; +} crypt_key_t; + +int crypt_key_gen(crypt_key_t *k); +int crypt_key_from_hex(crypt_key_t *k, char phex[CRYPT_PUBKEY_HEXSIZE], char shex[CRYPT_SECKEY_HEXSIZE]); +int crypt_key_from_hex_public(crypt_key_t *k, char phex[CRYPT_PUBKEY_HEXSIZE]); + +void crypt_key_export_public(crypt_key_t *k, char hex[CRYPT_PUBKEY_HEXSIZE]); +void crypt_key_export_secret(crypt_key_t *k, char hex[CRYPT_SECKEY_HEXSIZE]); + +typedef struct crypt_session_t { + unsigned char rx[crypto_kx_SESSIONKEYBYTES]; + unsigned char tx[crypto_kx_SESSIONKEYBYTES]; + crypt_key_t *remoteKey; +} crypt_session_t; + +int crypt_session_init(crypt_session_t *s, crypt_key_t *own, crypt_key_t *remote, bool dirClient); + +#endif /* _CRYPTO_H_ */ \ No newline at end of file diff --git a/src/crypto.h b/src/crypto.h deleted file mode 100644 index d0ab3bf..0000000 --- a/src/crypto.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _CRYPTO_H_ -#define _CRYPTO_H_ - - - -#endif /* _CRYPTO_H_ */ \ No newline at end of file