[WIP] Begin implementing http sig signing/verification
This commit is contained in:
parent
b344c7ae8a
commit
366e34069c
@ -24,8 +24,10 @@
|
||||
"require": {
|
||||
"doctrine/orm": "^2.6",
|
||||
"friendica/json-ld": "^1.1",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"phpseclib/phpseclib": "^2.0",
|
||||
"symfony/http-kernel": "^4.2"
|
||||
"symfony/http-kernel": "^4.2",
|
||||
"symfony/psr-http-message-bridge": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/dbunit": "^4.0",
|
||||
|
336
composer.lock
generated
336
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0b28ccdd3b389a1e12672e87cfe8a643",
|
||||
"content-hash": "7312404cd7d0385ed891364e07144079",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@ -911,6 +911,189 @@
|
||||
],
|
||||
"time": "2018-10-08T20:41:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
|
||||
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/promises": "^1.0",
|
||||
"guzzlehttp/psr7": "^1.4",
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "Required for using the Log middleware"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle is a PHP HTTP client library",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"client",
|
||||
"curl",
|
||||
"framework",
|
||||
"http",
|
||||
"http client",
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2018-04-22T15:46:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "v1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle promises library",
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"time": "2016-12-20T10:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"psr/http-message": "~1.0",
|
||||
"ralouphie/getallheaders": "^2.0.5"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Psr7\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "PSR-7 message implementation that also provides common utility methods",
|
||||
"keywords": [
|
||||
"http",
|
||||
"message",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"stream",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2018-12-04T20:46:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.13",
|
||||
@ -1003,6 +1186,56 @@
|
||||
],
|
||||
"time": "2018-12-16T17:45:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"time": "2016-08-06T14:39:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.1.0",
|
||||
@ -1050,6 +1283,46 @@
|
||||
],
|
||||
"time": "2018-11-20T15:27:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "2.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
|
||||
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~3.7.0",
|
||||
"satooshi/php-coveralls": ">=1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"time": "2016-02-11T07:05:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v4.2.1",
|
||||
@ -1566,6 +1839,67 @@
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/psr-http-message-bridge",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/psr-http-message-bridge.git",
|
||||
"reference": "53c15a6a7918e6c2ab16ae370ea607fb40cab196"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/53c15a6a7918e6c2ab16ae370ea607fb40cab196",
|
||||
"reference": "53c15a6a7918e6c2ab16ae370ea607fb40cab196",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"symfony/http-foundation": "^2.3.42 || ^3.4 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3.4 || 4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/http-factory-implementation": "To use the PSR-17 factory",
|
||||
"psr/http-message-implementation": "To use the HttpFoundation factory",
|
||||
"zendframework/zend-diactoros": "To use the Zend Diactoros factory"
|
||||
},
|
||||
"type": "symfony-bridge",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bridge\\PsrHttpMessage\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "PSR HTTP message bridge",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2018-08-30T16:28:28+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
32
src/Auth/AuthenticationService.php
Normal file
32
src/Auth/AuthenticationService.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace ActivityPub\Auth;
|
||||
|
||||
/**
|
||||
* The AuthenticationService class answers the question, "is this request authenticated
|
||||
* to act on behalf of this Actor?"
|
||||
*
|
||||
* It delegates most of the work to a passed-in Callable to allow library clients to
|
||||
* plug in their own authentication methods.
|
||||
*/
|
||||
class AuthenticationService
|
||||
{
|
||||
/**
|
||||
* The Callable that is called to determine if a request is authorized for an Actor
|
||||
*
|
||||
* @var Callable
|
||||
*
|
||||
*/
|
||||
private $authFunction;
|
||||
|
||||
/**
|
||||
* Constructs a new AuthenticationService
|
||||
*
|
||||
* @param Callable $authFunction A Callable that should accept
|
||||
*
|
||||
*/
|
||||
public function __construct( Callable $authFunction )
|
||||
{
|
||||
$this->authFunction = $authFunction;
|
||||
}
|
||||
}
|
||||
?>
|
116
src/Auth/HttpSignatureService.php
Normal file
116
src/Auth/HttpSignatureService.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
namespace ActivityPub\Auth;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\HeaderUtils;
|
||||
|
||||
/**
|
||||
* The HttpSignatureService provides methods to generate and verify HTTP signatures
|
||||
*/
|
||||
class HttpSignatureService
|
||||
{
|
||||
// TODO handle the Digest header better, both on generating and verifying
|
||||
const DEFAULT_HEADERS = array(
|
||||
'(request-target)',
|
||||
'host',
|
||||
'date',
|
||||
);
|
||||
|
||||
public function sign( Request $request, string $privateKey, $headers = self::DEFAULT_HEADERS )
|
||||
{
|
||||
// To generate a signature for a request:
|
||||
// 1. put together the signing string from the headers list
|
||||
// 2. generate an RSA-sha256 signature of the signing string using the private key
|
||||
// 3. return the signature base64-encoded
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the HTTP signature of $request
|
||||
*
|
||||
* @param Request $request The request to verify
|
||||
* @param string $publicKey The public key to use to verify the request
|
||||
* @return bool True if the signature is valid, false if it is missing or invalid
|
||||
*/
|
||||
public function verify( Request $request, string $publicKey )
|
||||
{
|
||||
// To verify a signature:
|
||||
// 1. Re-create the signing string from the request and the headers
|
||||
// 2. verify that the signature is signed correctly using the public key and the signing string
|
||||
// The signature can either be in the Authentication header or the Signature header.
|
||||
// If it's in the Authentication header, the params will be prefixed with the string "Signature",
|
||||
// e.g. Authentication: Signature keyId="key-1",algorithm="rsa-sha256",headers="(request-target) host date",signature="thesig"
|
||||
// as opposed to the Signature header, which just has the params as its value:
|
||||
// Signature: keyId="key-1",algorithm="rsa-sha256",headers="(request-target) host date",signature="thesig"
|
||||
$params = array();
|
||||
$headers = $request->headers;
|
||||
if ( $headers->has( 'signature' ) ) {
|
||||
$params = $this->parseSignatureParams( $headers->get( 'signature' ) );
|
||||
} else if ( $headers->has( 'authorization' ) &&
|
||||
substr($headers->get( 'authorization' ), 0, 9) === 'Signature' ) {
|
||||
$paramsStr = substr( $headers->get( 'authorization' ), 10 );
|
||||
$params = $this->parseSignatureParams( $paramsStr );
|
||||
}
|
||||
if ( count( $params ) === 0 ) {
|
||||
return false;
|
||||
}
|
||||
$targetHeaders = array( 'date' );
|
||||
if ( array_key_exists( 'headers', $params ) ) {
|
||||
$targetHeaders = $params['headers'];
|
||||
}
|
||||
$signingString = $this->getSigningString( $request, $targetHeaders );
|
||||
$signature = $params['signature'];
|
||||
// TODO handle different algorithms here, checking the 'algorithm' param and the key headers
|
||||
return openssl_verify(
|
||||
$signingString, $signature, $publicKey, OPENSSL_ALGO_SHA256
|
||||
) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signing string from the request
|
||||
*
|
||||
* @param Request $request The request
|
||||
* @param array $headers The headers to use to generate the signing string
|
||||
* @return string The signing string
|
||||
*/
|
||||
private function getSigningString( Request $request, $headers )
|
||||
{
|
||||
$signingComponents = array();
|
||||
foreach ( $headers as $header ) {
|
||||
$component = "${header}: ";
|
||||
if ( $header == '(request-target)' ) {
|
||||
$method = strtolower( $request->method );
|
||||
$path = $request->getRequestUri();
|
||||
$component = $component . $method . ' ' . $path;
|
||||
} else {
|
||||
// TODO handle 'digest' specially here too
|
||||
$values = $request->headers->get( $header, null, false );
|
||||
$component = $component . implode( ', ', $values );
|
||||
}
|
||||
$signingComponents[] = $component;
|
||||
}
|
||||
return implode( '\n', $signingComponents );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the signature params from the provided params string
|
||||
*
|
||||
* @param string $paramsStr The params represented as a string,
|
||||
* e.g. 'keyId="theKey",algorithm="rsa-sha256"'
|
||||
* @return array The params as an associative array
|
||||
*/
|
||||
private function parseSignatureParams( string $paramsStr )
|
||||
{
|
||||
$params = array();
|
||||
$split = HeaderUtils::split( $paramsStr, ',= ' );
|
||||
foreach ( $split as $paramArr ) {
|
||||
$paramName = $paramArr[0];
|
||||
$paramValue = $paramArr[1];
|
||||
if ( count( $paramValue ) === 1 ) {
|
||||
$paramValue = $paramValue[0];
|
||||
}
|
||||
$params[$paramName] = $paramValue;
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
?>
|
32
src/Auth/HttpSignatureValidator.php
Normal file
32
src/Auth/HttpSignatureValidator.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace ActivityPub\Auth;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* The HttpSignatureValidator is a subscriber to the kernel.request event
|
||||
* that validates HTTP signatures if present.
|
||||
*
|
||||
*/
|
||||
class HttpSignatureValidator implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => 'validateHttpSignature'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a valid HTTP signature on the request. If the request has a valid signature,
|
||||
* set the 'signed' and 'signedBy' keys on the request ('signedBy' is the id of the actor
|
||||
* whose key signed the request)
|
||||
*/
|
||||
public function validateHttpSignature( GetResponseEvent $event )
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
}
|
||||
}
|
||||
?>
|
73
test/Auth/HttpSignatureServiceTest.php
Normal file
73
test/Auth/HttpSignatureServiceTest.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
// tests:
|
||||
// - signature for request that specifies a header but is missing that header
|
||||
// - signature for request with malformed Signature header
|
||||
namespace ActivityPub\Test\Auth;
|
||||
|
||||
use ActivityPub\Auth\HttpSignatureService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class HttpSignatureServiceTest extends TestCase
|
||||
{
|
||||
const PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
|
||||
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
|
||||
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
|
||||
oYi+1hqp1fIekaxsyQIDAQAB
|
||||
-----END PUBLIC KEY-----";
|
||||
|
||||
const PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
|
||||
NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
|
||||
UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
|
||||
AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
|
||||
QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
|
||||
kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
|
||||
f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
|
||||
412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
|
||||
mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
|
||||
kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
|
||||
gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
|
||||
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
|
||||
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
|
||||
private $httpSignatureService;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->httpSignatureService = new HttpSignatureService();
|
||||
}
|
||||
|
||||
private static function getRequest()
|
||||
{
|
||||
$request = Request::create(
|
||||
'https://example.com/foo',
|
||||
Request::METHOD_POST,
|
||||
array( 'param' => 'value', 'pet' => 'dog' ),
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'{"hello": "world"}'
|
||||
);
|
||||
$request->headers->set( 'host', 'example.com' );
|
||||
$request->headers->set( 'content-type', 'application/json' );
|
||||
$request->headers->set(
|
||||
'digest', 'SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE='
|
||||
);
|
||||
$request->headers->set( 'content-length', 18 );
|
||||
$request->headers->set( 'date', 'Sun, 05 Jan 2014 21:31:40 GMT' );
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function testItVerifies()
|
||||
{
|
||||
$request = self::getRequest();
|
||||
$authHeader = 'Signature keyId="Test",algorithm="rsa-sha256",signature="SjWJWbWN7i0wzBvtPl8rbASWz5xQW6mcJmn+ibttBqtifLN7Sazz6m79cNfwwb8DMJ5cou1s7uEGKKCs+FLEEaDV5lp7q25WqS+lavg7T8hc0GppauB6hbgEKTwblDHYGEtbGmtdHgVCk9SuS13F0hZ8FD0k/5OxEPXe5WozsbM="';
|
||||
$request->headers->set( 'authorization', $authHeader );
|
||||
$verified = $this->httpSignatureService->verify( $request, self::PUBLIC_KEY );
|
||||
$this->assertTrue( $verified );
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user