summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG.md7
-rw-r--r--README.md1
-rw-r--r--css/ssl.css6
-rw-r--r--functions/connection.php979
-rw-r--r--functions/json.php61
-rw-r--r--functions/ocsp.php69
-rw-r--r--functions/parse_certificate.php1295
-rw-r--r--functions/textual.php16
-rw-r--r--functions/variables.php2
-rw-r--r--inc/footer.php75
-rw-r--r--inc/form.php56
-rw-r--r--index.php426
-rw-r--r--json.php56
14 files changed, 1365 insertions, 1685 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..484ab7e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+results/*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b86ce19..20bc282 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,13 +2,14 @@
## 2.1
-- Add json API endpoint (see README)
-- Rewrote internals to use same endpoint
+- Add json API endpoint (see README).
+- Rewrote internals to use same endpoint.
+- Add warnings for connection and certificate issues.
- Don't follow redirects during HTTP header gathering.
## 2.0
-- Add TLS_FALLBACK_SCSV check
+- Add TLS_FALLBACK_SCSV check.
- Lower some timeouts from 5 to 2.
## 1.9
diff --git a/README.md b/README.md
index 68062e1..0299492 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ Simple PHP script which decodes an SSL connection and/or certificate and display
- Issuer validation
- Date validation
- JSON API
+- Warnings for bad connection settings or certificate options
### Requirements
diff --git a/css/ssl.css b/css/ssl.css
index afb8586..f8d7bce 100644
--- a/css/ssl.css
+++ b/css/ssl.css
@@ -49,6 +49,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
border-right-style: solid;
border-right-width: 1px;
border-right-color: #ddd;
+ border-top-style: solid;
+ border-top-width: 1px;
+ border-top-color: #ddd;
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ border-bottom-color: #ddd;
height: 100%;
overflow-y: auto;
z-index: 1000;
diff --git a/functions/connection.php b/functions/connection.php
index 3cd4fc4..a1e718e 100644
--- a/functions/connection.php
+++ b/functions/connection.php
@@ -49,591 +49,367 @@ function server_http_headers($host, $port){
}
function ssl_conn_ciphersuites($host, $port, $ciphersuites){
- $old_error_reporting = error_reporting();
- error_reporting($old_error_reporting ^ E_WARNING);
- $results = array();
- foreach ($ciphersuites as $value) {
- $results[$value] = false;
- $stream = stream_context_create (array("ssl" =>
- array("verify_peer" => false,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- 'ciphers' => $value,
- "sni_enabled" => true)));
- $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
- if ( $read_stream === false ) {
- $results[$value] = false;
- } else {
- $results[$value] = true;
- }
- }
- error_reporting($old_error_reporting);
- return $results;
- }
-
- function ssl_conn_protocols($host, $port){
- $old_error_reporting = error_reporting();
- error_reporting($old_error_reporting ^ E_WARNING);
- $results = array('sslv3' => false,
- 'tlsv1.0' => false,
- 'tlsv1.1' => false,
- 'tlsv1.2' => false);
-
- $stream_sslv3 = stream_context_create (array("ssl" =>
- array("verify_peer" => false,
- "capture_session_meta" => true,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- 'crypto_method' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
- "sni_enabled" => true)));
- $read_stream_sslv3 = stream_socket_client("sslv3://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_sslv3);
- if ( $read_stream_sslv3 === false ) {
- $results['sslv3'] = false;
- } else {
- $results['sslv3'] = true;
- }
-
- $stream_tlsv10 = stream_context_create (array("ssl" =>
- array("verify_peer" => false,
- "capture_session_meta" => true,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_0_CLIENT,
- "sni_enabled" => true)));
- $read_stream_tlsv10 = stream_socket_client("tlsv1.0://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv10);
- if ( $read_stream_tlsv10 === false ) {
- $results['tlsv1.0'] = false;
- } else {
- $results['tlsv1.0'] = true;
- }
-
- $stream_tlsv11 = stream_context_create (array("ssl" =>
- array("verify_peer" => false,
- "capture_session_meta" => true,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_1_CLIENT,
- "sni_enabled" => true)));
- $read_stream_tlsv11 = stream_socket_client("tlsv1.1://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv11);
- if ( $read_stream_tlsv11 === false ) {
- $results['tlsv1.1'] = false;
- } else {
- $results['tlsv1.1'] = true;
- }
-
- $stream_tlsv12 = stream_context_create (array("ssl" =>
- array("verify_peer" => false,
- "capture_session_meta" => true,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_2_CLIENT,
- "sni_enabled" => true)));
- $read_stream_tlsv12 = stream_socket_client("tlsv1.2://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv12);
- if ( $read_stream_tlsv12 === false ) {
- $results['tlsv1.2'] = false;
- } else {
- $results['tlsv1.2'] = true;
- }
- error_reporting($old_error_reporting);
- return $results;
- }
+ $old_error_reporting = error_reporting();
+ error_reporting($old_error_reporting ^ E_WARNING);
+ $results = array();
+ foreach ($ciphersuites as $value) {
+ $results[$value] = false;
+ $stream = stream_context_create (array("ssl" =>
+ array("verify_peer" => false,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ 'ciphers' => $value,
+ "sni_enabled" => true)));
+ $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
+ if ( $read_stream === false ) {
+ $results[$value] = false;
+ } else {
+ $results[$value] = true;
+ }
+ }
+ error_reporting($old_error_reporting);
+ return $results;
+}
+function ssl_conn_protocols($host, $port){
+ $old_error_reporting = error_reporting();
+ error_reporting($old_error_reporting ^ E_WARNING);
+ $results = array('sslv3' => false,
+ 'tlsv1.0' => false,
+ 'tlsv1.1' => false,
+ 'tlsv1.2' => false);
-function ssl_conn_metadata($host, $port, $chain=null) {
- global $random_blurp;
- global $current_folder;
- $stream = stream_context_create (array("ssl" =>
+ $stream_sslv3 = stream_context_create (array("ssl" =>
array("verify_peer" => false,
"capture_session_meta" => true,
"verify_peer_name" => false,
"allow_self_signed" => true,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
"sni_enabled" => true)));
- $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
- if ( $read_stream === false ) {
- return false;
+ $read_stream_sslv3 = stream_socket_client("sslv3://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_sslv3);
+ if ( $read_stream_sslv3 === false ) {
+ $results['sslv3'] = false;
} else {
- $context = stream_context_get_params($read_stream);
- $context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
- $cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"])[0];
-
- if ($context_meta) {
- ?>
- <section id="conndata">
- <h3>Connection Data</h3>
- <table class="table table-striped table-bordered">
- <tbody>
- <tr>
- <td colspan="2"><strong>Connection Data</strong></td>
- </tr>
- <?php
- if ( $chain ) {
- ?>
- <tr>
- <td>Chain sent by Server (in server order)</td>
- <td style="font-family: monospace;">
- <?php
- $chain_length = count($chain);
- $certificate_chain = array();
- if ($chain_length <= 10) {
- for ($i = 0; $i < $chain_length; $i++) {
- if (openssl_x509_parse($chain[$i])['issuer']['CN'] && openssl_x509_parse($chain[$i])['subject']['CN']) {
- echo "Name...........: <i>";
- echo htmlspecialchars(openssl_x509_parse($chain[$i])['subject']['CN']);
- echo " </i><br>Issued by......:<i> ";
- echo htmlspecialchars(openssl_x509_parse($chain[$i])['issuer']['CN']);
- echo "</i><br>";
-
- $export_pem = "";
- openssl_x509_export($chain[$i], $export_pem);
- array_push($certificate_chain, $export_pem);
-
- if (openssl_x509_parse($chain[$i])['issuer']['CN'] == openssl_x509_parse($chain[$i + 1])['subject']['CN']){
- continue;
- } else {
- if ($i != $chain_length - 1) {
- echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>Error: Issuer does not match the next certificate CN. Chain order is probaby wrong.</span><br><br>";
- }
- }
- }
- }
- echo "<br>";
- } else {
- echo "<span class='text-danger'>Error: Certificate chain to large.</span><br>";
- }
-
- file_put_contents('/tmp/verify_cert.' . $random_blurp . '.pem', implode("\n", array_reverse($certificate_chain)).PHP_EOL , FILE_APPEND);
-
- $verify_output = 0;
- $verify_exit_code = 0;
- $verify_exec = exec(escapeshellcmd('openssl verify -verbose -purpose any -CAfile ' . getcwd() . '/cacert.pem /tmp/verify_cert.' . $random_blurp . '.pem') . "| grep -v OK", $verify_output, $verify_exit_code);
-
- if ($verify_exit_code != 1) {
- echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>Error: Validating certificate chain failed:</span><br>";
- echo "<pre>";
- echo str_replace('/tmp/verify_cert.' . $random_blurp . '.pem: ', '', implode("\n", $verify_output));
- echo "</pre>";
- } else {
- echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>Sucessfully validated certificate chain.</span><br>";
- }
+ $results['sslv3'] = true;
+ }
- unlink('/tmp/verify_cert.' . $random_blurp . '.pem');
+ $stream_tlsv10 = stream_context_create (array("ssl" =>
+ array("verify_peer" => false,
+ "capture_session_meta" => true,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_0_CLIENT,
+ "sni_enabled" => true)));
+ $read_stream_tlsv10 = stream_socket_client("tlsv1.0://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv10);
+ if ( $read_stream_tlsv10 === false ) {
+ $results['tlsv1.0'] = false;
+ } else {
+ $results['tlsv1.0'] = true;
+ }
- ?>
- </td>
- </tr>
+ $stream_tlsv11 = stream_context_create (array("ssl" =>
+ array("verify_peer" => false,
+ "capture_session_meta" => true,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_1_CLIENT,
+ "sni_enabled" => true)));
+ $read_stream_tlsv11 = stream_socket_client("tlsv1.1://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv11);
+ if ( $read_stream_tlsv11 === false ) {
+ $results['tlsv1.1'] = false;
+ } else {
+ $results['tlsv1.1'] = true;
+ }
- <?php
- }
- if ( fixed_gethostbyname($host) ) {
- ?>
- <tr>
- <td>IP / Hostname / Port</td>
- <td>
- <?php
- echo htmlspecialchars(fixed_gethostbyname($host));
- echo " - ";
- echo htmlspecialchars(gethostbyaddr(fixed_gethostbyname($host)));
- echo " - ";
- echo htmlspecialchars($port);
- ?>
- </td>
- </tr>
- <?php
- }
- ?>
- <tr>
- <td>Protocol</td>
- <td>
- <?php
- $protocols = ssl_conn_protocols($host, $port);
- foreach (array_reverse($protocols) as $key => $value) {
- if ( $value == true ) {
- if ( $key == "tlsv1.2") {
- echo '<p><span class="text-success glyphicon glyphicon-ok"></span> - <span class="text-success">TLSv1.2 (Supported)</span></p>';
- } else if ( $key == "tlsv1.1") {
- echo '<p><span class="glyphicon glyphicon-ok"></span> - TLSv1.1 (Supported)</p>';
- } else if ( $key == "tlsv1.0") {
- echo '<p><span class="glyphicon glyphicon-ok"></span> - TLSv1.0 (Supported)</p>';
- } else if ( $key == "sslv3") {
- echo '<p><span class="text-danger glyphicon glyphicon-ok"></span> - <span class="text-danger">SSLv3 (Supported)</span></p>';
- } else {
- echo '<p><span class="glyphicon glyphicon-ok"></span> - <span>'.$key.' (Supported)</span></p>';
- }
- } else {
- if ( $key == "tlsv1.2") {
- echo '<p><span class="text-danger glyphicon glyphicon-remove"></span> - <span class="text-danger">TLSv1.2 (Not supported)</span></p>';
- } else if ( $key == "tlsv1.1") {
- echo '<p><span class="glyphicon glyphicon-remove"></span> - TLSv1.1 (Not supported)</p>';
- } else if ( $key == "tlsv1.0") {
- echo '<p><span class="glyphicon glyphicon-remove"></span> - TLSv1.0 (Not supported)</p>';
- } else if ( $key == "sslv3") {
- echo '<p><span class="text-success glyphicon glyphicon-remove"></span> - <span class="text-success">SSLv3 (Not supported)</span></p>';
- } else {
- echo '<p><span class="glyphicon glyphicon-remove"></span> - <span>'.$key.'(Not supported)</span></p>';
- }
- }
- }
- ?>
+ $stream_tlsv12 = stream_context_create (array("ssl" =>
+ array("verify_peer" => false,
+ "capture_session_meta" => true,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv_1_2_CLIENT,
+ "sni_enabled" => true)));
+ $read_stream_tlsv12 = stream_socket_client("tlsv1.2://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream_tlsv12);
+ if ( $read_stream_tlsv12 === false ) {
+ $results['tlsv1.2'] = false;
+ } else {
+ $results['tlsv1.2'] = true;
+ }
+ error_reporting($old_error_reporting);
+ return $results;
+}
- </td>
- </tr>
- <?php
- if ($_GET['ciphersuites'] == 1) {
- ?>
- <tr>
- <td>Ciphersuites supported by server</td>
- <td>
- <?php
- $ciphersuites_to_test = array('ECDHE-RSA-AES256-GCM-SHA384',
- 'ECDHE-ECDSA-AES256-GCM-SHA384',
- 'ECDHE-RSA-AES256-SHA384',
- 'ECDHE-ECDSA-AES256-SHA384',
- 'ECDHE-RSA-AES256-SHA',
- 'ECDHE-ECDSA-AES256-SHA',
- 'SRP-DSS-AES-256-CBC-SHA',
- 'SRP-RSA-AES-256-CBC-SHA',
- 'SRP-AES-256-CBC-SHA',
- 'DH-DSS-AES256-GCM-SHA384',
- 'DHE-DSS-AES256-GCM-SHA384',
- 'DH-RSA-AES256-GCM-SHA384',
- 'DHE-RSA-AES256-GCM-SHA384',
- 'DHE-RSA-AES256-SHA256',
- 'DHE-DSS-AES256-SHA256',
- 'DH-RSA-AES256-SHA256',
- 'DH-DSS-AES256-SHA256',
- 'DHE-RSA-AES256-SHA',
- 'DHE-DSS-AES256-SHA',
- 'DH-RSA-AES256-SHA',
- 'DH-DSS-AES256-SHA',
- 'DHE-RSA-CAMELLIA256-SHA',
- 'DHE-DSS-CAMELLIA256-SHA',
- 'DH-RSA-CAMELLIA256-SHA',
- 'DH-DSS-CAMELLIA256-SHA',
- 'ECDH-RSA-AES256-GCM-SHA384',
- 'ECDH-ECDSA-AES256-GCM-SHA384',
- 'ECDH-RSA-AES256-SHA384',
- 'ECDH-ECDSA-AES256-SHA384',
- 'ECDH-RSA-AES256-SHA',
- 'ECDH-ECDSA-AES256-SHA',
- 'AES256-GCM-SHA384',
- 'AES256-SHA256',
- 'AES256-SHA',
- 'CAMELLIA256-SHA',
- 'PSK-AES256-CBC-SHA',
- 'ECDHE-RSA-AES128-GCM-SHA256',
- 'ECDHE-ECDSA-AES128-GCM-SHA256',
- 'ECDHE-RSA-AES128-SHA256',
- 'ECDHE-ECDSA-AES128-SHA256',
- 'ECDHE-RSA-AES128-SHA',
- 'ECDHE-ECDSA-AES128-SHA',
- 'SRP-DSS-AES-128-CBC-SHA',
- 'SRP-RSA-AES-128-CBC-SHA',
- 'SRP-AES-128-CBC-SHA',
- 'DH-DSS-AES128-GCM-SHA256',
- 'DHE-DSS-AES128-GCM-SHA256',
- 'DH-RSA-AES128-GCM-SHA256',
- 'DHE-RSA-AES128-GCM-SHA256',
- 'DHE-RSA-AES128-SHA256',
- 'DHE-DSS-AES128-SHA256',
- 'DH-RSA-AES128-SHA256',
- 'DH-DSS-AES128-SHA256',
- 'DHE-RSA-AES128-SHA',
- 'DHE-DSS-AES128-SHA',
- 'DH-RSA-AES128-SHA',
- 'DH-DSS-AES128-SHA',
- 'DHE-RSA-SEED-SHA',
- 'DHE-DSS-SEED-SHA',
- 'DH-RSA-SEED-SHA',
- 'DH-DSS-SEED-SHA',
- 'DHE-RSA-CAMELLIA128-SHA',
- 'DHE-DSS-CAMELLIA128-SHA',
- 'DH-RSA-CAMELLIA128-SHA',
- 'DH-DSS-CAMELLIA128-SHA',
- 'ECDH-RSA-AES128-GCM-SHA256',
- 'ECDH-ECDSA-AES128-GCM-SHA256',
- 'ECDH-RSA-AES128-SHA256',
- 'ECDH-ECDSA-AES128-SHA256',
- 'ECDH-RSA-AES128-SHA',
- 'ECDH-ECDSA-AES128-SHA',
- 'AES128-GCM-SHA256',
- 'AES128-SHA256',
- 'AES128-SHA',
- 'SEED-SHA',
- 'CAMELLIA128-SHA',
- 'IDEA-CBC-SHA',
- 'PSK-AES128-CBC-SHA',
- 'ECDHE-RSA-RC4-SHA',
- 'ECDHE-ECDSA-RC4-SHA',
- 'ECDH-RSA-RC4-SHA',
- 'ECDH-ECDSA-RC4-SHA',
- 'RC4-SHA',
- 'RC4-MD5',
- 'PSK-RC4-SHA',
- 'ECDHE-RSA-DES-CBC3-SHA',
- 'ECDHE-ECDSA-DES-CBC3-SHA',
- 'SRP-DSS-3DES-EDE-CBC-SHA',
- 'SRP-RSA-3DES-EDE-CBC-SHA',
- 'SRP-3DES-EDE-CBC-SHA',
- 'EDH-RSA-DES-CBC3-SHA',
- 'EDH-DSS-DES-CBC3-SHA',
- 'DH-RSA-DES-CBC3-SHA',
- 'DH-DSS-DES-CBC3-SHA',
- 'ECDH-RSA-DES-CBC3-SHA',
- 'ECDH-ECDSA-DES-CBC3-SHA',
- 'DES-CBC3-SHA',
- 'PSK-3DES-EDE-CBC-SHA',
- 'EDH-RSA-DES-CBC-SHA',
- 'EDH-DSS-DES-CBC-SHA',
- 'DH-RSA-DES-CBC-SHA',
- 'DH-DSS-DES-CBC-SHA',
- 'DES-CBC-SHA',
- 'EXP-EDH-RSA-DES-CBC-SHA',
- 'EXP-EDH-DSS-DES-CBC-SHA',
- 'EXP-DH-RSA-DES-CBC-SHA',
- 'EXP-DH-DSS-DES-CBC-SHA',
- 'EXP-DES-CBC-SHA',
- 'EXP-RC2-CBC-MD5',
- 'EXP-RC4-MD5',
- 'ECDHE-RSA-NULL-SHA',
- 'ECDHE-ECDSA-NULL-SHA',
- 'AECDH-NULL-SHA',
- 'ECDH-RSA-NULL-SHA',
- 'ECDH-ECDSA-NULL-SHA',
- 'NULL-SHA256',
- 'NULL-SHA',
- 'NULL-MD5');
+function ssl_conn_metadata($data) {
+ global $random_blurp;
+ global $current_folder;
+ $chain_length = count($data["chain"]);
+ echo "<section id='conndata'>";
+ if (is_array($data["warning"]) && count($data["warning"]) >= 1) {
+ $data["warning"] = array_unique($data["warning"]);
+ if (count($data["warning"]) == 1) {
+ echo "<h3>" . count($data["warning"]) . " warning!</h3>";
+ } else {
+ echo "<h3>" . count($data["warning"]) . " warnings!</h3>";
+ }
+ foreach ($data["warning"] as $key => $value) {
+ echo "<div class='alert alert-danger' role='alert'>";
+ echo htmlspecialchars($value);
+ echo "</div>";
+ }
+ }
+ echo "<table class='table table-striped table-bordered'>";
+ echo "<tbody>";
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Connection Data</strong></td>";
+ echo "</tr>";
+ echo "<tr>";
+ // chain
+ echo "<td>Chain sent by Server <br>(in server order)</td>";
+ echo "<td style='font-family: monospace;'>";
+ foreach ($data["chain"] as $key => $value) {
+ if (!empty($value['name'])) {
+ echo "Name...........: <i>";
+ echo htmlspecialchars(htmlspecialchars($value['name']));
+ echo " </i><br>Issued by......:<i> ";
+ echo htmlspecialchars(htmlspecialchars($value['issuer']));
+ echo "</i><br>";
+ }
+ if (isset($value["error"])) {
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>Error: Issuer does not match the next certificate CN. Chain order is probaby wrong.</span><br><br>";
+ }
+ }
+ echo "<br>";
+ if ($data["validation"]["status"] == "failed") {
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>Validating certificate chain failed:</span><br>";
+ echo "<pre>";
+ echo htmlspecialchars($data["validation"]["error"]);
+ echo "</pre>";
+ } else {
+ echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>Sucessfully validated certificate chain.</span><br>";
+ }
+ echo "</td>";
+ echo "</tr>";
+ // ip hostname port
+ if ( $data["hostname"] ) {
+ echo "<tr>";
+ echo "<td>IP / Hostname / Port</td>";
+ echo "<td>";
+ echo htmlspecialchars($data["ip"]);
+ echo " - ";
+ echo htmlspecialchars($data["hostname"]);
+ echo " - ";
+ echo htmlspecialchars($data["port"]);
+ echo "</td>";
+ echo "</tr>";
+ }
+ // protocols
+ echo "<tr>";
+ echo "<td>Protocols</td>";
+ echo "<td>";
+ $protocols = $data["protocols"];
+ foreach ($protocols as $key => $value) {
+ if ( $value == true ) {
+ if ( $key == "tlsv1.2") {
+ echo '<p><span class="text-success glyphicon glyphicon-ok"></span> - <span class="text-success">TLSv1.2 (Supported)</span></p>';
+ } else if ( $key == "tlsv1.1") {
+ echo '<p><span class="glyphicon glyphicon-ok"></span> - TLSv1.1 (Supported)</p>';
+ } else if ( $key == "tlsv1.0") {
+ echo '<p><span class="glyphicon glyphicon-ok"></span> - TLSv1.0 (Supported)</p>';
+ } else if ( $key == "sslv3") {
+ echo '<p><span class="text-danger glyphicon glyphicon-ok"></span> - <span class="text-danger">SSLv3 (Supported)</span></p>';
+ } else {
+ echo '<p><span class="glyphicon glyphicon-ok"></span> - <span>'.$key.' (Supported)</span></p>';
+ }
+ } else {
+ if ( $key == "tlsv1.2") {
+ echo '<p><span class="text-danger glyphicon glyphicon-remove"></span> - <span class="text-danger">TLSv1.2 (Not supported)</span></p>';
+ } else if ( $key == "tlsv1.1") {
+ echo '<p><span class="glyphicon glyphicon-remove"></span> - TLSv1.1 (Not supported)</p>';
+ } else if ( $key == "tlsv1.0") {
+ echo '<p><span class="glyphicon glyphicon-remove"></span> - TLSv1.0 (Not supported)</p>';
+ } else if ( $key == "sslv3") {
+ echo '<p><span class="text-success glyphicon glyphicon-remove"></span> - <span class="text-success">SSLv3 (Not supported)</span></p>';
+ } else {
+ echo '<p><span class="glyphicon glyphicon-remove"></span> - <span>'.$key.'(Not supported)</span></p>';
+ }
+ }
+ }
+ echo "</td>";
+ echo "</tr>";
+ //ciphersuites
+ if ($_GET['ciphersuites'] == 1) {
+ echo "<tr>";
+ echo "<td>Ciphersuites supported by server</td>";
+ echo "<td>";
+ $bad_ciphersuites = array('ECDHE-RSA-DES-CBC3-SHA',
+ 'ECDHE-ECDSA-DES-CBC3-SHA',
+ 'EDH-RSA-DES-CBC3-SHA',
+ 'EDH-DSS-DES-CBC3-SHA',
+ 'DH-RSA-DES-CBC3-SHA',
+ 'DH-DSS-DES-CBC3-SHA',
+ 'ECDH-RSA-DES-CBC3-SHA',
+ 'ECDH-ECDSA-DES-CBC3-SHA',
+ 'DES-CBC3-SHA',
+ 'EDH-RSA-DES-CBC-SHA',
+ 'EDH-DSS-DES-CBC-SHA',
+ 'DH-RSA-DES-CBC-SHA',
+ 'DH-DSS-DES-CBC-SHA',
+ 'DES-CBC-SHA',
+ 'EXP-EDH-RSA-DES-CBC-SHA',
+ 'EXP-EDH-DSS-DES-CBC-SHA',
+ 'EXP-DH-RSA-DES-CBC-SHA',
+ 'EXP-DH-DSS-DES-CBC-SHA',
+ 'EXP-DES-CBC-SHA',
+ 'EXP-EDH-RSA-DES-CBC-SHA',
+ 'EXP-EDH-DSS-DES-CBC-SHA',
+ 'EXP-DH-RSA-DES-CBC-SHA',
+ 'EXP-DH-DSS-DES-CBC-SHA',
+ 'EXP-DES-CBC-SHA',
+ 'EXP-RC2-CBC-MD5',
+ 'EXP-RC4-MD5',
+ 'RC4-MD5',
+ 'EXP-RC2-CBC-MD5',
+ 'EXP-RC4-MD5',
+ 'ECDHE-RSA-RC4-SHA',
+ 'ECDHE-ECDSA-RC4-SHA',
+ 'ECDH-RSA-RC4-SHA',
+ 'ECDH-ECDSA-RC4-SHA',
+ 'RC4-SHA',
+ 'RC4-MD5',
+ 'PSK-RC4-SHA',
+ 'EXP-RC4-MD5',
+ 'ECDHE-RSA-NULL-SHA',
+ 'ECDHE-ECDSA-NULL-SHA',
+ 'AECDH-NULL-SHA',
+ 'RC4-SHA',
+ 'RC4-MD5',
+ 'ECDH-RSA-NULL-SHA',
+ 'ECDH-ECDSA-NULL-SHA',
+ 'NULL-SHA256',
+ 'NULL-SHA',
+ 'NULL-MD5');
+ foreach ($data["supported_ciphersuites"] as $key => $value) {
+ if (in_array($value, $bad_ciphersuites)) {
+ $bad_ciphersuite = 1;
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span>";
+ echo "<span class='text-danger'> ";
+ echo htmlspecialchars($value);
+ echo "</span>";
+ } else {
+ echo "<span class='glyphicon glyphicon-minus'></span> ";
+ echo htmlspecialchars($value);
+ }
+ echo "<br>";
+ }
+ if ($bad_ciphersuite) {
+ echo "<p><br>Ciphersuites containing <a href='https://en.wikipedia.org/wiki/Null_cipher'>NULL</a>,";
+ echo " <a href='https://en.wikipedia.org/wiki/Export_of_cryptography_from_the_United_States'>EXP(ort)</a>,";
+ echo " <a href='https://en.wikipedia.org/wiki/Weak_key'>DES";
+ echo " and RC4</a> are marked RED because they are suboptimal.</p>";
+ }
+ echo "</td>";
+ echo "</tr>";
+ } else {
+ echo "<tr>";
+ echo "<td>Ciphersuite Used</td>";
+ echo "<td>";
+ echo htmlspecialchars($data['used_ciphersuite']['name']);
+ echo " (".htmlspecialchars($data['used_ciphersuite']['bits'])." bits)";
+ echo "</td>";
+ echo "</tr>";
+ }
+ //tls fallback scsv
+ echo "<tr>";
+ echo "<td>";
+ echo "<a href='http://googleonlinesecurity.blogspot.nl/2014/10/this-poodle-bites-exploiting-ssl-30.html'>TLS_FALLBACK_SCSV</a>";
+ echo "</td>";
+ echo "<td>";
+
+ if ($data["tls_fallback_scsv"] == "supported") {
+ echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>TLS_FALLBACK_SCSV supported.</span>";
+ } elseif ($data["tls_fallback_scsv"] == "unsupported") {
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>TLS_FALLBACK_SCSV not supported.</span>";
+ } else {
+ echo "Only 1 protocol enabled, fallback not possible, TLS_FALLBACK_SCSV not required.";
+ }
+ echo "</td>";
+ echo "</tr>";
+
+ // headers
+ echo "<tr>";
+ echo "<td>";
+ echo "<a href='https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html'>Strict Transport Security</a>";
+ echo "</td>";
+ echo "<td>";
+ // hsts
+ if ( $data["strict_transport_security"] == "not set" ) {
+ echo '<span class="text-danger glyphicon glyphicon-remove"></span> - <span class="text-danger">Not Set</span>';
+ } else {
+ echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>";
+ echo htmlspecialchars($data["strict_transport_security"]);
+ echo "</span>";
+ }
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td>";
+ echo "<a href='https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html'>HTTP Public Key Pinning Extension (HPKP)</a>";
+ echo "</td>";
+ echo "<td>";
+ //hpkp
+ if ( $data["public_key_pins"] == "not set" ) {
+ echo '<span>Not Set</span>';
+ } else {
+ echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>";
+ echo htmlspecialchars($data["public_key_pins"]);
+ }
+ if ( $data["public_key-pins_report_only"] ) {
+ echo "<b>Report Only</b>: ";
+ echo htmlspecialchars($data["public_key_pins_report_only"]);
+ }
- $bad_ciphersuites = array('ECDHE-RSA-DES-CBC3-SHA',
- 'ECDHE-ECDSA-DES-CBC3-SHA',
- 'EDH-RSA-DES-CBC3-SHA',
- 'EDH-DSS-DES-CBC3-SHA',
- 'DH-RSA-DES-CBC3-SHA',
- 'DH-DSS-DES-CBC3-SHA',
- 'ECDH-RSA-DES-CBC3-SHA',
- 'ECDH-ECDSA-DES-CBC3-SHA',
- 'DES-CBC3-SHA',
- 'EDH-RSA-DES-CBC-SHA',
- 'EDH-DSS-DES-CBC-SHA',
- 'DH-RSA-DES-CBC-SHA',
- 'DH-DSS-DES-CBC-SHA',
- 'DES-CBC-SHA',
- 'EXP-EDH-RSA-DES-CBC-SHA',
- 'EXP-EDH-DSS-DES-CBC-SHA',
- 'EXP-DH-RSA-DES-CBC-SHA',
- 'EXP-DH-DSS-DES-CBC-SHA',
- 'EXP-DES-CBC-SHA',
- 'EXP-EDH-RSA-DES-CBC-SHA',
- 'EXP-EDH-DSS-DES-CBC-SHA',
- 'EXP-DH-RSA-DES-CBC-SHA',
- 'EXP-DH-DSS-DES-CBC-SHA',
- 'EXP-DES-CBC-SHA',
- 'EXP-RC2-CBC-MD5',
- 'EXP-RC4-MD5',
- 'RC4-MD5',
- 'EXP-RC2-CBC-MD5',
- 'EXP-RC4-MD5',
- 'ECDHE-RSA-RC4-SHA',
- 'ECDHE-ECDSA-RC4-SHA',
- 'ECDH-RSA-RC4-SHA',
- 'ECDH-ECDSA-RC4-SHA',
- 'RC4-SHA',
- 'RC4-MD5',
- 'PSK-RC4-SHA',
- 'EXP-RC4-MD5',
- 'ECDHE-RSA-NULL-SHA',
- 'ECDHE-ECDSA-NULL-SHA',
- 'AECDH-NULL-SHA',
- 'RC4-SHA',
- 'RC4-MD5',
- 'ECDH-RSA-NULL-SHA',
- 'ECDH-ECDSA-NULL-SHA',
- 'NULL-SHA256',
- 'NULL-SHA',
- 'NULL-MD5');
- $supported_ciphersuites = ssl_conn_ciphersuites($host, $port, $ciphersuites_to_test);
-
- foreach ($supported_ciphersuites as $key => $value) {
- if($value == true){
- if (in_array($key, $bad_ciphersuites)) {
- $bad_ciphersuite = 1;
- echo "";
- echo "<span class='text-danger glyphicon glyphicon-remove'></span> ";
- } else {
- echo "<span class='glyphicon glyphicon-minus'></span> ";
- }
- echo htmlspecialchars($key);
- echo "<br>";
- } else {
- echo "<!-- ";
- echo "<span class='glyphicon glyphicon-remove'></span> - ";
- echo htmlspecialchars($key);
- echo " <br -->";
- }
- }
- if ($bad_ciphersuite) {
- ?>
- <p><br>Ciphersuites containing <a href="https://en.wikipedia.org/wiki/Null_cipher">NULL</a>, <a href="https://en.wikipedia.org/wiki/Export_of_cryptography_from_the_United_States">EXP(ort)</a>, <a href="https://en.wikipedia.org/wiki/Weak_key">DES and RC4</a> are marked RED because they are suboptimal.</p>
- <?php
- }
-
- ?>
- </td>
- </tr>
- <?php
- } else {
- ?>
- <tr>
- <td>Ciphersuite</td>
- <td>
- <?php
- echo htmlspecialchars($context_meta['cipher_name']);
- echo " (".htmlspecialchars($context_meta['cipher_bits'])." bits)";
- ?>
- </td>
- </tr>
- <?php
- }
- ?>
- <tr>
- <td>
- <a href="http://googleonlinesecurity.blogspot.nl/2014/10/this-poodle-bites-exploiting-ssl-30.html">TLS_FALLBACK_SCSV</a>
- </td>
- <td>
- <?php
- $fallback = tls_fallback_scsv($host, $port);
- // echo "<pre>";
- // var_dump($fallback);
- // echo "</pre>";
- if ($fallback['protocol_count'] == 1) {
- echo "Only 1 protocol enabled, fallback not possible, TLS_FALLBACK_SCSV not required.";
- } else {
- if ($fallback['tls_fallback_scsv_support'] == 1) {
- echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>TLS_FALLBACK_SCSV supported.</span>";
- } else {
- echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>TLS_FALLBACK_SCSV not supported.</span>";
- }
- }
- ?>
- </td>
- </tr>
- <?php
- $headers = server_http_headers($host, $port);
- ?>
- <tr>
- <td><a href="https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html">Strict Transport Security</a></td>
- <td>
- <?php
- if ( $headers["strict-transport-security"] ) {
- echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>";
- if ( is_array($headers["strict-transport-security"])) {
- echo htmlspecialchars(substr($headers["strict-transport-security"][0], 0, 50));
- echo "<br > <i>HSTS header was found multiple times. Only showing the first one.</i>";
- } else {
- echo htmlspecialchars(substr($headers["strict-transport-security"], 0, 50));
- }
- echo "</span>";
- } else {
- echo '<span class="text-danger glyphicon glyphicon-remove"></span> - <span class="text-danger">Not Set</span>';
- }
- ?>
- </td>
- </tr>
- <tr>
- <td><a href="https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html">HTTP Public Key Pinning Extension (HPKP)</a></td>
- <td>
- <?php
- if ( $headers["public-key-pins"] ) {
- echo "<span class='text-success glyphicon glyphicon-ok'></span> - <span class='text-success'>";
- if ( is_array($headers["public-key-pins"])) {
- echo htmlspecialchars(substr($headers["public-key-pins"][0], 0, 255));
- echo "<br > <i>HPKP header was found multiple times. Only showing the first one.</i>";
- echo "</span>";
- } else {
- echo htmlspecialchars(substr($headers["public-key-pins"], 0, 255));
- }
- } else {
- echo '<span>Not Set</span>';
- }
- ?>
- <?php
- if ( $headers["public-key-pins-report-only"] ) {
- echo "<b>Report Only</b>: ";
- if ( is_array($headers["public-key-pins-report-only"])) {
- echo htmlspecialchars(substr($headers["public-key-pins-report-only"][0], 0, 255));
- echo "<br > <i>HPKP Report Only header was found multiple times. Only showing the first one.</i>";
- } else {
- echo htmlspecialchars(substr($headers["public-key-pins-report-only"], 0, 255));
- }
- }
- ?>
- </td>
- </tr>
- <tr>
- <td>OCSP Stapling</td>
- <td>
- <?php
- $stapling = ocsp_stapling($host,$port);
- if($stapling["working"] == 1) {
- echo "<table class='table'>";
- foreach ($stapling as $key => $value) {
- if ($key != "working") {
- echo "<tr><td>" . $key . "</td><td>" . $value . "</td></tr>";
- }
- }
- echo "</table>";
- } else {
- echo "No response received.";
- }
- ?>
- </td>
- </tr>
- <tr>
- <td>This Server' OpenSSL Version</td>
- <td>
- <?php
- echo htmlspecialchars(shell_exec("openssl version"));
- ?>
- </td>
- </tr>
- <tr>
- <td>This Server' Date (RFC 2822)</td>
- <td>
- <?php
- echo htmlspecialchars(shell_exec("date --rfc-2822"));
- ?>
- </td>
- </tr>
- </tbody>
- </table>
- </section>
- <?php
+ echo "</td>";
+ echo "</tr>";
+ // ocsp stapling
+ echo "<tr>";
+ echo "<td>OCSP Stapling</td>";
+ echo "<td>";
+ if (isset($data["ocsp_stapling"]["working"])) {
+ if($data["ocsp_stapling"]["working"] == 1) {
+ echo "<table class='table'>";
+ foreach ($data["ocsp_stapling"] as $key => $value) {
+ if ($key != "working") {
+ echo "<tr><td>" . htmlspecialchars($key) . "</td><td>" . htmlspecialchars($value) . "</td></tr>";
+ }
+ }
+ echo "</table>";
} else {
- return false;
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>No OCSP stapling response received.</span>";
}
+ } else {
+ echo "<span class='text-danger glyphicon glyphicon-remove'></span> - <span class='text-danger'>No OCSP stapling response received.</span>";
}
+ echo "</td>";
+ // openssl version
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td>This Server's OpenSSL Version</td>";
+ echo "<td>";
+ echo htmlspecialchars(shell_exec("openssl version"));
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ //date
+ echo "<td>This Server's Date <br>(RFC 2822)</td>";
+ echo "<td>";
+ echo htmlspecialchars(shell_exec("date --rfc-2822"));
+ echo "</td>";
+ echo "</tr>";
+ echo "</tbody>";
+ echo "</table>";
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
$result = array();
global $random_blurp;
@@ -641,10 +417,10 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
$context = stream_context_get_params($read_stream);
$context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
$cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"])[0];
+ $result["checked_hostname"] = $host;
//chain
if (isset($context_meta)) {
if (isset($chain_data)) {
-
$chain_length = count($chain_data);
$certificate_chain = array();
if ($chain_length <= 10) {
@@ -660,6 +436,7 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
} else {
if ($i != $chain_length - 1) {
$result["chain"][$i]["error"] = "Issuer does not match the next certificate CN. Chain order is probaby wrong.";
+ $result["warning"][] = "Issuer does not match the next certificate CN. Chain order is probaby wrong.";
}
}
}
@@ -672,10 +449,11 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
$verify_exec = exec(escapeshellcmd('openssl verify -verbose -purpose any -CAfile ' . getcwd() . '/cacert.pem /tmp/verify_cert.' . $random_blurp . '.pem') . "| grep -v OK", $verify_output, $verify_exit_code);
if ($verify_exit_code != 1) {
- $result["chain"]["validation"]["status"] = "failed";
- $result["chain"]["validation"]["error"] = "Error: Validating certificate chain failed: " . str_replace('/tmp/verify_cert.' . $random_blurp . '.pem: ', '', implode("\n", $verify_output));
+ $result["validation"]["status"] = "failed";
+ $result["validation"]["error"] = "Error: Validating certificate chain failed: " . str_replace('/tmp/verify_cert.' . $random_blurp . '.pem: ', '', implode("\n", $verify_output));
+ $result["warning"][] = "Error: Validating certificate chain failed. Probably non-trusted root/self signed certificate, or the chain order is wrong.";
} else {
- $result["chain"]["validation"]["status"] = "success";
+ $result["validation"]["status"] = "success";
}
unlink('/tmp/verify_cert.' . $random_blurp . '.pem');
}
@@ -688,6 +466,17 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
// protocols
$result["protocols"] = array_reverse(ssl_conn_protocols($host, $port));
+ foreach ($result["protocols"] as $key => $value) {
+ if ( $value == true ) {
+ if ( $key == "sslv3") {
+ $result["warning"][] = 'SSLv3 supported. Please disable and upgrade to a newer protocol like TLSv1.2.';
+ }
+ } else {
+ if ( $key == "tlsv1.2") {
+ $result["warning"][] = 'TLSv1.2 unsupported. Please enable TLSv1.2.';
+ }
+ }
+ }
// ciphersuites
if ($_GET['ciphersuites'] == 1) {
@@ -809,55 +598,6 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
'NULL-SHA256',
'NULL-SHA',
'NULL-MD5');
-
- $bad_ciphersuites = array('ECDHE-RSA-DES-CBC3-SHA',
- 'ECDHE-ECDSA-DES-CBC3-SHA',
- 'EDH-RSA-DES-CBC3-SHA',
- 'EDH-DSS-DES-CBC3-SHA',
- 'DH-RSA-DES-CBC3-SHA',
- 'DH-DSS-DES-CBC3-SHA',
- 'ECDH-RSA-DES-CBC3-SHA',
- 'ECDH-ECDSA-DES-CBC3-SHA',
- 'DES-CBC3-SHA',
- 'EDH-RSA-DES-CBC-SHA',
- 'EDH-DSS-DES-CBC-SHA',
- 'DH-RSA-DES-CBC-SHA',
- 'DH-DSS-DES-CBC-SHA',
- 'DES-CBC-SHA',
- 'EXP-EDH-RSA-DES-CBC-SHA',
- 'EXP-EDH-DSS-DES-CBC-SHA',
- 'EXP-DH-RSA-DES-CBC-SHA',
- 'EXP-DH-DSS-DES-CBC-SHA',
- 'EXP-DES-CBC-SHA',
- 'EXP-EDH-RSA-DES-CBC-SHA',
- 'EXP-EDH-DSS-DES-CBC-SHA',
- 'EXP-DH-RSA-DES-CBC-SHA',
- 'EXP-DH-DSS-DES-CBC-SHA',
- 'EXP-DES-CBC-SHA',
- 'EXP-RC2-CBC-MD5',
- 'EXP-RC4-MD5',
- 'RC4-MD5',
- 'EXP-RC2-CBC-MD5',
- 'EXP-RC4-MD5',
- 'ECDHE-RSA-RC4-SHA',
- 'ECDHE-ECDSA-RC4-SHA',
- 'ECDH-RSA-RC4-SHA',
- 'ECDH-ECDSA-RC4-SHA',
- 'RC4-SHA',
- 'RC4-MD5',
- 'PSK-RC4-SHA',
- 'EXP-RC4-MD5',
- 'ECDHE-RSA-NULL-SHA',
- 'ECDHE-ECDSA-NULL-SHA',
- 'AECDH-NULL-SHA',
- 'RC4-SHA',
- 'RC4-MD5',
- 'ECDH-RSA-NULL-SHA',
- 'ECDH-ECDSA-NULL-SHA',
- 'NULL-SHA256',
- 'NULL-SHA',
- 'NULL-MD5');
-
$tested_ciphersuites = ssl_conn_ciphersuites($host, $port, $ciphersuites_to_test);
$result["supported_ciphersuites"] = array();
foreach ($tested_ciphersuites as $key => $value) {
@@ -879,6 +619,7 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
$result["tls_fallback_scsv"] = "supported";
} else {
$result["tls_fallback_scsv"] = "unsupported";
+ $result["warning"][] = "TLS_FALLBACK_SCSV unsupported. Please upgrade OpenSSL to enable. This offers downgrade attack protection.";
}
}
//hsts
@@ -891,6 +632,7 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
}
} else {
$result["strict_transport_security"] = 'not set';
+ $result["warning"][] = "HTTP Strict Transport Security not set.";
}
//hpkp
if ( $headers["public-key-pins"] ) {
@@ -915,6 +657,7 @@ function ssl_conn_metadata_json($host, $port, $read_stream, $chain_data=null) {
$result["ocsp_stapling"] = $stapling;
} else {
$result["ocsp_stapling"] = "not set";
+ $result["warning"][] = "OCSP Stapling not enabled.";
}
$result["openssl_version"] = shell_exec("openssl version");
diff --git a/functions/json.php b/functions/json.php
new file mode 100644
index 0000000..26058a6
--- /dev/null
+++ b/functions/json.php
@@ -0,0 +1,61 @@
+<?php
+// Copyright (C) 2015 Remy van Elst
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+function check_json($host,$port) {
+ $data = [];
+ $stream = stream_context_create (array("ssl" =>
+ array("capture_peer_cert" => true,
+ "capture_peer_cert_chain" => true,
+ "verify_peer" => false,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ "capture_session_meta" => true,
+ "sni_enabled" => true)));
+ $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
+ if ( $read_stream === false ) {
+ $data["error"] = ["Failed to connect: " . htmlspecialchars($errstr)];
+ return $data;
+ } else {
+ $context = stream_context_get_params($read_stream);
+ $context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
+ $cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"]);
+ $chain_data = $context["options"]["ssl"]["peer_certificate_chain"];
+ $chain_length = count($chain_data);
+ if (isset($chain_data) && $chain_length < 10) {
+ $chain_length = count($chain_data);
+ $chain_arr_keys = ($chain_data);
+ foreach(array_keys($chain_arr_keys) as $key) {
+ $curr = $chain_data[$key];
+ $next = $chain_data[$key+1];
+ $prev = $chain_data[$key-1];
+ $chain_key = (string)$key+1;
+ if ($key == 0) {
+ $data["connection"] = ssl_conn_metadata_json($host, $port, $read_stream, $chain_data);
+ $data["chain"][$chain_key] = cert_parse_json($curr, $next, $host, true);
+ } else {
+ $data["chain"][$chain_key] = cert_parse_json($curr, $next, null, false);
+ }
+ }
+ } else {
+ $data["error"] = ["Chain too long."];
+ return $data;
+ }
+ }
+ return $data;
+}
+
+?> \ No newline at end of file
diff --git a/functions/ocsp.php b/functions/ocsp.php
index c9d43eb..ca8ada6 100644
--- a/functions/ocsp.php
+++ b/functions/ocsp.php
@@ -20,7 +20,6 @@ function ocsp_stapling($host, $port){
if (strpos($output, "no response sent") !== false) {
$result = array("working" => 0,
"cert_status" => "No response sent");
- return;
}
if (strpos($output, "OCSP Response Data:") !== false) {
$lines = array();
@@ -45,65 +44,6 @@ function ocsp_stapling($host, $port){
return $result;
}
-function ocsp_verify($raw_cert_data, $raw_next_cert_data) {
- global $random_blurp;
- $cert_data = openssl_x509_parse($raw_cert_data);
- $tmp_dir = '/tmp/';
- $root_ca = getcwd() . '/cacert.pem';
-
- $pem_issuer = "";
- $pem_client = "";
- $ocsp_uri = explode("OCSP - URI:", $cert_data['extensions']['authorityInfoAccess'])[1];
- $ocsp_uri = explode("\n", $ocsp_uri)[0];
- $ocsp_uri = explode(" ", $ocsp_uri)[0];
- if (empty($ocsp_uri) ) {
- $result = array('unknown' => "Could not find OCSP URI", );
- return $result;
- }
- openssl_x509_export($raw_cert_data, $pem_client);
- openssl_x509_export($raw_next_cert_data, $pem_issuer);
- openssl_x509_export_to_file($raw_next_cert_data, $tmp_dir.$random_blurp.'.cert_issuer.pem');
- openssl_x509_export_to_file($raw_cert_data, $tmp_dir.$random_blurp.'.cert_client.pem');
-
- // Some OCSP's want HTTP/1.1 but OpenSSL does not do that. Add Host header as workaround.
- $ocsp_host = parse_url($ocsp_uri, PHP_URL_HOST);
-
- //echo '<pre>' . htmlspecialchars('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$tmp_dir.$random_blurp.'.cert_issuer.pem -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1') . '</pre>';
-
- $output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$tmp_dir.$random_blurp.'.cert_issuer.pem -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1');
- $filter_output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$tmp_dir.$random_blurp.'.cert_issuer.pem -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1 | grep -v -e "to get local issuer certificate" -e "signer certificate not found" -e "Response Verify" -e "'. $tmp_dir.$random_blurp.'.cert_client.pem"');
-
-
-
- $lines = array();
- $output = preg_replace("/[[:blank:]]+/"," ", $output);
- $ocsp_status_lines = explode("\n", $output);
- $ocsp_status_lines = array_map('trim', $ocsp_status_lines);
- foreach($ocsp_status_lines as $line) {
- if(endsWith($line, ":") == false) {
- list($k, $v) = explode(":", $line, 2);
- $lines[trim($k)] = trim($v);
- }
- }
-
- $result = array("This Update" => $lines["This Update"],
- "Next Update" => $lines["Next Update"],
- "Reason" => $lines["Reason"],
- "Revocation Time" => $lines["Revocation Time"],
- "ocsp_verify_status" => $lines[$tmp_dir . $random_blurp . ".cert_client.pem"]);
- if ($result["ocsp_verify_status"] == "good") {
- $result["good"] = $filter_output;
- } else if ($result["ocsp_verify_status"] == "revoked") {
- $result["revoked"] = $filter_output;
- } else {
- $result["unknown"] = $filter_output;
- }
- unlink($tmp_dir.$random_blurp.'.cert_client.pem');
- unlink($tmp_dir.$random_blurp.'.cert_issuer.pem');
- return $result;
-}
-
-
function ocsp_verify_json($raw_cert_data, $raw_next_cert_data, $ocsp_uri) {
global $random_blurp;
$result = array();
@@ -112,16 +52,19 @@ function ocsp_verify_json($raw_cert_data, $raw_next_cert_data, $ocsp_uri) {
$pem_issuer = "";
$pem_client = "";
openssl_x509_export($raw_cert_data, $pem_client);
+ openssl_x509_export_to_file($raw_cert_data, $tmp_dir.$random_blurp.'.cert_client.pem');
openssl_x509_export($raw_next_cert_data, $pem_issuer);
openssl_x509_export_to_file($raw_next_cert_data, $tmp_dir.$random_blurp.'.cert_issuer.pem');
- openssl_x509_export_to_file($raw_cert_data, $tmp_dir.$random_blurp.'.cert_client.pem');
+ $isser_loc = $tmp_dir.$random_blurp.'.cert_issuer.pem';
// Some OCSP's want HTTP/1.1 but OpenSSL does not do that. Add Host header as workaround.
$ocsp_host = parse_url($ocsp_uri, PHP_URL_HOST);
- $output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$tmp_dir.$random_blurp.'.cert_issuer.pem -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1');
+ //pre_dump('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$isser_loc.' -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1');
+
+ $output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$isser_loc .' -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1');
- $filter_output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$tmp_dir.$random_blurp.'.cert_issuer.pem -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1 | grep -v -e "to get local issuer certificate" -e "signer certificate not found" -e "Response Verify" -e "'. $tmp_dir.$random_blurp.'.cert_client.pem"');
+ $filter_output = shell_exec('openssl ocsp -no_nonce -CAfile '.$root_ca.' -issuer '.$isser_loc .' -cert '.$tmp_dir.$random_blurp.'.cert_client.pem -url "'. escapeshellcmd($ocsp_uri) . '" -header "HOST" "'. escapeshellcmd($ocsp_host) . '" 2>&1 | grep -v -e "to get local issuer certificate" -e "signer certificate not found" -e "Response Verify" -e "'. $tmp_dir.$random_blurp.'.cert_client.pem"');
$output = preg_replace("/[[:blank:]]+/"," ", $output);
$ocsp_status_lines = explode("\n", $output);
diff --git a/functions/parse_certificate.php b/functions/parse_certificate.php
index 1c7c959..e926e47 100644
--- a/functions/parse_certificate.php
+++ b/functions/parse_certificate.php
@@ -14,653 +14,636 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-function get_cert_cn($raw_cert_data){
- $cert_data = openssl_x509_parse($raw_cert_data);
- if ($cert_data['subject']['CN']) {
- return $cert_data['subject']['CN'];
+
+function csr_parse($data) {
+ echo "<table class='table table-striped table-bordered'>";
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Certificate Data</strong></td>";
+ echo "</tr>";
+ foreach ($data['subject'] as $key => $value) {
+ echo "<tr><td>";
+ switch ($key) {
+ case 'C':
+ echo "Country";
+ break;
+ case 'ST':
+ echo "State";
+ break;
+ case 'L':
+ echo "City";
+ break;
+ case 'O':
+ echo "Organization";
+ break;
+ case 'OU':
+ echo "Organizational Unit";
+ break;
+ case 'CN':
+ echo "Common Name";
+ break;
+ case 'mail':
+ echo "Email Address";
+ break;
+ default:
+ echo htmlspecialchars($key);
+ break;
+ }
+ echo "</td><td>";
+ switch ($key) {
+ case 'C':
+ echo htmlspecialchars($value);
+ echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
+ echo strtolower(htmlspecialchars($value));
+ echo '" alt="" />';
+ break;
+ case 'DC':
+ foreach ($value as $key => $value) {
+ echo htmlspecialchars($value) . ".";
+ }
+ break;
+ default:
+ if (is_array($value)) {
+ foreach ($value as $key => $value) {
+ echo htmlspecialchars($value) . " ";
+ }
+ } else {
+ echo htmlspecialchars($value);
+ }
+ break;
+ }
+ echo "</td></tr>\n";
+ }
+ echo "<tr><td>Public Key PEM (";
+ echo htmlspecialchars($data['details']['bits']);
+ if ($data['details']['rsa']) {
+ echo " RSA";
+ }
+ if ($data['details']['dsa']) {
+ echo " DSA";
+ }
+ if ($data['details']['dh']) {
+ echo " DH";
}
+ if ($data['details']['ec']) {
+ echo " ECDSA";
+ }
+ echo ")</td><td><pre>";
+ echo htmlspecialchars($data['details']['key']);
+ echo "</pre></td>";
+ echo "</table>";
}
-function cert_parse($raw_cert_data, $raw_next_cert_data=null, $csr=false, $host=null, $port=null, $is_issuer=false) {
- global $random_blurp;
- global $ev_oids;
- if ($csr == true && strpos($raw_cert_data, "BEGIN CERTIFICATE REQUEST") !== false) {
- ?>
- <table class="table table-striped table-bordered">
- <tr>
- <td colspan="2"><strong>Certificate Data</strong></td>
- </tr>
- <?php
- $cert_data = openssl_csr_get_public_key($raw_cert_data);
-
- $cert_details = openssl_pkey_get_details($cert_data);
- $cert_key = $cert_details['key'];
- $cert_subject = openssl_csr_get_subject($raw_cert_data);
-
- foreach ($cert_subject as $key => $value) {
- echo "<tr><td>";
- switch ($key) {
- case 'C':
- echo "Country";
- break;
- case 'ST':
- echo "State";
- break;
- case 'L':
- echo "City";
- break;
- case 'O':
- echo "Organization";
- break;
- case 'OU':
- echo "Organizational Unit";
- break;
- case 'CN':
- echo "Common Name";
- break;
- case 'mail':
- echo "Email Address";
- break;
- default:
- echo htmlspecialchars($key);
- break;
+function cert_parse($data) {
+ if (is_array($data["warning"]) && count($data["warning"]) >= 1) {
+ $data["warning"] = array_unique($data["warning"]);
+ if (count($data["warning"]) == 1) {
+ echo "<h3>" . count($data["warning"]) . " warning!</h3>";
+ } else {
+ echo "<h3>" . count($data["warning"]) . " warnings!</h3>";
+ }
+ foreach ($data["warning"] as $key => $value) {
+ echo "<div class='alert alert-danger' role='alert'>";
+ echo htmlspecialchars($value);
+ echo "</div>";
+ }
+ }
+ echo "<table class='table table-striped table-bordered'>";
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Certificate Data</strong></td>";
+ echo "</tr>";
+ $today = date("Y-m-d");
+ echo "<tr><td colspan='2'>\n";
+ echo "<table class='table'>\n";
+ echo "<thead><tr>\n";
+ echo "<th>Hostname</th>\n";
+ echo "<th>Not Expired</th>\n";
+ echo "<th>Issuer</th>\n";
+ echo "<th>CRL</th>\n";
+ echo "<th>OCSP</th>\n";
+ echo "<th>Signing Type</th>\n";
+ echo "</tr>\n</thead>\n<tbody>\n<tr>";
+ // hostname validation
+ if ($data["hostname_in_san_or_cn"] == "true") {
+ echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
+ } elseif ($data["hostname_in_san_or_cn"] == "false") {
+ echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ } elseif ($data["hostname_in_san_or_cn"] == "n/a; ca signing certificate") {
+ echo "<td></td>";
+ } else {
+ echo "<td><h1><span class='text-danger glyphicon glyphicon-question-sign'></span>&nbsp;</h1></td>";
+ }
+ // expired
+ if ( $today > date(DATE_RFC2822,$data['cert_data']['validFrom_time_t']) || strtotime($today) < strtotime(date(DATE_RFC2822,$data['cert_data']['validTo_time_t'])) ) {
+ echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
+ } else {
+ echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ }
+ // issuer
+ if (!empty($data["issuer_valid"])) {
+ if ($data["issuer_valid"] == true) {
+ echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
+ } else {
+ echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ }
+ } else {
+ echo '<td> </td>';
+ }
+ // crl
+ if ( !empty($data['crl'][1]['status']) ) {
+ if ($data['crl'][1]['status'] == "ok") {
+ echo "<td><h1><span class='text-success glyphicon glyphicon-ok'></span>&nbsp;</h1></td>";
+ } else {
+ echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ }
+ } else {
+ echo '<td> </td>';
+ }
+ // ocsp
+ if (!empty($data['ocsp'][1]['ocsp_uri'])) {
+ echo "<td>";
+ if ($data['ocsp'][1]["status"] == "good") {
+ echo '<h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1>';
+ } else if ($data['ocsp'][1]["status"] == "revoked") {
+ echo '<h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1>';
+ } else {
+ echo '<h1><span class="text-danger glyphicon glyphicon-question-sign"></span>&nbsp;</h1>';
+ }
+ echo "</td>";
+ } else {
+ echo "<td> </td>";
+ }
+ // self signed/ca/ca root
+ if (strpos($data['cert_data']['extensions']['basicConstraints'], "CA:TRUE") !== false && $data['cert_data']['issuer']['CN'] == $data['cert_data']['subject']['CN'] ) {
+ echo '<td><span class="text-success">CA Root Certificate</span></td>';
+ } else if (strpos($data['cert_data']['extensions']['basicConstraints'], "CA:TRUE") !== false) {
+ echo '<td><span class="text-success">CA Certificate</span></td>';
+ } else if ($data['cert_data']['issuer']['CN'] == $data['cert_data']['subject']['CN']) {
+ echo '<td><span class="text-danger">Self Signed</span></td>';
+ } else {
+ echo "<td>Signed by CA</td>";
+ }
+ echo "</tr>";
+ echo "</tbody></table>";
+ echo "</td></tr>";
+ if (!empty($data['cert_data']['subject']) ) {
+ foreach ($data['cert_data']['subject'] as $key => $value) {
+ echo "<tr><td>";
+ switch ($key) {
+ case 'C':
+ echo "Country";
+ break;
+ case 'ST':
+ echo "State";
+ break;
+ case 'L':
+ echo "City";
+ break;
+ case 'O':
+ echo "Organization";
+ break;
+ case 'OU':
+ echo "Organizational Unit";
+ break;
+ case 'CN':
+ echo "Common Name";
+ break;
+ case 'mail':
+ echo "Email Address";
+ break;
+ case 'businessCategory':
+ echo "Business Type";
+ break;
+ default:
+ echo htmlspecialchars($key);
+ break;
+ }
+ echo "</td><td>";
+ switch ($key) {
+ case 'C':
+ echo htmlspecialchars($value);
+ echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
+ echo strtolower(htmlspecialchars($value));
+ echo '" alt="" />';
+ break;
+ case 'DC':
+ foreach ($value as $key => $value) {
+ echo htmlspecialchars($value) . ".";
}
-
- echo "</td><td>";
- switch ($key) {
- case 'C':
- echo htmlspecialchars($value);
- echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
- echo strtolower(htmlspecialchars($value));
- echo '" alt="" />';
- break;
- case 'DC':
+ break;
+ default:
+ if (is_array($value)) {
foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . ".";
+ echo htmlspecialchars($value) . " ";
}
- break;
- default:
- if (is_array($value)) {
- foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . " ";
- }
- } else {
- echo htmlspecialchars($value);
- }
- break;
+ } else {
+ echo htmlspecialchars($value);
}
-
- echo "</td></tr>\n";
+ break;
}
- echo "</table>";
- return;
- } else {
- $cert_data = openssl_x509_parse($raw_cert_data);
+ echo "</td>";
+ echo "</tr>";
}
- if (empty($cert_data)) {
- echo "Data not valid.";
- continue;
+ }
+ // san
+ if (!empty($data['cert_data']['extensions']['subjectAltName'])) {
+ echo "<tr>";
+ echo "<td>Subject Alternative Names</td>";
+ echo "<td>";
+ foreach ( explode("DNS:", $data['cert_data']['extensions']['subjectAltName']) as $altName ) {
+ if ( !empty(str_replace(',', " ", "$altName"))) {
+ echo htmlspecialchars(str_replace(',', " ", "$altName"));
+ echo "<br>";
}
- ?>
- <table class="table table-striped table-bordered">
- <tr>
- <td colspan="2"><strong>Certificate Data</strong></td>
- </tr>
- <?php
- $next_cert_data = openssl_x509_parse($raw_next_cert_data);
- $today = date("Y-m-d");
- echo "<tr><td colspan='2'>\n";
- echo "<table class='table'>\n";
- echo "<thead><tr>\n";
- echo "<th>Hostname</th>\n";
- echo "<th>Not Expired</th>\n";
- echo "<th>Issuer</th>\n";
- echo "<th>CRL</th>\n";
- echo "<th>OCSP</th>\n";
- echo "<th>Signing Type</th>\n";
- echo "</tr>\n</thead>\n<tbody>\n<tr>";
- // hostname
- if ($is_issuer == false) {
- if ($csr == false) {
- if ($cert_data['subject']['CN']) {
- if ( verify_certificate_hostname($raw_cert_data, $host) ) {
- echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
- } else {
- echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
- }
+ }
+ echo "</td>";
+ echo "</tr>";
+ }
+ // validation type
+ echo "<tr>";
+ echo "<td>Type</td>";
+ echo "<td>";
+ if ($data["validation_type"] == "extended") {
+ echo '<span class="text-success">Extended Validation</span>';
+ } elseif ($data["validation_type"] == "organization") {
+ echo "Organization Validation";
+ } elseif ($data["validation_type"] == "domain") {
+ echo "Domain Validation";
+ }
+ // full subject
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td>Full Subject</td>";
+ echo "<td>";
+ echo htmlspecialchars($data['cert_data']['name']);
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Issuer</strong></td>";
+ echo "</tr>";
+ if (!empty($data['cert_data']['issuer']) ) {
+ foreach ($data['cert_data']['issuer'] as $key => $value) {
+ echo "<tr><td>";
+ switch ($key) {
+ case 'C':
+ echo "Country";
+ break;
+ case 'ST':
+ echo "State";
+ break;
+ case 'L':
+ echo "City";
+ break;
+ case 'O':
+ echo "Organization";
+ break;
+ case 'OU':
+ echo "Organizational Unit";
+ break;
+ case 'CN':
+ echo "Common Name";
+ break;
+ case 'mail':
+ echo "Email Address";
+ break;
+ case 'emailAddress':
+ echo "Email Address";
+ break;
+ default:
+ echo htmlspecialchars($key);
+ break;
+ }
+ echo "</td><td>";
+ switch ($key) {
+ case 'C':
+ echo htmlspecialchars($value);
+ echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
+ echo strtolower(htmlspecialchars($value));
+ echo '" alt="" />';
+ break;
+ case 'DC':
+ foreach ($value as $key => $value) {
+ echo htmlspecialchars($value) . ".";
+ }
+ break;
+ default:
+ if (is_array($value)) {
+ foreach ($value as $key => $value) {
+ echo htmlspecialchars($value) . " ";
}
} else {
- echo "<td></td>";
+ echo htmlspecialchars($value);
}
- } else {
- echo "<td></td>";
- }
-// expired
- if ( $today > date(DATE_RFC2822,$cert_data['validFrom_time_t']) || strtotime($today) < strtotime(date(DATE_RFC2822,$cert_data['validTo_time_t'])) ) {
- echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
- } else {
- echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ break;
}
-// issuer
- if ($raw_next_cert_data) {
- if (verify_cert_issuer_by_subject_hash($raw_cert_data, $raw_next_cert_data) ) {
- echo '<td><h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1></td>';
+ echo "</td>";
+ echo "</tr>";
+ }
+ }
+ // valid from
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Validity</strong></td>";
+ echo "</tr>";
+ if ( !empty($data['cert_data']['validFrom_time_t']) ) {
+ echo "<tr>";
+ echo "<td>Valid From</td>";
+ echo "<td>";
+ if ( $today < date(DATE_RFC2822,$data['cert_data']['validFrom_time_t']) ) {
+ echo '<span class="text-success glyphicon glyphicon-ok-sign"></span>';
+ echo '<span class="text-success"> - ';
+ } else {
+ echo '<span class="text-danger glyphicon glyphicon-exclamation-sign"></span>';
+ echo '<span class="text-danger"> - ';
+ }
+ echo htmlspecialchars(date(DATE_RFC2822,$data['cert_data']['validFrom_time_t']));
+ echo "</span>";
+ echo "</td>";
+ echo "</tr>";
+ }
+ // issued to expired
+ if ( !empty($data['cert_data']['validTo_time_t']) ) {
+ echo "<tr>";
+ echo "<td>Valid Until</td>";
+ echo "<td>";
+ if ( strtotime($today) < strtotime(date(DATE_RFC2822,$data['cert_data']['validTo_time_t'])) ) {
+ echo '<span class="text-success glyphicon glyphicon-ok-sign"></span>';
+ echo '<span class="text-success"> - ';
+ } else {
+ echo '<span class="text-danger glyphicon glyphicon-exclamation-sign"></span>';
+ echo '<span class="text-danger"> - ';
+ }
+ echo htmlspecialchars(date(DATE_RFC2822,$data['cert_data']['validTo_time_t']));
+ echo "</span>";
+ echo "</td>";
+ echo "</tr>";
+ };
+ if ( is_array($data['crl']) ) {
+ echo "<tr>";
+ echo "<td>CRL</td>";
+ echo "<td>";
+ foreach ($data['crl'] as $key => $value) {
+ if ($value) {
+ if ($value["status"] == "ok") {
+ echo "<span class='text-success glyphicon glyphicon-ok-sign'></span>";
+ echo "<span class='text-success'> - Not on CRL: " . htmlspecialchars($value["crl_uri"]) . "</span><br>";
+ echo "Last update: " . htmlspecialchars($value['crl_last_update']) . "<br>\n";
+ echo "Next update: " . htmlspecialchars($value['crl_next_update']) . "<br>\n";
+ } elseif ($value["status"] == "revoked") {
+ echo "<span class='text-danger glyphicon glyphicon-exclamation-sign'></span>";
+ echo "<span class='text-danger'> - Revoked on CRL: " . htmlspecialchars($value["crl_uri"]) . "</span><br>\n";
+ echo "<span class='text-danger'>Revocation date: " . htmlspecialchars($value["revoked_on"]) . "</span><br>\n";
+ echo "<br>Last update: " . htmlspecialchars($value['crl_last_update']) . "<br>\n";
+ echo "Next update: " . htmlspecialchars($value['crl_next_update']) . "<br>\n";
} else {
- echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ echo "<span class='text-danger glyphicon glyphicon-exclamation-sign'></span>";
+ echo "<span class='text-danger'> - CRL invalid: (" . htmlspecialchars($value["crl_uri"]) . ")</span><br>";
+ echo "<pre> " . htmlspecialchars($value["error"]) . "</pre>";
}
- } else {
- echo '<td> </td>';
}
-// crl
- if ( !empty($cert_data['extensions']['crlDistributionPoints']) ) {
- echo "<td><h1>" . crl_verify($raw_cert_data, false) . " &nbsp; </h1></td>";
- } else {
- echo '<td> </td>';
+ if (count($data['ocsp']) > 1) {
+ echo "<hr>";
}
-// ocsp
- if ( !empty($cert_data['extensions']['authorityInfoAccess']) && !empty($next_cert_data) ) {
- echo "<td>";
- $ocsp_uri = explode("OCSP - URI:", $cert_data['extensions']['authorityInfoAccess'])[1];
- $ocsp_uri = explode("\n", $ocsp_uri)[0];
- $ocsp_uri = explode(" ", $ocsp_uri)[0];
- if (!empty($ocsp_uri)) {
- $ocsp_result = ocsp_verify($raw_cert_data, $raw_next_cert_data);
- if ($ocsp_result["ocsp_verify_status"] == "good") {
- echo '<h1><span class="text-success glyphicon glyphicon-ok"></span>&nbsp;</h1>';
- } else if ($ocsp_result["ocsp_verify_status"] == "revoked") {
- echo '<h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1>';
- } else {
- echo '<h1><span class="text-danger glyphicon glyphicon-question-sign"></span>&nbsp;</h1>';
- }
+ }
+ echo "</td>";
+ echo "</tr>";
+ } else {
+ echo "<tr><td>CRL</td><td>No CRL URI found in certificate</td></tr>";
+ }
+ // ocsp
+ if ( is_array($data['ocsp'])) {
+ echo "<tr>";
+ echo "<td>OCSP</td>";
+ echo "<td>";
+ foreach ($data['ocsp'] as $key => $value) {
+ if ($value) {
+ if ($value["status"] == "good") {
+ echo '<span class="text-success glyphicon glyphicon-ok-sign"></span> ';
+ echo '<span class="text-success"> - OK: ';
+ echo htmlspecialchars($value['ocsp_uri']);
+ echo "</span><br>";
+ echo "Last update: " . htmlspecialchars($value["this_update"]) . "<br>\n";
+ echo "Next update: " . htmlspecialchars($value["next_update"]) . "<br>\n";
+ } else if ( $value["status"] == "revoked") {
+ echo '<span class="text-danger glyphicon glyphicon-remove-sign"></span>';
+ echo '<span class="text-danger"> - REVOKED: ';
+ echo htmlspecialchars($value['ocsp_uri']);
+ echo "</span><br>";
+ echo "<span class='text-danger'>Revocation Time: " . htmlspecialchars($value["revocation_time"]) . "<br>\n";
+ echo "Revocation Reason: " . htmlspecialchars($value["reason"]). "</span><br>";
+ echo "<br>Last update: " . htmlspecialchars($value["this_update"]) . "<br>\n";
+ echo "Next update: " . htmlspecialchars($value["next_update"]) . "<br>\n";
} else {
- echo "<td></td>";
+ echo '<span class="text-danger glyphicon glyphicon-question-sign"></span>';
+ echo '<span class="text-danger"> - UNKNOWN: ';
+ echo " - " . htmlspecialchars($value['ocsp_uri']) . "</span><br>";
+ echo "<pre>" . htmlspecialchars($value["error"]) . "</pre>";
}
- echo "</td>";
- } else {
- echo "<td> </td>";
}
- // self signed/ca/ca root
- if (strpos($cert_data['extensions']['basicConstraints'], "CA:TRUE") !== false && $cert_data['issuer']['CN'] == $cert_data['subject']['CN'] ) {
- echo '<td><span class="text-success">CA Root Certificate</span></td>';
- } else if (strpos($cert_data['extensions']['basicConstraints'], "CA:TRUE") !== false) {
- echo '<td><span class="text-success">CA Certificate</span></td>';
- } else if ($cert_data['issuer']['CN'] == $cert_data['subject']['CN']) {
- echo '<td><span class="text-danger">Self Signed</span></td>';
- } else {
- echo "<td>Signed by CA</td>";
+ if (count($data['ocsp']) > 1) {
+ echo "<hr>";
}
- echo "</tr>";
- echo "</tbody></table>";
- echo "</td></tr>";
-
-
- if (!empty($cert_data['subject']) ) {
- foreach ($cert_data['subject'] as $key => $value) {
- echo "<tr><td>";
- switch ($key) {
- case 'C':
- echo "Country";
- break;
- case 'ST':
- echo "State";
- break;
- case 'L':
- echo "City";
- break;
- case 'O':
- echo "Organization";
- break;
- case 'OU':
- echo "Organizational Unit";
- break;
- case 'CN':
- echo "Common Name";
- break;
- case 'mail':
- echo "Email Address";
- break;
- case 'businessCategory':
- echo "Business Type";
- break;
- default:
- echo htmlspecialchars($key);
- break;
- }
- echo "</td><td>";
- switch ($key) {
- case 'C':
- echo htmlspecialchars($value);
- echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
- echo strtolower(htmlspecialchars($value));
- echo '" alt="" />';
- break;
- case 'DC':
- foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . ".";
- }
- break;
- default:
- if (is_array($value)) {
- foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . " ";
- }
- } else {
- echo htmlspecialchars($value);
- }
- break;
- }
- echo "</td></tr>\n";
- }
-
-
+ }
+ } else {
+ if ($data["ocsp"] == "No issuer cert provided. Unable to send OCSP request.") {
+ echo "<tr><td>OCSP</td><td>No issuer certificate provided. Unable to send OCSP request.</td></tr>";
+ } else {
+ echo "<tr><td>OCSP</td><td>No OCSP URI found in certificate</td></tr>";
+ }
+ }
+ echo "<tr>";
+ echo "<td>Hostname Validation</td>";
+ echo "<td>";
+ // hostname validation
+ if ($data["hostname_in_san_or_cn"] == "true") {
+ echo "<span class='text-success glyphicon glyphicon-ok'></span>\n<span class='text-success'> - ";
+ echo htmlspecialchars($data['hostname_checked']);
+ echo " found in CN or SAN.</span>";
+ } elseif ($data["hostname_in_san_or_cn"] == "false") {
+ echo '<span class="text-danger glyphicon glyphicon-remove"></span><span class="text-danger"> - ';
+ echo htmlspecialchars($data['hostname_checked']);
+ echo ' NOT found in CN or SAN.</span>';
+ } elseif ($data["hostname_in_san_or_cn"] == "n/a; ca signing certificate") {
+ echo "Not applicable, this seems to be a CA signing certificate.";
+ } else {
+ echo "Not applicable, this seems to be a CA signing certificate.";
+ }
+ echo "</td>";
+ echo "</tr>";
+ // details
+ echo "<tr>";
+ echo "<td colspan='2'><strong>Details</strong></td>";
+ echo "</tr>";
+ if ( !empty($data['cert_data']['purposes']) ) {
+ echo "<tr>";
+ echo "<td>Purposes</td>";
+ echo "<td>";
+ foreach ($data['cert_data']['purposes'] as $key => $purpose) {
+ if ($purpose["general"]) {
+ echo htmlspecialchars($key);
+ echo " ";
}
- if (!empty($cert_data['extensions']['subjectAltName'])) {
- ?>
- <tr>
- <td>Subject Alternative Names</td>
- <td>
+ }
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td>Purposes CA</td>";
+ echo "<td>";
+ foreach ($data['cert_data']['purposes'] as $key => $purpose) {
+ if ($purpose["ca"]) {
+ echo htmlspecialchars($key);
+ echo " ";
+ }
+ }
+ echo "</td>";
+ echo "</tr>";
+ }
+ // serial number
+ if (!empty($data['serialNumber']) ) {
+ echo "<tr>";
+ echo "<td>Serial</td>";
+ echo "<td>";
+ echo htmlspecialchars($data['serialNumber']);
+ echo "</td>";
+ echo "</tr>";
+ }
+ echo "<tr>";
+ echo "<td>Key Size / Type</td>";
+ echo "<td>";
+ // key details
+ echo htmlspecialchars($data["key"]['bits']);
+ echo " bits ";
+ echo htmlspecialchars($data["key"]['type']);
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td>Signature Algorithm</td>";
+ echo "<td>";
+ echo $data["key"]["signature_algorithm"];
+ echo "</td>";
+ echo "</tr>";
+ if (count($data['cert_data']['extensions']) >= 1) {
+ echo "<tr>";
+ echo "<td>Extensions</td>";
+ echo "<td>";
+ ?>
+ <div class="panel-group" id="accordion<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab" id="heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <h4 class="panel-title">
+ <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" aria-expanded="false" aria-controls="collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ Click to Open/Close
+ </a>
+ </h4>
+ </div>
+ <div id="collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <div class="panel-body">
<?php
- foreach ( explode("DNS:", $cert_data['extensions']['subjectAltName']) as $altName ) {
- if ( !empty(str_replace(',', " ", "$altName"))) {
- echo htmlspecialchars(str_replace(',', " ", "$altName"));
- echo "<br>";
+ foreach ($data['cert_data']['extensions'] as $name=>$extension) {
+
+ if ( !empty(str_replace(',', " ", "$extension"))) {
+ echo "<strong>" . htmlspecialchars("$name") . "</strong>";
+ echo "<pre>";
+ echo htmlspecialchars($extension);
+ echo "</pre>";
}
}
- ?>
- </td>
- </tr>
- <?php
- }
- ?>
- <tr>
- <td>Type</td>
- <td>
- <?php
- if ( array_search(explode("Policy: ", explode("\n", $cert_data['extensions']['certificatePolicies'])[0])[1], $ev_oids) ) {
- echo '<span class="text-success">Extended Validation</span>';
- } else if ( isset($cert_data['subject']['O'] ) ) {
- echo "Organisation Validation";
- } else if ( isset($cert_data['subject']['CN'] ) ) {
- echo "Domain Validation";
- }
- ?>
- </td>
- </tr>
- <tr>
- <td>Full Subject</td>
- <td><?php echo htmlspecialchars($cert_data['name']); ?></td>
- </tr>
- <tr>
- <td colspan="2"><strong>Issuer</strong></td>
- </tr>
- <?php
- if (!empty($cert_data['issuer']) ) {
- foreach ($cert_data['issuer'] as $key => $value) {
- echo "<tr><td>";
- switch ($key) {
- case 'C':
- echo "Country";
- break;
- case 'ST':
- echo "State";
- break;
- case 'L':
- echo "City";
- break;
- case 'O':
- echo "Organization";
- break;
- case 'OU':
- echo "Organizational Unit";
- break;
- case 'CN':
- echo "Common Name";
- break;
- case 'mail':
- echo "Email Address";
- break;
- case 'emailAddress':
- echo "Email Address";
- break;
- default:
- echo htmlspecialchars($key);
- break;
- }
- echo "</td><td>";
- switch ($key) {
- case 'C':
- echo htmlspecialchars($value);
- echo ' <img src="'.htmlspecialchars($current_folder) . 'img/blank.gif" class="flag flag-';
- echo strtolower(htmlspecialchars($value));
- echo '" alt="" />';
- break;
- case 'DC':
- foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . ".";
- }
- break;
- default:
- if (is_array($value)) {
- foreach ($value as $key => $value) {
- echo htmlspecialchars($value) . " ";
- }
- } else {
- echo htmlspecialchars($value);
- }
- break;
- }
- echo "</td></tr>\n";
- }
- }
- ?>
- <tr>
- <td colspan="2"><strong>Validity</strong></td>
- </tr>
- <?php
- if ( !empty($cert_data['validFrom_time_t']) ) {
- ?>
- <tr>
- <td>Valid From</td>
- <td>
- <?php
- if ( $today < date(DATE_RFC2822,$cert_data['validFrom_time_t']) ) {
- echo '<span class="text-success glyphicon glyphicon-ok-sign"></span>';
- echo '<span class="text-success"> - ';
- } else {
- echo '<span class="text-danger glyphicon glyphicon-exclamation-sign"></span>';
- echo '<span class="text-danger"> - ';
-
- }
- echo htmlspecialchars(date(DATE_RFC2822,$cert_data['validFrom_time_t']));
- echo "</span>";
- ?>
- </td>
- </tr>
-
- <?php
- };
- if ( !empty($cert_data['validTo_time_t']) ) {
- ?>
- <tr>
- <td>Valid Until</td>
- <td>
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</td>";
+ echo "</tr>";
+ } else {
+ echo "<tr>";
+ echo "<td>Extensions</td>";
+ echo "<td>";
+ echo "None";
+ echo "</td>";
+ echo "</tr>";
+ }
+ if(!empty($data["key"]["certificate_pem"])) {
+ echo "<tr>";
+ echo "<td>Certificate PEM </td>";
+ echo "<td>";
+ ?>
+ <div class="panel-group" id="pem-accordion<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab" id="pem-heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <h4 class="panel-title">
+ <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" aria-expanded="false" aria-controls="pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ Click to Open/Close
+ </a>
+ </h4>
+ </div>
+ <div id="pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="pem-heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <div class="panel-body">
<?php
- if ( strtotime($today) < strtotime(date(DATE_RFC2822,$cert_data['validTo_time_t'])) ) {
- echo '<span class="text-success glyphicon glyphicon-ok-sign"></span>';
- echo '<span class="text-success"> - ';
- } else {
- echo '<span class="text-danger glyphicon glyphicon-exclamation-sign"></span>';
- echo '<span class="text-danger"> - ';
- }
- echo htmlspecialchars(date(DATE_RFC2822,$cert_data['validTo_time_t']));
- echo "</span>";
- ?>
- </td>
- </tr>
- <?php
- };
- if ( !empty($cert_data['extensions']['crlDistributionPoints']) ) {
- ?>
- <tr>
- <td>CRL</td>
- <td>
- <?php
- echo crl_verify($raw_cert_data);
- ?>
- </td>
- </tr>
- <?php
- } else {
- echo "<tr><td>CRL</td><td>No CRL URI found in certificate</td></tr>";
- }
- if ( !empty($cert_data['extensions']['authorityInfoAccess']) && !empty($next_cert_data) ) {
- ?>
- <tr>
- <td>OCSP</td>
- <td>
- <?php
- $ocsp_uri = explode("OCSP - URI:", $cert_data['extensions']['authorityInfoAccess'])[1];
- $ocsp_uri = explode("\n", $ocsp_uri)[0];
- $ocsp_uri = explode(" ", $ocsp_uri)[0];
-
- if ( isset($raw_next_cert_data) && !empty($ocsp_uri) ) {
- if ($ocsp_result["ocsp_verify_status"] == "good") {
- echo '<span class="text-success glyphicon glyphicon-ok-sign"></span> ';
- echo '<span class="text-success"> - OK: ';
- echo htmlspecialchars($ocsp_uri);
- echo "</span><br><pre>This update: " . htmlspecialchars($ocsp_result["This Update"]) . " - ";
- echo "<br>Next update: " . htmlspecialchars($ocsp_result["Next Update"]) . "</pre>";
- } else if ( $ocsp_result["ocsp_verify_status"] == "revoked") {
- echo '<span class="text-danger glyphicon glyphicon-remove-sign"></span>';
- echo '<span class="text-danger"> - REVOKED: ';
- echo htmlspecialchars($ocsp_uri);
- echo "</span><br><pre>This update: " . htmlspecialchars($ocsp_result["This Update"]);
- echo "<br>Next update: " . htmlspecialchars($ocsp_result["Next Update"]);
- echo "<br>Revocation Time: " . htmlspecialchars($ocsp_result["Revocation Time"]);
- echo "<br>Revocation Reason: " . htmlspecialchars($ocsp_result["Reason"]). "</pre>";
- } else {
- echo '<span class="text-danger glyphicon glyphicon-question-sign"></span>';
- echo '<span class="text-danger"> - UNKNOWN: ';
-
- echo " - " . htmlspecialchars($ocsp_uri) . "</span><br>";
- echo "<pre>" . htmlspecialchars($ocsp_result["unknown"]) . "</pre>";
- }
- } else {
- echo "No OCSP URI found in certificate";
- }
- ?>
- </td>
- </tr>
- <?php
- } else {
- echo "<tr><td>OCSP</td><td>No OCSP URI found in certificate</td></tr>";
- }
- if ($is_issuer == false && $csr == false) {
- if ($cert_data['subject']['CN']) {
- echo '<tr><td>Hostname</td>';
- if ( verify_certificate_hostname($raw_cert_data, $host, $port) ) {
- echo "<td><span class='text-success glyphicon glyphicon-ok'></span>\n<span class='text-success'> - ";
- echo htmlspecialchars($host);
- echo " found in CN or SAN.</span></td></tr>";
- } else {
+ echo "<pre>";
+ echo htmlspecialchars($data["key"]["certificate_pem"]);
+ echo "</pre>";
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</td>";
+ echo "</tr>";
+ }
- echo '<td><span class="text-danger glyphicon glyphicon-remove"></span><span class="text-danger"> - ';
- echo htmlspecialchars($host);
- echo ' NOT found in CN or SAN.</span></td></tr>';
- }
- }
- } else {
- if ($csr == false) {
- echo "<tr><td>Hostname</td><td>Not applicable, this seems to be a CA signing certificate.</td></tr>";
- } else {
- echo "<tr><td>Hostname</td><td>Not applicable, this seems to be a CSR.</td></tr>";
- }
- }
- ?>
- <tr>
- <td colspan="2"><strong>Details</strong></td>
- </tr>
- <?php
- if ( !empty($cert_data['purposes']) ) {
- ?>
- <tr>
- <td>Purposes</td>
- <td>
- <?php
- $purposes_len = count($cert_data['purposes']);
- foreach ($cert_data['purposes'] as $key => $purpose) {
- echo htmlspecialchars($purpose[2]);
- if ( $key != $purposes_len - 1) {
- echo ", ";
- }
- }
- ?>
- </td>
- </tr>
- <?php
- };
- if ( !empty($cert_data['serialNumber']) ) {
- ?>
- <tr>
- <td>Serial</td>
- <td><code>
- <?php
- $sn = str_split(strtoupper(bcdechex($cert_data['serialNumber'])), 2);
- $sn_len = count($sn);
- foreach ($sn as $key => $s) {
- echo htmlspecialchars($s);
- if ( $key != $sn_len - 1) {
- echo ":";
- }
- }
- ?>
- </code></td>
- </tr>
- <?php
- }
- ?>
- <tr>
- <td>Key Size / Type</td>
- <td>
+ if(!empty($data['key']['public_key_pem'])) {
+ echo "<tr>";
+ echo "<td>Public Key PEM </td>";
+ echo "<td>";
+ ?>
+ <div class="panel-group" id="pub-pem-accordion<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab" id="pub-pem-heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <h4 class="panel-title">
+ <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#pub-pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" aria-expanded="false" aria-controls="pub-pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ Click to Open/Close
+ </a>
+ </h4>
+ </div>
+ <div id="pub-pem-collapse<?php echo bcdechex($data['cert_data']['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="pub-pem-heading<?php echo bcdechex($data['cert_data']['serialNumber']); ?>">
+ <div class="panel-body">
<?php
-
+ echo "<pre>";
+ echo htmlspecialchars($data['key']['public_key_pem']);
+ echo "</pre>";
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</div>";
+ echo "</td>";
+ echo "</tr>";
+ echo "<tr>";
+ echo "<td><a href='https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html'>SPKI Hash</a></td>";
+ echo "<td>";
+ print(htmlspecialchars($data['key']['spki_hash']));
+ echo "</td>";
+ echo "</tr>";
+ }
+ echo "</tbody>";
+ echo "</table>";
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- $key_details = openssl_pkey_get_details(openssl_pkey_get_public($raw_cert_data));
- $export_pem = "";
- openssl_x509_export($raw_cert_data, $export_pem);
-
- if ( $key_details['rsa'] ) {
- echo htmlspecialchars($key_details['bits']);
- echo " bits RSA";
- } else if ( $key_details['dsa'] ) {
- echo htmlspecialchars($key_details['bits']);
- echo " bits DSA";
- } else if ( $key_details['dh'] ) {
- echo htmlspecialchars($key_details['bits']);
- echo " bits DH";
- } else {
- echo htmlspecialchars(var_dump($key_details['bits']));
- echo " bits";
- }
- ?>
- </td>
- </tr>
- <tr>
- <td>Signature Algorithm</td>
- <td>
- <?php
- $signature_algorithm = cert_signature_algorithm($raw_cert_data);
- echo htmlspecialchars($signature_algorithm);
- ?>
- </td>
- </tr>
- <tr>
- <td>Extensions</td>
- <td>
- <div class="panel-group" id="accordion<?php echo bcdechex($cert_data['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
- <div class="panel panel-default">
- <div class="panel-heading" role="tab" id="heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <h4 class="panel-title">
- <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" aria-expanded="false" aria-controls="collapse<?php echo bcdechex($cert_data['serialNumber']); ?>">
- Click to Open/Close
- </a>
- </h4>
- </div>
- <div id="collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <div class="panel-body">
- <?php
- foreach ( $cert_data['extensions'] as $name=>$extension ) {
- if ( !empty(str_replace(',', " ", "$extension"))) {
- echo "<strong>" . htmlspecialchars("$name") . "</strong>";
- echo "<pre>";
- echo htmlspecialchars($extension);
- echo "</pre>";
- }
- }
- ?>
- </div>
- </div>
- </div>
- </div>
- </td>
- </tr>
- <?php
- if(!empty($export_pem)) {
- ?>
- <tr>
- <td>Certificate PEM </td>
- <td>
- <div class="panel-group" id="pem-accordion<?php echo bcdechex($cert_data['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
- <div class="panel panel-default">
- <div class="panel-heading" role="tab" id="pem-heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <h4 class="panel-title">
- <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" aria-expanded="false" aria-controls="pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>">
- Click to Open/Close
- </a>
- </h4>
- </div>
- <div id="pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="pem-heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <div class="panel-body">
- <?php
- echo "<pre>";
- echo htmlspecialchars($export_pem);
- ?>
- </pre>
- </div>
- </div>
- </div>
- </div>
- </td>
- </tr>
- <?php
- }
- ?>
- <?php
- if(!empty($key_details['key'])) {
- ?>
- <tr>
- <td>Public Key PEM </td>
- <td>
- <div class="panel-group" id="pub-pem-accordion<?php echo bcdechex($cert_data['serialNumber']); ?>" role="tablist" aria-multiselectable="true">
- <div class="panel panel-default">
- <div class="panel-heading" role="tab" id="pub-pem-heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <h4 class="panel-title">
- <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#pub-pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" aria-expanded="false" aria-controls="pub-pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>">
- Click to Open/Close
- </a>
- </h4>
- </div>
- <div id="pub-pem-collapse<?php echo bcdechex($cert_data['serialNumber']); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="pub-pem-heading<?php echo bcdechex($cert_data['serialNumber']); ?>">
- <div class="panel-body">
-
- <?php
- echo "<pre>";
- echo htmlspecialchars($key_details['key']);
- ?>
- </pre>
- </div>
- </div>
- </div>
- </div>
- </td>
- </tr>
- <tr>
- <td><a href="https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html">SPKI Hash</a></td>
- <td>
- <?php
- $spki_hash = spki_hash($export_pem);
- print(htmlspecialchars($spki_hash));
- ?>
- </td>
- </tr>
- <?php
- }
- ?>
- </tbody>
- </table>
- <?php
- }
@@ -692,7 +675,7 @@ function csr_parse_json($csr) {
$cert_subject = openssl_csr_get_subject($csr);
$result["subject"] = $cert_subject;
$result["key"] = $cert_key;
- $result["details"] = $cert_details;
+ $result["details"] = $cert_details;
} elseif (strpos($csr, "BEGIN CERTIFICATE") !== false) {
$result = cert_parse_json($csr);
} else {
@@ -722,30 +705,74 @@ function cert_parse_json($raw_cert_data, $raw_next_cert_data=null, $host=null, $
$cert_data['purposes'] = $purposes;
$result["cert_data"] = $cert_data;
}
+
+// valid from
+ if ( !empty($result['cert_data']['validFrom_time_t']) ) {
+ if ( $today < date(DATE_RFC2822,$result['cert_data']['validFrom_time_t']) ) {
+ $result['cert_issued_in_future'] = false;
+ } else {
+ $result['cert_issued_in_future'] = true;
+ $result['warning'][] = "Certificate issue date is in the future: " . date(DATE_RFC2822,$data['cert_data']['validFrom_time_t']);
+ }
+ }
+ // expired
+ if (!empty($cert_data['validTo_time_t'])) {
+ if ($today > date(DATE_RFC2822,$cert_data['validFrom_time_t']) || strtotime($today) < strtotime(date(DATE_RFC2822,$cert_data['validTo_time_t']))) {
+ $result['cert_expired'] = false;
+ } else {
+ $result['cert_expired'] = true;
+ $result['warning'][] = "Certificate expired! Expiration date: " . date(DATE_RFC2822,$cert_data['validTo_time_t']);
+ }
+ }
+
if ( array_search(explode("Policy: ", explode("\n", $cert_data['extensions']['certificatePolicies'])[0])[1], $ev_oids) ) {
$result["validation_type"] = "extended";
} else if ( isset($cert_data['subject']['O'] ) ) {
- $result["validation_type"] = "organisation";
+ $result["validation_type"] = "organization";
} else if ( isset($cert_data['subject']['CN'] ) ) {
$result["validation_type"] = "domain";
}
+ // issuer
+ if ($raw_next_cert_data) {
+ if (verify_cert_issuer_by_subject_hash($raw_cert_data, $raw_next_cert_data) ) {
+ $result["issuer_valid"] = true;
+ } else {
+ $result["issuer_valid"] = false;
+ $result['warning'][] = "Provided certificate issuer does not match issuer in certificate. Sent chain order wrong.";
+ }
+ }
// crl
if (isset($cert_data['extensions']['crlDistributionPoints']) ) {
$result["crl"] = crl_verify_json($raw_cert_data);
+ if (is_array($result["crl"])) {
+ foreach ($result["crl"] as $key => $value) {
+ if ($value["status"] == "revoked") {
+ $result['warning'][] = "Certificate revoked on CRL: " . $value['crl_uri'] . ". Revocation time: " . $value['revoked_on'] . ".";
+ }
+ }
+ }
} else {
$result["crl"] = "No CRL URI found in certificate";
}
// ocsp
- if (isset($cert_data['extensions']['authorityInfoAccess']) && isset($next_cert_data) ) {
+ if (isset($cert_data['extensions']['authorityInfoAccess'])) {
$ocsp_uris = explode("OCSP - URI:", $cert_data['extensions']['authorityInfoAccess']);
unset($ocsp_uris[0]);
- if ( isset($raw_next_cert_data) && isset($ocsp_uris) ) {
- foreach ($ocsp_uris as $key => $ocsp_uri) {
- $ocsp_uri = explode("\n", $ocsp_uri)[0];
- $ocsp_uri = explode(" ", $ocsp_uri)[0];
- $result["ocsp"]["$key"] = ocsp_verify_json($raw_cert_data, $raw_next_cert_data, $ocsp_uri);
+ if (isset($ocsp_uris) ) {
+ if (isset($raw_next_cert_data)) {
+ foreach ($ocsp_uris as $key => $ocsp_uri) {
+ $ocsp_uri = explode("\n", $ocsp_uri)[0];
+ $ocsp_uri = explode(" ", $ocsp_uri)[0];
+ $result["ocsp"]["$key"] = ocsp_verify_json($raw_cert_data, $raw_next_cert_data, $ocsp_uri);
+ if ($result['ocsp'][$key]["status"] == "revoked") {
+ $result['warning'][] = "Certificate revoked on OCSP: " . $result['ocsp'][$key]['ocsp_uri'] . ". Revocation time: " . $result['ocsp'][$key]['revocation_time'] . ".";
+ } elseif ($result['ocsp'][$key]["status"] == "unknown") {
+ $result['warning'][] = "OCSP error on: " . $result['ocsp'][$key]['ocsp_uri'] . ".";
+ }
+ }
+ } else {
+ $result["ocsp"] = "No issuer cert provided. Unable to send OCSP request.";
}
-
} else {
$result["ocsp"] = "No OCSP URI found in certificate";
}
@@ -754,28 +781,30 @@ function cert_parse_json($raw_cert_data, $raw_next_cert_data=null, $host=null, $
}
// hostname validation
if ($validate_hostname == true) {
+ $result["hostname_checked"] = $host;
if (isset($cert_data['subject']['CN'])) {
if ( verify_certificate_hostname($raw_cert_data, $host) ) {
$result["hostname_in_san_or_cn"] = "true";
} else {
$result["hostname_in_san_or_cn"] = "false";
+ $result['warning'][] = "Hostname " . $host . " not found in certificate.";
}
}
} else {
$result["hostname_in_san_or_cn"] = "n/a; ca signing certificate";
}
- //serial
+ //serial number
if ( isset($cert_data['serialNumber']) ) {
- $serial = "";
+ $serial = [];
$sn = str_split(strtoupper(bcdechex($cert_data['serialNumber'])), 2);
$sn_len = count($sn);
foreach ($sn as $key => $s) {
- $serial += htmlspecialchars($s);
+ $serial[] = htmlspecialchars($s);
if ( $key != $sn_len - 1) {
- $serial += ":";
+ $serial[] = ":";
}
}
- $result["serial"] = $serial;
+ $result["serialNumber"] = implode("", $serial);
}
// key details
@@ -785,6 +814,9 @@ function cert_parse_json($raw_cert_data, $raw_next_cert_data=null, $host=null, $
if (isset($key_details['rsa'])) {
$result["key"]["type"] = "rsa";
$result["key"]["bits"] = $key_details['bits'];
+ if ($key_details['bits'] < 2048) {
+ $result['warning'][] = $key_details['bits'] . " bit RSA key is not safe. Upgrade to at least 4096 bits.";
+ }
} else if (isset($key_details['dsa'])) {
$result["key"]["type"] = "dsa";
$result["key"]["bits"] = $key_details['bits'];
@@ -800,6 +832,9 @@ function cert_parse_json($raw_cert_data, $raw_next_cert_data=null, $host=null, $
}
// signature algorithm
$result["key"]["signature_algorithm"] = cert_signature_algorithm($raw_cert_data);
+ if ($result["key"]["signature_algorithm"] == "sha1WithRSAEncryption") {
+ $result['warning'][] = "SHA-1 certificate. Upgrade (re-issue) to SHA-256 or better.";
+ }
if(isset($export_pem)) {
$result["key"]["certificate_pem"] = $export_pem;
}
diff --git a/functions/textual.php b/functions/textual.php
index 93a5838..4a1a48d 100644
--- a/functions/textual.php
+++ b/functions/textual.php
@@ -17,7 +17,20 @@
function pre_dump($var) {
echo "<pre>";
var_dump($var);
- echo "<pre>";
+ echo "</pre>";
+}
+
+function utf8encodeNestedArray($arr) {
+ // json_encode fails with binary data. utf-8 encode that first, some ca's like to encode images in their OID's (verisign, 1.3.6.1.5.5.7.1.12)...
+ $encoded_arr = array();
+ foreach ($arr as $key => $value) {
+ if (is_array($value)) {
+ $encoded_arr[utf8_encode($key)] = utf8encodeNestedArray($value);
+ } else {
+ $encoded_arr[utf8_encode($key)] = utf8_encode($value);
+ }
+ }
+ return $encoded_arr;
}
function startsWith($haystack, $needle) {
@@ -31,7 +44,6 @@ function endsWith($haystack, $needle) {
}
}
-
function get_current_folder(){
$url = $_SERVER['REQUEST_URI'];
$parts = explode('/',$url);
diff --git a/functions/variables.php b/functions/variables.php
index e58b59e..1154bb4 100644
--- a/functions/variables.php
+++ b/functions/variables.php
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+date_default_timezone_set('UTC');
+
$random_blurp = rand(1000,99999);
# 2014-11-10 (nov) from wikipedia
diff --git a/inc/footer.php b/inc/footer.php
new file mode 100644
index 0000000..410777d
--- /dev/null
+++ b/inc/footer.php
@@ -0,0 +1,75 @@
+<?php
+if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
+ ?>
+ <div class="footer">
+ <div class="col-md-6 col-md-offset-1 container">
+ <p class="text-muted">By <a href="https://raymii.org/s/software/OpenSSL_Decoder.html">Remy van Elst</a>. License: GNU AGPLv3. <a href="https://github.com/RaymiiOrg/ssl-decoder">Source code</a>. <a href="https://github.com/RaymiiOrg/ssl-decoder#json-api">JSON API</a>. <strong><a href="https://cipherli.st/">Strong SSL Ciphers & Config settings @ Cipherli.st</a></strong>. Version: 2.1</p>
+ </div>
+ </div>
+ </div>
+</div>
+<?php
+}
+?>
+
+
+<!-- Piwik -->
+<script type="text/javascript">
+ var _paq = _paq || [];
+ _paq.push(['trackPageView']);
+ _paq.push(['enableLinkTracking']);
+ (function() {
+ var u="//hosted-oswa.org/piwik/";
+ _paq.push(['setTrackerUrl', u+'piwik.php']);
+ _paq.push(['setSiteId', 34]);
+ var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+ g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
+ })();
+</script>
+<noscript><p><img src="//hosted-oswa.org/piwik/piwik.php?idsite=34" style="border:0;" alt="" /></p></noscript>
+<!-- End Piwik Code -->
+
+<script>
+
+ $(document).ready(function(){
+ var aChildren = $("nav li").children(); // find the a children of the list items
+ var aArray = []; // create the empty aArray
+ for (var i=0; i < aChildren.length; i++) {
+ var aChild = aChildren[i];
+ var ahref = $(aChild).attr('href');
+ if(ahref && strStartsWith(ahref, "#") ) {
+ aArray.push(ahref);
+ }
+ } // this for loop fills the aArray with attribute href values
+
+ $(window).scroll(function(){
+
+ var windowPos = $(window).scrollTop(); // get the offset of the window from the top of page
+ var windowHeight = $(window).height(); // get the height of the window
+ var docHeight = $(document).height();
+
+ for (var i=0; i < aArray.length; i++) {
+ var theID = aArray[i];
+ var divPos = $(theID).offset().top; // get the offset of the div from the top of page
+ var divHeight = $(theID).height(); // get the height of the div in question
+ if (windowPos >= divPos && windowPos < (divPos + divHeight)) {
+ $("a[href='" + theID + "']").addClass("nav-active");
+ } else {
+ $("a[href='" + theID + "']").removeClass("nav-active");
+ }
+ }
+
+ if(windowPos + windowHeight == docHeight) {
+ if (!$("nav li:last-child a").hasClass("nav-active")) {
+ var navActiveCurrent = $(".nav-active").attr("href");
+ $("a[href='" + navActiveCurrent + "']").removeClass("nav-active");
+ $("nav li:last-child a").addClass("nav-active");
+ }
+ }
+ });
+ });
+
+</script>
+
+ </body>
+ </html> \ No newline at end of file
diff --git a/inc/form.php b/inc/form.php
new file mode 100644
index 0000000..ef00824
--- /dev/null
+++ b/inc/form.php
@@ -0,0 +1,56 @@
+<div id='page-content-wrapper'>
+ <div class='container-fluid'>
+ <div class='row'>
+ <div class="col-md-10 col-md-offset-1">
+ <div class="page-header" >
+ <h1>SSL Decoder</h1>
+ </div>
+ <div id='sslform'>
+ <form class="form-horizontal">
+ <p>Fill in either host + port or paste a CSR/Certficiate. Port defaults to 443.<br></p>
+ <fieldset>
+ <div class="form-group">
+ <label class="col-md-1 control-label" for="host">Host</label>
+ <div class="col-md-5">
+ <input id="host" name="host" type="text" placeholder="raymii.org" class="form-control input-md" >
+ </div>
+ <label class="col-md-1 control-label" for="port">Port</label>
+ <div class="col-md-2">
+ <input id="port" name="port" type="text" placeholder="443" class="form-control input-md">
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-md-4 col-md-offset-1">
+ <div class="checkbox">
+ <label for="ciphersuites">
+ <!-- <input type="checkbox" name="ciphersuites" id="ciphersuites" value="1" checked="checked"> -->
+ <input type="checkbox" name="ciphersuites" id="ciphersuites" value="1" checked="checked">
+ Enumerate Ciphersuites (takes longer)
+ </label>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <div class="form-group">
+ <label class="col-md-1 control-label" for="csr">CSR / Certificate</label>
+ <div class="col-md-5">
+ <textarea class="form-control" rows=6 id="csr" name="csr"></textarea>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-md-4">
+ <label class="col-md-2 col-md-offset-1 control-label" for="s"></label>
+ <button id="s" name="s" class="btn btn-primary" onsubmit="showElementbyID(true, 'preloader'); showElementbyID(false, 'sslform'); makeRequest('/ssl/?port=' + this.form.port.value + '&csr=' + this.form.csr.value + '&s=&host=' + this.form.host.value,, 'showContent');return false" onclick="showElementbyID(true, 'preloader'); showElementbyID(false, 'sslform'); makeRequest('/ssl/?port=' + this.form.port.value + '&csr=' + this.form.csr.value + '&ciphersuites=' + this.form.ciphersuites.value + '&s=&host=' + this.form.host.value, 'showContent');return false">Submit</button>
+ </div>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ <div id="preloader">
+ <p>
+ <img src="<?php echo(htmlspecialchars($current_folder)); ?>img/ajax-loader.gif" />
+ <br>&nbsp;<br>
+ The SSL Decoder is processing your request. Please wait a few moments.<br>
+ </p>
+ </div>
+ <div id="resultDiv"></div> \ No newline at end of file
diff --git a/index.php b/index.php
index c4ecde0..3b0e4d6 100644
--- a/index.php
+++ b/index.php
@@ -41,8 +41,9 @@ foreach (glob("functions/*.php") as $filename) {
<a id="top-of-page"></a>
<?php
- if ( isset($_GET['host']) && !empty($_GET['host'])) {
+ if ( isset($_GET['host']) && !empty($_GET['host'])) {
echo '<div id="wrapper">';
+ $data = [];
$hostname = mb_strtolower(get($_GET['host']));
$host = parse_hostname($hostname);
if ($host['port']) {
@@ -51,340 +52,139 @@ foreach (glob("functions/*.php") as $filename) {
$port = get($_GET['port'], '443');
}
$host = $host['hostname'];
- $csr = get($_GET['csr'], '');
if ( !is_numeric($port) ) {
$port = 443;
}
- $stream = stream_context_create (array("ssl" =>
- array("capture_peer_cert" => true,
- "capture_peer_cert_chain" => true,
- "verify_peer" => false,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- "sni_enabled" => true)));
- $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
- if ( $read_stream !== false ) {
- $context = stream_context_get_params($read_stream);
- $chain_data = $context["options"]["ssl"]["peer_certificate_chain"];
- $chain_length = count($chain_data);
- if (!empty($chain_data) && $chain_length < 10) {
+ $data["data"] = check_json($host,$port);
+ if(isset($data["data"]["error"])) {
+ $data["error"] = $data["data"]["error"];
+ unset($data["data"]);
+ }
+
+ $chain_length = count($data["data"]["chain"]);
+ $chain_data = $data["data"]["chain"];
+ if ($chain_length >= 1 && $chain_length < 10) {
?>
<!-- Sidebar -->
<div id="sidebar-wrapper">
<nav>
- <ul class="sidebar-nav">
- <br>
- <li class="sidebar-brand">
- <h2>Navigation</h2>
- </li>
- <li><a href="#conndata"><strong>0</strong>: Connection Data</a></li>
- <?php
+ <ul class="sidebar-nav">
+ <br>
+ <li class="sidebar-brand">
+ <h2>Navigation</h2>
+ </li>
+ <li><a href="#conndata"><strong>0</strong>: Connection Data</a></li>
+ <?php
foreach ($chain_data as $key => $value) {
- $nextkey = $key + 1;
- echo "<li><a href='#cert".$nextkey."'><strong>".$nextkey."</strong> : ". htmlspecialchars(get_cert_cn($value)) ."</a></li>";
+ echo "<li><a href='#cert".(string)$key."'><strong>".$key."</strong> : ". htmlspecialchars($value["cert_data"]["subject"]["CN"]) ."</a></li>";
}
- ?>
- <li><a href="<?php echo(htmlspecialchars($current_folder)); ?>">Try another website</a></li>
- <li><hr></li>
- <li><a href="https://cipherli.st/">Strong Cipherlists</a></li>
- <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html">Apache SSL Tutorial</a></li>
- <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html">NGINX SSL Tutorial</a></li>
- <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_lighttpd.html">Lighttpd SSL Tutorial</a></li>
- <li><a href="https://raymii.org">Raymii.org</a></li>
- </ul>
+ ?>
+ <li><a href="<?php echo(htmlspecialchars($current_folder)); ?>">Try another website</a></li>
+ <li><hr></li>
+ <li><a href="https://cipherli.st/">Strong Cipherlists</a></li>
+ <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html">Apache SSL Tutorial</a></li>
+ <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html">NGINX SSL Tutorial</a></li>
+ <li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_lighttpd.html">Lighttpd SSL Tutorial</a></li>
+ <li><a href="https://raymii.org">Raymii.org</a></li>
+ </ul>
</nav>
</div>
<!-- /#sidebar-wrapper -->
- <?php
- }
- }
+ <?php
+ }
+ }
+
+ if ( !isset($_GET['host']) || !isset($_GET['csr']) ) {
+ require_once("inc/form.php");
+ } else {
+ echo "<div id='page-content-wrapper'>";
+ echo "<div class='container-fluid'>";
+ echo "<div class='row'>";
+ // if ajax-ed, don't show header again
+ if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
+ echo "<div class='col-md-10 col-md-offset-1'>";
+ echo "<div class='page-header'>";
+ echo "<h1><a style='color:black;' href=\"";
+ echo(htmlspecialchars($current_folder));
+ echo "\">SSL Decoder</a></h1>";
+ echo "</div>";
+ // set back to 1 after debugging
+ $write_cache = 1;
+ if (!is_dir('results')) {
+ mkdir('results');
}
- ?>
-<div id="page-content-wrapper">
- <div class="container-fluid">
- <div class="row">
- <?php
- if ( !isset($_GET['host']) || !isset($_GET['csr']) ) {
- ?>
- <div class="col-md-10 col-md-offset-1">
- <div class="page-header" >
- <h1>SSL Decoder</h1>
- </div>
- <div id='sslform'>
- <form class="form-horizontal">
- <p>Fill in either host + port or paste a CSR/Certficiate. Port defaults to 443.<br></p>
- <fieldset>
-
- <div class="form-group">
- <label class="col-md-1 control-label" for="host">Host</label>
- <div class="col-md-5">
- <input id="host" name="host" type="text" placeholder="raymii.org" class="form-control input-md" >
- </div>
- <label class="col-md-1 control-label" for="port">Port</label>
- <div class="col-md-2">
- <input id="port" name="port" type="text" placeholder="443" class="form-control input-md">
- </div>
- </div>
- <div class="form-group">
- <div class="col-md-4 col-md-offset-1">
- <div class="checkbox">
- <label for="ciphersuites">
- <input type="checkbox" name="ciphersuites" id="ciphersuites" value="1" checked="checked">
- Enumerate Ciphersuites (takes longer)
- </label>
- </div>
- </div>
- </div>
-
- <hr>
-
- <div class="form-group">
- <label class="col-md-1 control-label" for="csr">CSR / Certificate</label>
- <div class="col-md-5">
- <textarea class="form-control" rows=6 id="csr" name="csr"></textarea>
- </div>
- </div>
-
- <div class="form-group">
- <div class="col-md-4">
- <label class="col-md-2 col-md-offset-1 control-label" for="s"></label>
- <button id="s" name="s" class="btn btn-primary" onsubmit="showElementbyID(true, 'preloader'); showElementbyID(false, 'sslform'); makeRequest('/ssl/?port=' + this.form.port.value + '&csr=' + this.form.csr.value + '&s=&host=' + this.form.host.value,, 'showContent');return false" onclick="showElementbyID(true, 'preloader'); showElementbyID(false, 'sslform'); makeRequest('/ssl/?port=' + this.form.port.value + '&csr=' + this.form.csr.value + '&ciphersuites=' + this.form.ciphersuites.value + '&s=&host=' + this.form.host.value, 'showContent');return false">Submit</button>
- </div>
- </div>
-
- </fieldset>
- </form>
- </div>
-
- <div id="preloader"><p><img src="<?php echo(htmlspecialchars($current_folder)); ?>img/ajax-loader.gif" /><br>&nbsp;<br>The SSL Decoder is processing your request. Please wait a few moments.<br></p></div>
-
- <div id="resultDiv"></div>
-
-
- <?php
- } else {
- if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
- ?>
- <div class="col-md-10 col-md-offset-1">
- <div class="page-header" >
- <h1>SSL Decoder</h1>
- </div>
- <?php
- // set back to 1 after debugging
- $write_cache = 1;
- if (!is_dir('results')) {
- mkdir('results');
- }
- $epoch = date('U');
- $random_bla = md5(uniqid(rand(), true));
- }
- $hostname = mb_strtolower(get($_GET['host']));
- $host = parse_hostname($hostname);
- if ($host['port']) {
- $port = $host['port'];
- } else {
- $port = get($_GET['port'], '443');
- }
- $host = $host['hostname'];
- $csr = get($_GET['csr'], '');
- if ( !is_numeric($port) ) {
- $port = 443;
- }
-
- if ( empty($csr) && !empty($host) ) {
-
- echo "<p><strong>This tool does not make conclusions. Please check the data and define the validity yourself!</strong></p><br>";
-
- $stream = stream_context_create (array("ssl" =>
- array("capture_peer_cert" => true,
- "capture_peer_cert_chain" => true,
- "verify_peer" => false,
- "capture_session_meta" => true,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- "sni_enabled" => true)));
- $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2,
- STREAM_CLIENT_CONNECT, $stream);
-
- if ( $read_stream === false ) {
- echo "<span class='text-danger'> Failed to connect:" . htmlspecialchars($errno) ." " . htmlspecialchars($errstr) . "</span>";
- echo "<hr>";
- $write_cache = 0;
- } else {
- $hostfilename = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).])", '', $host);
- $hostfilename = preg_replace("([\.]{2,})", '', $host);
- $hostfilename = preg_replace("([^a-z0-9])", '', $host);
- $cache_filename = (string) "results/saved." . $hostfilename . "." . $epoch . "." . $random_bla . ".html";
-
-
- if ($write_cache == 1) {
- ?>
- <p>This result is saved at most 60 days on <a href="<?php echo(htmlspecialchars($current_folder) . $cache_filename); ?>">the following URL</a>. Do note that this might be deleted earlier if space runs out.</p>
- <?php
- }
- $context = stream_context_get_params($read_stream);
- $context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
- $cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"]);
- $chain_data = $context["options"]["ssl"]["peer_certificate_chain"];
- if (!empty($chain_data)) {
- $chain_length = count($chain_data);
- $chain_arr_keys = ($chain_data);
- foreach(array_keys($chain_arr_keys) as $key) {
- $curr = $chain_data[$key];
- $next = $chain_data[$key+1];
- $prev = $chain_data[$key-1];
-
- if ($key == 0) {
-
- echo ssl_conn_metadata($host, $port, $chain_data);
- echo "<div class='content'><section id='cert1'>";
- echo "<header><h2 class='sticky'>Certificate for '". htmlspecialchars($host) ."'</h2></header>";
-
- if ( $chain_length > $key) {
- cert_parse($curr, $next, false, $host, $port, false);
- } else {
- cert_parse($curr, null, false, $host, $port, false);
- }
- echo "</section></div>";
- } else {
- if ($key == 10) {
- echo "<span class='text-danger'>Error: Certificate Chain to long.</span><br>.";
- $write_cache = 0;
- continue;
- }
- if ($key > 10) {
- $write_cache = 0;
- continue;
- }
- $nextkey = $key + 1;
- echo "<div class='content'><section id='cert" . $nextkey . "'>";
- echo "<header><h2 class='sticky'>Chain $key - " . htmlspecialchars(get_cert_cn($curr)) . "</h2></header>";
-
- if ( $chain_length > $key) {
- cert_parse($curr, $next, false, null, null, true);
- } else {
- cert_parse($curr, null, false, null, null, true);
- }
- echo "</section></div>";
- }
-
- }
- }
-
- }
- } else if (!empty($csr) && empty($host) ) {
-
- $cache_filename = (string) "results/saved.csr." . $epoch . "." . $random_bla . ".html";
-
- echo "<p><strong>This tool does not make conclusions. Please check the data and define the validity yourself!</strong><br>\n &nbsp;</p> <br>";
- if (strpos($csr, "BEGIN CERTIFICATE REQUEST") !== false) {
- echo "<header><h2>CSR </h2></header><p>";
- } else {
- echo "<header><h2>Certificate </h2></header><p>";
- }
- cert_parse($csr, null, true);
-
- } else {
- echo "<span class='text-danger'> Host or Certificate required.</span>";
- echo "<hr>";
- $write_cache = 0;
- }
- }
+ $epoch = date('U');
+ $random_bla = md5(uniqid(rand(), true));
+ }
+
+ if ( empty($_GET['csr']) && !empty($host) ) {
+ echo "<p><strong>This tool does not make conclusions. Please check the data and define the validity yourself!</strong></p>";
+ if ( !empty($data["error"]) ) {
+ echo "<span class='text-danger'>" . htmlspecialchars($data["error"][0]) . "</span>";
+ echo "<hr>";
+ $write_cache = 0;
+ } else {
+ $hostfilename = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).])", '', $host);
+ $hostfilename = preg_replace("([\.]{2,})", '', $host);
+ $hostfilename = preg_replace("([^a-z0-9])", '', $host);
+ $cache_filename = (string) "results/saved." . $hostfilename . "." . $epoch . "." . $random_bla . ".html";
if ($write_cache == 1) {
- ?>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h2 class="panel-title">Saved result</h2>
- </div>
- <div class="panel-body">
- <p>This result is saved at most 60 days on <a href="<?php echo(htmlspecialchars($current_folder) . $cache_filename); ?>">the following URL</a>. Do note that this might be deleted earlier if space runs out.</p>
- </div>
- </div>
- <?php
+ echo "This result is saved at most 60 days on <a href=\"";
+ echo(htmlspecialchars($current_folder) . $cache_filename);
+ echo "\">the following URL</a>. Do note that this might be deleted earlier if space runs out.";
}
- ?>
- </div>
- </div>
- </div>
-
- <?php
- if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
- ?>
- <div class="footer">
- <div class="col-md-6 col-md-offset-1 container">
- <p class="text-muted">By <a href="https://raymii.org/s/software/OpenSSL_Decoder.html">Remy van Elst</a>. License: GNU AGPLv3. <a href="https://github.com/RaymiiOrg/ssl-decoder">Source code</a>. <strong><a href="https://cipherli.st/">Strong SSL Ciphers & Config settings @ Cipherli.st</a></strong>. Version: 2.1</p>
- </div>
- </div>
- </div>
- </div>
- <?php
- }
- ?>
-
-<!-- Piwik -->
-<script type="text/javascript">
- var _paq = _paq || [];
- _paq.push(['trackPageView']);
- _paq.push(['enableLinkTracking']);
- (function() {
- var u="//hosted-oswa.org/piwik/";
- _paq.push(['setTrackerUrl', u+'piwik.php']);
- _paq.push(['setSiteId', 34]);
- var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
- g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
- })();
-</script>
-<noscript><p><img src="//hosted-oswa.org/piwik/piwik.php?idsite=34" style="border:0;" alt="" /></p></noscript>
-<!-- End Piwik Code -->
+ // connection data
+ echo "<div class='content'><section id='conndata'>";
+ echo "<header><h2>Connection Data for " . htmlspecialchars($host) . "</h2></header>";
+ ssl_conn_metadata($data["data"]["connection"]);
+ echo "</section></div>";
+
+ // certificates
+ foreach ($data["data"]["chain"] as $key => $value) {
+ echo "<div class='content'><section id='cert" . $key . "'>";
+ echo "<header><h2>Certificate for '". htmlspecialchars($value["cert_data"]["subject"]["CN"]) ."'</h2></header>";
+ //pre_dump($value);
+ cert_parse($value);
+ echo "</section></div>";
+ }
+ }
+ } elseif (!empty($_GET['csr']) && empty($host) ) {
+ $data = csr_parse_json($_GET['csr']);
+ echo "<p><strong>This tool does not make conclusions. Please check the data and define the validity yourself!</strong><br>\n &nbsp;</p>";
+ $cache_filename = (string) "results/saved.csr." . $epoch . "." . $random_bla . ".html";
+ if ($write_cache == 1) {
+ echo "This result is saved at most 60 days on <a href=\"";
+ echo(htmlspecialchars($current_folder) . $cache_filename);
+ echo "\">the following URL</a>. Do note that this might be deleted earlier if space runs out.";
+ }
-<script>
-
- $(document).ready(function(){
- var aChildren = $("nav li").children(); // find the a children of the list items
- var aArray = []; // create the empty aArray
- for (var i=0; i < aChildren.length; i++) {
- var aChild = aChildren[i];
- var ahref = $(aChild).attr('href');
- if(ahref && strStartsWith(ahref, "#") ) {
- aArray.push(ahref);
- }
- } // this for loop fills the aArray with attribute href values
-
- $(window).scroll(function(){
-
- var windowPos = $(window).scrollTop(); // get the offset of the window from the top of page
- var windowHeight = $(window).height(); // get the height of the window
- var docHeight = $(document).height();
-
- for (var i=0; i < aArray.length; i++) {
- var theID = aArray[i];
- var divPos = $(theID).offset().top; // get the offset of the div from the top of page
- var divHeight = $(theID).height(); // get the height of the div in question
- if (windowPos >= divPos && windowPos < (divPos + divHeight)) {
- $("a[href='" + theID + "']").addClass("nav-active");
- } else {
- $("a[href='" + theID + "']").removeClass("nav-active");
- }
- }
-
- if(windowPos + windowHeight == docHeight) {
- if (!$("nav li:last-child a").hasClass("nav-active")) {
- var navActiveCurrent = $(".nav-active").attr("href");
- $("a[href='" + navActiveCurrent + "']").removeClass("nav-active");
- $("nav li:last-child a").addClass("nav-active");
- }
- }
- });
- });
+ if (strpos($_GET['csr'], "BEGIN CERTIFICATE REQUEST") !== false) {
+ echo "<header><h2>CSR </h2></header><p>";
+ csr_parse($data);
+ } else {
+ echo "<header><h2>Certificate </h2></header><p>";
+ cert_parse($data);
+ }
+ } else {
+ echo "<span class='text-danger'> Host or Certificate required.</span>";
+ echo "<hr>";
+ $write_cache = 0;
+ }
+ }
-</script>
+
+
+ ?>
+ </div>
+ </div>
+ </div>
- </body>
- </html>
<?php
+require_once("inc/footer.php");
+
if ($write_cache == 1) {
if (!file_exists($cache_filename)) {
file_put_contents($cache_filename, ob_get_contents());
diff --git a/json.php b/json.php
index 11ffef0..f83d7f9 100644
--- a/json.php
+++ b/json.php
@@ -4,62 +4,6 @@ foreach (glob("functions/*.php") as $filename) {
include $filename;
}
-function utf8encodeNestedArray($arr) {
- // json_encode fails with binary data. utf-8 encode that first, some ca's like to encode images in their OID's (verisign, 1.3.6.1.5.5.7.1.12)...
- $encoded_arr = array();
- foreach ($arr as $key => $value) {
- if (is_array($value)) {
- $encoded_arr[utf8_encode($key)] = utf8encodeNestedArray($value);
- } else {
- $encoded_arr[utf8_encode($key)] = utf8_encode($value);
- }
- }
- return $encoded_arr;
-}
-
-function check_json($host,$port) {
- $data = [];
- $stream = stream_context_create (array("ssl" =>
- array("capture_peer_cert" => true,
- "capture_peer_cert_chain" => true,
- "verify_peer" => false,
- "verify_peer_name" => false,
- "allow_self_signed" => true,
- "capture_session_meta" => true,
- "sni_enabled" => true)));
- $read_stream = stream_socket_client("ssl://$host:$port", $errno, $errstr, 2, STREAM_CLIENT_CONNECT, $stream);
- if ( $read_stream === false ) {
- $data["error"] = ["Failed to connect: " . htmlspecialchars($errstr)];
- return $data;
- } else {
- $context = stream_context_get_params($read_stream);
- $context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
- $cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"]);
- $chain_data = $context["options"]["ssl"]["peer_certificate_chain"];
- $chain_length = count($chain_data);
- if (isset($chain_data) && $chain_length < 10) {
- $chain_length = count($chain_data);
- $chain_arr_keys = ($chain_data);
- foreach(array_keys($chain_arr_keys) as $key) {
- $curr = $chain_data[$key];
- $next = $chain_data[$key+1];
- $prev = $chain_data[$key-1];
- $chain_key = (string)$key+1;
- if ($key == 0) {
- $data["connection"] = ssl_conn_metadata_json($host, $port, $read_stream, $chain_data);
- $data["chain"][$chain_key] = cert_parse_json($curr, $next, false, $host, true);
- } else {
- $data["chain"][$chain_key] = cert_parse_json($curr, $next, false, null, false);
- }
- }
- } else {
- $data["error"] = ["Chain too long."];
- return $data;
- }
- }
- return $data;
-}
-
if ( isset($_GET['host']) && !empty($_GET['host'])) {
$data = [];
$hostname = mb_strtolower(get($_GET['host']));