Skip to content

Commit 8e0d5c2

Browse files
Fix ntor key derivation and implement EXTEND2 circuit extension
- Fix ntor server handshake key assignment: stop swapping forward/backward labels since CircuitCrypto uses spec convention (Kf=decrypt incoming, Kb=encrypt outgoing) - Fix ntor constants: correct sizes for NTOR_SERVER_STR (6B), NTOR_KEY_STR (36B), NTOR_EXPAND_STR (35B), NTOR_MAC_STR (28B), NTOR_VERIFY_STR (31B) - Implement proper stream-level flow control (500-cell window with pending response queue) - Add decrypt_relay_cell_or_forward: supports both "for us" and "forward to next hop" paths with proper digest state management - Implement EXTEND2 handler: parses link specifiers, opens TLS connection to target relay, performs Tor link protocol handshake, forwards CREATE2/CREATED2, sends EXTENDED2 back to client - Add bidirectional relay cell forwarding with backward encryption - Preserve RELAY_EARLY flag when forwarding cells (required by spec) - Result: Tor client achieves 100% bootstrap through C++ bridge Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d88e4c8 commit 8e0d5c2

File tree

3 files changed

+601
-96
lines changed

3 files changed

+601
-96
lines changed

include/tor/crypto/ntor.hpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,32 @@ inline constexpr std::array<uint8_t, 24> NTOR_PROTO_ID = {
2121
'5', '1', '9', '-', 's', 'h', 'a', '2', '5', '6', '-', '1'
2222
};
2323

24-
// Server string constant
25-
inline constexpr std::array<uint8_t, 15> NTOR_SERVER_STR = {
26-
'S', 'e', 'r', 'v', 'e', 'r', ' ', 'k', 'e', 'y', ' ', 'd', 'a', 't', 'a'
24+
// Server string constant: "Server"
25+
inline constexpr std::array<uint8_t, 6> NTOR_SERVER_STR = {
26+
'S', 'e', 'r', 'v', 'e', 'r'
2727
};
2828

29-
// Expand string constant
30-
inline constexpr std::array<uint8_t, 18> NTOR_EXPAND_STR = {
31-
'n', 't', 'o', 'r', '-', 'c', 'u', 'r', 'v', 'e',
32-
'2', '5', '5', '1', '9', '-', '1', ':'
29+
// t_key = PROTOID | ":key_extract" (for KEY_SEED derivation)
30+
inline constexpr std::array<uint8_t, 36> NTOR_KEY_STR = {
31+
'n', 't', 'o', 'r', '-', 'c', 'u', 'r', 'v', 'e', '2', '5',
32+
'5', '1', '9', '-', 's', 'h', 'a', '2', '5', '6', '-', '1',
33+
':', 'k', 'e', 'y', '_', 'e', 'x', 't', 'r', 'a', 'c', 't'
34+
};
35+
36+
// m_expand = PROTOID | ":key_expand" (HKDF info for key expansion)
37+
inline constexpr std::array<uint8_t, 35> NTOR_EXPAND_STR = {
38+
'n', 't', 'o', 'r', '-', 'c', 'u', 'r', 'v', 'e', '2', '5',
39+
'5', '1', '9', '-', 's', 'h', 'a', '2', '5', '6', '-', '1',
40+
':', 'k', 'e', 'y', '_', 'e', 'x', 'p', 'a', 'n', 'd'
3341
};
3442

35-
// MAC string constant
43+
// t_mac = PROTOID | ":mac"
3644
inline constexpr std::array<uint8_t, 28> NTOR_MAC_STR = {
3745
'n', 't', 'o', 'r', '-', 'c', 'u', 'r', 'v', 'e', '2', '5', '5', '1',
3846
'9', '-', 's', 'h', 'a', '2', '5', '6', '-', '1', ':', 'm', 'a', 'c'
3947
};
4048

41-
// Verify string constant
49+
// t_verify = PROTOID | ":verify"
4250
inline constexpr std::array<uint8_t, 31> NTOR_VERIFY_STR = {
4351
'n', 't', 'o', 'r', '-', 'c', 'u', 'r', 'v', 'e', '2', '5', '5', '1',
4452
'9', '-', 's', 'h', 'a', '2', '5', '6', '-', '1', ':', 'v', 'e', 'r',
@@ -131,8 +139,8 @@ namespace ntor_detail {
131139
size_t length
132140
);
133141

134-
// Compute secret_input for ntor
135-
[[nodiscard]] std::array<uint8_t, 32> compute_secret_input(
142+
// Compute raw secret_input concatenation for ntor
143+
[[nodiscard]] std::vector<uint8_t> compute_secret_input(
136144
const std::array<uint8_t, 32>& exp_xy,
137145
const std::array<uint8_t, 32>& exp_xb,
138146
const NodeId& node_id,

0 commit comments

Comments
 (0)