[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/ -> MSBLOB.php (source)

   1  <?php
   2  
   3  /**
   4   * Miccrosoft BLOB Formatted RSA Key Handler
   5   *
   6   * More info:
   7   *
   8   * https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx
   9   *
  10   * PHP version 5
  11   *
  12   * @category  Crypt
  13   * @package   RSA
  14   * @author    Jim Wigginton <[email protected]>
  15   * @copyright 2015 Jim Wigginton
  16   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  17   * @link      http://phpseclib.sourceforge.net
  18   */
  19  
  20  namespace phpseclib3\Crypt\RSA\Formats\Keys;
  21  
  22  use ParagonIE\ConstantTime\Base64;
  23  use phpseclib3\Common\Functions\Strings;
  24  use phpseclib3\Exception\UnsupportedFormatException;
  25  use phpseclib3\Math\BigInteger;
  26  
  27  /**
  28   * Microsoft BLOB Formatted RSA Key Handler
  29   *
  30   * @package RSA
  31   * @author  Jim Wigginton <[email protected]>
  32   * @access  public
  33   */
  34  abstract class MSBLOB
  35  {
  36      /**
  37       * Public/Private Key Pair
  38       *
  39       * @access private
  40       */
  41      const PRIVATEKEYBLOB = 0x7;
  42      /**
  43       * Public Key
  44       *
  45       * @access private
  46       */
  47      const PUBLICKEYBLOB = 0x6;
  48      /**
  49       * Public Key
  50       *
  51       * @access private
  52       */
  53      const PUBLICKEYBLOBEX = 0xA;
  54      /**
  55       * RSA public key exchange algorithm
  56       *
  57       * @access private
  58       */
  59      const CALG_RSA_KEYX = 0x0000A400;
  60      /**
  61       * RSA public key exchange algorithm
  62       *
  63       * @access private
  64       */
  65      const CALG_RSA_SIGN = 0x00002400;
  66      /**
  67       * Public Key
  68       *
  69       * @access private
  70       */
  71      const RSA1 = 0x31415352;
  72      /**
  73       * Private Key
  74       *
  75       * @access private
  76       */
  77      const RSA2 = 0x32415352;
  78  
  79      /**
  80       * Break a public or private key down into its constituent components
  81       *
  82       * @access public
  83       * @param string $key
  84       * @param string $password optional
  85       * @return array
  86       */
  87      public static function load($key, $password = '')
  88      {
  89          if (!Strings::is_stringable($key)) {
  90              throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
  91          }
  92  
  93          $key = Base64::decode($key);
  94  
  95          if (!is_string($key)) {
  96              throw new \UnexpectedValueException('Base64 decoding produced an error');
  97          }
  98          if (strlen($key) < 20) {
  99              throw new \UnexpectedValueException('Key appears to be malformed');
 100          }
 101  
 102          // PUBLICKEYSTRUC  publickeystruc
 103          // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
 104          extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8)));
 105          /**
 106           * @var string $type
 107           * @var string $version
 108           * @var integer $reserved
 109           * @var integer $algo
 110           */
 111          switch (ord($type)) {
 112              case self::PUBLICKEYBLOB:
 113              case self::PUBLICKEYBLOBEX:
 114                  $publickey = true;
 115                  break;
 116              case self::PRIVATEKEYBLOB:
 117                  $publickey = false;
 118                  break;
 119              default:
 120                  throw new \UnexpectedValueException('Key appears to be malformed');
 121          }
 122  
 123          $components = ['isPublicKey' => $publickey];
 124  
 125          // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
 126          switch ($algo) {
 127              case self::CALG_RSA_KEYX:
 128              case self::CALG_RSA_SIGN:
 129                  break;
 130              default:
 131                  throw new \UnexpectedValueException('Key appears to be malformed');
 132          }
 133  
 134          // RSAPUBKEY rsapubkey
 135          // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
 136          // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
 137          extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12)));
 138          /**
 139           * @var integer $magic
 140           * @var integer $bitlen
 141           * @var string $pubexp
 142           */
 143          switch ($magic) {
 144              case self::RSA2:
 145                  $components['isPublicKey'] = false;
 146                  // fall-through
 147              case self::RSA1:
 148                  break;
 149              default:
 150                  throw new \UnexpectedValueException('Key appears to be malformed');
 151          }
 152  
 153          $baseLength = $bitlen / 16;
 154          if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
 155              throw new \UnexpectedValueException('Key appears to be malformed');
 156          }
 157  
 158          $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
 159          // BYTE modulus[rsapubkey.bitlen/8]
 160          $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
 161  
 162          if ($publickey) {
 163              return $components;
 164          }
 165  
 166          $components['isPublicKey'] = false;
 167  
 168          // BYTE prime1[rsapubkey.bitlen/16]
 169          $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
 170          // BYTE prime2[rsapubkey.bitlen/16]
 171          $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
 172          // BYTE exponent1[rsapubkey.bitlen/16]
 173          $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
 174          // BYTE exponent2[rsapubkey.bitlen/16]
 175          $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
 176          // BYTE coefficient[rsapubkey.bitlen/16]
 177          $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
 178          if (isset($components['privateExponent'])) {
 179              $components['publicExponent'] = $components['privateExponent'];
 180          }
 181          // BYTE privateExponent[rsapubkey.bitlen/8]
 182          $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
 183  
 184          return $components;
 185      }
 186  
 187      /**
 188       * Convert a private key to the appropriate format.
 189       *
 190       * @access public
 191       * @param \phpseclib3\Math\BigInteger $n
 192       * @param \phpseclib3\Math\BigInteger $e
 193       * @param \phpseclib3\Math\BigInteger $d
 194       * @param array $primes
 195       * @param array $exponents
 196       * @param array $coefficients
 197       * @param string $password optional
 198       * @return string
 199       */
 200      public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '')
 201      {
 202          if (count($primes) != 2) {
 203              throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys');
 204          }
 205  
 206          if (!empty($password) && is_string($password)) {
 207              throw new UnsupportedFormatException('MSBLOB private keys do not support encryption');
 208          }
 209  
 210          $n = strrev($n->toBytes());
 211          $e = str_pad(strrev($e->toBytes()), 4, "\0");
 212          $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
 213          $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
 214          $key .= $n;
 215          $key .= strrev($primes[1]->toBytes());
 216          $key .= strrev($primes[2]->toBytes());
 217          $key .= strrev($exponents[1]->toBytes());
 218          $key .= strrev($exponents[2]->toBytes());
 219          $key .= strrev($coefficients[2]->toBytes());
 220          $key .= strrev($d->toBytes());
 221  
 222          return Base64::encode($key);
 223      }
 224  
 225      /**
 226       * Convert a public key to the appropriate format
 227       *
 228       * @access public
 229       * @param \phpseclib3\Math\BigInteger $n
 230       * @param \phpseclib3\Math\BigInteger $e
 231       * @return string
 232       */
 233      public static function savePublicKey(BigInteger $n, BigInteger $e)
 234      {
 235          $n = strrev($n->toBytes());
 236          $e = str_pad(strrev($e->toBytes()), 4, "\0");
 237          $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
 238          $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
 239          $key .= $n;
 240  
 241          return Base64::encode($key);
 242      }
 243  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer