RSA: auto-detect public keys vs private keys

This commit is contained in:
terrafrost 2014-04-17 10:30:32 -05:00
parent dfa583b9ea
commit 317efaf28a
2 changed files with 117 additions and 7 deletions

View File

@ -477,7 +477,7 @@ class Crypt_RSA
case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>=') && file_exists($this->configFile):
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
ob_start();
phpinfo();
@phpinfo();
$content = ob_get_contents();
ob_end_clean();
@ -1478,6 +1478,19 @@ class Crypt_RSA
$this->publicExponent = false;
}
switch ($type) {
case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
case CRYPT_RSA_PUBLIC_FORMAT_RAW:
$this->setPublicKey();
break;
case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
switch (true) {
case strpos($key, '-BEGIN PUBLIC KEY-') !== false:
case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false:
$this->setPublicKey();
}
}
return true;
}
@ -1504,7 +1517,9 @@ class Crypt_RSA
* used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
* message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
* and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
* exponent this won't work unless you manually add the public exponent.
* exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used
* is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being
* public.
*
* Do note that when a new key is loaded the index will be cleared.
*
@ -1560,6 +1575,40 @@ class Crypt_RSA
return true;
}
/**
* Defines the private key
*
* If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force
* phpseclib to treat the key as a private key. This function will do that.
*
* Do note that when a new key is loaded the index will be cleared.
*
* Returns true on success, false on failure
*
* @see getPublicKey()
* @access public
* @param String $key optional
* @param Integer $type optional
* @return Boolean
*/
function setPrivateKey($key = false, $type = false)
{
if ($key === false && !empty($this->publicExponent)) {
unset($this->publicExponent);
return true;
}
$rsa = new Crypt_RSA();
if (!$rsa->loadKey($key, $type)) {
return false;
}
unset($rsa->publicExponent);
// don't overwrite the old key if the new key is invalid
$this->loadKey($rsa);
return true;
}
/**
* Returns the public key
*

View File

@ -36,7 +36,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPrivateKey()));
}
public function testPKCS1SpacesKey()
@ -58,7 +58,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
-----END RSA PRIVATE KEY-----';
$key = str_replace(array("\r", "\n", "\r\n"), ' ', $key);
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPrivateKey()));
}
public function testPKCS1NoHeaderKey()
@ -77,7 +77,7 @@ X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPrivateKey()));
}
public function testPKCS1NoWhitespaceNoHeaderKey()
@ -95,7 +95,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
'X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl' .
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPrivateKey()));
}
public function testRawPKCS1Key()
@ -115,6 +115,67 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$key = base64_decode($key);
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPrivateKey()));
}
public function testPubKey1()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPublicKey()) && $rsa->getPrivateKey() === false);
}
public function testPubKey2()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPublicKey()) && $rsa->getPrivateKey() === false);
}
public function testPubKey3()
{
$rsa = new Crypt_RSA();
$key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4e' .
'CZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMS' .
'GkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== ' .
'phpseclib-generated-key';
$this->assertTrue($rsa->loadKey($key) && is_string($rsa->getPublicKey()) && $rsa->getPrivateKey() === false);
}
public function testSetPrivate()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key) && $rsa->setPrivateKey() && is_string("$rsa") && $rsa->getPublicKey() === false);
}
}