Better signature validation

merge-requests/5/head
Terence Eden 2024-03-17 09:16:44 +00:00
rodzic 864315d5f7
commit 3045406f76
1 zmienionych plików z 77 dodań i 30 usunięć

Wyświetl plik

@ -1485,13 +1485,46 @@ HTML;
$headers = array_change_key_case( $headers, CASE_LOWER ); $headers = array_change_key_case( $headers, CASE_LOWER );
// Validate the timestamp is within ±30 seconds // Validate the timestamp is within ±30 seconds
if ( !isset( $headers["date"] ) ) { return null; } // No date set // 7.2.4 of https://datatracker.ietf.org/doc/rfc9421/ says compare the Date header and the published date of the message
if ( !isset( $headers["date"] ) ) {
// No date set
// Filename for the log
$filename = "{$timestamp}.{$type}.Signature.Date_Failure.txt";
// Save headers and request data to the timestamped file in the logs directory
file_put_contents( $directories["logs"] . "/{$filename}",
"Original Body:\n" . print_r( $body, true ) . "\n\n" .
"Original Headers:\n" . print_r( $headers, true ) . "\n\n"
);
return null;
}
$dateHeader = $headers["date"]; $dateHeader = $headers["date"];
$headerDatetime = DateTime::createFromFormat('D, d M Y H:i:s T', $dateHeader); $headerDatetime = DateTime::createFromFormat('D, d M Y H:i:s T', $dateHeader);
$currentDatetime = new DateTime(); $currentDatetime = new DateTime();
// First, check if the message was sent more than 30 seconds ago
// Calculate the time difference in seconds // Calculate the time difference in seconds
$timeDifference = abs( $currentDatetime->getTimestamp() - $headerDatetime->getTimestamp() ); $timeDifference = abs( $currentDatetime->getTimestamp() - $headerDatetime->getTimestamp() );
if ( $timeDifference > 30 ) {
// Write a log detailing the error
// Filename for the log
$filename = "{$timestamp}.{$type}.Signature.Delay_Failure.txt";
// Save headers and request data to the timestamped file in the logs directory
file_put_contents( $directories["logs"] . "/{$filename}",
"Header Date:\n" . print_r( $dateHeader, true ) . "\n" .
"Server Date:\n" . print_r( $currentDatetime->format('D, d M Y H:i:s T'), true ) ."\n" .
"Original Body:\n" . print_r( $body, true ) . "\n\n" .
"Original Headers:\n" . print_r( $headers, true ) . "\n\n"
);
return false;
}
// Is there a significant difference between the Date header and the published timestamp?
$published = $body["published"];
$publishedDatetime = new DateTime($published);
// Calculate the time difference in seconds
$timeDifference = abs( $publishedDatetime->getTimestamp() - $headerDatetime->getTimestamp() );
if ( $timeDifference > 30 ) { if ( $timeDifference > 30 ) {
// Write a log detailing the error // Write a log detailing the error
// Filename for the log // Filename for the log
@ -1499,8 +1532,10 @@ HTML;
// Save headers and request data to the timestamped file in the logs directory // Save headers and request data to the timestamped file in the logs directory
file_put_contents( $directories["logs"] . "/{$filename}", file_put_contents( $directories["logs"] . "/{$filename}",
"Original Date:\n" . print_r( $dateHeader, true ) . "\n" . "Header Date:\n" . print_r( $dateHeader, true ) . "\n" .
"Local Date:\n" . print_r( $currentDatetime->format('D, d M Y H:i:s T'), true ) . "\n" "Published Date:\n" . print_r( $publishedDatetime->format('D, d M Y H:i:s T'), true ) ."\n" .
"Original Body:\n" . print_r( $body, true ) . "\n\n" .
"Original Headers:\n" . print_r( $headers, true ) . "\n\n"
); );
return false; return false;
} }
@ -1588,8 +1623,21 @@ HTML;
$actorPublicKey = $actorData["publicKey"]["publicKeyPem"]; $actorPublicKey = $actorData["publicKey"]["publicKeyPem"];
if ( $publicKey != $actorPublicKey ) { if ( $publicKey != $actorPublicKey ) {
$verified = false; // Filename for the log
} else { $filename = "{$timestamp}.{$type}.Signature.Mismatch_Failure.txt";
// Save headers and request data to the timestamped file in the logs directory
file_put_contents( $directories["logs"] . "/{$filename}",
"Original Body:\n" . print_r( $body, true ) . "\n\n" .
"Original Headers:\n" . print_r( $headers, true ) . "\n\n" .
"Signature Headers:\n" . print_r( $signatureHeaders, true ) . "\n\n" .
"publicKeyURL:\n" . print_r( $publicKeyURL, true ) . "\n\n" .
"publicKey:\n" . print_r( $publicKey, true ) . "\n\n" .
"actorPublicKey:\n" . print_r( $actorPublicKey, true ) . "\n"
);
return false;
}
// Get the remaining parts // Get the remaining parts
$signature = base64_decode( $signatureParts["signature"] ); $signature = base64_decode( $signatureParts["signature"] );
$algorithm = $signatureParts["algorithm"]; $algorithm = $signatureParts["algorithm"];
@ -1618,7 +1666,6 @@ HTML;
} else { } else {
$verified = null; $verified = null;
} }
}
// Filename for the log // Filename for the log
$filename = "{$timestamp}.{$type}.Signature.". json_encode( $verified ) . ".txt"; $filename = "{$timestamp}.{$type}.Signature.". json_encode( $verified ) . ".txt";