Browse Source

add option to make a signed get given a key

main v1.14.0
Aaron Parecki 1 month ago
parent
commit
f9e219a210
3 changed files with 75 additions and 3 deletions
  1. +4
    -0
      lib/XRay.php
  2. +21
    -3
      lib/XRay/Fetcher.php
  3. +50
    -0
      lib/XRay/HTTPSig.php

+ 4
- 0
lib/XRay.php View File

@ -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]);
}
}

+ 21
- 3
lib/XRay/Fetcher.php View File

@ -1,8 +1,13 @@
<?php
namespace p3k\XRay;
use DateTime;
class Fetcher {
private $http;
use HTTPSig;
public function __construct($http) {
$this->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 [

+ 50
- 0
lib/XRay/HTTPSig.php View File

@ -0,0 +1,50 @@
<?php
namespace p3k\XRay;
trait HTTPSig {
protected function _headersToSigningString($headers) {
return implode("\n", array_map(function($k, $v){
return strtolower($k).': '.$v;
}, array_keys($headers), $headers));
}
protected function _headersToCurlArray($headers) {
return array_map(function($k, $v){
return "$k: $v";
}, array_keys($headers), $headers);
}
protected function _digest($payload) {
return base64_encode(hash('sha256', $payload, true));
}
protected function _headersToSign($target, $date) {
$headers = [
'(request-target)' => '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;
}
}

Loading…
Cancel
Save