static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
static $one;
if (!isset($one)) {
$one = new BigInteger(1);
}
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY')) {
$data = preg_split('#[\\r\\n]+#', $key);
$data = array_splice($data, 2, -1);
$data = implode('', $data);
$components = OpenSSH::load($data);
if ($components === false) {
return false;
}
if (!preg_match('#Comment: "(.+)"#', $key, $matches)) {
return false;
}
$components['comment'] = str_replace(array('\\\\', '\\"'), array('\\', '"'), $matches[1]);
return $components;
}
$components = array('isPublicKey' => false);
$key = preg_split('#\\r\\n|\\r|\\n#', $key);
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
if ($type != 'ssh-rsa') {
return false;
}
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
$components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
$publicLength = trim(preg_replace('#Public-Lines: (\\d+)#', '$1', $key[3]));
$public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
$public = substr($public, 11);
extract(unpack('Nlength', Strings::shift($public, 4)));
$components['publicExponent'] = new BigInteger(Strings::shift($public, $length), -256);
extract(unpack('Nlength', Strings::shift($public, 4)));
$components['modulus'] = new BigInteger(Strings::shift($public, $length), -256);
$privateLength = trim(preg_replace('#Private-Lines: (\\d+)#', '$1', $key[$publicLength + 4]));
$private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
switch ($encryption) {
case 'aes256-cbc':
$symkey = static::generateSymmetricKey($password, 32);
$crypto = new AES(AES::MODE_CBC);
}
if ($encryption != 'none') {
$crypto->setKey($symkey);
$crypto->setIV(str_repeat("", $crypto->getBlockLength() >> 3));
$crypto->disablePadding();
$private = $crypto->decrypt($private);
}
extract(unpack('Nlength', Strings::shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['privateExponent'] = new BigInteger(Strings::shift($private, $length), -256);
extract(unpack('Nlength', Strings::shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['primes'] = array(1 => new BigInteger(Strings::shift($private, $length), -256));
extract(unpack('Nlength', Strings::shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['primes'][] = new BigInteger(Strings::shift($private, $length), -256);
$temp = $components['primes'][1]->subtract($one);
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
$temp = $components['primes'][2]->subtract($one);
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
extract(unpack('Nlength', Strings::shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['coefficients'] = array(2 => new BigInteger(Strings::shift($private, $length), -256));
return $components;
}