|
|
|
|
@ -98,41 +98,6 @@ class HttpSignature
|
|
|
|
|
return $headers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function instanceActorSignWithDigest(
|
|
|
|
|
string $url,
|
|
|
|
|
string $digest,
|
|
|
|
|
array $addlHeaders = [],
|
|
|
|
|
string $method = 'post'
|
|
|
|
|
): array {
|
|
|
|
|
$keyId = config('app.url').'/i/actor#main-key';
|
|
|
|
|
$privateKey = Cache::rememberForever(InstanceActor::PKI_PRIVATE, function () {
|
|
|
|
|
$instance = InstanceActor::first()
|
|
|
|
|
?: tap(Artisan::call('instance:actor'), fn () => sleep(10)) && InstanceActor::first();
|
|
|
|
|
if (! $instance) {
|
|
|
|
|
throw new \Exception('Failed to generate or retrieve InstanceActor.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $instance->private_key;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
abort_if(! $privateKey, 400, 'Missing instance actor key, please run php artisan instance:actor');
|
|
|
|
|
|
|
|
|
|
$headers = self::_headersToSign($url, $digest, $method);
|
|
|
|
|
$headers = array_merge($headers, $addlHeaders);
|
|
|
|
|
$stringToSign = self::_headersToSigningString($headers);
|
|
|
|
|
$signedHeaders = implode(' ', array_map('strtolower', array_keys($headers)));
|
|
|
|
|
|
|
|
|
|
$key = openssl_pkey_get_private($privateKey);
|
|
|
|
|
openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256);
|
|
|
|
|
$signature = base64_encode($signature);
|
|
|
|
|
|
|
|
|
|
$signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"';
|
|
|
|
|
unset($headers['(request-target)']);
|
|
|
|
|
$headers['Signature'] = $signatureHeader;
|
|
|
|
|
|
|
|
|
|
return self::_headersToCurlArray($headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function parseSignatureHeader($signature)
|
|
|
|
|
{
|
|
|
|
|
$parts = explode(',', $signature);
|
|
|
|
|
@ -191,6 +156,41 @@ class HttpSignature
|
|
|
|
|
return [$verified, $signingString];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function instanceActorSignWithDigest(
|
|
|
|
|
string $url,
|
|
|
|
|
string $digest,
|
|
|
|
|
array $addlHeaders = [],
|
|
|
|
|
string $method = 'post'
|
|
|
|
|
): array {
|
|
|
|
|
$keyId = config('app.url').'/i/actor#main-key';
|
|
|
|
|
$privateKey = Cache::rememberForever(InstanceActor::PKI_PRIVATE, function () {
|
|
|
|
|
$instance = InstanceActor::first()
|
|
|
|
|
?: tap(Artisan::call('instance:actor'), fn () => sleep(10)) && InstanceActor::first();
|
|
|
|
|
if (! $instance) {
|
|
|
|
|
throw new \Exception('Failed to generate or retrieve InstanceActor.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $instance->private_key;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
abort_if(! $privateKey, 400, 'Missing instance actor key, please run php artisan instance:actor');
|
|
|
|
|
|
|
|
|
|
$headers = self::_headersToSign($url, $digest, $method);
|
|
|
|
|
$headers = array_merge($headers, $addlHeaders);
|
|
|
|
|
$stringToSign = self::_headersToSigningString($headers);
|
|
|
|
|
$signedHeaders = implode(' ', array_map('strtolower', array_keys($headers)));
|
|
|
|
|
|
|
|
|
|
$key = openssl_pkey_get_private($privateKey);
|
|
|
|
|
openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256);
|
|
|
|
|
$signature = base64_encode($signature);
|
|
|
|
|
|
|
|
|
|
$signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"';
|
|
|
|
|
unset($headers['(request-target)']);
|
|
|
|
|
$headers['Signature'] = $signatureHeader;
|
|
|
|
|
|
|
|
|
|
return $headers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static function _headersToSigningString($headers)
|
|
|
|
|
{
|
|
|
|
|
return implode("\n", array_map(function ($k, $v) {
|
|
|
|
|
|