diff --git a/src/crypt.c b/src/crypt.c index 9efb2d7..259cb0f 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -1,7 +1,7 @@ #include "crypt.h" -#include #include +#include int crypt_key_gen(crypt_key_t *const k) { if (crypto_kx_keypair(k->kx_pub, k->kx_sec) < 0) { @@ -17,7 +17,7 @@ int crypt_key_gen(crypt_key_t *const k) { return 0; } -int crypt_key_from_hex(crypt_key_t *const k, char phex[CRYPT_PKEY_HEXLEN], char shex[CRYPT_SKEY_HEXLEN]) { +int crypt_key_from_hex(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN], const char shex[CRYPT_SKEY_HEXLEN]) { if (sodium_hex2bin(k->kx_pub, CRYPT_KX_PKEY_LEN, phex, CRYPT_KX_PKEY_LEN * 2, NULL, NULL, NULL) < 0) return -1; if (sodium_hex2bin(k->kx_sec, CRYPT_KX_SKEY_LEN, shex, CRYPT_KX_SKEY_LEN * 2, NULL, NULL, NULL) < 0) @@ -32,7 +32,7 @@ int crypt_key_from_hex(crypt_key_t *const k, char phex[CRYPT_PKEY_HEXLEN], char return 0; } -int crypt_key_from_hex_public(crypt_key_t *const k, char phex[CRYPT_PKEY_HEXLEN]) { +int crypt_key_from_hex_public(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN]) { if (sodium_hex2bin(k->kx_pub, CRYPT_KX_PKEY_LEN, phex, CRYPT_KX_PKEY_LEN * 2, NULL, NULL, NULL) < 0) return -1; if (sodium_hex2bin(k->sign_pub, CRYPT_SIGN_PKEY_LEN, phex+(CRYPT_KX_PKEY_LEN * 2), CRYPT_SIGN_PKEY_LEN * 2, NULL, NULL, NULL) < 0) @@ -104,14 +104,23 @@ int crypt_store_key(const crypt_key_t *const k, FILE *const pub, FILE *const sec return 0; } -unsigned char *crypt_hello(const crypt_key_t *const own, long long unsigned int *const sign_len) { - char pub_hex[CRYPT_PKEY_HEXLEN]; - crypt_key_export_public(own, pub_hex); - *sign_len = crypto_sign_BYTES + CRYPT_PKEY_HEXLEN; - unsigned char *sign = (unsigned char *)malloc(*sign_len * sizeof(unsigned char)); - if (crypto_sign(sign, sign_len, (const unsigned char *)pub_hex, CRYPT_PKEY_HEXLEN, own->sign_sec) == -1) +unsigned char *crypt_hello(const crypt_key_t *const own) { + unsigned char *hello = (unsigned char *)malloc(CRYPT_HELLO_LEN * sizeof(unsigned char)); + + crypt_key_export_public(own, (char *const)hello); + + if (crypto_sign_detached(hello+CRYPT_PKEY_HEXLEN, NULL, (const unsigned char *)hello, CRYPT_PKEY_HEXLEN, own->sign_sec) == -1) { return NULL; - return sign; + } + + return hello; +} + +int crypt_hello_verify(const unsigned char *const hello, crypt_key_t *const remote) { + if (crypt_key_from_hex_public(remote, (const char *const)hello) < 0) + return -1; + + return crypto_sign_verify_detached(hello+CRYPT_PKEY_HEXLEN, (const unsigned char *const)hello, CRYPT_PKEY_HEXLEN, remote->sign_pub); } int crypt_session_init(crypt_session_t *const s, const crypt_key_t *const own, crypt_key_t *const remote, const bool is_client) { diff --git a/src/crypt.h b/src/crypt.h index ee3aa8f..66054e5 100644 --- a/src/crypt.h +++ b/src/crypt.h @@ -8,10 +8,15 @@ #define CRYPT_KX_PKEY_LEN crypto_kx_PUBLICKEYBYTES #define CRYPT_KX_SKEY_LEN crypto_kx_SECRETKEYBYTES + #define CRYPT_SIGN_PKEY_LEN crypto_sign_PUBLICKEYBYTES #define CRYPT_SIGN_SKEY_LEN crypto_sign_SECRETKEYBYTES +#define CRYPT_SIGN_LEN crypto_sign_BYTES + #define CRYPT_SESS_KEY_LEN crypto_kx_SESSIONKEYBYTES +#define CRYPT_HELLO_LEN CRYPT_PKEY_HEXLEN + CRYPT_SIGN_LEN + #define CRYPT_PKEY_HEXLEN (CRYPT_KX_PKEY_LEN + CRYPT_SIGN_PKEY_LEN) * 2 #define CRYPT_SKEY_HEXLEN (CRYPT_SIGN_PKEY_LEN + CRYPT_SIGN_SKEY_LEN) * 2 @@ -27,9 +32,9 @@ typedef struct crypt_key_t { // Generates the new pairs of a key exchange and sign keys. int crypt_key_gen(crypt_key_t *const k); // Initialise a crypt_key_t with a provided hex representaions of public and secret keys. -int crypt_key_from_hex(crypt_key_t *const k, char phex[CRYPT_PKEY_HEXLEN], char shex[CRYPT_SKEY_HEXLEN]); +int crypt_key_from_hex(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN], const char shex[CRYPT_SKEY_HEXLEN]); // Initialise a crypt_key_t with a provided hex representaion of just a public key. Used for remote keys. -int crypt_key_from_hex_public(crypt_key_t *const k, char phex[CRYPT_PKEY_HEXLEN]); +int crypt_key_from_hex_public(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN]); // Securely erase the fields of a crypt_key_t struct. void crypt_key_destroy(crypt_key_t *const k); @@ -48,7 +53,9 @@ int crypt_store_key(const crypt_key_t *const k, FILE *const pub, FILE *const sec // Returns a hello packet consisting of a public key and its sign. // The packet is sign_len long. -unsigned char *crypt_hello(const crypt_key_t *const own, long long unsigned int *const sign_len); +unsigned char *crypt_hello(const crypt_key_t *const own); +// Verify a hello message. It only shows that a remote public key's sign is ok. +int crypt_hello_verify(const unsigned char *const hello, crypt_key_t *const remote); // Stores symmetric keys used for a data encryption in both directions // and a remote public key. diff --git a/src/main.c b/src/main.c index 941fee5..65ff704 100644 --- a/src/main.c +++ b/src/main.c @@ -48,8 +48,6 @@ int main(int argc, char **argv) { crypt_store_key(&own, fp, fs); - printf("p1 = [%s]\ns1 = [%s]\n", phex, shex); - fflush(fp); fflush(fs); @@ -63,11 +61,14 @@ int main(int argc, char **argv) { crypt_key_export_public(&ownr, phexr); crypt_key_export_secret(&ownr, shexr); - printf("p2 = [%s]\ns2 = [%s]\n", phexr, shexr); - fclose(fp); fclose(fs); + unsigned char *h = crypt_hello(&own); + + int o = crypt_hello_verify(h, &ownr); + printf("o = %i\n", o); + crypt_key_destroy(&own); crypt_key_destroy(&ownr);