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.6 KiB
						
					
					
				
			
		
		
	
	
							168 lines
						
					
					
						
							4.6 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 Private key certificate content. | 
						|
 * @property string $publicCertificate 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); | 
						|
	} | 
						|
} |