mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-01 23:10:52 +00:00
Remove unused POW code, will revisit later.
This commit is contained in:
parent
e2509af163
commit
93b4ac5cb2
@ -106,7 +106,6 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
|
|||||||
case Packet::VERB_PUSH_DIRECT_PATHS: return _doPUSH_DIRECT_PATHS(RR,peer);
|
case Packet::VERB_PUSH_DIRECT_PATHS: return _doPUSH_DIRECT_PATHS(RR,peer);
|
||||||
case Packet::VERB_CIRCUIT_TEST: return _doCIRCUIT_TEST(RR,peer);
|
case Packet::VERB_CIRCUIT_TEST: return _doCIRCUIT_TEST(RR,peer);
|
||||||
case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,peer);
|
case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,peer);
|
||||||
case Packet::VERB_REQUEST_PROOF_OF_WORK: return _doREQUEST_PROOF_OF_WORK(RR,peer);
|
|
||||||
case Packet::VERB_USER_MESSAGE:
|
case Packet::VERB_USER_MESSAGE:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1421,70 +1420,6 @@ bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const S
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
// If this were allowed from anyone, it would itself be a DOS vector. Right
|
|
||||||
// now we only allow it from roots and controllers of networks you have joined.
|
|
||||||
bool allowed = RR->topology->isUpstream(peer->identity());
|
|
||||||
if (!allowed) {
|
|
||||||
std::vector< SharedPtr<Network> > allNetworks(RR->node->allNetworks());
|
|
||||||
for(std::vector< SharedPtr<Network> >::const_iterator n(allNetworks.begin());n!=allNetworks.end();++n) {
|
|
||||||
if (peer->address() == (*n)->controller()) {
|
|
||||||
allowed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowed) {
|
|
||||||
const uint64_t pid = packetId();
|
|
||||||
const unsigned int difficulty = (*this)[ZT_PACKET_IDX_PAYLOAD + 1];
|
|
||||||
const unsigned int challengeLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 2);
|
|
||||||
if (challengeLength > ZT_PROTO_MAX_PACKET_LENGTH)
|
|
||||||
return true; // sanity check, drop invalid size
|
|
||||||
const unsigned char *challenge = field(ZT_PACKET_IDX_PAYLOAD + 4,challengeLength);
|
|
||||||
|
|
||||||
switch((*this)[ZT_PACKET_IDX_PAYLOAD]) {
|
|
||||||
|
|
||||||
// Salsa20/12+SHA512 hashcash
|
|
||||||
case 0x01: {
|
|
||||||
if (difficulty <= 14) {
|
|
||||||
unsigned char result[16];
|
|
||||||
computeSalsa2012Sha512ProofOfWork(difficulty,challenge,challengeLength,result);
|
|
||||||
TRACE("PROOF_OF_WORK computed for %s: difficulty==%u, challengeLength==%u, result: %.16llx%.16llx",peer->address().toString().c_str(),difficulty,challengeLength,Utils::ntoh(*(reinterpret_cast<const uint64_t *>(result))),Utils::ntoh(*(reinterpret_cast<const uint64_t *>(result + 8))));
|
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
|
||||||
outp.append((unsigned char)Packet::VERB_REQUEST_PROOF_OF_WORK);
|
|
||||||
outp.append(pid);
|
|
||||||
outp.append((uint16_t)sizeof(result));
|
|
||||||
outp.append(result,sizeof(result));
|
|
||||||
outp.armor(peer->key(),true);
|
|
||||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
|
||||||
} else {
|
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
|
||||||
outp.append((unsigned char)Packet::VERB_REQUEST_PROOF_OF_WORK);
|
|
||||||
outp.append(pid);
|
|
||||||
outp.append((unsigned char)Packet::ERROR_INVALID_REQUEST);
|
|
||||||
outp.armor(peer->key(),true);
|
|
||||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
TRACE("dropped REQUEST_PROOF_OF_WORK from %s(%s): unrecognized proof of work type",peer->address().toString().c_str(),_path->address().toString().c_str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer->received(_path,hops(),pid,Packet::VERB_REQUEST_PROOF_OF_WORK,0,Packet::VERB_NOP,false);
|
|
||||||
} else {
|
|
||||||
TRACE("dropped REQUEST_PROOF_OF_WORK from %s(%s): not trusted enough",peer->address().toString().c_str(),_path->address().toString().c_str());
|
|
||||||
}
|
|
||||||
} catch ( ... ) {
|
|
||||||
TRACE("dropped REQUEST_PROOF_OF_WORK from %s(%s): unexpected exception",peer->address().toString().c_str(),_path->address().toString().c_str());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid)
|
void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid)
|
||||||
{
|
{
|
||||||
const uint64_t now = RR->node->now();
|
const uint64_t now = RR->node->now();
|
||||||
@ -1499,82 +1434,4 @@ void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncomingPacket::computeSalsa2012Sha512ProofOfWork(unsigned int difficulty,const void *challenge,unsigned int challengeLength,unsigned char result[16])
|
|
||||||
{
|
|
||||||
unsigned char salsabuf[131072]; // 131072 == protocol constant, size of memory buffer for this proof of work function
|
|
||||||
char candidatebuf[ZT_PROTO_MAX_PACKET_LENGTH + 256];
|
|
||||||
unsigned char shabuf[ZT_SHA512_DIGEST_LEN];
|
|
||||||
const uint64_t s20iv = 0; // zero IV for Salsa20
|
|
||||||
char *const candidate = (char *)(( ((uintptr_t)&(candidatebuf[0])) | 0xf ) + 1); // align to 16-byte boundary to ensure that uint64_t type punning of initial nonce is okay
|
|
||||||
Salsa20 s20;
|
|
||||||
unsigned int d;
|
|
||||||
unsigned char *p;
|
|
||||||
|
|
||||||
Utils::getSecureRandom(candidate,16);
|
|
||||||
memcpy(candidate + 16,challenge,challengeLength);
|
|
||||||
|
|
||||||
if (difficulty > 512)
|
|
||||||
difficulty = 512; // sanity check
|
|
||||||
|
|
||||||
try_salsa2012sha512_again:
|
|
||||||
++*(reinterpret_cast<volatile uint64_t *>(candidate));
|
|
||||||
|
|
||||||
SHA512::hash(shabuf,candidate,16 + challengeLength);
|
|
||||||
s20.init(shabuf,256,&s20iv);
|
|
||||||
memset(salsabuf,0,sizeof(salsabuf));
|
|
||||||
s20.encrypt12(salsabuf,salsabuf,sizeof(salsabuf));
|
|
||||||
SHA512::hash(shabuf,salsabuf,sizeof(salsabuf));
|
|
||||||
|
|
||||||
d = difficulty;
|
|
||||||
p = shabuf;
|
|
||||||
while (d >= 8) {
|
|
||||||
if (*(p++))
|
|
||||||
goto try_salsa2012sha512_again;
|
|
||||||
d -= 8;
|
|
||||||
}
|
|
||||||
if (d > 0) {
|
|
||||||
if ( ((((unsigned int)*p) << d) & 0xff00) != 0 )
|
|
||||||
goto try_salsa2012sha512_again;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(result,candidate,16);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IncomingPacket::testSalsa2012Sha512ProofOfWorkResult(unsigned int difficulty,const void *challenge,unsigned int challengeLength,const unsigned char proposedResult[16])
|
|
||||||
{
|
|
||||||
unsigned char salsabuf[131072]; // 131072 == protocol constant, size of memory buffer for this proof of work function
|
|
||||||
char candidate[ZT_PROTO_MAX_PACKET_LENGTH + 256];
|
|
||||||
unsigned char shabuf[ZT_SHA512_DIGEST_LEN];
|
|
||||||
const uint64_t s20iv = 0; // zero IV for Salsa20
|
|
||||||
Salsa20 s20;
|
|
||||||
unsigned int d;
|
|
||||||
unsigned char *p;
|
|
||||||
|
|
||||||
if (difficulty > 512)
|
|
||||||
difficulty = 512; // sanity check
|
|
||||||
|
|
||||||
memcpy(candidate,proposedResult,16);
|
|
||||||
memcpy(candidate + 16,challenge,challengeLength);
|
|
||||||
|
|
||||||
SHA512::hash(shabuf,candidate,16 + challengeLength);
|
|
||||||
s20.init(shabuf,256,&s20iv);
|
|
||||||
memset(salsabuf,0,sizeof(salsabuf));
|
|
||||||
s20.encrypt12(salsabuf,salsabuf,sizeof(salsabuf));
|
|
||||||
SHA512::hash(shabuf,salsabuf,sizeof(salsabuf));
|
|
||||||
|
|
||||||
d = difficulty;
|
|
||||||
p = shabuf;
|
|
||||||
while (d >= 8) {
|
|
||||||
if (*(p++))
|
|
||||||
return false;
|
|
||||||
d -= 8;
|
|
||||||
}
|
|
||||||
if (d > 0) {
|
|
||||||
if ( ((((unsigned int)*p) << d) & 0xff00) != 0 )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
@ -111,27 +111,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline uint64_t receiveTime() const throw() { return _receiveTime; }
|
inline uint64_t receiveTime() const throw() { return _receiveTime; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the Salsa20/12+SHA512 proof of work function
|
|
||||||
*
|
|
||||||
* @param difficulty Difficulty in bits (max: 64)
|
|
||||||
* @param challenge Challenge string
|
|
||||||
* @param challengeLength Length of challenge in bytes (max allowed: ZT_PROTO_MAX_PACKET_LENGTH)
|
|
||||||
* @param result Buffer to fill with 16-byte result
|
|
||||||
*/
|
|
||||||
static void computeSalsa2012Sha512ProofOfWork(unsigned int difficulty,const void *challenge,unsigned int challengeLength,unsigned char result[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify the result of Salsa20/12+SHA512 proof of work
|
|
||||||
*
|
|
||||||
* @param difficulty Difficulty in bits (max: 64)
|
|
||||||
* @param challenge Challenge bytes
|
|
||||||
* @param challengeLength Length of challenge in bytes (max allowed: ZT_PROTO_MAX_PACKET_LENGTH)
|
|
||||||
* @param proposedResult Result supplied by client
|
|
||||||
* @return True if result is valid
|
|
||||||
*/
|
|
||||||
static bool testSalsa2012Sha512ProofOfWorkResult(unsigned int difficulty,const void *challenge,unsigned int challengeLength,const unsigned char proposedResult[16]);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// These are called internally to handle packet contents once it has
|
// These are called internally to handle packet contents once it has
|
||||||
// been authenticated, decrypted, decompressed, and classified.
|
// been authenticated, decrypted, decompressed, and classified.
|
||||||
@ -152,7 +131,6 @@ private:
|
|||||||
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
||||||
bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
||||||
bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
||||||
bool _doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
|
|
||||||
|
|
||||||
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid);
|
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid);
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ const char *Packet::verbString(Verb v)
|
|||||||
case VERB_PUSH_DIRECT_PATHS: return "PUSH_DIRECT_PATHS";
|
case VERB_PUSH_DIRECT_PATHS: return "PUSH_DIRECT_PATHS";
|
||||||
case VERB_CIRCUIT_TEST: return "CIRCUIT_TEST";
|
case VERB_CIRCUIT_TEST: return "CIRCUIT_TEST";
|
||||||
case VERB_CIRCUIT_TEST_REPORT: return "CIRCUIT_TEST_REPORT";
|
case VERB_CIRCUIT_TEST_REPORT: return "CIRCUIT_TEST_REPORT";
|
||||||
case VERB_REQUEST_PROOF_OF_WORK: return "REQUEST_PROOF_OF_WORK";
|
|
||||||
case VERB_USER_MESSAGE: return "USER_MESSAGE";
|
case VERB_USER_MESSAGE: return "USER_MESSAGE";
|
||||||
}
|
}
|
||||||
return "(unknown)";
|
return "(unknown)";
|
||||||
|
@ -891,8 +891,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
VERB_MULTICAST_FRAME = 0x0e,
|
VERB_MULTICAST_FRAME = 0x0e,
|
||||||
|
|
||||||
// 0x0f is reserved for an old deprecated message
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push of potential endpoints for direct communication:
|
* Push of potential endpoints for direct communication:
|
||||||
* <[2] 16-bit number of paths>
|
* <[2] 16-bit number of paths>
|
||||||
@ -1044,49 +1042,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
VERB_CIRCUIT_TEST_REPORT = 0x12,
|
VERB_CIRCUIT_TEST_REPORT = 0x12,
|
||||||
|
|
||||||
/**
|
|
||||||
* Request proof of work:
|
|
||||||
* <[1] 8-bit proof of work type>
|
|
||||||
* <[1] 8-bit proof of work difficulty>
|
|
||||||
* <[2] 16-bit length of proof of work challenge>
|
|
||||||
* <[...] proof of work challenge>
|
|
||||||
*
|
|
||||||
* This requests that a peer perform a proof of work calucation. It can be
|
|
||||||
* sent by highly trusted peers (e.g. root servers, network controllers)
|
|
||||||
* under suspected denial of service conditions in an attempt to filter
|
|
||||||
* out "non-serious" peers and remain responsive to those proving their
|
|
||||||
* intent to actually communicate.
|
|
||||||
*
|
|
||||||
* If the peer obliges to perform the work, it does so and responds with
|
|
||||||
* an OK containing the result. Otherwise it may ignore the message or
|
|
||||||
* response with an ERROR_INVALID_REQUEST or ERROR_UNSUPPORTED_OPERATION.
|
|
||||||
*
|
|
||||||
* Proof of work type IDs:
|
|
||||||
* 0x01 - Salsa20/12+SHA512 hashcash function
|
|
||||||
*
|
|
||||||
* Salsa20/12+SHA512 is based on the following composite hash function:
|
|
||||||
*
|
|
||||||
* (1) Compute SHA512(candidate)
|
|
||||||
* (2) Use the first 256 bits of the result of #1 as a key to encrypt
|
|
||||||
* 131072 zero bytes with Salsa20/12 (with a zero IV).
|
|
||||||
* (3) Compute SHA512(the result of step #2)
|
|
||||||
* (4) Accept this candiate if the first [difficulty] bits of the result
|
|
||||||
* from step #3 are zero. Otherwise generate a new candidate and try
|
|
||||||
* again.
|
|
||||||
*
|
|
||||||
* This is performed repeatedly on candidates generated by appending the
|
|
||||||
* supplied challenge to an arbitrary nonce until a valid candidate
|
|
||||||
* is found. This chosen prepended nonce is then returned as the result
|
|
||||||
* in OK.
|
|
||||||
*
|
|
||||||
* OK payload:
|
|
||||||
* <[2] 16-bit length of result>
|
|
||||||
* <[...] computed proof of work>
|
|
||||||
*
|
|
||||||
* ERROR has no payload.
|
|
||||||
*/
|
|
||||||
VERB_REQUEST_PROOF_OF_WORK = 0x13,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A message with arbitrary user-definable content:
|
* A message with arbitrary user-definable content:
|
||||||
* <[8] 64-bit arbitrary message type ID>
|
* <[8] 64-bit arbitrary message type ID>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user