diff --git a/lib/XRay.php b/lib/XRay.php index da76868..da1c687 100644 --- a/lib/XRay.php +++ b/lib/XRay.php @@ -81,5 +81,9 @@ class XRay { if(!isset($result['source-format'])) $result['source-format'] = null; return $result; } + + public function httpsig($opts) { + $this->defaultOptions = array_merge($this->defaultOptions, ['httpsig' => $opts]); + } } diff --git a/lib/XRay/Fetcher.php b/lib/XRay/Fetcher.php index 3231fb4..55a6de0 100644 --- a/lib/XRay/Fetcher.php +++ b/lib/XRay/Fetcher.php @@ -1,8 +1,13 @@ http = $http; @@ -60,6 +65,13 @@ class Fetcher { } $headers = []; + + if(isset($opts['httpsig'])) { + // If we're making a signed GET, include the default headers that mastodon requires as part of the signature + $date = new DateTime('UTC'); + $date = $date->format('D, d M Y H:i:s \G\M\T'); + $headers = $this->_headersToSign($url, $date); + } $accept = 'application/mf2+json, application/activity+json, text/html, application/json, application/xml, text/xml'; if(isset($opts['accept'])) { @@ -73,12 +85,18 @@ class Fetcher { $accept = 'application/xml, text/xml'; } - $headers[] = 'Accept: '.$accept; + // Override with the accept header here + $headers['Accept'] = $accept; if(isset($opts['token'])) - $headers[] = 'Authorization: Bearer ' . $opts['token']; + $headers['Authorization'] = 'Bearer ' . $opts['token']; + + if(isset($opts['httpsig'])) { + echo "Signing HTTP Request\n"; + $this->_httpSign($headers, $opts['httpsig']); + } - $result = $this->http->get($url, $headers); + $result = $this->http->get($url, $this->_headersToCurlArray($headers)); if($result['error']) { return [ diff --git a/lib/XRay/HTTPSig.php b/lib/XRay/HTTPSig.php new file mode 100644 index 0000000..5a916e2 --- /dev/null +++ b/lib/XRay/HTTPSig.php @@ -0,0 +1,50 @@ + 'get '.parse_url($target, PHP_URL_PATH), + 'Date' => $date, + 'Host' => parse_url($target, PHP_URL_HOST), + 'Content-Type' => 'application/activity+json', + ]; + + return $headers; + } + + protected function _httpSign(&$headers, $key) { + $stringToSign = $this->_headersToSigningString($headers); + + $signedHeaders = implode(' ', array_map('strtolower', array_keys($headers))); + + $privateKey = openssl_pkey_get_private('file://'.$key['key']); + + openssl_sign($stringToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256); + $signature = base64_encode($signature); + + $signatureHeader = 'keyId="'.$key['keyId'].'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + + unset($headers['(request-target)']); + + $headers['Signature'] = $signatureHeader; + } + +}