* @copyright PayPal_Ahmad (Nov. 04, 2006) * @copyright Unknown Modifier * @copyright Thomas Foerster * @package PayPal */ class PayPalEWP { private $certificate; // Certificate resource private $certificateFile; // Path to the certificate file private $privateKey; // Private key resource (matching certificate) private $privateKeyFile; // Path to the private key file private $paypalCertificate; // PayPal public certificate resource private $paypalCertificateFile; // Path to PayPal public certificate file private $certificateID; // ID assigned by PayPal to the $certificate. private $tempFileDirectory; public $error; /** * Constructor * * @param string $certID The certificate ID assigned when the certificate was uploaded to PayPal * @param string $pubCertFile The path to the client (public) certificate * @param string $privCertFile The path to the private key corresponding to the certificate * @param string $paypalCert The path to the PayPal certificate */ public function __construct($certID, $pubCertFile, $privCertFile, $paypalCert) { $this->error = 0; if ($certID != '') { $this->setCertificateID($certID); } if ($pubCertFile != '' && $privCertFile != '') { if (!$this->setCertificate($pubCertFile, $privCertFile)) { $this->error = 1; } } if ($paypalCert != '') { if (!$this->setPayPalCertificate($paypalCert)) { $this->error = 2; } } $this->tempFileDirectory = $this->getTempDir(); } /** * Destructor * */ public function __destruct() { } /** * Returns a usable tempdir * * If the "sys_get_temp_dir" doesn't exist (php >= 5.2.1), try to find the most suitable tempdir to use * Based on code from minghong at www.php.net/manual/en/function.sys-get-temp-dir.php * * @return string Tempdir * @see http://www.php.net/manual/en/function.sys-get-temp-dir.php * @author minghong * @author Thomas Foerster */ private function getTempDir() { if ( !function_exists('sys_get_temp_dir') ) { // Try to get from environment variable if ( !empty($_ENV['TMP']) ) { return realpath( $_ENV['TMP'] ); } else if ( !empty($_ENV['TMPDIR']) ) { return realpath( $_ENV['TMPDIR'] ); } else if ( !empty($_ENV['TEMP']) ) { return realpath( $_ENV['TEMP'] ); } // Detect by creating a temporary file else { // Try to use system's temporary directory // as random name shouldn't exist $temp_file = tempnam( md5(uniqid(rand(), true)), '' ); if ( $temp_file ) { $temp_dir = realpath( dirname($temp_file) ); unlink( $temp_file ); return $temp_dir; } else { return false; } } } else { return sys_get_temp_dir(); } } /** * Sets the ID assigned by PayPal to the client certificate * * @param string $id The certificate ID assigned when the certificate was uploaded to PayPal */ public function setCertificateID($id) { $this->certificateID = $id; } /** * set the client certificate and private key pair. * * @param string $certificateFilename The path to the client (public) certificate * @param string $privateKeyFilename The path to the private key corresponding to the certificate * @return bool TRUE if the private key matches the certificate, FALSE otherwise */ public function setCertificate($certificateFilename, $privateKeyFilename) { if (is_readable($certificateFilename) && is_readable($privateKeyFilename)) { $handle = fopen($certificateFilename, "r"); if ($handle === false) return false; $size = filesize($certificateFilename); $certificate = fread($handle, $size); @fclose($handle); unset($handle); $handle = fopen($privateKeyFilename, "r"); if ($handle === false) return false; $size = filesize($privateKeyFilename); $privateKey = fread($handle, $size); @fclose($handle); if (($certificate !== false) && ($privateKey !== false) && openssl_x509_check_private_key($certificate, $privateKey)) { $this->certificate = $certificate; $this->certificateFile = $certificateFilename; $this->privateKey = $privateKey; $this->privateKeyFile = $privateKeyFilename; return true; } } else { return false; } } /** * Sets the PayPal certificate * * @param string $fileName The path to the PayPal certificate * @return bool TRUE if the certificate is read successfully, FALSE otherwise. */ public function setPayPalCertificate($fileName) { if (is_readable($fileName)) { $handle = fopen($fileName, "r"); if ($handle === false) return false; $size = filesize($fileName); $certificate = fread($handle, $size); if ($certificate === false) return false; fclose($handle); $this->paypalCertificate = $certificate; $this->paypalCertificateFile = $fileName; return true; } else { return false; } } /** * Sets the directory into which temporary files are written * * @param string $directory Directory in which to write temporary files * @return bool TRUE if directory is usable */ public function setTempFileDirectory($directory) { if (is_dir($directory) && is_writable($directory)) { $this->tempFileDirectory = $directory; return true; } else { return false; } } /** * Using the previously set certificates and tempFileDirectory to encrypt the button information * * @param array $parameters Array with parameter names as keys * @return mixed The encrypted string for the _s_xclick button form field OR false */ public function encryptButton($parameters) { // Check encryption data is available. if (($this->certificateID == '') || !isset($this->certificate) || !isset($this->paypalCertificate)) return false; $clearText = ''; $encryptedText = ''; // initialize data. $data = "cert_id=" . $this->certificateID . "\n"; foreach($parameters as $k => $v) { $d[] = "$k=$v"; } $data .= join("\n", $d); $dataFile = tempnam($this->tempFileDirectory, 'data'); $out = fopen("{$dataFile}_data.txt", 'wb'); fwrite($out, $data); fclose($out); $out=fopen("{$dataFile}_signed.txt", "w+"); if (!openssl_pkcs7_sign("{$dataFile}_data.txt", "{$dataFile}_signed.txt", $this->certificate, $this->privateKey, array(), PKCS7_BINARY)) return false; fclose($out); $signedData = explode("\n\n", file_get_contents("{$dataFile}_signed.txt")); $out = fopen("{$dataFile}_signed.txt", 'wb'); fwrite($out, base64_decode($signedData[1])); fclose($out); if (!openssl_pkcs7_encrypt("{$dataFile}_signed.txt", "{$dataFile}_encrypted.txt", $this->paypalCertificate, array(), PKCS7_BINARY)) return false; $encryptedData = explode("\n\n", file_get_contents("{$dataFile}_encrypted.txt")); $encryptedText = $encryptedData[1]; @unlink($dataFile); @unlink("{$dataFile}_data.txt"); @unlink("{$dataFile}_signed.txt"); @unlink("{$dataFile}_encrypted.txt"); return "-----BEGIN PKCS7-----\n".$encryptedText."\n-----END PKCS7-----"; } }