tor/src/test/test_hs_ntor_cl.c

256 lines
8.8 KiB
C

/* 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;
}
}