From 9bd3c793d3ceb5a0f32900aa83eb58e9f549e356 Mon Sep 17 00:00:00 2001 From: Jim Wigginton Date: Sun, 6 Dec 2009 07:26:52 +0000 Subject: [PATCH] - an inability to unpad doesn't necessarily mean that padding is enabled when it shouldn't be - it might also mean that the key being used is the wrong one. git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@67 21d32557-59b3-4da0-833f-c5933fad653e --- phpseclib/Crypt/DES.php | 9 ++-- phpseclib/Crypt/RSA.php | 81 +++++++++++++++++++++++------------ phpseclib/Crypt/Rijndael.php | 9 ++-- phpseclib/Crypt/TripleDES.php | 9 ++-- phpseclib/Net/SSH2.php | 6 ++- 5 files changed, 71 insertions(+), 43 deletions(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 2ea4bbce..c99924a3 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -53,7 +53,7 @@ * @author Jim Wigginton * @copyright MMVII Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: DES.php,v 1.9 2009-11-23 19:06:06 terrafrost Exp $ + * @version $Id: DES.php,v 1.10 2009-12-06 07:26:52 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -523,7 +523,8 @@ class Crypt_DES { /** * Unpads a string * - * If padding is enabled and the reported padding length is invalid, padding will be, hence forth, disabled. + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. * * @see Crypt_DES::_pad() * @access private @@ -537,9 +538,7 @@ class Crypt_DES { $length = ord($text[strlen($text) - 1]); if (!$length || $length > 8) { - user_error("The number of bytes reported as being padded ($length) is invalid (block size = 8)", E_USER_NOTICE); - $this->padding = false; - return $text; + return false; } return substr($text, 0, -$length); diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 8dd16975..0696a21d 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -62,7 +62,7 @@ * @author Jim Wigginton * @copyright MMIX Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: RSA.php,v 1.3 2009-12-04 21:05:32 terrafrost Exp $ + * @version $Id: RSA.php,v 1.4 2009-12-06 07:26:52 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -762,9 +762,10 @@ class Crypt_RSA { $key = $des->decrypt($ciphertext); } else { $key = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $key)); - if ($key === false) { - return false; - } + } + + if ($key === false) { + return false; } $private = false; @@ -852,6 +853,10 @@ class Crypt_RSA { function loadKey($key, $type = CRYPT_RSA_PRIVATE_FORMAT_PKCS1) { $components = $this->_parseKey($key, $type); + if ($components === false) { + return false; + } + $this->modulus = $components['modulus']; $this->k = strlen($this->modulus->toBytes()); $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent']; @@ -906,7 +911,7 @@ class Crypt_RSA { function setPublicKey($key, $type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1) { $components = $this->_parseKey($key, $type); - if (!$this->modulus->equals($components['modulus'])) { + if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) { return false; } $this->publicExponent = $components['publicExponent']; @@ -926,6 +931,10 @@ class Crypt_RSA { */ function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1) { + if (empty($this->modulus) || empty($this->publicExponent)) { + return false; + } + $oldFormat = $this->publicKeyFormat; $this->publicKeyFormat = $type; $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent); @@ -1834,7 +1843,12 @@ class Crypt_RSA { { switch ($this->encryptionMode) { case CRYPT_RSA_ENCRYPTION_PKCS1: - $plaintext = str_split($plaintext, $this->k - 11); + $length = $this->k - 11; + if ($length <= 0) { + return false; + } + + $plaintext = str_split($plaintext, $length); $ciphertext = ''; foreach ($plaintext as $m) { $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m); @@ -1842,7 +1856,12 @@ class Crypt_RSA { return $ciphertext; //case CRYPT_RSA_ENCRYPTION_OAEP: default: - $plaintext = str_split($plaintext, $this->k - 2 * $this->hLen - 2); + $length = $this->k - 2 * $this->hLen - 2; + if ($length <= 0) { + return false; + } + + $plaintext = str_split($plaintext, $length); $ciphertext = ''; foreach ($plaintext as $m) { $ciphertext.= $this->_rsaes_oaep_encrypt($m); @@ -1861,31 +1880,31 @@ class Crypt_RSA { */ function decrypt($ciphertext) { + if ($this->k <= 0) { + return false; + } + + $ciphertext = str_split($ciphertext, $this->k); + $plaintext = ''; + switch ($this->encryptionMode) { case CRYPT_RSA_ENCRYPTION_PKCS1: - $ciphertext = str_split($ciphertext, $this->k); - $plaintext = ''; - foreach ($ciphertext as $c) { - $temp = $this->_rsaes_pkcs1_v1_5_decrypt($c); - if ($temp === false) { - return false; - } - $plaintext.= $temp; - } - return $plaintext; + $decrypt = '_rsaes_pkcs1_v1_5_decrypt'; + break; //case CRYPT_RSA_ENCRYPTION_OAEP: default: - $ciphertext = str_split($ciphertext, $this->k); - $plaintext = ''; - foreach ($ciphertext as $c) { - $temp = $this->_rsaes_oaep_decrypt($c); - if ($temp === false) { - return false; - } - $plaintext.= $temp; - } - return $plaintext; + $decrypt = '_rsaes_oaep_decrypt'; } + + foreach ($ciphertext as $c) { + $temp = $this->$decrypt($c); + if ($temp === false) { + return false; + } + $plaintext.= $temp; + } + + return $plaintext; } /** @@ -1898,6 +1917,10 @@ class Crypt_RSA { */ function sign($message) { + if (empty($this->modulus) || empty($this->exponent)) { + return false; + } + switch ($this->signatureMode) { case CRYPT_RSA_SIGNATURE_PKCS1: return $this->_rsassa_pkcs1_v1_5_sign($message); @@ -1918,6 +1941,10 @@ class Crypt_RSA { */ function verify($message, $signature) { + if (empty($this->modulus) || empty($this->exponent)) { + return false; + } + switch ($this->signatureMode) { case CRYPT_RSA_SIGNATURE_PKCS1: return $this->_rsassa_pkcs1_v1_5_verify($message, $signature); diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index cc9e8c04..5ca59e1f 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -64,7 +64,7 @@ * @author Jim Wigginton * @copyright MMVIII Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: Rijndael.php,v 1.8 2009-11-23 19:06:07 terrafrost Exp $ + * @version $Id: Rijndael.php,v 1.9 2009-12-06 07:26:52 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -1034,7 +1034,8 @@ class Crypt_Rijndael { /** * Unpads a string. * - * If padding is enabled and the reported padding length is invalid, padding will be, hence forth, disabled. + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. * * @see Crypt_Rijndael::_pad() * @access private @@ -1048,9 +1049,7 @@ class Crypt_Rijndael { $length = ord($text[strlen($text) - 1]); if (!$length || $length > $this->block_size) { - user_error("The number of bytes reported as being padded ($length) is invalid (block size = {$this->block_size})", E_USER_NOTICE); - $this->padding = false; - return $text; + return false; } return substr($text, 0, -$length); diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 92bad483..44fea10f 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -47,7 +47,7 @@ * @author Jim Wigginton * @copyright MMVII Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: TripleDES.php,v 1.9 2009-11-23 19:06:07 terrafrost Exp $ + * @version $Id: TripleDES.php,v 1.10 2009-12-06 07:26:52 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -576,7 +576,8 @@ class Crypt_TripleDES { /** * Unpads a string * - * If padding is enabled and the reported padding length is invalid, padding will be, hence forth, disabled. + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. * * @see Crypt_TripleDES::_pad() * @access private @@ -590,9 +591,7 @@ class Crypt_TripleDES { $length = ord($text[strlen($text) - 1]); if (!$length || $length > 8) { - user_error("The number of bytes reported as being padded ($length) is invalid (block size = 8)", E_USER_NOTICE); - $this->padding = false; - return $text; + return false; } return substr($text, 0, -$length); diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 0860ccad..4b9b9eba 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -60,7 +60,7 @@ * @author Jim Wigginton * @copyright MMVII Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: SSH2.php,v 1.29 2009-12-03 19:04:10 terrafrost Exp $ + * @version $Id: SSH2.php,v 1.30 2009-12-06 07:26:52 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -1308,6 +1308,10 @@ class Net_SSH2 { { // see http://tools.ietf.org/html/rfc4253#page-15 $publickey = $privatekey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_RAW); + if ($publickey === false) { + return false; + } + $publickey = array( 'e' => $publickey['e']->toBytes(true), 'n' => $publickey['n']->toBytes(true)