[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * XML Formatted RSA Key Handler 5 * 6 * More info: 7 * 8 * http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue 9 * http://www.w3.org/TR/xkms2/#XKMS_2_0_Paragraph_269 10 * http://en.wikipedia.org/wiki/XML_Signature 11 * http://en.wikipedia.org/wiki/XKMS 12 * 13 * PHP version 5 14 * 15 * @author Jim Wigginton <terrafrost@php.net> 16 * @copyright 2015 Jim Wigginton 17 * @license http://www.opensource.org/licenses/mit-license.html MIT License 18 * @link http://phpseclib.sourceforge.net 19 */ 20 21 namespace phpseclib3\Crypt\RSA\Formats\Keys; 22 23 use phpseclib3\Common\Functions\Strings; 24 use phpseclib3\Exception\BadConfigurationException; 25 use phpseclib3\Exception\UnsupportedFormatException; 26 use phpseclib3\Math\BigInteger; 27 28 /** 29 * XML Formatted RSA Key Handler 30 * 31 * @author Jim Wigginton <terrafrost@php.net> 32 */ 33 abstract class XML 34 { 35 /** 36 * Break a public or private key down into its constituent components 37 * 38 * @param string $key 39 * @param string $password optional 40 * @return array 41 */ 42 public static function load($key, $password = '') 43 { 44 if (!Strings::is_stringable($key)) { 45 throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); 46 } 47 48 if (!class_exists('DOMDocument')) { 49 throw new BadConfigurationException('The dom extension is not setup correctly on this system'); 50 } 51 52 $components = [ 53 'isPublicKey' => false, 54 'primes' => [], 55 'exponents' => [], 56 'coefficients' => [] 57 ]; 58 59 $use_errors = libxml_use_internal_errors(true); 60 61 $dom = new \DOMDocument(); 62 if (substr($key, 0, 5) != '<?xml') { 63 $key = '<xml>' . $key . '</xml>'; 64 } 65 if (!$dom->loadXML($key)) { 66 libxml_use_internal_errors($use_errors); 67 throw new \UnexpectedValueException('Key does not appear to contain XML'); 68 } 69 $xpath = new \DOMXPath($dom); 70 $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; 71 foreach ($keys as $key) { 72 // $dom->getElementsByTagName($key) is case-sensitive 73 $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); 74 if (!$temp->length) { 75 continue; 76 } 77 $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); 78 switch ($key) { 79 case 'modulus': 80 $components['modulus'] = $value; 81 break; 82 case 'exponent': 83 $components['publicExponent'] = $value; 84 break; 85 case 'p': 86 $components['primes'][1] = $value; 87 break; 88 case 'q': 89 $components['primes'][2] = $value; 90 break; 91 case 'dp': 92 $components['exponents'][1] = $value; 93 break; 94 case 'dq': 95 $components['exponents'][2] = $value; 96 break; 97 case 'inverseq': 98 $components['coefficients'][2] = $value; 99 break; 100 case 'd': 101 $components['privateExponent'] = $value; 102 } 103 } 104 105 libxml_use_internal_errors($use_errors); 106 107 foreach ($components as $key => $value) { 108 if (is_array($value) && !count($value)) { 109 unset($components[$key]); 110 } 111 } 112 113 if (isset($components['modulus']) && isset($components['publicExponent'])) { 114 if (count($components) == 3) { 115 $components['isPublicKey'] = true; 116 } 117 return $components; 118 } 119 120 throw new \UnexpectedValueException('Modulus / exponent not present'); 121 } 122 123 /** 124 * Convert a private key to the appropriate format. 125 * 126 * @param \phpseclib3\Math\BigInteger $n 127 * @param \phpseclib3\Math\BigInteger $e 128 * @param \phpseclib3\Math\BigInteger $d 129 * @param array $primes 130 * @param array $exponents 131 * @param array $coefficients 132 * @param string $password optional 133 * @return string 134 */ 135 public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') 136 { 137 if (count($primes) != 2) { 138 throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); 139 } 140 141 if (!empty($password) && is_string($password)) { 142 throw new UnsupportedFormatException('XML private keys do not support encryption'); 143 } 144 145 return "<RSAKeyPair>\r\n" . 146 ' <Modulus>' . Strings::base64_encode($n->toBytes()) . "</Modulus>\r\n" . 147 ' <Exponent>' . Strings::base64_encode($e->toBytes()) . "</Exponent>\r\n" . 148 ' <P>' . Strings::base64_encode($primes[1]->toBytes()) . "</P>\r\n" . 149 ' <Q>' . Strings::base64_encode($primes[2]->toBytes()) . "</Q>\r\n" . 150 ' <DP>' . Strings::base64_encode($exponents[1]->toBytes()) . "</DP>\r\n" . 151 ' <DQ>' . Strings::base64_encode($exponents[2]->toBytes()) . "</DQ>\r\n" . 152 ' <InverseQ>' . Strings::base64_encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" . 153 ' <D>' . Strings::base64_encode($d->toBytes()) . "</D>\r\n" . 154 '</RSAKeyPair>'; 155 } 156 157 /** 158 * Convert a public key to the appropriate format 159 * 160 * @param \phpseclib3\Math\BigInteger $n 161 * @param \phpseclib3\Math\BigInteger $e 162 * @return string 163 */ 164 public static function savePublicKey(BigInteger $n, BigInteger $e) 165 { 166 return "<RSAKeyValue>\r\n" . 167 ' <Modulus>' . Strings::base64_encode($n->toBytes()) . "</Modulus>\r\n" . 168 ' <Exponent>' . Strings::base64_encode($e->toBytes()) . "</Exponent>\r\n" . 169 '</RSAKeyValue>'; 170 } 171 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body