1<?php 2 3/** 4 * Raw RSA Key Handler 5 * 6 * PHP version 5 7 * 8 * An array containing two \phpseclib3\Math\BigInteger objects. 9 * 10 * The exponent can be indexed with any of the following: 11 * 12 * 0, e, exponent, publicExponent 13 * 14 * The modulus can be indexed with any of the following: 15 * 16 * 1, n, modulo, modulus 17 * 18 * @category Crypt 19 * @package RSA 20 * @author Jim Wigginton <terrafrost@php.net> 21 * @copyright 2015 Jim Wigginton 22 * @license http://www.opensource.org/licenses/mit-license.html MIT License 23 * @link http://phpseclib.sourceforge.net 24 */ 25 26namespace phpseclib3\Crypt\RSA\Formats\Keys; 27 28use phpseclib3\Math\BigInteger; 29 30/** 31 * Raw RSA Key Handler 32 * 33 * @package RSA 34 * @author Jim Wigginton <terrafrost@php.net> 35 * @access public 36 */ 37abstract class Raw 38{ 39 /** 40 * Break a public or private key down into its constituent components 41 * 42 * @access public 43 * @param string $key 44 * @param string $password optional 45 * @return array 46 */ 47 public static function load($key, $password = '') 48 { 49 if (!is_array($key)) { 50 throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); 51 } 52 53 $key = array_change_key_case($key, CASE_LOWER); 54 55 $components = ['isPublicKey' => false]; 56 57 foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { 58 if (isset($key[$index])) { 59 $components['publicExponent'] = $key[$index]; 60 break; 61 } 62 } 63 64 foreach (['n', 'modulo', 'modulus', 1] as $index) { 65 if (isset($key[$index])) { 66 $components['modulus'] = $key[$index]; 67 break; 68 } 69 } 70 71 if (!isset($components['publicExponent']) || !isset($components['modulus'])) { 72 throw new \UnexpectedValueException('Modulus / exponent not present'); 73 } 74 75 if (isset($key['primes'])) { 76 $components['primes'] = $key['primes']; 77 } elseif (isset($key['p']) && isset($key['q'])) { 78 $indices = [ 79 ['p', 'q'], 80 ['prime1', 'prime2'] 81 ]; 82 foreach ($indices as $index) { 83 list($i0, $i1) = $index; 84 if (isset($key[$i0]) && isset($key[$i1])) { 85 $components['primes'] = [1 => $key[$i0], $key[$i1]]; 86 } 87 } 88 } 89 90 if (isset($key['exponents'])) { 91 $components['exponents'] = $key['exponents']; 92 } else { 93 $indices = [ 94 ['dp', 'dq'], 95 ['exponent1', 'exponent2'] 96 ]; 97 foreach ($indices as $index) { 98 list($i0, $i1) = $index; 99 if (isset($key[$i0]) && isset($key[$i1])) { 100 $components['exponents'] = [1 => $key[$i0], $key[$i1]]; 101 } 102 } 103 } 104 105 if (isset($key['coefficients'])) { 106 $components['coefficients'] = $key['coefficients']; 107 } else { 108 foreach (['inverseq', 'q\'', 'coefficient'] as $index) { 109 if (isset($key[$index])) { 110 $components['coefficients'] = [2 => $key[$index]]; 111 } 112 } 113 } 114 115 if (!isset($components['primes'])) { 116 $components['isPublicKey'] = true; 117 return $components; 118 } 119 120 if (!isset($components['exponents'])) { 121 $one = new BigInteger(1); 122 $temp = $components['primes'][1]->subtract($one); 123 $exponents = [1 => $components['publicExponent']->modInverse($temp)]; 124 $temp = $components['primes'][2]->subtract($one); 125 $exponents[] = $components['publicExponent']->modInverse($temp); 126 $components['exponents'] = $exponents; 127 } 128 129 if (!isset($components['coefficients'])) { 130 $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; 131 } 132 133 foreach (['privateexponent', 'd'] as $index) { 134 if (isset($key[$index])) { 135 $components['privateExponent'] = $key[$index]; 136 break; 137 } 138 } 139 140 return $components; 141 } 142 143 /** 144 * Convert a private key to the appropriate format. 145 * 146 * @access public 147 * @param \phpseclib3\Math\BigInteger $n 148 * @param \phpseclib3\Math\BigInteger $e 149 * @param \phpseclib3\Math\BigInteger $d 150 * @param array $primes 151 * @param array $exponents 152 * @param array $coefficients 153 * @param string $password optional 154 * @param array $options optional 155 * @return array 156 */ 157 public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) 158 { 159 if (!empty($password) && is_string($password)) { 160 throw new UnsupportedFormatException('Raw private keys do not support encryption'); 161 } 162 163 return [ 164 'e' => clone $e, 165 'n' => clone $n, 166 'd' => clone $d, 167 'primes' => array_map(function ($var) { 168 return clone $var; 169 }, $primes), 170 'exponents' => array_map(function ($var) { 171 return clone $var; 172 }, $exponents), 173 'coefficients' => array_map(function ($var) { 174 return clone $var; 175 }, $coefficients) 176 ]; 177 } 178 179 /** 180 * Convert a public key to the appropriate format 181 * 182 * @access public 183 * @param \phpseclib3\Math\BigInteger $n 184 * @param \phpseclib3\Math\BigInteger $e 185 * @return array 186 */ 187 public static function savePublicKey(BigInteger $n, BigInteger $e) 188 { 189 return ['e' => clone $e, 'n' => clone $n]; 190 } 191} 192