1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- <?php
- namespace Braintree;
- class WebhookNotificationGateway
- {
- public function __construct($gateway)
- {
- $this->config = $gateway->config;
- $this->config->assertHasAccessTokenOrKeys();
- }
- public function parse($signature, $payload)
- {
- if (is_null($signature)) {
- throw new Exception\InvalidSignature("signature cannot be null");
- }
- if (is_null($payload)) {
- throw new Exception\InvalidSignature("payload cannot be null");
- }
- if (preg_match("/[^A-Za-z0-9+=\/\n]/", $payload) === 1) {
- throw new Exception\InvalidSignature("payload contains illegal characters");
- }
- self::_validateSignature($signature, $payload);
- $xml = base64_decode($payload);
- $attributes = Xml::buildArrayFromXml($xml);
- return WebhookNotification::factory($attributes['notification']);
- }
- public function verify($challenge)
- {
- if (!preg_match('/^[a-f0-9]{20,32}$/', $challenge)) {
- throw new Exception\InvalidChallenge("challenge contains non-hex characters");
- }
- $publicKey = $this->config->getPublicKey();
- $digest = Digest::hexDigestSha1($this->config->getPrivateKey(), $challenge);
- return "{$publicKey}|{$digest}";
- }
- private function _payloadMatches($signature, $payload)
- {
- $payloadSignature = Digest::hexDigestSha1($this->config->getPrivateKey(), $payload);
- return Digest::secureCompare($signature, $payloadSignature);
- }
- private function _validateSignature($signatureString, $payload)
- {
- $signaturePairs = preg_split("/&/", $signatureString);
- $signature = self::_matchingSignature($signaturePairs);
- if (!$signature) {
- throw new Exception\InvalidSignature("no matching public key");
- }
- if (!(self::_payloadMatches($signature, $payload) || self::_payloadMatches($signature, $payload . "\n"))) {
- throw new Exception\InvalidSignature("signature does not match payload - one has been modified");
- }
- }
- private function _matchingSignature($signaturePairs)
- {
- foreach ($signaturePairs as $pair)
- {
- $components = preg_split("/\|/", $pair);
- if ($components[0] == $this->config->getPublicKey()) {
- return $components[1];
- }
- }
- return null;
- }
- }
- class_alias('Braintree\WebhookNotificationGateway', 'Braintree_WebhookNotificationGateway');
|