changelog typo fix
[tor.git] / src / test / test_ntor_cl.c
blob6df123162e7434c4fc624c1d20b85223c27e1680
1 /* Copyright (c) 2012-2016, 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 #define N_ARGS(n) STMT_BEGIN { \
17 if (argc < (n)) { \
18 fprintf(stderr, "%s needs %d arguments.\n",argv[1],n); \
19 return 1; \
20 } \
21 } STMT_END
22 #define BASE16(idx, var, n) STMT_BEGIN { \
23 const char *s = argv[(idx)]; \
24 if (base16_decode((char*)var, n, s, strlen(s)) < 0 ) { \
25 fprintf(stderr, "couldn't decode argument %d (%s)\n",idx,s); \
26 return 1; \
27 } \
28 } STMT_END
29 #define INT(idx, var) STMT_BEGIN { \
30 var = atoi(argv[(idx)]); \
31 if (var <= 0) { \
32 fprintf(stderr, "bad integer argument %d (%s)\n",idx,argv[(idx)]); \
33 } \
34 } STMT_END
36 static int
37 client1(int argc, char **argv)
39 /* client1 nodeID B -> msg state */
40 curve25519_public_key_t B;
41 uint8_t node_id[DIGEST_LEN];
42 ntor_handshake_state_t *state = NULL;
43 uint8_t msg[NTOR_ONIONSKIN_LEN];
45 char buf[1024];
47 N_ARGS(4);
48 BASE16(2, node_id, DIGEST_LEN);
49 BASE16(3, B.public_key, CURVE25519_PUBKEY_LEN);
51 if (onion_skin_ntor_create(node_id, &B, &state, msg)<0) {
52 fprintf(stderr, "handshake failed");
53 return 2;
56 base16_encode(buf, sizeof(buf), (const char*)msg, sizeof(msg));
57 printf("%s\n", buf);
58 base16_encode(buf, sizeof(buf), (void*)state, sizeof(*state));
59 printf("%s\n", buf);
61 ntor_handshake_state_free(state);
62 return 0;
65 static int
66 server1(int argc, char **argv)
68 uint8_t msg_in[NTOR_ONIONSKIN_LEN];
69 curve25519_keypair_t kp;
70 di_digest256_map_t *keymap=NULL;
71 uint8_t node_id[DIGEST_LEN];
72 int keybytes;
74 uint8_t msg_out[NTOR_REPLY_LEN];
75 uint8_t *keys = NULL;
76 char *hexkeys = NULL;
77 int result = 0;
79 char buf[256];
81 /* server1: b nodeID msg N -> msg keys */
82 N_ARGS(6);
83 BASE16(2, kp.seckey.secret_key, CURVE25519_SECKEY_LEN);
84 BASE16(3, node_id, DIGEST_LEN);
85 BASE16(4, msg_in, NTOR_ONIONSKIN_LEN);
86 INT(5, keybytes);
88 curve25519_public_key_generate(&kp.pubkey, &kp.seckey);
89 dimap_add_entry(&keymap, kp.pubkey.public_key, &kp);
91 keys = tor_malloc(keybytes);
92 hexkeys = tor_malloc(keybytes*2+1);
93 if (onion_skin_ntor_server_handshake(
94 msg_in, keymap, NULL, node_id, msg_out, keys,
95 (size_t)keybytes)<0) {
96 fprintf(stderr, "handshake failed");
97 result = 2;
98 goto done;
101 base16_encode(buf, sizeof(buf), (const char*)msg_out, sizeof(msg_out));
102 printf("%s\n", buf);
103 base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
104 printf("%s\n", hexkeys);
106 done:
107 tor_free(keys);
108 tor_free(hexkeys);
109 dimap_free(keymap, NULL);
110 return result;
113 static int
114 client2(int argc, char **argv)
116 struct ntor_handshake_state_t state;
117 uint8_t msg[NTOR_REPLY_LEN];
118 int keybytes;
119 uint8_t *keys;
120 char *hexkeys;
121 int result = 0;
123 N_ARGS(5);
124 BASE16(2, (&state), sizeof(state));
125 BASE16(3, msg, sizeof(msg));
126 INT(4, keybytes);
128 keys = tor_malloc(keybytes);
129 hexkeys = tor_malloc(keybytes*2+1);
130 if (onion_skin_ntor_client_handshake(&state, msg, keys, keybytes, NULL)<0) {
131 fprintf(stderr, "handshake failed");
132 result = 2;
133 goto done;
136 base16_encode(hexkeys, keybytes*2+1, (const char*)keys, keybytes);
137 printf("%s\n", hexkeys);
139 done:
140 tor_free(keys);
141 tor_free(hexkeys);
142 return result;
146 main(int argc, char **argv)
149 client1: nodeID B -> msg state
150 server1: b nodeID msg N -> msg keys
151 client2: state msg N -> keys
153 if (argc < 2) {
154 fprintf(stderr, "I need arguments. Read source for more info.\n");
155 return 1;
156 } else if (!strcmp(argv[1], "client1")) {
157 return client1(argc, argv);
158 } else if (!strcmp(argv[1], "server1")) {
159 return server1(argc, argv);
160 } else if (!strcmp(argv[1], "client2")) {
161 return client2(argc, argv);
162 } else {
163 fprintf(stderr, "What's a %s?\n", argv[1]);
164 return 1;