File: /home/petsclubcc/shop/modules/amazonpay/src/classes/AmazonPayKeyShareHandler.php
<?php
/**
* 2007-2021 patworx.de
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade AmazonPay to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author patworx multimedia GmbH <service@patworx.de>
* @copyright 2007-2021 patworx multimedia GmbH
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
use phpseclib\Crypt\AES;
class AmazonPayKeyShareHandler
{
private $jsonData;
private $encrypted_data;
private $is_valid = false;
private $data;
private $amazon_public_key;
/**
* AmazonPayKeyShareHandler constructor.
*/
public function __construct()
{
AmazonPayLogger::getInstance()->addLog(Tools::file_get_contents('php://input'), 1);
try {
$this->jsonData = Tools::file_get_contents('php://input');
$this->encrypted_data = Tools::jsonDecode($this->jsonData, true);
if (isset($this->encrypted_data['encryptedKey']) &&
isset($this->encrypted_data['encryptedPayload']) &&
isset($this->encrypted_data['iv']) &&
isset($this->encrypted_data['sigKeyID']) &&
isset($this->encrypted_data['signature'])
) {
if ($this->hasKeyPair()) {
$this->is_valid = true;
}
}
} catch (\Exception $e) {
return;
}
}
/**
* decrypt payload
*/
public function decrypt()
{
$this->setAmazonPublicKey();
$decoded_signature = AmazonPayVendorEncodeDecode::base64_decode($this->encrypted_data['signature']);
$payloadVerify = $this->encrypted_data;
unset($payloadVerify['signature']);
$payloadVerifyJson = Tools::jsonEncode($payloadVerify);
if (openssl_verify($payloadVerifyJson, AmazonPayVendorEncodeDecode::base64_decode($this->encrypted_data['signature']), $this->key2pem($this->amazon_public_key), 'SHA256')) {
$decryptedKey = null;
openssl_private_decrypt(
AmazonPayVendorEncodeDecode::base64_decode($this->encrypted_data['encryptedKey']),
$decryptedKey,
$this->getPrivateKey(),
OPENSSL_PKCS1_OAEP_PADDING
);
$aes = new AES();
$aes->setKey($decryptedKey);
$aes->setIV(AmazonPayVendorEncodeDecode::base64_decode($this->encrypted_data['iv']));
$aes->setKeyLength(256);
$finalPayload = $aes->decrypt(AmazonPayVendorEncodeDecode::base64_decode($this->encrypted_data['encryptedPayload']));
// Remove binary characters
$finalPayload = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $finalPayload);
if ($this->data = Tools::jsonDecode($finalPayload)) {
return true;
}
}
return false;
}
/*
* store into database
*/
public function store()
{
foreach (AmazonPayDefinitions::$keyShareJson as $jsonKey => $value) {
if (isset($this->data[$jsonKey])) {
Configuration::updateValue($value, $this->data[$jsonKey]);
}
}
return $this->data;
}
/**
* @return false|string
*/
public function setAmazonPublicKey()
{
$url = AmazonPayHelper::getPublicKeyURL();
$this->amazon_public_key = Tools::file_get_contents($url . '?sigkey_id=' . $this->encrypted_data['sigKeyID']);
return $this->amazon_public_key;
}
protected function getPrivateKey()
{
return Configuration::get('AMAZONPAY_KEYEXCHANGE_PRIVATE_KEY');
}
/**
* @param $key
* @return string
*/
protected function key2pem($key)
{
return "-----BEGIN PUBLIC KEY-----\n" .
chunk_split($key, 64, "\n") .
"-----END PUBLIC KEY-----\n";
}
/**
* @return bool
*/
public static function createKeyPair()
{
try {
$config = array(
"digest_alg" => "sha512",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $privKey);
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
if ($pubKey != '' && $privKey != '') {
Configuration::updateValue('AMAZONPAY_KEYEXCHANGE_PUBLIC_KEY', $pubKey);
Configuration::updateValue('AMAZONPAY_KEYEXCHANGE_PRIVATE_KEY', $privKey);
return true;
}
} catch (Exception $e) {
return false;
}
return false;
}
/**
* @return bool
*/
protected function hasKeyPair()
{
return Configuration::get('AMAZONPAY_KEYEXCHANGE_PUBLIC_KEY') != '' &&
Configuration::get('AMAZONPAY_KEYEXCHANGE_PRIVATE_KEY') != '';
}
/**
* @return bool
*/
public function isValid()
{
return $this->is_valid;
}
}