diff options
Diffstat (limited to 'src/test/test_hs_ntor_cl.c')
-rw-r--r-- | src/test/test_hs_ntor_cl.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/test/test_hs_ntor_cl.c b/src/test/test_hs_ntor_cl.c new file mode 100644 index 0000000000..ed1eda58ea --- /dev/null +++ b/src/test/test_hs_ntor_cl.c @@ -0,0 +1,255 @@ +/* Copyright (c) 2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** This is a wrapper over the little-t-tor HS ntor functions. The wrapper is + * used by src/test/hs_ntor_ref.py to conduct the HS ntor integration + * tests. + * + * The logic of this wrapper is basically copied from src/test/test_ntor_cl.c + */ + +#include "orconfig.h" +#include <stdio.h> +#include <stdlib.h> + +#define ONION_NTOR_PRIVATE +#include "or.h" +#include "util.h" +#include "compat.h" +#include "crypto.h" +#include "crypto_curve25519.h" +#include "hs_ntor.h" +#include "onion_ntor.h" + +#define N_ARGS(n) STMT_BEGIN { \ + if (argc < (n)) { \ + fprintf(stderr, "%s needs %d arguments.\n",argv[1],n); \ + return 1; \ + } \ + } STMT_END +#define BASE16(idx, var, n) STMT_BEGIN { \ + const char *s = argv[(idx)]; \ + if (base16_decode((char*)var, n, s, strlen(s)) < (int)n ) { \ + fprintf(stderr, "couldn't decode argument %d (%s)\n",idx,s); \ + return 1; \ + } \ + } STMT_END +#define INT(idx, var) STMT_BEGIN { \ + var = atoi(argv[(idx)]); \ + if (var <= 0) { \ + fprintf(stderr, "bad integer argument %d (%s)\n",idx,argv[(idx)]); \ + } \ + } STMT_END + +/** The first part of the HS ntor protocol. The client-side computes all + necessary key material and sends the appropriate message to the service. */ +static int +client1(int argc, char **argv) +{ + int retval; + + /* Inputs */ + curve25519_public_key_t intro_enc_pubkey; + ed25519_public_key_t intro_auth_pubkey; + curve25519_keypair_t client_ephemeral_enc_keypair; + uint8_t subcredential[DIGEST256_LEN]; + + /* Output */ + hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys; + + char buf[256]; + + N_ARGS(6); + BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); + BASE16(3, intro_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); + BASE16(4, client_ephemeral_enc_keypair.seckey.secret_key, + CURVE25519_SECKEY_LEN); + BASE16(5, subcredential, DIGEST256_LEN); + + /* Generate keypair */ + curve25519_public_key_generate(&client_ephemeral_enc_keypair.pubkey, + &client_ephemeral_enc_keypair.seckey); + + retval = hs_ntor_client_get_introduce1_keys(&intro_auth_pubkey, + &intro_enc_pubkey, + &client_ephemeral_enc_keypair, + subcredential, + &hs_ntor_intro_cell_keys); + if (retval < 0) { + goto done; + } + + /* Send ENC_KEY */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_intro_cell_keys.enc_key, + sizeof(hs_ntor_intro_cell_keys.enc_key)); + printf("%s\n", buf); + /* Send MAC_KEY */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_intro_cell_keys.mac_key, + sizeof(hs_ntor_intro_cell_keys.mac_key)); + printf("%s\n", buf); + + done: + return retval; +} + +/** The second part of the HS ntor protocol. The service-side computes all + necessary key material and sends the appropriate message to the client */ +static int +server1(int argc, char **argv) +{ + int retval; + + /* Inputs */ + curve25519_keypair_t intro_enc_keypair; + ed25519_public_key_t intro_auth_pubkey; + curve25519_public_key_t client_ephemeral_enc_pubkey; + uint8_t subcredential[DIGEST256_LEN]; + + /* Output */ + hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys; + hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys; + curve25519_keypair_t service_ephemeral_rend_keypair; + + char buf[256]; + + N_ARGS(6); + BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); + BASE16(3, intro_enc_keypair.seckey.secret_key, CURVE25519_SECKEY_LEN); + BASE16(4, client_ephemeral_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); + BASE16(5, subcredential, DIGEST256_LEN); + + /* Generate keypair */ + curve25519_public_key_generate(&intro_enc_keypair.pubkey, + &intro_enc_keypair.seckey); + curve25519_keypair_generate(&service_ephemeral_rend_keypair, 0); + + /* Get INTRODUCE1 keys */ + retval = hs_ntor_service_get_introduce1_keys(&intro_auth_pubkey, + &intro_enc_keypair, + &client_ephemeral_enc_pubkey, + subcredential, + &hs_ntor_intro_cell_keys); + if (retval < 0) { + goto done; + } + + /* Get RENDEZVOUS1 keys */ + retval = hs_ntor_service_get_rendezvous1_keys(&intro_auth_pubkey, + &intro_enc_keypair, + &service_ephemeral_rend_keypair, + &client_ephemeral_enc_pubkey, + &hs_ntor_rend_cell_keys); + if (retval < 0) { + goto done; + } + + /* Send ENC_KEY */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_intro_cell_keys.enc_key, + sizeof(hs_ntor_intro_cell_keys.enc_key)); + printf("%s\n", buf); + /* Send MAC_KEY */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_intro_cell_keys.mac_key, + sizeof(hs_ntor_intro_cell_keys.mac_key)); + printf("%s\n", buf); + /* Send AUTH_MAC */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_rend_cell_keys.rend_cell_auth_mac, + sizeof(hs_ntor_rend_cell_keys.rend_cell_auth_mac)); + printf("%s\n", buf); + /* Send NTOR_KEY_SEED */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_rend_cell_keys.ntor_key_seed, + sizeof(hs_ntor_rend_cell_keys.ntor_key_seed)); + printf("%s\n", buf); + /* Send service ephemeral pubkey (Y) */ + base16_encode(buf, sizeof(buf), + (const char*)service_ephemeral_rend_keypair.pubkey.public_key, + sizeof(service_ephemeral_rend_keypair.pubkey.public_key)); + printf("%s\n", buf); + + done: + return retval; +} + +/** The final step of the ntor protocol, the client computes and returns the + * rendezvous key material. */ +static int +client2(int argc, char **argv) +{ + int retval; + + /* Inputs */ + curve25519_public_key_t intro_enc_pubkey; + ed25519_public_key_t intro_auth_pubkey; + curve25519_keypair_t client_ephemeral_enc_keypair; + curve25519_public_key_t service_ephemeral_rend_pubkey; + uint8_t subcredential[DIGEST256_LEN]; + + /* Output */ + hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys; + + char buf[256]; + + N_ARGS(7); + BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); + BASE16(3, client_ephemeral_enc_keypair.seckey.secret_key, + CURVE25519_SECKEY_LEN); + BASE16(4, intro_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); + BASE16(5, service_ephemeral_rend_pubkey.public_key, CURVE25519_PUBKEY_LEN); + BASE16(6, subcredential, DIGEST256_LEN); + + /* Generate keypair */ + curve25519_public_key_generate(&client_ephemeral_enc_keypair.pubkey, + &client_ephemeral_enc_keypair.seckey); + + /* Get RENDEZVOUS1 keys */ + retval = hs_ntor_client_get_rendezvous1_keys(&intro_auth_pubkey, + &client_ephemeral_enc_keypair, + &intro_enc_pubkey, + &service_ephemeral_rend_pubkey, + &hs_ntor_rend_cell_keys); + if (retval < 0) { + goto done; + } + + /* Send AUTH_MAC */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_rend_cell_keys.rend_cell_auth_mac, + sizeof(hs_ntor_rend_cell_keys.rend_cell_auth_mac)); + printf("%s\n", buf); + /* Send NTOR_KEY_SEED */ + base16_encode(buf, sizeof(buf), + (const char*)hs_ntor_rend_cell_keys.ntor_key_seed, + sizeof(hs_ntor_rend_cell_keys.ntor_key_seed)); + printf("%s\n", buf); + + done: + return 1; +} + +/** Perform a different part of the protocol depdning on the argv used. */ +int +main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "I need arguments. Read source for more info.\n"); + return 1; + } + + curve25519_init(); + if (!strcmp(argv[1], "client1")) { + return client1(argc, argv); + } else if (!strcmp(argv[1], "server1")) { + return server1(argc, argv); + } else if (!strcmp(argv[1], "client2")) { + return client2(argc, argv); + } else { + fprintf(stderr, "What's a %s?\n", argv[1]); + return 1; + } +} + |