Exception
6 years ago
WebAuthException
6 years ago
certs
6 years ago
AppInfo.php
6 years ago
AppInfoLoadException.php
6 years ago
ArrayEntryStore.php
6 years ago
AuthBase.php
6 years ago
AuthInfo.php
6 years ago
AuthInfoLoadException.php
6 years ago
Checker.php
6 years ago
Client.php
6 years ago
Curl.php
6 years ago
CurlStreamRelay.php
6 years ago
DeserializeException.php
6 years ago
DropboxMetadataHeaderCatcher.php
6 years ago
Exception.php
6 years ago
Host.php
6 years ago
HttpResponse.php
6 years ago
OAuth1AccessToken.php
6 years ago
OAuth1Upgrader.php
6 years ago
Path.php
6 years ago
RequestUtil.php
6 years ago
RootCertificates.php
6 years ago
SSLTester.php
6 years ago
Security.php
6 years ago
StreamReadException.php
6 years ago
Util.php
6 years ago
ValueStore.php
6 years ago
WebAuth.php
6 years ago
WebAuthBase.php
6 years ago
WebAuthNoRedirect.php
6 years ago
WriteMode.php
6 years ago
autoload.php
6 years ago
strict.php
6 years ago
SSLTester.php
129 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Dropbox; |
| 4 | |
| 5 | /** |
| 6 | * Call the <code>test()</code> method. |
| 7 | */ |
| 8 | class SSLTester |
| 9 | { |
| 10 | /** |
| 11 | * Peforms a few basic tests of your PHP installation's SSL implementation to see |
| 12 | * if it insecure in an obvious way. Results are written with "echo" and the output |
| 13 | * is HTML-safe. |
| 14 | * |
| 15 | * @return bool |
| 16 | * Returns <code>true</code> if all the tests passed. |
| 17 | */ |
| 18 | static function test() |
| 19 | { |
| 20 | $hostOs = php_uname('s').' '.php_uname('r'); |
| 21 | $phpVersion = phpversion(); |
| 22 | $curlVersionInfo = \curl_version(); |
| 23 | $curlVersion = $curlVersionInfo['version']; |
| 24 | $curlSslBackend = $curlVersionInfo['ssl_version']; |
| 25 | |
| 26 | echo "-----------------------------------------------------------------------------\n"; |
| 27 | echo "Testing your PHP installation's SSL implementation for a few obvious problems...\n"; |
| 28 | echo "-----------------------------------------------------------------------------\n"; |
| 29 | echo "- Host OS: $hostOs\n"; |
| 30 | echo "- PHP version: $phpVersion\n"; |
| 31 | echo "- cURL version: $curlVersion\n"; |
| 32 | echo "- cURL SSL backend: $curlSslBackend\n"; |
| 33 | |
| 34 | echo "Basic SSL tests\n"; |
| 35 | $basicFailures = self::testMulti(array( |
| 36 | array("www.dropbox.com", 'testAllowed'), |
| 37 | array("www.digicert.com", 'testAllowed'), |
| 38 | array("www.v.dropbox.com", 'testHostnameMismatch'), |
| 39 | array("testssl-expire.disig.sk", 'testUntrustedCert'), |
| 40 | )); |
| 41 | |
| 42 | echo "Pinned certificate tests\n"; |
| 43 | $pinnedCertFailures = self::testMulti(array( |
| 44 | array("www.verisign.com", 'testUntrustedCert'), |
| 45 | array("www.globalsign.fr", 'testUntrustedCert'), |
| 46 | )); |
| 47 | |
| 48 | if ($basicFailures) { |
| 49 | echo "-----------------------------------------------------------------------------\n"; |
| 50 | echo "WARNING: Your PHP installation's SSL support is COMPLETELY INSECURE.\n"; |
| 51 | echo "Your app's communication with the Dropbox API servers can be viewed and\n"; |
| 52 | echo "manipulated by others. Try upgrading your version of PHP.\n"; |
| 53 | echo "-----------------------------------------------------------------------------\n"; |
| 54 | return false; |
| 55 | } |
| 56 | else if ($pinnedCertFailures) { |
| 57 | echo "-----------------------------------------------------------------------------\n"; |
| 58 | echo "WARNING: Your PHP installation's cURL module doesn't support SSL certificate\n"; |
| 59 | echo "pinning, which is an important security feature of the Dropbox SDK.\n"; |
| 60 | echo "\n"; |
| 61 | echo "This SDK uses CURLOPT_CAINFO and CURLOPT_CAPATH to tell PHP cURL to only trust\n"; |
| 62 | echo "our custom certificate list. But your PHP installation's cURL module seems to\n"; |
| 63 | echo "trust certificates that aren't on that list.\n"; |
| 64 | echo "\n"; |
| 65 | echo "More information on SSL certificate pinning:\n"; |
| 66 | echo "https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#What_Is_Pinning.3F\n"; |
| 67 | echo "-----------------------------------------------------------------------------\n"; |
| 68 | return false; |
| 69 | } |
| 70 | else { |
| 71 | return true; |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | private static function testMulti($tests) |
| 76 | { |
| 77 | $anyFailed = false; |
| 78 | foreach ($tests as $test) { |
| 79 | list($host, $testType) = $test; |
| 80 | |
| 81 | echo " - ".str_pad("$testType ($host) ", 50, "."); |
| 82 | $url = "https://$host/"; |
| 83 | $passed = self::$testType($url); |
| 84 | if ($passed) { |
| 85 | echo " ok\n"; |
| 86 | } else { |
| 87 | echo " FAILED\n"; |
| 88 | $anyFailed = true; |
| 89 | } |
| 90 | } |
| 91 | return $anyFailed; |
| 92 | } |
| 93 | |
| 94 | private static function testAllowed($url) |
| 95 | { |
| 96 | $curl = RequestUtil::mkCurl("test-ssl", $url); |
| 97 | $curl->set(CURLOPT_RETURNTRANSFER, true); |
| 98 | $curl->exec(); |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | private static function testUntrustedCert($url) |
| 103 | { |
| 104 | return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem, verify that the CA cert is OK'); |
| 105 | } |
| 106 | |
| 107 | private static function testHostnameMismatch($url) |
| 108 | { |
| 109 | return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem: Invalid certificate chain'); |
| 110 | } |
| 111 | |
| 112 | private static function testDisallowed($url, $expectedExceptionMessage) |
| 113 | { |
| 114 | $curl = RequestUtil::mkCurl("test-ssl", $url); |
| 115 | $curl->set(CURLOPT_RETURNTRANSFER, true); |
| 116 | try { |
| 117 | $curl->exec(); |
| 118 | } |
| 119 | catch (Exception_NetworkIO $ex) { |
| 120 | if (strpos($ex->getMessage(), $expectedExceptionMessage) == 0) { |
| 121 | return true; |
| 122 | } else { |
| 123 | throw $ex; |
| 124 | } |
| 125 | } |
| 126 | return false; |
| 127 | } |
| 128 | } |
| 129 |