RsaSha1.php 5.21 KB
Newer Older
1 2 3 4 5 6 7
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

8
namespace yii\authclient\signature;
9 10 11 12 13 14 15

use yii\base\InvalidConfigException;
use yii\base\NotSupportedException;

/**
 * RsaSha1 represents 'RSA-SHA1' signature method.
 *
16
 * > **Note:** This class requires PHP "OpenSSL" extension(<http://php.net/manual/en/book.openssl.php>).
17
 *
Qiang Xue committed
18 19
 * @property string $privateCertificate Private key certificate content.
 * @property string $publicCertificate Public key certificate content.
20 21 22 23 24 25
 *
 * @author Paul Klimov <klimov.paul@gmail.com>
 * @since 2.0
 */
class RsaSha1 extends BaseMethod
{
26 27
    /**
     * @var string OpenSSL private key certificate content.
28
     * This value can be fetched from file specified by [[privateCertificateFile]].
29 30 31 32
     */
    protected $_privateCertificate;
    /**
     * @var string OpenSSL public key certificate content.
33
     * This value can be fetched from file specified by [[publicCertificateFile]].
34 35
     */
    protected $_publicCertificate;
36 37


38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
    /**
     * @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';
    }

    /**
106 107
     * Creates initial value for [[publicCertificate]].
     * This method will attempt to fetch the certificate value from [[publicCertificateFile]] file.
108
     * @throws InvalidConfigException on failure.
109
     * @return string public certificate content.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
     */
    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 '';
        }
    }

    /**
125 126
     * Creates initial value for [[privateCertificate]].
     * This method will attempt to fetch the certificate value from [[privateCertificateFile]] file.
127
     * @throws InvalidConfigException on failure.
128
     * @return string private certificate content.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
     */
    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);
    }
AlexGx committed
176
}