Subversion Repositories oidplus

Rev

Rev 846 | Rev 1042 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /**
  4.  * DSA Public Key
  5.  *
  6.  * @category  Crypt
  7.  * @package   DSA
  8.  * @author    Jim Wigginton <terrafrost@php.net>
  9.  * @copyright 2015 Jim Wigginton
  10.  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  11.  * @link      http://phpseclib.sourceforge.net
  12.  */
  13.  
  14. namespace phpseclib3\Crypt\DSA;
  15.  
  16. use phpseclib3\Crypt\Common;
  17. use phpseclib3\Crypt\DSA;
  18. use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature;
  19.  
  20. /**
  21.  * DSA Public Key
  22.  *
  23.  * @package DSA
  24.  * @author  Jim Wigginton <terrafrost@php.net>
  25.  * @access  public
  26.  */
  27. class PublicKey extends DSA implements Common\PublicKey
  28. {
  29.     use Common\Traits\Fingerprint;
  30.  
  31.     /**
  32.      * Verify a signature
  33.      *
  34.      * @see self::verify()
  35.      * @access public
  36.      * @param string $message
  37.      * @param string $signature
  38.      * @return mixed
  39.      */
  40.     public function verify($message, $signature)
  41.     {
  42.         $format = $this->sigFormat;
  43.  
  44.         $params = $format::load($signature);
  45.         if ($params === false || count($params) != 2) {
  46.             return false;
  47.         }
  48.         extract($params);
  49.  
  50.         if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
  51.             $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
  52.  
  53.             $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash());
  54.  
  55.             if ($result != -1) {
  56.                 return (bool) $result;
  57.             }
  58.         }
  59.  
  60.         $q_1 = $this->q->subtract(self::$one);
  61.         if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) {
  62.             return false;
  63.         }
  64.  
  65.         $w = $s->modInverse($this->q);
  66.         $h = $this->hash->hash($message);
  67.         $h = $this->bits2int($h);
  68.         list(, $u1) = $h->multiply($w)->divide($this->q);
  69.         list(, $u2) = $r->multiply($w)->divide($this->q);
  70.         $v1 = $this->g->powMod($u1, $this->p);
  71.         $v2 = $this->y->powMod($u2, $this->p);
  72.         list(, $v) = $v1->multiply($v2)->divide($this->p);
  73.         list(, $v) = $v->divide($this->q);
  74.  
  75.         return $v->equals($r);
  76.     }
  77.  
  78.     /**
  79.      * Returns the public key
  80.      *
  81.      * @param string $type
  82.      * @param array $options optional
  83.      * @return string
  84.      */
  85.     public function toString($type, array $options = [])
  86.     {
  87.         $type = self::validatePlugin('Keys', $type, 'savePublicKey');
  88.  
  89.         return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options);
  90.     }
  91. }
  92.