mirror of
https://github.com/danog/phpseclib.git
synced 2025-01-22 04:51:19 +01:00
Merge branch '3.0'
This commit is contained in:
commit
2e549e3aa1
@ -87,6 +87,9 @@ abstract class OpenSSH
|
|||||||
case 'none':
|
case 'none':
|
||||||
break;
|
break;
|
||||||
case 'aes256-ctr':
|
case 'aes256-ctr':
|
||||||
|
if ($kdfname != 'bcrypt') {
|
||||||
|
throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)');
|
||||||
|
}
|
||||||
[$salt, $rounds] = Strings::unpackSSH2('sN', $kdfoptions);
|
[$salt, $rounds] = Strings::unpackSSH2('sN', $kdfoptions);
|
||||||
$crypto = new AES('ctr');
|
$crypto = new AES('ctr');
|
||||||
//$crypto->setKeyLength(256);
|
//$crypto->setKeyLength(256);
|
||||||
@ -94,7 +97,7 @@ abstract class OpenSSH
|
|||||||
$crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32);
|
$crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used');
|
throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)');
|
||||||
}
|
}
|
||||||
|
|
||||||
[$publicKey, $paddedKey] = Strings::unpackSSH2('ss', $key);
|
[$publicKey, $paddedKey] = Strings::unpackSSH2('ss', $key);
|
||||||
@ -169,10 +172,6 @@ abstract class OpenSSH
|
|||||||
*/
|
*/
|
||||||
protected static function wrapPrivateKey(string $publicKey, string $privateKey, $password, array $options): string
|
protected static function wrapPrivateKey(string $publicKey, string $privateKey, $password, array $options): string
|
||||||
{
|
{
|
||||||
if (!empty($password) && is_string($password)) {
|
|
||||||
throw new UnsupportedFormatException('Encrypted OpenSSH private keys are not supported');
|
|
||||||
}
|
|
||||||
|
|
||||||
[, $checkint] = unpack('N', Random::string(4));
|
[, $checkint] = unpack('N', Random::string(4));
|
||||||
|
|
||||||
$comment = $options['comment'] ?? self::$comment;
|
$comment = $options['comment'] ?? self::$comment;
|
||||||
@ -180,6 +179,8 @@ abstract class OpenSSH
|
|||||||
$privateKey .
|
$privateKey .
|
||||||
Strings::packSSH2('s', $comment);
|
Strings::packSSH2('s', $comment);
|
||||||
|
|
||||||
|
$usesEncryption = !empty($password) && is_string($password);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
from http://tools.ietf.org/html/rfc4253#section-6 :
|
from http://tools.ietf.org/html/rfc4253#section-6 :
|
||||||
|
|
||||||
@ -187,11 +188,22 @@ abstract class OpenSSH
|
|||||||
'padding_length', 'payload', and 'random padding' MUST be a multiple
|
'padding_length', 'payload', and 'random padding' MUST be a multiple
|
||||||
of the cipher block size or 8, whichever is larger.
|
of the cipher block size or 8, whichever is larger.
|
||||||
*/
|
*/
|
||||||
$paddingLength = (7 * strlen($paddedKey)) % 8;
|
$blockSize = $usesEncryption ? 16 : 8;
|
||||||
|
$paddingLength = (($blockSize - 1) * strlen($paddedKey)) % $blockSize;
|
||||||
for ($i = 1; $i <= $paddingLength; $i++) {
|
for ($i = 1; $i <= $paddingLength; $i++) {
|
||||||
$paddedKey .= chr($i);
|
$paddedKey .= chr($i);
|
||||||
}
|
}
|
||||||
$key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey);
|
if (!$usesEncryption) {
|
||||||
|
$key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey);
|
||||||
|
} else {
|
||||||
|
$rounds = $options['rounds'] ?? 16;
|
||||||
|
$salt = Random::string(16);
|
||||||
|
$kdfoptions = Strings::packSSH2('sN', $salt, $rounds);
|
||||||
|
$crypto = new AES('ctr');
|
||||||
|
$crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32);
|
||||||
|
$paddedKey = $crypto->encrypt($paddedKey);
|
||||||
|
$key = Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey);
|
||||||
|
}
|
||||||
$key = "openssh-key-v1\0$key";
|
$key = "openssh-key-v1\0$key";
|
||||||
|
|
||||||
return "-----BEGIN OPENSSH PRIVATE KEY-----\n" .
|
return "-----BEGIN OPENSSH PRIVATE KEY-----\n" .
|
||||||
|
@ -567,4 +567,13 @@ MIIEDwIBADATBgcqhkjOPQIBBggqhkjOPQMBBwSCA/MwggPvAgEBBIID6P//////
|
|||||||
|
|
||||||
$this->assertSameNL($raw, $key->toString('MontgomeryPrivate'));
|
$this->assertSameNL($raw, $key->toString('MontgomeryPrivate'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOpenSSHEncryptedCreation()
|
||||||
|
{
|
||||||
|
$key = EC::createKey('Ed25519');
|
||||||
|
$key = $key->withPassword('test')->toString('OpenSSH');
|
||||||
|
|
||||||
|
$key = PublicKeyLoader::load($key, 'test');
|
||||||
|
$this->assertInstanceOf(PrivateKey::class, $key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user