|
@@ -46,6 +46,7 @@
|
|
|
#include "crypto.h"
|
|
|
#include "directory.h"
|
|
|
#include "entrynodes.h"
|
|
|
+#include "hs_ntor.h"
|
|
|
#include "main.h"
|
|
|
#include "microdesc.h"
|
|
|
#include "networkstatus.h"
|
|
@@ -1331,7 +1332,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|
|
* service circuits and <b>key_data</b> must be at least
|
|
|
* HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
|
|
|
*
|
|
|
- * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL
|
|
|
+ * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
|
|
|
* bytes, which are used as follows:
|
|
|
* - 20 to initialize f_digest
|
|
|
* - 20 to initialize b_digest
|
|
@@ -1339,9 +1340,12 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|
|
* - 16 to key b_crypto
|
|
|
*
|
|
|
* (If 'reverse' is true, then f_XX and b_XX are swapped.)
|
|
|
+ *
|
|
|
+ * Return 0 if init was successful, else -1 if it failed.
|
|
|
*/
|
|
|
int
|
|
|
-circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
|
|
+circuit_init_cpath_crypto(crypt_path_t *cpath,
|
|
|
+ const char *key_data, size_t key_data_len,
|
|
|
int reverse, int is_hs_v3)
|
|
|
{
|
|
|
crypto_digest_t *tmp_digest;
|
|
@@ -1354,6 +1358,13 @@ circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
|
|
tor_assert(!(cpath->f_crypto || cpath->b_crypto ||
|
|
|
cpath->f_digest || cpath->b_digest));
|
|
|
|
|
|
+ /* Basic key size validation */
|
|
|
+ if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
|
|
|
+ return -1;
|
|
|
+ } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
/* If we are using this cpath for next gen onion services use SHA3-256,
|
|
|
otherwise use good ol' SHA1 */
|
|
|
if (is_hs_v3) {
|
|
@@ -1450,7 +1461,7 @@ circuit_finish_handshake(origin_circuit_t *circ,
|
|
|
|
|
|
onion_handshake_state_release(&hop->handshake_state);
|
|
|
|
|
|
- if (circuit_init_cpath_crypto(hop, keys, 0, 0)<0) {
|
|
|
+ if (circuit_init_cpath_crypto(hop, keys, sizeof(keys), 0, 0)<0) {
|
|
|
return -END_CIRC_REASON_TORPROTOCOL;
|
|
|
}
|
|
|
|
|
@@ -1517,12 +1528,14 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason)
|
|
|
int
|
|
|
onionskin_answer(or_circuit_t *circ,
|
|
|
const created_cell_t *created_cell,
|
|
|
- const char *keys,
|
|
|
+ const char *keys, size_t keys_len,
|
|
|
const uint8_t *rend_circ_nonce)
|
|
|
{
|
|
|
cell_t cell;
|
|
|
crypt_path_t *tmp_cpath;
|
|
|
|
|
|
+ tor_assert(keys_len == CPATH_KEY_MATERIAL_LEN);
|
|
|
+
|
|
|
if (created_cell_format(&cell, created_cell) < 0) {
|
|
|
log_warn(LD_BUG,"couldn't format created cell (type=%d, len=%d)",
|
|
|
(int)created_cell->cell_type, (int)created_cell->handshake_len);
|
|
@@ -1538,7 +1551,7 @@ onionskin_answer(or_circuit_t *circ,
|
|
|
log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.",
|
|
|
(unsigned int)get_uint32(keys),
|
|
|
(unsigned int)get_uint32(keys+20));
|
|
|
- if (circuit_init_cpath_crypto(tmp_cpath, keys, 0, 0)<0) {
|
|
|
+ if (circuit_init_cpath_crypto(tmp_cpath, keys, keys_len, 0, 0)<0) {
|
|
|
log_warn(LD_BUG,"Circuit initialization failed");
|
|
|
tor_free(tmp_cpath);
|
|
|
return -1;
|