PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.22.3
JetBackup – Backup, Restore & Migrate v3.1.22.3
3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / RSA / Formats / Keys / MSBLOB.php
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / RSA / Formats / Keys Last commit date
.htaccess 1 year ago JWK.php 1 year ago MSBLOB.php 1 year ago OpenSSH.php 1 year ago PKCS1.php 1 year ago PKCS8.php 1 year ago PSS.php 1 year ago PuTTY.php 1 year ago Raw.php 1 year ago XML.php 1 year ago index.html 1 year ago web.config 1 year ago
MSBLOB.php
211 lines
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 * @author Jim Wigginton <terrafrost@php.net>
13 * @copyright 2015 Jim Wigginton
14 * @license http://www.opensource.org/licenses/mit-license.html MIT License
15 * @link http://phpseclib.sourceforge.net
16 */
17
18 declare(strict_types=1);
19
20 namespace phpseclib3\Crypt\RSA\Formats\Keys;
21
22 use phpseclib3\Common\Functions\Strings;
23 use phpseclib3\Exception\InvalidArgumentException;
24 use phpseclib3\Exception\UnexpectedValueException;
25 use phpseclib3\Exception\UnsupportedFormatException;
26 use phpseclib3\Math\BigInteger;
27
28 /**
29 * Microsoft BLOB Formatted RSA Key Handler
30 *
31 * @author Jim Wigginton <terrafrost@php.net>
32 */
33 abstract class MSBLOB
34 {
35 /**
36 * Public/Private Key Pair
37 */
38 public const PRIVATEKEYBLOB = 0x7;
39 /**
40 * Public Key
41 */
42 public const PUBLICKEYBLOB = 0x6;
43 /**
44 * Public Key
45 */
46 public const PUBLICKEYBLOBEX = 0xA;
47 /**
48 * RSA public key exchange algorithm
49 */
50 public const CALG_RSA_KEYX = 0x0000A400;
51 /**
52 * RSA public key exchange algorithm
53 */
54 public const CALG_RSA_SIGN = 0x00002400;
55 /**
56 * Public Key
57 */
58 public const RSA1 = 0x31415352;
59 /**
60 * Private Key
61 */
62 public const RSA2 = 0x32415352;
63
64 /**
65 * Break a public or private key down into its constituent components
66 *
67 * @param string|array $key
68 */
69 public static function load($key, ?string $password = null): array
70 {
71 if (!Strings::is_stringable($key)) {
72 throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
73 }
74
75 $key = Strings::base64_decode($key);
76
77 if (!is_string($key)) {
78 throw new UnexpectedValueException('Base64 decoding produced an error');
79 }
80 if (strlen($key) < 20) {
81 throw new UnexpectedValueException('Key appears to be malformed');
82 }
83
84 // PUBLICKEYSTRUC publickeystruc
85 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
86 extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8)));
87 /**
88 * @var string $type
89 * @var string $version
90 * @var integer $reserved
91 * @var integer $algo
92 */
93 switch (ord($type)) {
94 case self::PUBLICKEYBLOB:
95 case self::PUBLICKEYBLOBEX:
96 $publickey = true;
97 break;
98 case self::PRIVATEKEYBLOB:
99 $publickey = false;
100 break;
101 default:
102 throw new UnexpectedValueException('Key appears to be malformed');
103 }
104
105 $components = ['isPublicKey' => $publickey];
106
107 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
108 switch ($algo) {
109 case self::CALG_RSA_KEYX:
110 case self::CALG_RSA_SIGN:
111 break;
112 default:
113 throw new UnexpectedValueException('Key appears to be malformed');
114 }
115
116 // RSAPUBKEY rsapubkey
117 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
118 // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
119 extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12)));
120 /**
121 * @var integer $magic
122 * @var integer $bitlen
123 * @var string $pubexp
124 */
125 switch ($magic) {
126 case self::RSA2:
127 $components['isPublicKey'] = false;
128 // fall-through
129 case self::RSA1:
130 break;
131 default:
132 throw new UnexpectedValueException('Key appears to be malformed');
133 }
134
135 $baseLength = $bitlen / 16;
136 if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
137 throw new UnexpectedValueException('Key appears to be malformed');
138 }
139
140 $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
141 // BYTE modulus[rsapubkey.bitlen/8]
142 $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
143
144 if ($publickey) {
145 return $components;
146 }
147
148 $components['isPublicKey'] = false;
149
150 // BYTE prime1[rsapubkey.bitlen/16]
151 $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
152 // BYTE prime2[rsapubkey.bitlen/16]
153 $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
154 // BYTE exponent1[rsapubkey.bitlen/16]
155 $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
156 // BYTE exponent2[rsapubkey.bitlen/16]
157 $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
158 // BYTE coefficient[rsapubkey.bitlen/16]
159 $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
160 if (isset($components['privateExponent'])) {
161 $components['publicExponent'] = $components['privateExponent'];
162 }
163 // BYTE privateExponent[rsapubkey.bitlen/8]
164 $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
165
166 return $components;
167 }
168
169 /**
170 * Convert a private key to the appropriate format.
171 */
172 public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null): string
173 {
174 if (count($primes) != 2) {
175 throw new InvalidArgumentException('MSBLOB does not support multi-prime RSA keys');
176 }
177
178 if (!empty($password) && is_string($password)) {
179 throw new UnsupportedFormatException('MSBLOB private keys do not support encryption');
180 }
181
182 $n = strrev($n->toBytes());
183 $e = str_pad(strrev($e->toBytes()), 4, "\0");
184 $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
185 $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
186 $key .= $n;
187 $key .= strrev($primes[1]->toBytes());
188 $key .= strrev($primes[2]->toBytes());
189 $key .= strrev($exponents[1]->toBytes());
190 $key .= strrev($exponents[2]->toBytes());
191 $key .= strrev($coefficients[2]->toBytes());
192 $key .= strrev($d->toBytes());
193
194 return Strings::base64_encode($key);
195 }
196
197 /**
198 * Convert a public key to the appropriate format
199 */
200 public static function savePublicKey(BigInteger $n, BigInteger $e): string
201 {
202 $n = strrev($n->toBytes());
203 $e = str_pad(strrev($e->toBytes()), 4, "\0");
204 $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
205 $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
206 $key .= $n;
207
208 return Strings::base64_encode($key);
209 }
210 }
211