Renew challenge on expiry
This commit is contained in:
parent
0a11d9ff27
commit
1fe03a6906
@ -113,6 +113,17 @@ private:
|
|||||||
*/
|
*/
|
||||||
void processMessage(SignedMessage* message);
|
void processMessage(SignedMessage* message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks that the message is valid and prepares a challenge.
|
||||||
|
*
|
||||||
|
* This function is also called when a challenge response arrives too late.
|
||||||
|
*
|
||||||
|
* @param message The message to respond to
|
||||||
|
*
|
||||||
|
* Note: Prepares the response in the outgoing message buffer.
|
||||||
|
*/
|
||||||
|
void checkAndPrepareChallenge(Message* message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepare a server challenge for a local or socket message.
|
* @brief Prepare a server challenge for a local or socket message.
|
||||||
*
|
*
|
||||||
|
@ -59,8 +59,11 @@ enum class MessageResult: uint8_t {
|
|||||||
/// @brief A message is already being processed
|
/// @brief A message is already being processed
|
||||||
TooManyRequests = 8,
|
TooManyRequests = 8,
|
||||||
|
|
||||||
|
/// @brief The received message result was invalid
|
||||||
|
InvalidMessageResult = 9,
|
||||||
|
|
||||||
|
/// @brief An invalid Url parameter was set sending a message to the device over a local connection
|
||||||
InvalidUrlParameter = 10,
|
InvalidUrlParameter = 10,
|
||||||
InvalidResponseAuthentication = 11,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ void SesameController::sendPreparedResponseToServer() {
|
|||||||
void SesameController::processMessage(SignedMessage* message) {
|
void SesameController::processMessage(SignedMessage* message) {
|
||||||
// Result must be empty
|
// Result must be empty
|
||||||
if (message->message.result != MessageResult::MessageAccepted) {
|
if (message->message.result != MessageResult::MessageAccepted) {
|
||||||
prepareResponseBuffer(MessageResult::ClientChallengeInvalid);
|
prepareResponseBuffer(MessageResult::InvalidMessageResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isAuthenticMessage(message, keyConfig.remoteKey)) {
|
if (!isAuthenticMessage(message, keyConfig.remoteKey)) {
|
||||||
@ -125,7 +125,7 @@ void SesameController::processMessage(SignedMessage* message) {
|
|||||||
}
|
}
|
||||||
switch (message->message.messageType) {
|
switch (message->message.messageType) {
|
||||||
case MessageType::initial:
|
case MessageType::initial:
|
||||||
prepareChallenge(&message->message);
|
checkAndPrepareChallenge(&message->message);
|
||||||
return;
|
return;
|
||||||
case MessageType::request:
|
case MessageType::request:
|
||||||
completeUnlockRequest(&message->message);
|
completeUnlockRequest(&message->message);
|
||||||
@ -136,12 +136,16 @@ void SesameController::processMessage(SignedMessage* message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SesameController::prepareChallenge(Message* message) {
|
void SesameController::checkAndPrepareChallenge(Message* message) {
|
||||||
// Server challenge must be empty
|
// Server challenge must be empty
|
||||||
if (message->serverChallenge != 0) {
|
if (message->serverChallenge != 0) {
|
||||||
prepareResponseBuffer(MessageResult::ClientChallengeInvalid);
|
prepareResponseBuffer(MessageResult::ClientChallengeInvalid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
prepareChallenge(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SesameController::prepareChallenge(Message* message) {
|
||||||
if (hasCurrentChallenge()) {
|
if (hasCurrentChallenge()) {
|
||||||
Serial.println("[INFO] Overwriting old challenge");
|
Serial.println("[INFO] Overwriting old challenge");
|
||||||
}
|
}
|
||||||
@ -155,10 +159,6 @@ void SesameController::prepareChallenge(Message* message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SesameController::completeUnlockRequest(Message* message) {
|
void SesameController::completeUnlockRequest(Message* message) {
|
||||||
if (!hasCurrentChallenge()) {
|
|
||||||
prepareResponseBuffer(MessageResult::ClientChallengeInvalid, message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Client and server challenge must match
|
// Client and server challenge must match
|
||||||
if (message->clientChallenge != currentClientChallenge) {
|
if (message->clientChallenge != currentClientChallenge) {
|
||||||
prepareResponseBuffer(MessageResult::ClientChallengeInvalid, message);
|
prepareResponseBuffer(MessageResult::ClientChallengeInvalid, message);
|
||||||
@ -168,6 +168,15 @@ void SesameController::completeUnlockRequest(Message* message) {
|
|||||||
prepareResponseBuffer(MessageResult::ServerChallengeMismatch, message);
|
prepareResponseBuffer(MessageResult::ServerChallengeMismatch, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!hasCurrentChallenge()) {
|
||||||
|
// Directly send new challenge on expiry, since rest of message is valid
|
||||||
|
// This allows the remote to directly try again without requesting a new challenge.
|
||||||
|
// Security note: The client nonce is reused in this case, but an attacker would still
|
||||||
|
// not be able to create a valid unlock request due to the new server nonce.
|
||||||
|
prepareChallenge(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clearCurrentChallenge();
|
clearCurrentChallenge();
|
||||||
|
|
||||||
// Move servo
|
// Move servo
|
||||||
|
Loading…
Reference in New Issue
Block a user