test_hs_ntor_cl.c (9252B)
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** This is a wrapper over the little-t-tor HS ntor functions. The wrapper is 5 * used by src/test/hs_ntor_ref.py to conduct the HS ntor integration 6 * tests. 7 * 8 * The logic of this wrapper is basically copied from src/test/test_ntor_cl.c 9 */ 10 11 #include "orconfig.h" 12 #include <stdio.h> 13 #include <stdlib.h> 14 15 #define ONION_NTOR_PRIVATE 16 #include "core/or/or.h" 17 #include "lib/crypt_ops/crypto_cipher.h" 18 #include "lib/crypt_ops/crypto_curve25519.h" 19 #include "lib/crypt_ops/crypto_ed25519.h" 20 #include "lib/crypt_ops/crypto_format.h" 21 #include "lib/crypt_ops/crypto_init.h" 22 #include "core/crypto/hs_ntor.h" 23 #include "core/crypto/onion_ntor.h" 24 25 #define N_ARGS(n) STMT_BEGIN { \ 26 if (argc < (n)) { \ 27 fprintf(stderr, "%s needs %d arguments.\n",argv[1],n); \ 28 return 1; \ 29 } \ 30 } STMT_END 31 #define BASE16(idx, var, n) STMT_BEGIN { \ 32 const char *s = argv[(idx)]; \ 33 if (base16_decode((char*)var, n, s, strlen(s)) < (int)n ) { \ 34 fprintf(stderr, "couldn't decode argument %d (%s)\n",idx,s); \ 35 return 1; \ 36 } \ 37 } STMT_END 38 #define INT(idx, var) STMT_BEGIN { \ 39 var = atoi(argv[(idx)]); \ 40 if (var <= 0) { \ 41 fprintf(stderr, "bad integer argument %d (%s)\n",idx,argv[(idx)]); \ 42 } \ 43 } STMT_END 44 45 /** The first part of the HS ntor protocol. The client-side computes all 46 necessary key material and sends the appropriate message to the service. */ 47 static int 48 client1(int argc, char **argv) 49 { 50 int retval; 51 52 /* Inputs */ 53 curve25519_public_key_t intro_enc_pubkey; 54 ed25519_public_key_t intro_auth_pubkey; 55 curve25519_keypair_t client_ephemeral_enc_keypair; 56 hs_subcredential_t subcredential; 57 58 /* Output */ 59 hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys; 60 61 char buf[256]; 62 63 N_ARGS(6); 64 BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); 65 BASE16(3, intro_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); 66 BASE16(4, client_ephemeral_enc_keypair.seckey.secret_key, 67 CURVE25519_SECKEY_LEN); 68 BASE16(5, subcredential.subcred, DIGEST256_LEN); 69 70 /* Generate keypair */ 71 curve25519_public_key_generate(&client_ephemeral_enc_keypair.pubkey, 72 &client_ephemeral_enc_keypair.seckey); 73 74 retval = hs_ntor_client_get_introduce1_keys(&intro_auth_pubkey, 75 &intro_enc_pubkey, 76 &client_ephemeral_enc_keypair, 77 &subcredential, 78 &hs_ntor_intro_cell_keys); 79 if (retval < 0) { 80 goto done; 81 } 82 83 /* Send ENC_KEY */ 84 base16_encode(buf, sizeof(buf), 85 (const char*)hs_ntor_intro_cell_keys.enc_key, 86 sizeof(hs_ntor_intro_cell_keys.enc_key)); 87 printf("%s\n", buf); 88 /* Send MAC_KEY */ 89 base16_encode(buf, sizeof(buf), 90 (const char*)hs_ntor_intro_cell_keys.mac_key, 91 sizeof(hs_ntor_intro_cell_keys.mac_key)); 92 printf("%s\n", buf); 93 94 done: 95 return retval; 96 } 97 98 /** The second part of the HS ntor protocol. The service-side computes all 99 necessary key material and sends the appropriate message to the client */ 100 static int 101 server1(int argc, char **argv) 102 { 103 int retval; 104 105 /* Inputs */ 106 curve25519_keypair_t intro_enc_keypair; 107 ed25519_public_key_t intro_auth_pubkey; 108 curve25519_public_key_t client_ephemeral_enc_pubkey; 109 hs_subcredential_t subcredential; 110 111 /* Output */ 112 hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys; 113 hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys; 114 curve25519_keypair_t service_ephemeral_rend_keypair; 115 116 char buf[256]; 117 118 N_ARGS(6); 119 BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); 120 BASE16(3, intro_enc_keypair.seckey.secret_key, CURVE25519_SECKEY_LEN); 121 BASE16(4, client_ephemeral_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); 122 BASE16(5, subcredential.subcred, DIGEST256_LEN); 123 124 /* Generate keypair */ 125 curve25519_public_key_generate(&intro_enc_keypair.pubkey, 126 &intro_enc_keypair.seckey); 127 curve25519_keypair_generate(&service_ephemeral_rend_keypair, 0); 128 129 /* Get INTRODUCE1 keys */ 130 retval = hs_ntor_service_get_introduce1_keys(&intro_auth_pubkey, 131 &intro_enc_keypair, 132 &client_ephemeral_enc_pubkey, 133 &subcredential, 134 &hs_ntor_intro_cell_keys); 135 if (retval < 0) { 136 goto done; 137 } 138 139 /* Get RENDEZVOUS1 keys */ 140 retval = hs_ntor_service_get_rendezvous1_keys(&intro_auth_pubkey, 141 &intro_enc_keypair, 142 &service_ephemeral_rend_keypair, 143 &client_ephemeral_enc_pubkey, 144 &hs_ntor_rend_cell_keys); 145 if (retval < 0) { 146 goto done; 147 } 148 149 /* Send ENC_KEY */ 150 base16_encode(buf, sizeof(buf), 151 (const char*)hs_ntor_intro_cell_keys.enc_key, 152 sizeof(hs_ntor_intro_cell_keys.enc_key)); 153 printf("%s\n", buf); 154 /* Send MAC_KEY */ 155 base16_encode(buf, sizeof(buf), 156 (const char*)hs_ntor_intro_cell_keys.mac_key, 157 sizeof(hs_ntor_intro_cell_keys.mac_key)); 158 printf("%s\n", buf); 159 /* Send AUTH_MAC */ 160 base16_encode(buf, sizeof(buf), 161 (const char*)hs_ntor_rend_cell_keys.rend_cell_auth_mac, 162 sizeof(hs_ntor_rend_cell_keys.rend_cell_auth_mac)); 163 printf("%s\n", buf); 164 /* Send NTOR_KEY_SEED */ 165 base16_encode(buf, sizeof(buf), 166 (const char*)hs_ntor_rend_cell_keys.ntor_key_seed, 167 sizeof(hs_ntor_rend_cell_keys.ntor_key_seed)); 168 printf("%s\n", buf); 169 /* Send service ephemeral pubkey (Y) */ 170 base16_encode(buf, sizeof(buf), 171 (const char*)service_ephemeral_rend_keypair.pubkey.public_key, 172 sizeof(service_ephemeral_rend_keypair.pubkey.public_key)); 173 printf("%s\n", buf); 174 175 done: 176 return retval; 177 } 178 179 /** The final step of the ntor protocol, the client computes and returns the 180 * rendezvous key material. */ 181 static int 182 client2(int argc, char **argv) 183 { 184 int retval; 185 186 /* Inputs */ 187 curve25519_public_key_t intro_enc_pubkey; 188 ed25519_public_key_t intro_auth_pubkey; 189 curve25519_keypair_t client_ephemeral_enc_keypair; 190 curve25519_public_key_t service_ephemeral_rend_pubkey; 191 hs_subcredential_t subcredential; 192 193 /* Output */ 194 hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys; 195 196 char buf[256]; 197 198 N_ARGS(7); 199 BASE16(2, intro_auth_pubkey.pubkey, ED25519_PUBKEY_LEN); 200 BASE16(3, client_ephemeral_enc_keypair.seckey.secret_key, 201 CURVE25519_SECKEY_LEN); 202 BASE16(4, intro_enc_pubkey.public_key, CURVE25519_PUBKEY_LEN); 203 BASE16(5, service_ephemeral_rend_pubkey.public_key, CURVE25519_PUBKEY_LEN); 204 BASE16(6, subcredential.subcred, DIGEST256_LEN); 205 206 /* Generate keypair */ 207 curve25519_public_key_generate(&client_ephemeral_enc_keypair.pubkey, 208 &client_ephemeral_enc_keypair.seckey); 209 210 /* Get RENDEZVOUS1 keys */ 211 retval = hs_ntor_client_get_rendezvous1_keys(&intro_auth_pubkey, 212 &client_ephemeral_enc_keypair, 213 &intro_enc_pubkey, 214 &service_ephemeral_rend_pubkey, 215 &hs_ntor_rend_cell_keys); 216 if (retval < 0) { 217 goto done; 218 } 219 220 /* Send AUTH_MAC */ 221 base16_encode(buf, sizeof(buf), 222 (const char*)hs_ntor_rend_cell_keys.rend_cell_auth_mac, 223 sizeof(hs_ntor_rend_cell_keys.rend_cell_auth_mac)); 224 printf("%s\n", buf); 225 /* Send NTOR_KEY_SEED */ 226 base16_encode(buf, sizeof(buf), 227 (const char*)hs_ntor_rend_cell_keys.ntor_key_seed, 228 sizeof(hs_ntor_rend_cell_keys.ntor_key_seed)); 229 printf("%s\n", buf); 230 231 done: 232 return 1; 233 } 234 235 /** Perform a different part of the protocol depdning on the argv used. */ 236 int 237 main(int argc, char **argv) 238 { 239 if (argc < 2) { 240 fprintf(stderr, "I need arguments. Read source for more info.\n"); 241 return 1; 242 } 243 244 init_logging(1); 245 curve25519_init(); 246 if (crypto_global_init(0, NULL, NULL) < 0) 247 return 1; 248 249 if (!strcmp(argv[1], "client1")) { 250 return client1(argc, argv); 251 } else if (!strcmp(argv[1], "server1")) { 252 return server1(argc, argv); 253 } else if (!strcmp(argv[1], "client2")) { 254 return client2(argc, argv); 255 } else { 256 fprintf(stderr, "What's a %s?\n", argv[1]); 257 return 1; 258 } 259 }