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.  * PKCS#8 Formatted DH Key Handler
  5.  *
  6.  * PHP version 5
  7.  *
  8.  * Processes keys with the following headers:
  9.  *
  10.  * -----BEGIN ENCRYPTED PRIVATE KEY-----
  11.  * -----BEGIN PRIVATE KEY-----
  12.  * -----BEGIN PUBLIC KEY-----
  13.  *
  14.  * @category  Crypt
  15.  * @package   DH
  16.  * @author    Jim Wigginton <terrafrost@php.net>
  17.  * @copyright 2015 Jim Wigginton
  18.  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  19.  * @link      http://phpseclib.sourceforge.net
  20.  */
  21.  
  22. namespace phpseclib3\Crypt\DH\Formats\Keys;
  23.  
  24. use phpseclib3\Common\Functions\Strings;
  25. use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
  26. use phpseclib3\File\ASN1;
  27. use phpseclib3\File\ASN1\Maps;
  28. use phpseclib3\Math\BigInteger;
  29.  
  30. /**
  31.  * PKCS#8 Formatted DH Key Handler
  32.  *
  33.  * @package DH
  34.  * @author  Jim Wigginton <terrafrost@php.net>
  35.  * @access  public
  36.  */
  37. abstract class PKCS8 extends Progenitor
  38. {
  39.     /**
  40.      * OID Name
  41.      *
  42.      * @var string
  43.      * @access private
  44.      */
  45.     const OID_NAME = 'dhKeyAgreement';
  46.  
  47.     /**
  48.      * OID Value
  49.      *
  50.      * @var string
  51.      * @access private
  52.      */
  53.     const OID_VALUE = '1.2.840.113549.1.3.1';
  54.  
  55.     /**
  56.      * Child OIDs loaded
  57.      *
  58.      * @var bool
  59.      * @access private
  60.      */
  61.     protected static $childOIDsLoaded = false;
  62.  
  63.     /**
  64.      * Break a public or private key down into its constituent components
  65.      *
  66.      * @access public
  67.      * @param string $key
  68.      * @param string $password optional
  69.      * @return array
  70.      */
  71.     public static function load($key, $password = '')
  72.     {
  73.         if (!Strings::is_stringable($key)) {
  74.             throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
  75.         }
  76.  
  77.         $isPublic = strpos($key, 'PUBLIC') !== false;
  78.  
  79.         $key = parent::load($key, $password);
  80.  
  81.         $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey';
  82.  
  83.         switch (true) {
  84.             case !$isPublic && $type == 'publicKey':
  85.                 throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
  86.             case $isPublic && $type == 'privateKey':
  87.                 throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
  88.         }
  89.  
  90.         $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
  91.         if (empty($decoded)) {
  92.             throw new \RuntimeException('Unable to decode BER of parameters');
  93.         }
  94.         $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP);
  95.         if (!is_array($components)) {
  96.             throw new \RuntimeException('Unable to perform ASN1 mapping on parameters');
  97.         }
  98.  
  99.         $decoded = ASN1::decodeBER($key[$type]);
  100.         switch (true) {
  101.             case empty($decoded):
  102.             case !is_array($decoded):
  103.             case !isset($decoded[0]['content']):
  104.             case !$decoded[0]['content'] instanceof BigInteger:
  105.                 throw new \RuntimeException('Unable to decode BER of parameters');
  106.         }
  107.         $components[$type] = $decoded[0]['content'];
  108.  
  109.         return $components;
  110.     }
  111.  
  112.     /**
  113.      * Convert a private key to the appropriate format.
  114.      *
  115.      * @access public
  116.      * @param \phpseclib3\Math\BigInteger $prime
  117.      * @param \phpseclib3\Math\BigInteger $base
  118.      * @param \phpseclib3\Math\BigInteger $privateKey
  119.      * @param \phpseclib3\Math\BigInteger $publicKey
  120.      * @param string $password optional
  121.      * @param array $options optional
  122.      * @return string
  123.      */
  124.     public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = [])
  125.     {
  126.         $params = [
  127.             'prime' => $prime,
  128.             'base' => $base
  129.         ];
  130.         $params = ASN1::encodeDER($params, Maps\DHParameter::MAP);
  131.         $params = new ASN1\Element($params);
  132.         $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]);
  133.         return self::wrapPrivateKey($key, [], $params, $password, null, '', $options);
  134.     }
  135.  
  136.     /**
  137.      * Convert a public key to the appropriate format
  138.      *
  139.      * @access public
  140.      * @param \phpseclib3\Math\BigInteger $prime
  141.      * @param \phpseclib3\Math\BigInteger $base
  142.      * @param \phpseclib3\Math\BigInteger $publicKey
  143.      * @param array $options optional
  144.      * @return string
  145.      */
  146.     public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = [])
  147.     {
  148.         $params = [
  149.             'prime' => $prime,
  150.             'base' => $base
  151.         ];
  152.         $params = ASN1::encodeDER($params, Maps\DHParameter::MAP);
  153.         $params = new ASN1\Element($params);
  154.         $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]);
  155.         return self::wrapPublicKey($key, $params);
  156.     }
  157. }
  158.