2019-01-16 18:32:32 +01:00
|
|
|
/* Copyright (c) 2012-2019, The Tor Project, Inc. */
|
2012-12-08 06:52:44 +01:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#include "orconfig.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#define ONION_NTOR_PRIVATE
|
2018-07-05 22:34:59 +02:00
|
|
|
#include "core/or/or.h"
|
2018-07-11 20:08:22 +02:00
|
|
|
#include "lib/crypt_ops/crypto_cipher.h"
|
2018-06-21 18:47:11 +02:00
|
|
|
#include "lib/crypt_ops/crypto_curve25519.h"
|
2018-07-11 22:54:05 +02:00
|
|
|
#include "lib/crypt_ops/crypto_init.h"
|
2018-07-05 22:34:59 +02:00
|
|
|
#include "core/crypto/onion_ntor.h"
|
2012-12-08 06:52:44 +01:00
|
|
|
|
|
|
|
#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)]; \
|
2016-06-17 16:41:45 +02:00
|
|
|
if (base16_decode((char*)var, n, s, strlen(s)) < (int)n ) { \
|
2012-12-08 06:52:44 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
static int
|
|
|
|
client1(int argc, char **argv)
|
|
|
|
{
|
|
|
|
/* client1 nodeID B -> msg state */
|
|
|
|
curve25519_public_key_t B;
|
|
|
|
uint8_t node_id[DIGEST_LEN];
|
2013-02-11 20:57:10 +01:00
|
|
|
ntor_handshake_state_t *state = NULL;
|
2012-12-08 06:52:44 +01:00
|
|
|
uint8_t msg[NTOR_ONIONSKIN_LEN];
|
|
|
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
N_ARGS(4);
|
|
|
|
BASE16(2, node_id, DIGEST_LEN);
|
|
|
|
BASE16(3, B.public_key, CURVE25519_PUBKEY_LEN);
|
|
|
|
|
|
|
|
if (onion_skin_ntor_create(node_id, &B, &state, msg)<0) {
|
|
|
|
fprintf(stderr, "handshake failed");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
base16_encode(buf, sizeof(buf), (const char*)msg, sizeof(msg));
|
|
|
|
printf("%s\n", buf);
|
|
|
|
base16_encode(buf, sizeof(buf), (void*)state, sizeof(*state));
|
|
|
|
printf("%s\n", buf);
|
2013-02-11 20:57:10 +01:00
|
|
|
|
2012-12-08 06:52:44 +01:00
|
|
|
ntor_handshake_state_free(state);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
server1(int argc, char **argv)
|
|
|
|
{
|
|
|
|
uint8_t msg_in[NTOR_ONIONSKIN_LEN];
|
|
|
|
curve25519_keypair_t kp;
|
|
|
|
di_digest256_map_t *keymap=NULL;
|
|
|
|
uint8_t node_id[DIGEST_LEN];
|
|
|
|
int keybytes;
|
|
|
|
|
|
|
|
uint8_t msg_out[NTOR_REPLY_LEN];
|
2013-02-11 20:57:10 +01:00
|
|
|
uint8_t *keys = NULL;
|
|
|
|
char *hexkeys = NULL;
|
|
|
|
int result = 0;
|
2012-12-08 06:52:44 +01:00
|
|
|
|
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
/* server1: b nodeID msg N -> msg keys */
|
|
|
|
N_ARGS(6);
|
|
|
|
BASE16(2, kp.seckey.secret_key, CURVE25519_SECKEY_LEN);
|
|
|
|
BASE16(3, node_id, DIGEST_LEN);
|
|
|
|
BASE16(4, msg_in, NTOR_ONIONSKIN_LEN);
|
|
|
|
INT(5, keybytes);
|
|
|
|
|
|
|
|
curve25519_public_key_generate(&kp.pubkey, &kp.seckey);
|
|
|
|
dimap_add_entry(&keymap, kp.pubkey.public_key, &kp);
|
|
|
|
|
|
|
|
keys = tor_malloc(keybytes);
|
|
|
|
hexkeys = tor_malloc(keybytes*2+1);
|
|
|
|
if (onion_skin_ntor_server_handshake(
|
|
|
|
msg_in, keymap, NULL, node_id, msg_out, keys,
|
|
|
|
(size_t)keybytes)<0) {
|
|
|
|
fprintf(stderr, "handshake failed");
|
2013-02-11 20:57:10 +01:00
|
|
|
result = 2;
|
|
|
|
goto done;
|
2012-12-08 06:52:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
base16_encode(buf, sizeof(buf), (const char*)msg_out, sizeof(msg_out));
|
|
|
|
printf("%s\n", buf);
|
|
|
|
base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
|
|
|
|
printf("%s\n", hexkeys);
|
|
|
|
|
2013-02-11 20:57:10 +01:00
|
|
|
done:
|
2012-12-08 06:52:44 +01:00
|
|
|
tor_free(keys);
|
|
|
|
tor_free(hexkeys);
|
2015-11-16 13:21:56 +01:00
|
|
|
dimap_free(keymap, NULL);
|
2013-02-11 20:57:10 +01:00
|
|
|
return result;
|
2012-12-08 06:52:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
client2(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct ntor_handshake_state_t state;
|
|
|
|
uint8_t msg[NTOR_REPLY_LEN];
|
|
|
|
int keybytes;
|
|
|
|
uint8_t *keys;
|
|
|
|
char *hexkeys;
|
2013-02-11 20:57:10 +01:00
|
|
|
int result = 0;
|
2012-12-08 06:52:44 +01:00
|
|
|
|
|
|
|
N_ARGS(5);
|
|
|
|
BASE16(2, (&state), sizeof(state));
|
|
|
|
BASE16(3, msg, sizeof(msg));
|
|
|
|
INT(4, keybytes);
|
|
|
|
|
|
|
|
keys = tor_malloc(keybytes);
|
|
|
|
hexkeys = tor_malloc(keybytes*2+1);
|
2014-10-16 19:26:42 +02:00
|
|
|
if (onion_skin_ntor_client_handshake(&state, msg, keys, keybytes, NULL)<0) {
|
2012-12-08 06:52:44 +01:00
|
|
|
fprintf(stderr, "handshake failed");
|
2013-02-11 20:57:10 +01:00
|
|
|
result = 2;
|
|
|
|
goto done;
|
2012-12-08 06:52:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
|
|
|
|
printf("%s\n", hexkeys);
|
|
|
|
|
2013-02-11 20:57:10 +01:00
|
|
|
done:
|
2012-12-08 06:52:44 +01:00
|
|
|
tor_free(keys);
|
|
|
|
tor_free(hexkeys);
|
2013-02-11 20:57:10 +01:00
|
|
|
return result;
|
2012-12-08 06:52:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
client1: nodeID B -> msg state
|
|
|
|
server1: b nodeID msg N -> msg keys
|
|
|
|
client2: state msg N -> keys
|
|
|
|
*/
|
|
|
|
if (argc < 2) {
|
|
|
|
fprintf(stderr, "I need arguments. Read source for more info.\n");
|
|
|
|
return 1;
|
2016-05-03 17:12:39 +02:00
|
|
|
}
|
|
|
|
|
2018-07-11 22:54:05 +02:00
|
|
|
init_logging(1);
|
2016-05-03 17:12:39 +02:00
|
|
|
curve25519_init();
|
2018-07-11 22:54:05 +02:00
|
|
|
if (crypto_global_init(0, NULL, NULL) < 0)
|
|
|
|
return 1;
|
|
|
|
|
2016-05-03 17:12:39 +02:00
|
|
|
if (!strcmp(argv[1], "client1")) {
|
2012-12-08 06:52:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|