From 3a5ab5276ec7767244b1f1831e01402844ec49b2 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 22 Sep 2012 11:32:41 -0500 Subject: [PATCH 01/26] CRYPT_MODE_DES_CBC should have been CRYPT_DES_MODE_CBC Thanks arook! --- phpseclib/Crypt/DES.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 2fd7a9b8..f6c1f301 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -291,7 +291,7 @@ class Crypt_DES { * @return Crypt_DES * @access public */ - function Crypt_DES($mode = CRYPT_MODE_DES_CBC) + function Crypt_DES($mode = CRYPT_DES_MODE_CBC) { if ( !defined('CRYPT_DES_MODE') ) { switch (true) { @@ -1292,4 +1292,4 @@ class Crypt_DES { } // vim: ts=4:sw=4:et: -// vim6: fdl=1: +// vim6: fdl=1: \ No newline at end of file From 0e0eebf4564f4da5702e1bb6a6fc6095aaaaacdf Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 12 Nov 2012 00:46:03 -0600 Subject: [PATCH 02/26] CS adjustments, make loadXXX() take in binary data, and make getDN() == getIssuerDN() for CRLs --- phpseclib/File/X509.php | 63 ++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 21a6cb6a..f9c68eb4 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -59,15 +59,35 @@ if (!class_exists('File_ASN1')) { */ define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1); +/**#@+ + * @access public + * @see File_X509::getDN() + */ /** - * Name format tokens for the getDN() method. + * Return internal array representation */ define('FILE_X509_DN_ARRAY', 0); // Internal array representation. -define('FILE_X509_DN_STRING', 1); // String. -define('FILE_X509_DN_ASN1', 2); // ASN.1 Name string. -define('FILE_X509_DN_OPENSSL', 3); // OpenSSL compatible array. -define('FILE_X509_DN_CANON', 4); // Canonical ASN.1 RDNs string. -define('FILE_X509_DN_HASH', 5); // Name hash for file indexing. +/** + * Return string + */ +define('FILE_X509_DN_STRING', 1) +/** + * Return ASN.1 name string + */ +define('FILE_X509_DN_ASN1', 2); +/** + * Return OpenSSL compatible array + */ +define('FILE_X509_DN_OPENSSL', 3); +/** + * Return canonical ASN.1 RDNs string + */ +define('FILE_X509_DN_CANON', 4); +/** + * Return name ash for file indexing + */ +define('FILE_X509_DN_HASH', 5); +/**#@-*/ /** * Pure-PHP X.509 Parser @@ -1346,8 +1366,11 @@ class File_X509 { subject=/O=organization/OU=org unit/CN=common name issuer=/O=organization/CN=common name */ - $cert = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $cert); - $cert = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $cert) ? base64_decode($cert) : false; + $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $cert); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + if ($temp != false) { + $cert = $temp; + } if ($cert === false) { $this->currentCert = false; @@ -2361,7 +2384,7 @@ class File_X509 { return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']); } - return false; + return false; } /** @@ -2385,7 +2408,7 @@ class File_X509 { return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']); } - return false; + return false; } /** @@ -2407,7 +2430,7 @@ class File_X509 { return $this->getDNProp($propname, $this->currentCert['tbsCertList']['issuer'], $withType); } - return false; + return false; } /** @@ -2431,7 +2454,7 @@ class File_X509 { return $this->getDNProp($propname, $this->currentCert['certificationRequestInfo']['subject'], $withType); } - return false; + return false; } /** @@ -2518,8 +2541,11 @@ class File_X509 { $asn1 = new File_ASN1(); - $csr = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); - $orig = $csr = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $csr) ? base64_decode($csr) : false; + $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + if ($temp != false) { + $orig = $csr = $temp; + } if ($csr === false) { $this->currentCert = false; @@ -2612,8 +2638,11 @@ class File_X509 { { $asn1 = new File_ASN1(); - $crl = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]#', '', $crl); - $orig = $crl = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $crl) ? base64_decode($crl) : false; + $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + if ($temp != false) { + $orig = $crl = $temp; + } if ($crl === false) { $this->currentCert = false; @@ -2636,6 +2665,8 @@ class File_X509 { $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + $this->dn = $crl['tbsCertList']['issuer']; + $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1); $rclist = &$this->_subArray($crl,'tbsCertList/revokedCertificates'); if (is_array($rclist)) { From 661eb8db3fd21bad581827dc6cfa0254bc58d711 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 12 Nov 2012 01:05:24 -0600 Subject: [PATCH 03/26] Missing ; --- phpseclib/File/X509.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index f9c68eb4..0ef8edc2 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -70,7 +70,7 @@ define('FILE_X509_DN_ARRAY', 0); // Internal array representation. /** * Return string */ -define('FILE_X509_DN_STRING', 1) +define('FILE_X509_DN_STRING', 1); /** * Return ASN.1 name string */ From 1abc7e742b55545104c1465670a11387ff37ecf9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 12 Nov 2012 23:51:41 -0600 Subject: [PATCH 04/26] X509: CSRs and CRLs didn't have the signatureSubject variable saved properly --- phpseclib/File/X509.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 0ef8edc2..81a22b38 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -2544,8 +2544,9 @@ class File_X509 { $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; if ($temp != false) { - $orig = $csr = $temp; + $csr = $temp; } + $orig = $csr; if ($csr === false) { $this->currentCert = false; @@ -2641,8 +2642,9 @@ class File_X509 { $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; if ($temp != false) { - $orig = $crl = $temp; + $crl = $temp; } + $orig = $crl; if ($crl === false) { $this->currentCert = false; From 1fd87dcd35d4d4e323859de4c2f115c97d93dde3 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 13 Nov 2012 00:33:15 -0600 Subject: [PATCH 05/26] Fix bug in listRevoked() and make it so getSubjectDN() doesn't return issuer DN for CRLs --- phpseclib/File/X509.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 81a22b38..8dbb8faa 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -2232,7 +2232,7 @@ class File_X509 { function getDN($format = FILE_X509_DN_ARRAY, $dn = NULL) { if (!isset($dn)) { - $dn = $this->dn; + $dn = isset($this->currentCert['tbsCertList']) ? this->currentCert['tbsCertList']['issuer'] : $this->dn; } switch ((int) $format) { @@ -2667,8 +2667,6 @@ class File_X509 { $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $this->dn = $crl['tbsCertList']['issuer']; - $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1); $rclist = &$this->_subArray($crl,'tbsCertList/revokedCertificates'); if (is_array($rclist)) { @@ -3658,7 +3656,7 @@ class File_X509 { $result = array(); - if (!is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { foreach ($rclist as $rc) { $result[] = $rc['userCertificate']->toString(); } From d492d197483dddbfa29a8fd6f7e0732db733d2fb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 13 Nov 2012 00:37:54 -0600 Subject: [PATCH 06/26] X509: Missing $ --- phpseclib/File/X509.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 8dbb8faa..d8abdeb2 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -2232,7 +2232,7 @@ class File_X509 { function getDN($format = FILE_X509_DN_ARRAY, $dn = NULL) { if (!isset($dn)) { - $dn = isset($this->currentCert['tbsCertList']) ? this->currentCert['tbsCertList']['issuer'] : $this->dn; + $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; } switch ((int) $format) { From 691f4d1e62812b34f62fcb6b07d15518d0b5b45d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 13 Nov 2012 00:43:45 -0600 Subject: [PATCH 07/26] Make it so loadCA() doesn't have to be called before loadX509() or loadCRL() --- phpseclib/File/X509.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index d8abdeb2..6ad74675 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1660,8 +1660,16 @@ class File_X509 { */ function loadCA($cert) { + $olddn = $this->dn; + $oldcert = $this->currentCert; + $oldsigsubj = $this->signatureSubject; + $cert = $this->loadX509($cert); if (!$cert) { + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; + return false; } @@ -1690,8 +1698,10 @@ class File_X509 { //} $this->CAs[] = $cert; - unset($this->currentCert); - unset($this->signatureSubject); + + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; return true; } From 8cf6bb0b1cbd629491f331759d8bb80062472eed Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 14 Nov 2012 04:34:33 -0600 Subject: [PATCH 08/26] SSH1: Fix E_NOTICE (thanks dayton967!) --- phpseclib/Net/SSH1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index 69669aa7..67e09652 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -428,7 +428,7 @@ class Net_SSH1 { * @var Array * @access private */ - var $interactive_buffer = ''; + var $interactiveBuffer = ''; /** * Default Constructor. From 2a1909fd7140cfd7b41ee1b4a2f5f5cf4e9dc318 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 16 Nov 2012 02:59:06 -0600 Subject: [PATCH 09/26] Set $this->paddable to true in a few missing places --- phpseclib/Crypt/DES.php | 2 +- phpseclib/Crypt/TripleDES.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index f6c1f301..0d6dd00e 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -723,7 +723,7 @@ class Crypt_DES { mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV); } - return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext; + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } if (!is_array($this->keys)) { diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index bbabf169..faf8c18a 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -265,6 +265,7 @@ class Crypt_TripleDES { new Crypt_DES(CRYPT_DES_MODE_CBC), new Crypt_DES(CRYPT_DES_MODE_CBC) ); + $this->paddable = true; // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects $this->des[0]->disablePadding(); From 406e7e90e91379cd0d167e4cc1563d2895d820bb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 18 Nov 2012 16:16:11 -0600 Subject: [PATCH 10/26] CS adjustments --- phpseclib/File/X509.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 6ad74675..008a34f1 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -3426,10 +3426,10 @@ class File_X509 { /** * Compute a public key identifier. * - * Although key identifiers may be set to any unique value, this function + * Although key identifiers may be set to any unique value, this function * computes key identifiers from public key according to the two * recommended methods (4.2.1.2 RFC 3280). - * Highly polymorphic: try to accept all possible forms of key: + * Highly polymorphic: try to accept all possible forms of key: * - Key object * - File_X509 object with public or private key defined * - Certificate or CSR array @@ -3497,7 +3497,7 @@ class File_X509 { $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40); } - return $hash; + return $hash; } /** @@ -3560,7 +3560,6 @@ class File_X509 { * @access private * @return Integer or false */ - function _revokedCertificate(&$rclist, $serial, $create = false) { $serial = new Math_BigInteger($serial); From 126c396a517a2f1f1c2d0955b9c81cb1a8b87063 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 18 Nov 2012 16:29:15 -0600 Subject: [PATCH 11/26] More CS adjustments --- phpseclib/File/ASN1.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index ea323e1d..0ed044fd 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -1184,7 +1184,6 @@ class File_ASN1 { * @return String * @access public */ - function convert($in, $from = FILE_ASN1_TYPE_UTF8_STRING, $to = FILE_ASN1_TYPE_UTF8_STRING) { if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) { From 7e120a0f3073025d69ed9bcbe3374c54b802f897 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 19 Nov 2012 21:10:22 -0600 Subject: [PATCH 12/26] Make validateSignature() behave more intuitively --- phpseclib/File/X509.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 008a34f1..08de8341 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1809,9 +1809,7 @@ class File_X509 { * Validate a signature * * Works on X.509 certs, CSR's and CRL's. - * Returns 1 if the signature is verified, 0 if it is not correct or -1 on error - * - * To know if a signature is valid one should do validateSignature() === 1 + * Returns true if the signature is verified, false if it is not correct or NULL on error * * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. * @@ -1861,10 +1859,10 @@ class File_X509 { } } if (count($this->CAs) == $i && ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) { - return 0; + return false; } } elseif (!isset($signingCert) || ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) { - return 0; + return false; } return $this->_validateSignature( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], @@ -1898,7 +1896,7 @@ class File_X509 { } } if (!isset($signingCert)) { - return 0; + return false; } return $this->_validateSignature( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], @@ -1908,14 +1906,14 @@ class File_X509 { $this->signatureSubject ); default: - return 0; + return false; } } /** * Validates a signature * - * Returns 1 if the signature is verified, 0 if it is not correct or -1 on error + * Returns true if the signature is verified, false if it is not correct or NULL on error * * @param String $publicKeyAlgorithm * @param String $publicKey @@ -1947,18 +1945,18 @@ class File_X509 { $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); if (!@$rsa->verify($signatureSubject, $signature)) { - return 0; + return false; } break; default: - return -1; + return NULL; } break; default: - return -1; + return NULL; } - return 1; + return true; } /** From fbf3ba353eb83fef7f81ec39fcbe1951c9572abb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 19 Nov 2012 23:00:04 -0600 Subject: [PATCH 13/26] Null pad RSA ciphertext's to be the length of the modulo and improve XML parsing --- phpseclib/Crypt/RSA.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 7df1ded7..98f6d15f 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1148,7 +1148,8 @@ class Crypt_RSA { xml_set_object($xml, $this); xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler'); xml_set_character_data_handler($xml, '_data_handler'); - if (!xml_parse($xml, $key)) { + // add to account for "dangling" tags like ... that are sometimes added + if (!xml_parse($xml, '' . $key . '')) { return false; } @@ -2481,7 +2482,6 @@ class Crypt_RSA { } // Compare - return $this->_equals($em, $em2); } @@ -2569,6 +2569,8 @@ class Crypt_RSA { } $ciphertext = str_split($ciphertext, $this->k); + $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT); + $plaintext = ''; switch ($this->encryptionMode) { @@ -2637,4 +2639,4 @@ class Crypt_RSA { return $this->_rsassa_pss_verify($message, $signature); } } -} +} \ No newline at end of file From 2c85e6d07acf0b1591324436dd2810b2f6fa3f6a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 21 Nov 2012 23:03:22 -0600 Subject: [PATCH 14/26] Update download link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01550575..4e1330e8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ MIT-licensed pure-PHP implementations of an arbitrary-precision integer arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, AES, SSH-1, SSH-2, SFTP, and X.509 -* [Download (0.3.0)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.0.zip/download) +* [Download (0.3.1)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.1.zip/download) * [Browse Git](https://github.com/phpseclib/phpseclib) * [Documentation](http://phpseclib.sourceforge.net/) * [Support](http://www.frostjedi.com/phpbb/viewforum.php?f=46) From 6c33012a4ace88bf89076693e25f0826d63eb942 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 22 Nov 2012 12:11:15 -0600 Subject: [PATCH 15/26] Suppress further error messages if connection is prematurely disconnected --- phpseclib/Net/SSH2.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 144eba40..ec44a55c 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2000,6 +2000,7 @@ class Net_SSH2 { { if (!is_resource($this->fsock) || feof($this->fsock)) { user_error('Connection closed prematurely', E_USER_NOTICE); + $this->bitmask = 0; return false; } @@ -2345,6 +2346,7 @@ class Net_SSH2 { { if (!is_resource($this->fsock) || feof($this->fsock)) { user_error('Connection closed prematurely', E_USER_NOTICE); + $this->bitmask = 0; return false; } From 875cef8bbd4756e1f408952959233b6a8575d254 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 22 Nov 2012 13:08:30 -0600 Subject: [PATCH 16/26] Revamp logging --- phpseclib/Net/SSH2.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index ec44a55c..99dea7c7 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -699,6 +699,13 @@ class Net_SSH2 { */ var $quiet_mode = false; + /** + * Time of first network activity + * + * @access private + */ + var $last_packet; + /** * Default Constructor. * @@ -712,6 +719,7 @@ class Net_SSH2 { */ function Net_SSH2($host, $port = 22, $timeout = 10) { + $this->last_packet = strtok(microtime(), ' ') + strtok(''); // == microtime(true) in PHP5 $this->message_numbers = array( 1 => 'NET_SSH2_MSG_DISCONNECT', 2 => 'NET_SSH2_MSG_IGNORE', @@ -2052,10 +2060,12 @@ class Net_SSH2 { $this->get_seq_no++; if (defined('NET_SSH2_LOGGING')) { + $current = strtok(microtime(), ' ') + strtok(''); $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; $message_number = '<- ' . $message_number . - ' (' . round($stop - $start, 4) . 's)'; + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; $this->_append_log($message_number, $payload); + $this->last_packet = $current; } return $this->_filter($payload); @@ -2385,10 +2395,12 @@ class Net_SSH2 { $stop = strtok(microtime(), ' ') + strtok(''); if (defined('NET_SSH2_LOGGING')) { + $current = strtok(microtime(), ' ') + strtok(''); $message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')'; $message_number = '-> ' . $message_number . - ' (' . round($stop - $start, 4) . 's)'; + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; $this->_append_log($message_number, $data); + $this->last_packet = $current; } return $result; @@ -2425,8 +2437,8 @@ class Net_SSH2 { // identified case NET_SSH2_LOG_REALTIME: echo "
\r\n" . $this->_format_log(array($message), array($message_number)) . "\r\n
\r\n"; - flush(); - ob_flush(); + @flush(); + @ob_flush(); break; // basically the same thing as NET_SSH2_LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILE // needs to be defined and that the resultant log file will be capped out at NET_SSH2_LOG_MAX_SIZE. From 346bc5dcc865daaf14eef46b07ddc5a728fce19a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 22 Nov 2012 14:25:57 -0600 Subject: [PATCH 17/26] Make it so none is a supported authentication method --- phpseclib/Net/SSH2.php | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 99dea7c7..7e876e88 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1441,7 +1441,7 @@ class Net_SSH2 { * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} * by sending dummy SSH_MSG_IGNORE messages. */ - function login($username, $password = '') + function login($username, $password = null) { if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) { return false; @@ -1473,6 +1473,34 @@ class Net_SSH2 { return $this->_privatekey_login($username, $password); } + if (!isset($password)) { + $packet = pack('CNa*Na*Na*CNa*', + NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection', + strlen('none'), 'none' + ); + + if (!$this->_send_binary_packet($packet)) { + return false; + } + + $response = $this->_get_binary_packet(); + if ($response === false) { + user_error('Connection closed by server', E_USER_NOTICE); + return false; + } + + extract(unpack('Ctype', $this->_string_shift($response, 1))); + + switch ($type) { + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= NET_SSH2_MASK_LOGIN; + return true; + //case NET_SSH2_MSG_USERAUTH_FAILURE: + default: + return false; + } + } + $packet = pack('CNa*Na*Na*CNa*', NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection', strlen('password'), 'password', 0, strlen($password), $password From 76cb693d62e7dfb6f86fb72bdb1e6395fd302e12 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 23 Nov 2012 19:04:04 -0600 Subject: [PATCH 18/26] CS adjustments, make it so PEM-encoded CRLs can be read (again) and make it so already decoded CSRs and CRLs can be read --- phpseclib/File/X509.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 08de8341..e852fce8 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1354,7 +1354,7 @@ class File_X509 { if (is_array($cert) && isset($cert['tbsCertificate'])) { $this->currentCert = $cert; unset($this->signatureSubject); - return false; + return $cert; } $asn1 = new File_ASN1(); @@ -2545,6 +2545,12 @@ class File_X509 { */ function loadCSR($csr) { + if (is_array($csr) && isset($csr['certificationRequestInfo'])) { + $this->currentCert = $csr; + unset($this->signatureSubject); + return $csr; + } + // see http://tools.ietf.org/html/rfc2986 $asn1 = new File_ASN1(); @@ -2645,9 +2651,15 @@ class File_X509 { */ function loadCRL($crl) { + if (is_array($crl) && isset($crl['tbsCertList'])) { + $this->currentCert = $crl; + unset($this->signatureSubject); + return $crl; + } + $asn1 = new File_ASN1(); - $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr); + $temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $crl); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; if ($temp != false) { $crl = $temp; @@ -2988,8 +3000,7 @@ class File_X509 { if (!empty($this->endDate)) { $tbsCertList['nextUpdate'] = array('generalTime' => $this->endDate); // $this->setEndDate() - } - else { + } else { unset($tbsCertList['nextUpdate']); } @@ -2999,7 +3010,7 @@ class File_X509 { else { $crlNumber = $this->getExtension('id-ce-cRLNumber'); $crlNumber = $crlNumber !== false ? $crlNumber->add(new Math_BigInteger(1)) : NULL; - } + } $this->removeExtension('id-ce-authorityKeyIdentifier'); $this->removeExtension('id-ce-issuerAltName'); From 0b9f743343d9138ebcf673165a3518021f101938 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 25 Nov 2012 23:06:58 -0600 Subject: [PATCH 19/26] Add getChain() function Also improve loading of raw certs --- phpseclib/File/X509.php | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index e852fce8..04dcf180 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1352,8 +1352,19 @@ class File_X509 { function loadX509($cert) { if (is_array($cert) && isset($cert['tbsCertificate'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + $this->dn = $cert['tbsCertificate']['subject']; + if (!isset($this->dn)) { + return false; + } $this->currentCert = $cert; + + $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); + $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : NULL; + unset($this->signatureSubject); + return $cert; } @@ -1663,12 +1674,14 @@ class File_X509 { $olddn = $this->dn; $oldcert = $this->currentCert; $oldsigsubj = $this->signatureSubject; + $oldkeyid = $this->currentKeyIdentifier; $cert = $this->loadX509($cert); if (!$cert) { $this->dn = $olddn; $this->currentCert = $oldcert; $this->signatureSubject = $oldsigsubj; + $this->currentKeyIdentifier = $oldkeyid; return false; } @@ -2465,6 +2478,51 @@ class File_X509 { return false; } + /** + * Get the certificate chain for the current cert + * + * @access public + * @return Mixed + */ + function getChain() + { + $chain = array($this->currentCert); + + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + if (empty($this->CAs)) { + return $chain; + } + while (true) { + $currentCert = $chain[count($chain) - 1]; + for ($i = 0; $i < count($this->CAs); $i++) { + $ca = $this->CAs[$i]; + if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if ($currentCert === $ca) { + break 3; + } + $chain[] = $ca; + break 2; + } + } + } + if ($i == count($this->CAs)) { + break; + } + } + foreach ($chain as $key=>$value) { + $chain[$key] = new File_X509(); + $chain[$key]->loadX509($value); + } + return $chain; + } + /** * Set public key * @@ -2546,6 +2604,13 @@ class File_X509 { function loadCSR($csr) { if (is_array($csr) && isset($csr['certificationRequestInfo'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + $this->dn = $csr['certificationRequestInfo']['subject']; + if (!isset($this->dn)) { + return false; + } + $this->currentCert = $csr; unset($this->signatureSubject); return $csr; From 8ea452ed3120dbbeb1d76fd653cde41188efd660 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 27 Nov 2012 10:11:49 -0600 Subject: [PATCH 20/26] type in comment (testing out github.com's edit via web interface) --- phpseclib/File/X509.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 04dcf180..2f0ce3c1 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -84,7 +84,7 @@ define('FILE_X509_DN_OPENSSL', 3); */ define('FILE_X509_DN_CANON', 4); /** - * Return name ash for file indexing + * Return name hash for file indexing */ define('FILE_X509_DN_HASH', 5); /**#@-*/ From ff945763153013639b632640a93628b8e91938cb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 27 Nov 2012 14:38:30 -0600 Subject: [PATCH 21/26] Remove unused fields from pack() --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 7e876e88..deb92e63 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1474,7 +1474,7 @@ class Net_SSH2 { } if (!isset($password)) { - $packet = pack('CNa*Na*Na*CNa*', + $packet = pack('CNa*Na*Na*', NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection', strlen('none'), 'none' ); From dbc10491e72545bbef9bfbf398e5d83cae0071a5 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 28 Nov 2012 08:17:57 -0600 Subject: [PATCH 22/26] Fix an E_NOTICE (thanks chubbypama!) --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index deb92e63..29a8f0f4 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1959,7 +1959,7 @@ class Net_SSH2 { while (true) { if ($mode == NET_SSH2_READ_REGEX) { preg_match($expect, $this->interactiveBuffer, $matches); - $match = $matches[0]; + $match = isset($matches[0]) ? $matches[0] : array(); } $pos = !empty($match) ? strpos($this->interactiveBuffer, $match) : false; if ($pos !== false) { From 3caaa91160d7e59569362928241f685d967d3722 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 28 Nov 2012 23:33:15 -0600 Subject: [PATCH 23/26] Replace user_error() with new _handle_error() function To use exceptions do define('PHPSECLIB_USE_EXCEPTIONS', true). To have the exceptions thrown by phpseclib be of a certain class define PHPSECLIB_EXCEPTION_CLASS. --- phpseclib/Crypt/DES.php | 20 +++++- phpseclib/Crypt/RSA.php | 68 ++++++++++++-------- phpseclib/Crypt/Rijndael.php | 26 ++++++-- phpseclib/File/ANSI.php | 20 +++++- phpseclib/File/ASN1.php | 24 +++++++- phpseclib/File/X509.php | 20 +++++- phpseclib/Net/SFTP.php | 42 ++++++------- phpseclib/Net/SSH1.php | 68 ++++++++++++-------- phpseclib/Net/SSH2.php | 116 ++++++++++++++++++++--------------- 9 files changed, 274 insertions(+), 130 deletions(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 0d6dd00e..6a6d3389 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -937,7 +937,7 @@ class Crypt_DES { if (($length & 7) == 0) { return $text; } else { - user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE); + $this->_handle_error("The plaintext's length ($length) is not a multiple of the block size (8)"); $this->padding = true; } } @@ -1289,6 +1289,24 @@ class Crypt_DES { $string = substr($string, $index); return $substr; } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + user_error($err_msg); + } + } } // vim: ts=4:sw=4:et: diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 98f6d15f..df090857 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1746,7 +1746,7 @@ class Crypt_RSA { { $x = $x->toBytes(); if (strlen($x) > $xLen) { - user_error('Integer too large', E_USER_NOTICE); + $this->_handle_error('Integer too large'); return false; } return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); @@ -1908,7 +1908,7 @@ class Crypt_RSA { function _rsaep($m) { if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range', E_USER_NOTICE); + $this->_handle_error('Message representative out of range'); return false; } return $this->_exponentiate($m); @@ -1926,7 +1926,7 @@ class Crypt_RSA { function _rsadp($c) { if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) { - user_error('Ciphertext representative out of range', E_USER_NOTICE); + $this->_handle_error('Ciphertext representative out of range'); return false; } return $this->_exponentiate($c); @@ -1944,7 +1944,7 @@ class Crypt_RSA { function _rsasp1($m) { if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range', E_USER_NOTICE); + $this->_handle_error('Message representative out of range'); return false; } return $this->_exponentiate($m); @@ -1962,7 +1962,7 @@ class Crypt_RSA { function _rsavp1($s) { if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) { - user_error('Signature representative out of range', E_USER_NOTICE); + $this->_handle_error('Signature representative out of range'); return false; } return $this->_exponentiate($s); @@ -2013,7 +2013,7 @@ class Crypt_RSA { // be output. if ($mLen > $this->k - 2 * $this->hLen - 2) { - user_error('Message too long', E_USER_NOTICE); + $this->_handle_error('Message too long'); return false; } @@ -2074,7 +2074,7 @@ class Crypt_RSA { // be output. if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } @@ -2083,7 +2083,7 @@ class Crypt_RSA { $c = $this->_os2ip($c); $m = $this->_rsadp($c); if ($m === false) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } $em = $this->_i2osp($m, $this->k); @@ -2101,12 +2101,12 @@ class Crypt_RSA { $lHash2 = substr($db, 0, $this->hLen); $m = substr($db, $this->hLen); if ($lHash != $lHash2) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } $m = ltrim($m, chr(0)); if (ord($m[0]) != 1) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } @@ -2131,7 +2131,7 @@ class Crypt_RSA { // Length checking if ($mLen > $this->k - 11) { - user_error('Message too long', E_USER_NOTICE); + $this->_handle_error('Message too long'); return false; } @@ -2175,7 +2175,7 @@ class Crypt_RSA { // Length checking if (strlen($c) != $this->k) { // or if k < 11 - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } @@ -2185,7 +2185,7 @@ class Crypt_RSA { $m = $this->_rsadp($c); if ($m === false) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } $em = $this->_i2osp($m, $this->k); @@ -2193,7 +2193,7 @@ class Crypt_RSA { // EME-PKCS1-v1_5 decoding if (ord($em[0]) != 0 || ord($em[1]) > 2) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } @@ -2201,7 +2201,7 @@ class Crypt_RSA { $m = substr($em, strlen($ps) + 3); if (strlen($ps) < 8) { - user_error('Decryption error', E_USER_NOTICE); + $this->_handle_error('Decryption error'); return false; } @@ -2229,7 +2229,7 @@ class Crypt_RSA { $mHash = $this->hash->hash($m); if ($emLen < $this->hLen + $sLen + 2) { - user_error('Encoding error', E_USER_NOTICE); + $this->_handle_error('Encoding error'); return false; } @@ -2334,7 +2334,7 @@ class Crypt_RSA { // Length checking if (strlen($s) != $this->k) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } @@ -2345,12 +2345,12 @@ class Crypt_RSA { $s2 = $this->_os2ip($s); $m2 = $this->_rsavp1($s2); if ($m2 === false) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } $em = $this->_i2osp($m2, $modBits >> 3); if ($em === false) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } @@ -2400,7 +2400,7 @@ class Crypt_RSA { $tLen = strlen($t); if ($emLen < $tLen + 11) { - user_error('Intended encoded message length too short', E_USER_NOTICE); + $this->_handle_error('Intended encoded message length too short'); return false; } @@ -2426,7 +2426,7 @@ class Crypt_RSA { $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); if ($em === false) { - user_error('RSA modulus too short', E_USER_NOTICE); + $this->_handle_error('RSA modulus too short'); return false; } @@ -2455,7 +2455,7 @@ class Crypt_RSA { // Length checking if (strlen($s) != $this->k) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } @@ -2464,12 +2464,12 @@ class Crypt_RSA { $s = $this->_os2ip($s); $m2 = $this->_rsavp1($s); if ($m2 === false) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } $em = $this->_i2osp($m2, $this->k); if ($em === false) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return false; } @@ -2477,7 +2477,7 @@ class Crypt_RSA { $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); if ($em2 === false) { - user_error('RSA modulus too short', E_USER_NOTICE); + $this->_handle_error('RSA modulus too short'); return false; } @@ -2639,4 +2639,22 @@ class Crypt_RSA { return $this->_rsassa_pss_verify($message, $signature); } } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } \ No newline at end of file diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index e7f17a6f..71155c89 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -582,7 +582,7 @@ class Crypt_Rijndael { * * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}: - * $hash, $salt, $count + * $hash, $salt, $method * Set $dkLen by calling setKeyLength() * * @param String $password @@ -601,7 +601,7 @@ class Crypt_Rijndael { } // WPA and WPA use the SSID as the salt if (!isset($salt)) { - $salt = 'phpseclib/salt'; + $salt = 'phpseclib'; } // RFC2898#section-4.2 uses 1,000 iterations by default // WPA and WPA2 use 4,096. @@ -1365,7 +1365,7 @@ class Crypt_Rijndael { if ($length % $this->block_size == 0) { return $text; } else { - user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE); + $this->_handle_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); $this->padding = true; } } @@ -1472,7 +1472,25 @@ class Crypt_Rijndael { $string = substr($string, $index); return $substr; } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + user_error($err_msg); + } + } } // vim: ts=4:sw=4:et: -// vim6: fdl=1: +// vim6: fdl=1: \ No newline at end of file diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php index 29ad949e..b601e222 100644 --- a/phpseclib/File/ANSI.php +++ b/phpseclib/File/ANSI.php @@ -409,7 +409,7 @@ class File_ANSI { case 47: $back = 'white'; break; default: - user_error('Unsupported attribute: ' . $mod); + $this->_handle_error('Unsupported attribute: ' . $mod); $this->ansi = ''; break 2; } @@ -537,4 +537,22 @@ class File_ANSI { return '
' . $scrollback . '
'; } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 0ed044fd..dcc8da45 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -955,7 +955,7 @@ class File_ASN1 { case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); if ($oid === false) { - user_error('Invalid OID', E_USER_NOTICE); + $this->_handle_error('Invalid OID'); return false; } $value = ''; @@ -1008,7 +1008,7 @@ class File_ASN1 { $filters = $filters[$part]; } if ($filters === false) { - user_error('No filters defined for ' . implode('/', $loc), E_USER_NOTICE); + $this->_handle_error('No filters defined for ' . implode('/', $loc)); return false; } return $this->_encode_der($source, $filters + $mapping); @@ -1032,7 +1032,7 @@ class File_ASN1 { $value = $source ? "\xFF" : "\x00"; break; default: - user_error('Mapping provides no type definition for ' . implode('/', $this->location), E_USER_NOTICE); + $this->_handle_error('Mapping provides no type definition for ' . implode('/', $this->location)); return false; } @@ -1270,4 +1270,22 @@ class File_ASN1 { } return $out; } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 2f0ce3c1..7e1e6b8d 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1569,7 +1569,7 @@ class File_X509 { $map = $this->_getMapping($id); if (is_bool($map)) { if (!$map) { - user_error($id . ' is not a currently supported extension', E_USER_NOTICE); + $this->_handle_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { @@ -3839,4 +3839,22 @@ class File_X509 { return false; } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index fc2bf2e9..3fb149df 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -399,7 +399,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_VERSION) { - user_error('Expected SSH_FXP_VERSION', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_VERSION'); return false; } @@ -588,7 +588,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); return false; } @@ -645,7 +645,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); return false; } @@ -655,7 +655,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -731,7 +731,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); return false; } @@ -780,7 +780,7 @@ class Net_SFTP extends Net_SSH2 { } break 2; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); return false; } } @@ -793,7 +793,7 @@ class Net_SFTP extends Net_SSH2 { // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -996,7 +996,7 @@ class Net_SFTP extends Net_SSH2 { return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); return false; } @@ -1089,7 +1089,7 @@ class Net_SFTP extends Net_SSH2 { */ $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1116,7 +1116,7 @@ class Net_SFTP extends Net_SSH2 { return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); return false; } @@ -1249,7 +1249,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1288,7 +1288,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1365,7 +1365,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); return false; } @@ -1374,7 +1374,7 @@ class Net_SFTP extends Net_SSH2 { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 if ($mode & NET_SFTP_LOCAL_FILE) { if (!is_file($data)) { - user_error("$data is not a valid file", E_USER_NOTICE); + $this->_handle_error("$data is not a valid file"); return false; } $fp = @fopen($data, 'rb'); @@ -1425,7 +1425,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1453,7 +1453,7 @@ class Net_SFTP extends Net_SSH2 { while ($i--) { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1504,7 +1504,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); return false; } @@ -1542,7 +1542,7 @@ class Net_SFTP extends Net_SSH2 { $this->_logError($response); break 2; default: - user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS'); if ($local_file !== false) { fclose($fp); } @@ -1560,7 +1560,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1604,7 +1604,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } @@ -1723,7 +1723,7 @@ class Net_SFTP extends Net_SSH2 { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_FXP_STATUS'); return false; } diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index 67e09652..b6a5e652 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -467,7 +467,7 @@ class Net_SSH1 { $this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout); if (!$this->fsock) { - user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE); + $this->_handle_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); return; } @@ -484,11 +484,11 @@ class Net_SSH1 { } if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) { - user_error('Can only connect to SSH servers', E_USER_NOTICE); + $this->_handle_error('Can only connect to SSH servers'); return; } if ($parts[1][0] != 1) { - user_error("Cannot connect to SSH $parts[1] servers", E_USER_NOTICE); + $this->_handle_error("Cannot connect to SSH $parts[1] servers"); return; } @@ -496,7 +496,7 @@ class Net_SSH1 { $response = $this->_get_binary_packet(); if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) { - user_error('Expected SSH_SMSG_PUBLIC_KEY', E_USER_NOTICE); + $this->_handle_error('Expected SSH_SMSG_PUBLIC_KEY'); return; } @@ -584,7 +584,7 @@ class Net_SSH1 { $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_SESSION_KEY', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_SESSION_KEY'); return; } @@ -614,7 +614,7 @@ class Net_SSH1 { $response = $this->_get_binary_packet(); if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { - user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_SMSG_SUCCESS'); return; } @@ -638,7 +638,7 @@ class Net_SSH1 { $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_USER', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_USER'); return false; } @@ -648,14 +648,14 @@ class Net_SSH1 { $this->bitmap |= NET_SSH1_MASK_LOGIN; return true; } else if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) { - user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE); + $this->_handle_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); return false; } $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_AUTH_PASSWORD', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_AUTH_PASSWORD'); return false; } @@ -673,7 +673,7 @@ class Net_SSH1 { } else if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) { return false; } else { - user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE); + $this->_handle_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); return false; } } @@ -701,14 +701,14 @@ class Net_SSH1 { function exec($cmd, $block = true) { if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_EXEC_CMD', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_EXEC_CMD'); return false; } @@ -753,21 +753,21 @@ class Net_SSH1 { $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_REQUEST_PTY', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_REQUEST_PTY'); return false; } $response = $this->_get_binary_packet(); if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { - user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_SMSG_SUCCESS'); return false; } $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_EXEC_SHELL', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_EXEC_SHELL'); return false; } @@ -806,12 +806,12 @@ class Net_SSH1 { function read($expect, $mode = NET_SSH1_READ_SIMPLE) { if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session', E_USER_NOTICE); + $this->_handle_error('Unable to initiate an interactive shell session'); return false; } @@ -841,19 +841,19 @@ class Net_SSH1 { function interactiveWrite($cmd) { if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session', E_USER_NOTICE); + $this->_handle_error('Unable to initiate an interactive shell session'); return false; } $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd); if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_STDIN', E_USER_NOTICE); + $this->_handle_error('Error sending SSH_CMSG_STDIN'); return false; } @@ -876,12 +876,12 @@ class Net_SSH1 { function interactiveRead() { if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session', E_USER_NOTICE); + $this->_handle_error('Unable to initiate an interactive shell session'); return false; } @@ -960,7 +960,7 @@ class Net_SSH1 { function _get_binary_packet() { if (feof($this->fsock)) { - //user_error('connection closed prematurely', E_USER_NOTICE); + //$this->_handle_error('connection closed prematurely'); return false; } @@ -984,7 +984,7 @@ class Net_SSH1 { $temp = unpack('Ncrc', substr($raw, -4)); //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) { - // user_error('Bad CRC in packet from server', E_USER_NOTICE); + // $this->_handle_error('Bad CRC in packet from server'); // return false; //} @@ -1017,7 +1017,7 @@ class Net_SSH1 { */ function _send_binary_packet($data) { if (feof($this->fsock)) { - //user_error('connection closed prematurely', E_USER_NOTICE); + //$this->_handle_error('connection closed prematurely'); return false; } @@ -1418,4 +1418,22 @@ class Net_SSH1 { { return rtrim($this->server_identification); } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 29a8f0f4..7ca86f43 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -793,7 +793,7 @@ class Net_SSH2 { $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 $this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout); if (!$this->fsock) { - user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE); + $this->_handle_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); return; } $elapsed = strtok(microtime(), ' ') + strtok('') - $start; @@ -801,7 +801,7 @@ class Net_SSH2 { $timeout-= $elapsed; if ($timeout <= 0) { - user_error(rtrim("Cannot connect to $host. Timeout error"), E_USER_NOTICE); + $this->_handle_error(rtrim("Cannot connect to $host. Timeout error")); return; } @@ -814,7 +814,7 @@ class Net_SSH2 { // on windows this returns a "Warning: Invalid CRT parameters detected" error // the !count() is done as a workaround for if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { - user_error(rtrim("Cannot connect to $host. Banner timeout"), E_USER_NOTICE); + $this->_handle_error(rtrim("Cannot connect to $host. Banner timeout")); return; } @@ -836,7 +836,7 @@ class Net_SSH2 { } if (feof($this->fsock)) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -870,7 +870,7 @@ class Net_SSH2 { } if ($matches[1] != '1.99' && $matches[1] != '2.0') { - user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE); + $this->_handle_error("Cannot connect to SSH $matches[1] servers"); return; } @@ -878,12 +878,12 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return; } if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) { - user_error('Expected SSH_MSG_KEXINIT', E_USER_NOTICE); + $this->_handle_error('Expected SSH_MSG_KEXINIT'); return; } @@ -1028,7 +1028,7 @@ class Net_SSH2 { // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++); if ($i == count($encryption_algorithms)) { - user_error('No compatible server to client encryption algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible server to client encryption algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1065,7 +1065,7 @@ class Net_SSH2 { for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++); if ($i == count($encryption_algorithms)) { - user_error('No compatible client to server encryption algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible client to server encryption algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1103,7 +1103,7 @@ class Net_SSH2 { // through diffie-hellman key exchange a symmetric key is obtained for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++); if ($i == count($kex_algorithms)) { - user_error('No compatible key exchange algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible key exchange algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1156,19 +1156,19 @@ class Net_SSH2 { $data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes); if (!$this->_send_binary_packet($data)) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_KEXDH_REPLY) { - user_error('Expected SSH_MSG_KEXDH_REPLY', E_USER_NOTICE); + $this->_handle_error('Expected SSH_MSG_KEXDH_REPLY'); return false; } @@ -1206,12 +1206,12 @@ class Net_SSH2 { for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++); if ($i == count($server_host_key_algorithms)) { - user_error('No compatible server host key algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible server host key algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) { - user_error('Sever Host Key Algorithm Mismatch', E_USER_NOTICE); + $this->_handle_error('Sever Host Key Algorithm Mismatch'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1226,14 +1226,14 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_NEWKEYS) { - user_error('Expected SSH_MSG_NEWKEYS', E_USER_NOTICE); + $this->_handle_error('Expected SSH_MSG_NEWKEYS'); return false; } @@ -1347,7 +1347,7 @@ class Net_SSH2 { for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++); if ($i == count($mac_algorithms)) { - user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible client to server message authentication algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1372,7 +1372,7 @@ class Net_SSH2 { for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++); if ($i == count($mac_algorithms)) { - user_error('No compatible server to client message authentication algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible server to client message authentication algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -1414,14 +1414,14 @@ class Net_SSH2 { for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++); if ($i == count($compression_algorithms)) { - user_error('No compatible server to client compression algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible server to client compression algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } $this->decompress = $compression_algorithms[$i] == 'zlib'; for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++); if ($i == count($compression_algorithms)) { - user_error('No compatible client to server compression algorithms found', E_USER_NOTICE); + $this->_handle_error('No compatible client to server compression algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } $this->compress = $compression_algorithms[$i] == 'zlib'; @@ -1457,14 +1457,14 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) { - user_error('Expected SSH_MSG_SERVICE_ACCEPT', E_USER_NOTICE); + $this->_handle_error('Expected SSH_MSG_SERVICE_ACCEPT'); return false; } @@ -1485,7 +1485,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1521,7 +1521,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1593,7 +1593,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1706,7 +1706,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1741,7 +1741,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1894,7 +1894,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -1905,7 +1905,7 @@ class Net_SSH2 { break; case NET_SSH2_MSG_CHANNEL_FAILURE: default: - user_error('Unable to request pseudo-terminal', E_USER_NOTICE); + $this->_handle_error('Unable to request pseudo-terminal'); return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } @@ -1946,12 +1946,12 @@ class Net_SSH2 { $this->curTimeout = $this->timeout; if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session', E_USER_NOTICE); + $this->_handle_error('Unable to initiate an interactive shell session'); return false; } @@ -1985,12 +1985,12 @@ class Net_SSH2 { function write($cmd) { if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { - user_error('Operation disallowed prior to login()', E_USER_NOTICE); + $this->_handle_error('Operation disallowed prior to login()'); return false; } if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session', E_USER_NOTICE); + $this->_handle_error('Unable to initiate an interactive shell session'); return false; } @@ -2035,7 +2035,7 @@ class Net_SSH2 { function _get_binary_packet() { if (!is_resource($this->fsock) || feof($this->fsock)) { - user_error('Connection closed prematurely', E_USER_NOTICE); + $this->_handle_error('Connection closed prematurely'); $this->bitmask = 0; return false; } @@ -2052,7 +2052,7 @@ class Net_SSH2 { $raw = $this->decrypt->decrypt($raw); } if ($raw === false) { - user_error('Unable to decrypt content', E_USER_NOTICE); + $this->_handle_error('Unable to decrypt content'); return false; } @@ -2076,7 +2076,7 @@ class Net_SSH2 { if ($this->hmac_check !== false) { $hmac = fread($this->fsock, $this->hmac_size); if ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) { - user_error('Invalid HMAC', E_USER_NOTICE); + $this->_handle_error('Invalid HMAC'); return false; } } @@ -2243,7 +2243,7 @@ class Net_SSH2 { $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server', E_USER_NOTICE); + $this->_handle_error('Connection closed by server'); return false; } @@ -2265,7 +2265,7 @@ class Net_SSH2 { return $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended); //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: default: - user_error('Unable to open channel', E_USER_NOTICE); + $this->_handle_error('Unable to open channel'); return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } break; @@ -2275,7 +2275,7 @@ class Net_SSH2 { return true; //case NET_SSH2_MSG_CHANNEL_FAILURE: default: - user_error('Unable to request pseudo-terminal', E_USER_NOTICE); + $this->_handle_error('Unable to request pseudo-terminal'); return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } case NET_SSH2_MSG_CHANNEL_CLOSE: @@ -2364,7 +2364,7 @@ class Net_SSH2 { case NET_SSH2_MSG_CHANNEL_EOF: break; default: - user_error('Error reading channel data', E_USER_NOTICE); + $this->_handle_error('Error reading channel data'); return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } } @@ -2383,7 +2383,7 @@ class Net_SSH2 { function _send_binary_packet($data) { if (!is_resource($this->fsock) || feof($this->fsock)) { - user_error('Connection closed prematurely', E_USER_NOTICE); + $this->_handle_error('Connection closed prematurely'); $this->bitmask = 0; return false; } @@ -2894,7 +2894,7 @@ class Net_SSH2 { padding, unsigned, and in network byte order). */ $temp = unpack('Nlength', $this->_string_shift($signature, 4)); if ($temp['length'] != 40) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -2902,7 +2902,7 @@ class Net_SSH2 { $s = new Math_BigInteger($this->_string_shift($signature, 20), 256); if ($r->compare($q) >= 0 || $s->compare($q) >= 0) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -2922,7 +2922,7 @@ class Net_SSH2 { list(, $v) = $v->divide($q); if (!$v->equals($r)) { - user_error('Bad server signature', E_USER_NOTICE); + $this->_handle_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } @@ -2947,7 +2947,7 @@ class Net_SSH2 { $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW); if (!$rsa->verify($this->exchange_hash, $signature)) { - user_error('Bad server signature', E_USER_NOTICE); + $this->_handle_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } */ @@ -2962,7 +2962,7 @@ class Net_SSH2 { // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source. if ($s->compare(new Math_BigInteger()) < 0 || $s->compare($n->subtract(new Math_BigInteger(1))) > 0) { - user_error('Invalid signature', E_USER_NOTICE); + $this->_handle_error('Invalid signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } @@ -2973,15 +2973,33 @@ class Net_SSH2 { $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h; if ($s != $h) { - user_error('Bad server signature', E_USER_NOTICE); + $this->_handle_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } break; default: - user_error('Unsupported signature format', E_USER_NOTICE); + $this->_handle_error('Unsupported signature format'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } return $this->signature_format . ' ' . base64_encode($this->server_public_host_key); } + + /** + * Error Handler + * + * Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined. + * Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions. + * + * @param String $string + * @access private + */ + function _handle_error($err_msg) { + if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) { + $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; + throw(new $class($err_msg)); + } else { + $this->_handle_error($err_msg); + } + } } \ No newline at end of file From 3c6ae4312fecc4ce8558cefd302c73173ae3fde0 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 29 Nov 2012 00:19:09 -0600 Subject: [PATCH 24/26] The user_error in _handle_error shouldn't be replaced.. --- phpseclib/Crypt/RSA.php | 2 +- phpseclib/File/ANSI.php | 2 +- phpseclib/File/ASN1.php | 2 +- phpseclib/File/X509.php | 2 +- phpseclib/Net/SSH1.php | 2 +- phpseclib/Net/SSH2.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index df090857..7b921ac1 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -2654,7 +2654,7 @@ class Crypt_RSA { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } \ No newline at end of file diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php index b601e222..4f500f9b 100644 --- a/phpseclib/File/ANSI.php +++ b/phpseclib/File/ANSI.php @@ -552,7 +552,7 @@ class File_ANSI { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index dcc8da45..241048b2 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -1285,7 +1285,7 @@ class File_ASN1 { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 7e1e6b8d..b4361bad 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -3854,7 +3854,7 @@ class File_X509 { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index b6a5e652..6b1f504e 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -1433,7 +1433,7 @@ class Net_SSH1 { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 7ca86f43..bdee4222 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2999,7 +2999,7 @@ class Net_SSH2 { $class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception'; throw(new $class($err_msg)); } else { - $this->_handle_error($err_msg); + user_error($err_msg); } } } \ No newline at end of file From d130d2274dd28a0c427a690671eab69d122b5c5e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 30 Nov 2012 08:31:16 -0600 Subject: [PATCH 25/26] Make the save*() functions save in multiple formats Currently only PEM and DER supported. Also make fuzzing enhancements --- phpseclib/File/X509.php | 92 +++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index b4361bad..eca1ef24 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -66,7 +66,7 @@ define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1); /** * Return internal array representation */ -define('FILE_X509_DN_ARRAY', 0); // Internal array representation. +define('FILE_X509_DN_ARRAY', 0); /** * Return string */ @@ -89,11 +89,35 @@ define('FILE_X509_DN_CANON', 4); define('FILE_X509_DN_HASH', 5); /**#@-*/ +/**#@+ + * @access public + * @see File_X509::saveX509() + * @see File_X509::saveCSR() + * @see File_X509::saveCRL() + */ +/** + * Save as PEM + * + * ie. a base64-encoded PEM with a header and a footer + */ +define('FILE_X509_FORMAT_PEM', 0); +/** + * Save as DER + */ +define('FILE_X509_FORMAT_DER', 1); +/** + * Save as a SPKAC + * + * Only works on CSRs. Not currently supported. + */ +define('FILE_X509_FORMAT_SPKAC', 2); +/**#@-*/ + /** * Pure-PHP X.509 Parser * * @author Jim Wigginton - * @version 0.3.0 + * @version 0.3.1 * @access public * @package File_X509 */ @@ -1419,21 +1443,27 @@ class File_X509 { * Save X.509 certificate * * @param Array $cert + * @param Integer $format optional * @access public * @return String */ - function saveX509($cert) + function saveX509($cert, $format = FILE_X509_FORMAT_PEM) { if (!is_array($cert) || !isset($cert['tbsCertificate'])) { return false; } - if (is_array($cert['tbsCertificate']['subjectPublicKeyInfo'])) { - switch ($cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm']) { - case 'rsaEncryption': - $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = - base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); - } + switch (true) { + // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" + case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): + case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): + break; + default: + switch ($algorithm) { + case 'rsaEncryption': + $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = + base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); + } } $asn1 = new File_ASN1(); @@ -1465,7 +1495,13 @@ class File_X509 { $cert = $asn1->encodeDER($cert, $this->Certificate); - return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert)) . '-----END CERTIFICATE-----'; + switch ($format) { + case FILE_X509_FORMAT_DER: + return $cert; + // case FILE_X509_FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert)) . '-----END CERTIFICATE-----'; + } } /** @@ -2677,19 +2713,26 @@ class File_X509 { * Save CSR request * * @param Array $csr + * @param Integer $format optional * @access public * @return String */ - function saveCSR($csr) + function saveCSR($csr, $format = FILE_X509_FORMAT_PEM) { if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { return false; } - switch ($csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm']) { - case 'rsaEncryption': - $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = - base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); + switch (true) { + case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): + case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']); + break; + default: + switch ($algorithm) { + case 'rsaEncryption': + $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = + base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); + } } $asn1 = new File_ASN1(); @@ -2704,7 +2747,13 @@ class File_X509 { $csr = $asn1->encodeDER($csr, $this->CertificationRequest); - return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr)) . '-----END CERTIFICATE REQUEST-----'; + switch ($format) { + case FILE_X509_FORMAT_DER: + return $csr; + // case FILE_X509_FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr)) . '-----END CERTIFICATE REQUEST-----'; + } } /** @@ -2770,10 +2819,11 @@ class File_X509 { * Save Certificate Revocation List. * * @param Array $crl + * @param Integer $format optional * @access public * @return String */ - function saveCRL($crl) + function saveCRL($crl, $format = FILE_X509_FORMAT_PEM) { if (!is_array($crl) || !isset($crl['tbsCertList'])) { return false; @@ -2811,7 +2861,13 @@ class File_X509 { $crl = $asn1->encodeDER($crl, $this->CertificateList); - return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl)) . '-----END X509 CRL-----'; + switch ($format) { + case FILE_X509_FORMAT_DER: + return $crl; + // case FILE_X509_FORMAT_PEM: + default: + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl)) . '-----END X509 CRL-----'; + } } /** From 27f6012d623997b1fb2b37c4be98023326d44cfd Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 1 Dec 2012 10:52:10 -0600 Subject: [PATCH 26/26] Make it so extension OIDs can be File_ASN1_Elements --- phpseclib/File/X509.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index eca1ef24..82574ac9 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1625,6 +1625,10 @@ class File_X509 { */ function _getMapping($extnId) { + if (!is_string($extnId)) { // eg. if it's a File_ASN1_Element object + return true; + } + switch ($extnId) { case 'id-ce-keyUsage': return $this->KeyUsage;