fold in another changes item
[tor.git] / src / test / test_ntor_cl.c
blobf2b7a72ad54de49b25ba9e8252ec89d11391eee3
1 /* Copyright (c) 2012-2013, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #include "orconfig.h"
5 #include <stdio.h>
6 #include <stdlib.h>
8 #define ONION_NTOR_PRIVATE
9 #include "or.h"
10 #include "util.h"
11 #include "compat.h"
12 #include "crypto.h"
13 #include "crypto_curve25519.h"
14 #include "onion_ntor.h"
16 #ifndef CURVE25519_ENABLED
17 #error "This isn't going to work without curve25519."
18 #endif
20 #define N_ARGS(n) STMT_BEGIN { \
21 if (argc < (n)) { \
22 fprintf(stderr, "%s needs %d arguments.\n",argv[1],n); \
23 return 1; \
24 } \
25 } STMT_END
26 #define BASE16(idx, var, n) STMT_BEGIN { \
27 const char *s = argv[(idx)]; \
28 if (base16_decode((char*)var, n, s, strlen(s)) < 0 ) { \
29 fprintf(stderr, "couldn't decode argument %d (%s)\n",idx,s); \
30 return 1; \
31 } \
32 } STMT_END
33 #define INT(idx, var) STMT_BEGIN { \
34 var = atoi(argv[(idx)]); \
35 if (var <= 0) { \
36 fprintf(stderr, "bad integer argument %d (%s)\n",idx,argv[(idx)]); \
37 } \
38 } STMT_END
40 static int
41 client1(int argc, char **argv)
43 /* client1 nodeID B -> msg state */
44 curve25519_public_key_t B;
45 uint8_t node_id[DIGEST_LEN];
46 ntor_handshake_state_t *state = NULL;
47 uint8_t msg[NTOR_ONIONSKIN_LEN];
49 char buf[1024];
51 N_ARGS(4);
52 BASE16(2, node_id, DIGEST_LEN);
53 BASE16(3, B.public_key, CURVE25519_PUBKEY_LEN);
55 if (onion_skin_ntor_create(node_id, &B, &state, msg)<0) {
56 fprintf(stderr, "handshake failed");
57 return 2;
60 base16_encode(buf, sizeof(buf), (const char*)msg, sizeof(msg));
61 printf("%s\n", buf);
62 base16_encode(buf, sizeof(buf), (void*)state, sizeof(*state));
63 printf("%s\n", buf);
65 ntor_handshake_state_free(state);
66 return 0;
69 static int
70 server1(int argc, char **argv)
72 uint8_t msg_in[NTOR_ONIONSKIN_LEN];
73 curve25519_keypair_t kp;
74 di_digest256_map_t *keymap=NULL;
75 uint8_t node_id[DIGEST_LEN];
76 int keybytes;
78 uint8_t msg_out[NTOR_REPLY_LEN];
79 uint8_t *keys = NULL;
80 char *hexkeys = NULL;
81 int result = 0;
83 char buf[256];
85 /* server1: b nodeID msg N -> msg keys */
86 N_ARGS(6);
87 BASE16(2, kp.seckey.secret_key, CURVE25519_SECKEY_LEN);
88 BASE16(3, node_id, DIGEST_LEN);
89 BASE16(4, msg_in, NTOR_ONIONSKIN_LEN);
90 INT(5, keybytes);
92 curve25519_public_key_generate(&kp.pubkey, &kp.seckey);
93 dimap_add_entry(&keymap, kp.pubkey.public_key, &kp);
95 keys = tor_malloc(keybytes);
96 hexkeys = tor_malloc(keybytes*2+1);
97 if (onion_skin_ntor_server_handshake(
98 msg_in, keymap, NULL, node_id, msg_out, keys,
99 (size_t)keybytes)<0) {
100 fprintf(stderr, "handshake failed");
101 result = 2;
102 goto done;
105 base16_encode(buf, sizeof(buf), (const char*)msg_out, sizeof(msg_out));
106 printf("%s\n", buf);
107 base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
108 printf("%s\n", hexkeys);
110 done:
111 tor_free(keys);
112 tor_free(hexkeys);
113 return result;
116 static int
117 client2(int argc, char **argv)
119 struct ntor_handshake_state_t state;
120 uint8_t msg[NTOR_REPLY_LEN];
121 int keybytes;
122 uint8_t *keys;
123 char *hexkeys;
124 int result = 0;
126 N_ARGS(5);
127 BASE16(2, (&state), sizeof(state));
128 BASE16(3, msg, sizeof(msg));
129 INT(4, keybytes);
131 keys = tor_malloc(keybytes);
132 hexkeys = tor_malloc(keybytes*2+1);
133 if (onion_skin_ntor_client_handshake(&state, msg, keys, keybytes)<0) {
134 fprintf(stderr, "handshake failed");
135 result = 2;
136 goto done;
139 base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
140 printf("%s\n", hexkeys);
142 done:
143 tor_free(keys);
144 tor_free(hexkeys);
145 return result;
149 main(int argc, char **argv)
152 client1: nodeID B -> msg state
153 server1: b nodeID msg N -> msg keys
154 client2: state msg N -> keys
156 if (argc < 2) {
157 fprintf(stderr, "I need arguments. Read source for more info.\n");
158 return 1;
159 } else if (!strcmp(argv[1], "client1")) {
160 return client1(argc, argv);
161 } else if (!strcmp(argv[1], "server1")) {
162 return server1(argc, argv);
163 } else if (!strcmp(argv[1], "client2")) {
164 return client2(argc, argv);
165 } else {
166 fprintf(stderr, "What's a %s?\n", argv[1]);
167 return 1;