From 74bf3d1a68ac437809f3a84c796bf19b9babd158 Mon Sep 17 00:00:00 2001 From: Terence Eden Date: Wed, 14 Feb 2024 09:45:04 +0000 Subject: [PATCH] Move signing to its own function --- index.php | 120 +++++++++++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/index.php b/index.php index 03b52b7..e17505f 100644 --- a/index.php +++ b/index.php @@ -222,42 +222,14 @@ "object" => "https://{$server}/{$username}", ] ]; - $message_json = json_encode( $message ); // The Accept is sent to the server of the user who requested the follow // TODO: The path doesn't *always* end with/inbox $host = $inbox_host; $path = parse_url( $inbox_actor, PHP_URL_PATH ) . "/inbox"; - - // Set up signing - $keyId = "https://{$server}/{$username}#main-key"; - // Generate signing variables - $hash = hash( 'sha256', $message_json, true ); - $digest = base64_encode( $hash ); - $date = date( 'D, d M Y H:i:s \G\M\T' ); - - $signer = openssl_get_privatekey( $key_private ); - $stringToSign = "(request-target): post $path\nhost: $host\ndate: $date\ndigest: SHA-256=$digest"; - openssl_sign( - $stringToSign, - $signature, - $signer, - OPENSSL_ALGO_SHA256 - ); - $signature_b64 = base64_encode( $signature ); - - $header = 'keyId="' . $keyId . '",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="' . $signature_b64 . '"'; - - // Header for POST reply - $headers = array( - "Host: {$host}", - "Date: {$date}", - "Digest: SHA-256={$digest}", - "Signature: {$header}", - "Content-Type: application/activity+json", - "Accept: application/activity+json", - ); + // Get the signed headers + $headers = generate_signed_headers( $message, $host, $path ); // Specify the URL of the remote server's inbox // TODO: The path doesn't *always* end with /inbox @@ -267,7 +239,7 @@ $ch = curl_init( $remoteServerUrl ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" ); - curl_setopt( $ch, CURLOPT_POSTFIELDS, $message_json ); + curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($message) ); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); $response = curl_exec( $ch ); @@ -290,6 +262,53 @@ ); } + function generate_signed_headers( $message, $host, $path ) { + global $server, $username, $key_private; + + // Encode the message to JSON + $message_json = json_encode( $message ); + + // Location of the Public Key + $keyId = "https://{$server}/{$username}#main-key"; + + // Generate signing variables + $hash = hash( 'sha256', $message_json, true ); + $digest = base64_encode( $hash ); + $date = date( 'D, d M Y H:i:s \G\M\T' ); + + // Get the Private Key + $signer = openssl_get_privatekey( $key_private ); + + // Sign the path, host, date, and digest + $stringToSign = "(request-target): post $path\nhost: $host\ndate: $date\ndigest: SHA-256=$digest"; + + // The signing function returns the variable $signature + // https://www.php.net/manual/en/function.openssl-sign.php + openssl_sign( + $stringToSign, + $signature, + $signer, + OPENSSL_ALGO_SHA256 + ); + // Encode the signature + $signature_b64 = base64_encode( $signature ); + + // Full signature header + $signature_header = 'keyId="' . $keyId . '",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="' . $signature_b64 . '"'; + + // Header for POST reply + $headers = array( + "Host: {$host}", + "Date: {$date}", + "Digest: SHA-256={$digest}", + "Signature: {$signature_header}", + "Content-Type: application/activity+json", + "Accept: application/activity+json", + ); + + return $headers; + } + function write() { // Display an HTML form for the user to enter a message. echo <<< HTML @@ -361,7 +380,6 @@ HTML; ], "object" => $note ]; - $message_json = json_encode($message); // Create the context for the permalink $note = [ "@context" => "https://www.w3.org/ns/activitystreams", ...$note ]; @@ -385,37 +403,10 @@ HTML; // Each POST to an inbox needs to be signed separately foreach ( $hosts as $host ) { $path = '/inbox'; - - // Set up signing - $privateKey = $key_private; - $keyId = "https://{$server}/{$username}#main-key"; - - $hash = hash( "sha256", $message_json, true ); - $digest = base64_encode( $hash ); - $date = date( 'D, d M Y H:i:s \G\M\T' ); - - $signer = openssl_get_privatekey( $key_private ); - $stringToSign = "(request-target): post $path\nhost: $host\ndate: $date\ndigest: SHA-256=$digest"; - openssl_sign( - $stringToSign, - $signature, - $signer, - OPENSSL_ALGO_SHA256 - ); - $signature_b64 = base64_encode( $signature ); - - $header = 'keyId="' . $keyId . '",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="' . $signature_b64 . '"'; - - // Header for POST reply - $headers = array( - "Host: {$host}", - "Date: {$date}", - "Digest: SHA-256={$digest}", - "Signature: {$header}", - "Content-Type: application/activity+json", - "Accept: application/activity+json", - ); - + + // Get the signed headers + $headers = generate_signed_headers( $message, $host, $path ); + // Specify the URL of the remote server $remoteServerUrl = "https://{$host}{$path}"; @@ -424,7 +415,7 @@ HTML; curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" ); - curl_setopt( $ch, CURLOPT_POSTFIELDS, $message_json ); + curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($message) ); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); // Add the handle to the multi-handle @@ -447,6 +438,7 @@ HTML; die(); } +// "One to stun, two to kill, three to make sure" die(); die(); die(); \ No newline at end of file