You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.7 KiB
168 lines
4.7 KiB
<?php |
|
/** |
|
* @link http://www.yiiframework.com/ |
|
* @copyright Copyright (c) 2008 Yii Software LLC |
|
* @license http://www.yiiframework.com/license/ |
|
*/ |
|
|
|
namespace yii\authclient\signature; |
|
|
|
use yii\base\InvalidConfigException; |
|
use yii\base\NotSupportedException; |
|
|
|
/** |
|
* RsaSha1 represents 'RSA-SHA1' signature method. |
|
* |
|
* Note: This class require PHP "OpenSSL" extension({@link http://php.net/manual/en/book.openssl.php}). |
|
* |
|
* @property string $privateCertificate OpenSSL private key certificate content. |
|
* @property string $publicCertificate OpenSSL public key certificate content. |
|
* |
|
* @author Paul Klimov <klimov.paul@gmail.com> |
|
* @since 2.0 |
|
*/ |
|
class RsaSha1 extends BaseMethod |
|
{ |
|
/** |
|
* @var string OpenSSL private key certificate content. |
|
* This value can be fetched from file specified by {@link privateCertificateFile}. |
|
*/ |
|
protected $_privateCertificate; |
|
/** |
|
* @var string OpenSSL public key certificate content. |
|
* This value can be fetched from file specified by {@link publicCertificateFile}. |
|
*/ |
|
protected $_publicCertificate; |
|
/** |
|
* @var string path to the file, which holds private key certificate. |
|
*/ |
|
public $privateCertificateFile = ''; |
|
/** |
|
* @var string path to the file, which holds public key certificate. |
|
*/ |
|
public $publicCertificateFile = ''; |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function init() |
|
{ |
|
if (!function_exists('openssl_sign')) { |
|
throw new NotSupportedException('PHP "OpenSSL" extension is required.'); |
|
} |
|
} |
|
|
|
/** |
|
* @param string $publicCertificate public key certificate content. |
|
*/ |
|
public function setPublicCertificate($publicCertificate) |
|
{ |
|
$this->_publicCertificate = $publicCertificate; |
|
} |
|
|
|
/** |
|
* @return string public key certificate content. |
|
*/ |
|
public function getPublicCertificate() |
|
{ |
|
if ($this->_publicCertificate === null) { |
|
$this->_publicCertificate = $this->initPublicCertificate(); |
|
} |
|
return $this->_publicCertificate; |
|
} |
|
|
|
/** |
|
* @param string $privateCertificate private key certificate content. |
|
*/ |
|
public function setPrivateCertificate($privateCertificate) |
|
{ |
|
$this->_privateCertificate = $privateCertificate; |
|
} |
|
|
|
/** |
|
* @return string private key certificate content. |
|
*/ |
|
public function getPrivateCertificate() |
|
{ |
|
if ($this->_privateCertificate === null) { |
|
$this->_privateCertificate = $this->initPrivateCertificate(); |
|
} |
|
return $this->_privateCertificate; |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function getName() |
|
{ |
|
return 'RSA-SHA1'; |
|
} |
|
|
|
/** |
|
* Creates initial value for {@link publicCertificate}. |
|
* This method will attempt to fetch the certificate value from {@link publicCertificateFile} file. |
|
* @throws InvalidConfigException on failure. |
|
* @return string public certificate content. |
|
*/ |
|
protected function initPublicCertificate() |
|
{ |
|
if (!empty($this->publicCertificateFile)) { |
|
if (!file_exists($this->publicCertificateFile)) { |
|
throw new InvalidConfigException("Public certificate file '{$this->publicCertificateFile}' does not exist!"); |
|
} |
|
return file_get_contents($this->publicCertificateFile); |
|
} else { |
|
return ''; |
|
} |
|
} |
|
|
|
/** |
|
* Creates initial value for {@link privateCertificate}. |
|
* This method will attempt to fetch the certificate value from {@link privateCertificateFile} file. |
|
* @throws InvalidConfigException on failure. |
|
* @return string private certificate content. |
|
*/ |
|
protected function initPrivateCertificate() |
|
{ |
|
if (!empty($this->privateCertificateFile)) { |
|
if (!file_exists($this->privateCertificateFile)) { |
|
throw new InvalidConfigException("Private certificate file '{$this->privateCertificateFile}' does not exist!"); |
|
} |
|
return file_get_contents($this->privateCertificateFile); |
|
} else { |
|
return ''; |
|
} |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function generateSignature($baseString, $key) |
|
{ |
|
$privateCertificateContent = $this->getPrivateCertificate(); |
|
// Pull the private key ID from the certificate |
|
$privateKeyId = openssl_pkey_get_private($privateCertificateContent); |
|
// Sign using the key |
|
openssl_sign($baseString, $signature, $privateKeyId); |
|
// Release the key resource |
|
openssl_free_key($privateKeyId); |
|
return base64_encode($signature); |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function verify($signature, $baseString, $key) |
|
{ |
|
$decodedSignature = base64_decode($signature); |
|
// Fetch the public key cert based on the request |
|
$publicCertificate = $this->getPublicCertificate(); |
|
// Pull the public key ID from the certificate |
|
$publicKeyId = openssl_pkey_get_public($publicCertificate); |
|
// Check the computed signature against the one passed in the query |
|
$verificationResult = openssl_verify($baseString, $decodedSignature, $publicKeyId); |
|
// Release the key resource |
|
openssl_free_key($publicKeyId); |
|
return ($verificationResult == 1); |
|
} |
|
} |