diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 0f8cb95e..d5bd3a0f 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.10 2010-01-29 06:21:16 terrafrost Exp $ + * @version $Id: RSA.php,v 1.11 2010-02-26 03:40:25 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -767,35 +767,80 @@ class Crypt_RSA { implementation are part of the standard, as well. * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ - if (preg_match('#DEK-Info: DES-EDE3-CBC,(.+)#', $key, $matches)) { - $iv = pack('H*', trim($matches[1])); + if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = pack('H*', trim($matches[2])); $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8); - $ciphertext = base64_decode(preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key)); + $ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key); + $ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false; if ($ciphertext === false) { - return false; + $ciphertext = $key; } - if (!class_exists('Crypt_TripleDES')) { - require_once('Crypt/TripleDES.php'); + switch ($matches[1]) { + case 'DES-EDE3-CBC': + if (!class_exists('Crypt_TripleDES')) { + require_once('Crypt/TripleDES.php'); + } + $crypto = new Crypt_TripleDES(); + break; + case 'DES-CBC': + if (!class_exists('Crypt_DES')) { + require_once('Crypt/DES.php'); + } + $crypto = new Crypt_DES(); + break; + default: + return false; } - $des = new Crypt_TripleDES(); - $des->setKey($symkey); - $des->setIV($iv); - $key = $des->decrypt($ciphertext); + $crypto->setKey($symkey); + $crypto->setIV($iv); + $decoded = $crypto->decrypt($ciphertext); } else { - $key = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $key)); + $decoded = preg_replace('#-.+-|[\r\n]#', '', $key); + $decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false; } - if ($key === false) { + if ($decoded !== false) { + $key = $decoded; + } + + $components = array(); + + if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($key) != strlen($key)) { return false; } - $private = false; - $components = array(); + $tag = ord($this->_string_shift($key)); + if ($tag == CRYPT_RSA_ASN1_SEQUENCE) { + /* intended for keys for which OpenSSL's asn1parse returns the following: + + 0:d=0 hl=4 l= 290 cons: SEQUENCE + 4:d=1 hl=2 l= 13 cons: SEQUENCE + 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption + 17:d=2 hl=2 l= 0 prim: NULL + 19:d=1 hl=4 l= 271 prim: BIT STRING */ + $this->_string_shift($key, $this->_decodeLength($key)); + $this->_string_shift($key); // skip over the BIT STRING tag + $this->_decodeLength($key); // skip over the BIT STRING length + // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of + // unused bits in teh final subsequent octet. The number shall be in the range zero to seven." + // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2) + $this->_string_shift($key); + if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($key) != strlen($key)) { + return false; + } + $tag = ord($this->_string_shift($key)); + } + if ($tag != CRYPT_RSA_ASN1_INTEGER) { + return false; + } - $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_SEQUENCE - $this->_decodeLength($key); // skip over the length of the above sequence - $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER $length = $this->_decodeLength($key); $temp = $this->_string_shift($key, $length); if (strlen($temp) != 1 || ord($temp) > 2) { @@ -806,7 +851,9 @@ class Crypt_RSA { return $components; } - $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER + if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) { + return false; + } $length = $this->_decodeLength($key); $components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); @@ -831,10 +878,14 @@ class Crypt_RSA { $length = $this->_decodeLength($key); $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), -256)); if (!empty($key)) { - $key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE + if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) { + return false; + } $this->_decodeLength($key); while (!empty($key)) { - $key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE + if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) { + return false; + } $this->_decodeLength($key); $key = substr($key, 1); $length = $this->_decodeLength($key); @@ -855,13 +906,25 @@ class Crypt_RSA { return false; } - $components = array(); - extract(unpack('Nlength', $this->_string_shift($key, 4))); - $components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256); - extract(unpack('Nlength', $this->_string_shift($key, 4))); - $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256); + $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa"; - return $components; + extract(unpack('Nlength', $this->_string_shift($key, 4))); + $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256); + extract(unpack('Nlength', $this->_string_shift($key, 4))); + $modulus = new Math_BigInteger($this->_string_shift($key, $length), -256); + + if ($cleanup && strlen($key)) { + extract(unpack('Nlength', $this->_string_shift($key, 4))); + return array( + 'modulus' => new Math_BigInteger($this->_string_shift($key, $length), -256), + 'publicExponent' => $modulus + ); + } else { + return array( + 'modulus' => $modulus, + 'publicExponent' => $publicExponent + ); + } } } diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 203e2847..3a5b28d2 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.12 2010-02-09 06:10:26 terrafrost Exp $ + * @version $Id: TripleDES.php,v 1.13 2010-02-26 03:40:25 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -284,7 +284,7 @@ class Crypt_TripleDES { $key = str_pad($key, 24, chr(0)); // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this: // http://php.net/function.mcrypt-encrypt#47973 - $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); + //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); } $this->key = $key; switch (true) { @@ -386,7 +386,7 @@ class Crypt_TripleDES { $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { - mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); } return $ciphertext; @@ -477,7 +477,7 @@ class Crypt_TripleDES { $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); if (!$this->continuousBuffer) { - mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); } return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext; diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index b4445d01..4fd16af1 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -67,7 +67,7 @@ * @author Jim Wigginton * @copyright MMVI Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: BigInteger.php,v 1.29 2010-02-21 07:45:31 terrafrost Exp $ + * @version $Id: BigInteger.php,v 1.30 2010-02-26 03:40:26 terrafrost Exp $ * @link http://pear.php.net/package/Math_BigInteger */ @@ -860,7 +860,7 @@ class Math_BigInteger { $carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT52; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 $sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT52 : $sum; - $temp = floor($sum / 0x4000000); + $temp = (int) ($sum / 0x4000000); $value[$i] = $sum - 0x4000000 * $temp; // eg. a faster alternative to fmod($sum, 0x4000000) $value[$j] = $temp; @@ -996,7 +996,7 @@ class Math_BigInteger { $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 $sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT52 : $sum; - $temp = floor($sum / 0x4000000); + $temp = (int) ($sum / 0x4000000); $x_value[$i] = $sum - 0x4000000 * $temp; $x_value[$j] = $temp; @@ -1144,7 +1144,7 @@ class Math_BigInteger { for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $product_value[$j] = $temp - 0x4000000 * $carry; } @@ -1157,7 +1157,7 @@ class Math_BigInteger { for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $product_value[$k] = $temp - 0x4000000 * $carry; } @@ -1245,13 +1245,13 @@ class Math_BigInteger { $i2 = $i << 1; $temp = $square_value[$i2] + $value[$i] * $value[$i]; - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $square_value[$i2] = $temp - 0x4000000 * $carry; // note how we start from $i+1 instead of 0 as we do in multiplication. for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $square_value[$k] = $temp - 0x4000000 * $carry; } @@ -1449,7 +1449,7 @@ class Math_BigInteger { if ($x_window[0] == $y_window[0]) { $quotient_value[$q_index] = 0x3FFFFFF; } else { - $quotient_value[$q_index] = floor( + $quotient_value[$q_index] = (int) ( ($x_window[0] * 0x4000000 + $x_window[1]) / $y_window[0] @@ -1519,7 +1519,7 @@ class Math_BigInteger { for ($i = count($dividend) - 1; $i >= 0; --$i) { $temp = 0x4000000 * $carry + $dividend[$i]; - $result[$i] = floor($temp / $divisor); + $result[$i] = (int) ($temp / $divisor); $carry = $temp - $divisor * $result[$i]; } @@ -2089,7 +2089,7 @@ class Math_BigInteger { for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $product_value[$j] = $temp - 0x4000000 * $carry; } @@ -2105,7 +2105,7 @@ class Math_BigInteger { for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $product_value[$k] = $temp - 0x4000000 * $carry; } @@ -2154,7 +2154,7 @@ class Math_BigInteger { for ($i = 0; $i < $k; ++$i) { $temp = $result[MATH_BIGINTEGER_VALUE][$i] * $cache[MATH_BIGINTEGER_DATA][$key]; - $temp = $temp - 0x4000000 * floor($temp / 0x4000000); + $temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000)); $temp = $this->_regularMultiply(array($temp), $n); $temp = array_merge($this->_array_repeat(0, $i), $temp); $result = $this->_add($result[MATH_BIGINTEGER_VALUE], false, $temp, false); @@ -2206,9 +2206,9 @@ class Math_BigInteger { $a = array(MATH_BIGINTEGER_VALUE => $this->_array_repeat(0, $n + 1)); for ($i = 0; $i < $n; ++$i) { $temp = $a[MATH_BIGINTEGER_VALUE][0] + $x[$i] * $y[0]; - $temp = $temp - 0x4000000 * floor($temp / 0x4000000); + $temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000)); $temp = $temp * $cache[MATH_BIGINTEGER_DATA][$key]; - $temp = $temp - 0x4000000 * floor($temp / 0x4000000); + $temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000)); $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false); $a = $this->_add($a[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false); $a[MATH_BIGINTEGER_VALUE] = array_slice($a[MATH_BIGINTEGER_VALUE], 1); @@ -3307,7 +3307,7 @@ class Math_BigInteger { return; } - $num_digits = floor($shift / 26); + $num_digits = (int) ($shift / 26); $shift %= 26; $shift = 1 << $shift; @@ -3315,7 +3315,7 @@ class Math_BigInteger { for ($i = 0; $i < count($this->value); ++$i) { $temp = $this->value[$i] * $shift + $carry; - $carry = floor($temp / 0x4000000); + $carry = (int) ($temp / 0x4000000); $this->value[$i] = $temp - $carry * 0x4000000; } @@ -3342,7 +3342,7 @@ class Math_BigInteger { return; } - $num_digits = floor($shift / 26); + $num_digits = (int) ($shift / 26); $shift %= 26; $carry_shift = 26 - $shift; $carry_mask = (1 << $shift) - 1;