summaryrefslogtreecommitdiffstats
path: root/functions
diff options
context:
space:
mode:
Diffstat (limited to 'functions')
-rw-r--r--functions/connection.php506
-rw-r--r--functions/crl.php99
-rw-r--r--functions/numerical.php30
-rw-r--r--functions/ocsp.php101
-rw-r--r--functions/parse_certificate.php651
-rw-r--r--functions/textual.php30
-rw-r--r--functions/variables.php24
-rw-r--r--functions/verify_certifitcate.php80
8 files changed, 1521 insertions, 0 deletions
diff --git a/functions/connection.php b/functions/connection.php
new file mode 100644
index 0000000..33af1ad
--- /dev/null
+++ b/functions/connection.php
@@ -0,0 +1,506 @@
+<!--
+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 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+function fixed_gethostbyname($host) {
+ $ip = gethostbyname($host);
+ if ($ip != $host) {
+ return $ip;
+ } else {
+ return false;
+ }
+}
+
+function get(&$var, $default=null) {
+ return isset($var) ? $var : $default;
+}
+
+function server_http_headers($host, $port){
+ stream_context_set_default(
+ array("ssl" =>
+ array("verify_peer" => false,
+ "capture_session_meta" => true,
+ "verify_peer_name" => false,
+ "allow_self_signed" => true,
+ "sni_enabled" => true),
+ 'http' => array(
+ 'method' => 'HEAD'
+ )
+ )
+ );
+ $headers = get_headers("https://$host:$port", 1);
+ if (!empty($headers)) {
+ return $headers;
+ }
+}
+
+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;
+ }
+
+
+function ssl_conn_metadata($host, $port, $chain=null) {
+$stream = stream_context_create (array("ssl" =>
+ array("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 ) {
+ return 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) {
+ ?>
+ <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
+ foreach ($chain as $key => $cert) {
+ if ( $key == 10) {
+ echo "<span class='text-danger'>Error: Certificate chain to large.</span><br>";
+ continue;
+ }
+ if ( $key > 10) {
+ continue;
+ }
+ if (openssl_x509_parse($cert)['issuer']['CN'] && openssl_x509_parse($cert)['subject']['CN']) {
+ echo "Name...........: <i>";
+ echo htmlspecialchars(openssl_x509_parse($cert)['subject']['CN']);
+ echo " </i><br>Issued by......:<i> ";
+ echo htmlspecialchars(openssl_x509_parse($cert)['issuer']['CN']);
+ echo "</i><br>";
+ }
+ }
+ ?>
+ </td>
+ </tr>
+
+ <?php
+ }
+ if ( fixed_gethostbyname($host) ) {
+ ?>
+ <tr>
+ <td>IP / Hostname</td>
+ <td>
+ <?php
+ echo fixed_gethostbyname($host);
+ echo " - ";
+ echo gethostbyaddr(fixed_gethostbyname($host));
+ ?>
+ </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>';
+ }
+ }
+ }
+ ?>
+
+ </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');
+ $supported_ciphersuites = ssl_conn_ciphersuites($host, $port, $ciphersuites_to_test);
+
+ foreach ($supported_ciphersuites as $key => $value) {
+ if($value == true){
+ echo "";
+ echo "<span class='text-success glyphicon glyphicon-ok'></span> - ";
+ echo htmlspecialchars($key);
+ echo "<br>";
+ } else {
+ echo "<!-- ";
+ echo "<span class='glyphicon glyphicon-remove'></span> - ";
+ echo htmlspecialchars($key);
+ echo " <br -->";
+ }
+
+ }
+
+ ?>
+ </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
+ }
+ $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"] ) {
+ 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));
+ }
+ } 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"] ) {
+ 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>";
+ } 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>
+ <?php
+ } else {
+ return false;
+ }
+}
+}
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/functions/crl.php b/functions/crl.php
new file mode 100644
index 0000000..7e477b2
--- /dev/null
+++ b/functions/crl.php
@@ -0,0 +1,99 @@
+<!--
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+function crl_verify($raw_cert_data, $verbose=true) {
+ global $random_blurp;
+ $cert_data = openssl_x509_parse($raw_cert_data);
+ $cert_serial_nm = strtoupper(bcdechex($cert_data['serialNumber']));
+ $crl_uris = [];
+ $crl_uri = explode("\nFull Name:\n ", $cert_data['extensions']['crlDistributionPoints']);
+ foreach ($crl_uri as $key => $uri) {
+ if (!empty($uri) ) {
+ $uri = explode("URI:", $uri);
+ foreach ($uri as $key => $crluri) {
+ if (!empty($crluri) ) {
+ $crl_uris[] = preg_replace('/\s+/', '', $crluri);
+ }
+ }
+ }
+ }
+ foreach ($crl_uris as $key => $uri) {
+ if (!empty($uri)) {
+ if (0 === strpos($uri, 'http')) {
+ $fp = fopen ("/tmp/" . $random_blurp . "." . $key . ".crl", 'w+');
+ $ch = curl_init(($uri));
+ curl_setopt($ch, CURLOPT_TIMEOUT, 5);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ if(curl_exec($ch) === false)
+ {
+ echo '<pre>Curl error: ' . htmlspecialchars(curl_error($ch)) ."</pre>";
+ }
+ curl_close($ch);
+ if(stat("/tmp/" . $random_blurp . "." . $key . ".crl")['size'] < 10 ) {
+ return false;
+ }
+ $crl_text = shell_exec("openssl crl -noout -text -inform der -in /tmp/" . $random_blurp . "." . $key . ".crl 2>&1");
+
+ $crl_last_update = shell_exec("openssl crl -noout -lastupdate -inform der -in /tmp/" . $random_blurp . "." . $key . ".crl");
+
+ $crl_next_update = shell_exec("openssl crl -noout -nextupdate -inform der -in /tmp/" . $random_blurp . "." . $key . ".crl");
+
+ unlink("/tmp/" . $random_blurp . "." . $key . ".crl");
+
+ if ( strpos($crl_text, "unable to load CRL") === 0 ) {
+ if ( $verbose ) {
+ $result = "<span class='text-danger glyphicon glyphicon-exclamation-sign'></span> - <span class='text-danger'>CRL invalid. (" . $uri . ")</span><br><pre> " . htmlspecialchars($crl_text) . "</pre>";
+ return $result;
+ } else {
+ $result = "<span class='text-danger glyphicon glyphicon-remove'></span>";
+ return $result;
+ }
+ }
+
+ $crl_info = explode("Revoked Certificates:", $crl_text)[0];
+
+ $crl_certificates = explode("Revoked Certificates:", $crl_text)[1];
+
+ $crl_certificates = explode("Serial Number:", $crl_certificates);
+ $revcert = array('bla' => "die bla");
+ foreach ($crl_certificates as $key => $revoked_certificate) {
+ if (!empty($revoked_certificate)) {
+ $revcert[str_replace(" ", "", explode("\n", $revoked_certificate)[0])] = str_replace(" Revocation Date: ", "", explode("\n", $revoked_certificate)[1]);
+ }
+ }
+ if( array_key_exists($cert_serial_nm, $revcert) ) {
+ if ( $verbose ) {
+ $result = "<span class='text-danger glyphicon glyphicon-exclamation-sign'></span> - <span class='text-danger'>REVOKED on " . $revcert[$cert_serial_nm] . ". " . $uri . "</span><br><pre> " . $crl_last_update . " " . $crl_next_update . "</pre>";
+ } else {
+ $result = "<span class='text-danger glyphicon glyphicon-remove'></span>";
+ }
+ } else {
+ if ( $verbose ) {
+ $result = "<span class='text-success glyphicon glyphicon-ok-sign'></span> <span class='text-success'> - " . $uri . "</span><br><pre> " . $crl_last_update . " " . $crl_next_update . "</pre>";
+ } else {
+ $result = "<span class='text-success glyphicon glyphicon-ok'></span>";
+ }
+ }
+ return $result;
+ }
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/functions/numerical.php b/functions/numerical.php
new file mode 100644
index 0000000..a363374
--- /dev/null
+++ b/functions/numerical.php
@@ -0,0 +1,30 @@
+<!--
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+function bcdechex($dec) {
+ $hex = '';
+ do {
+ $last = bcmod($dec, 16);
+ $hex = dechex($last).$hex;
+ $dec = bcdiv(bcsub($dec, $last), 16);
+ } while($dec>0);
+ return $hex;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/functions/ocsp.php b/functions/ocsp.php
new file mode 100644
index 0000000..21b03d7
--- /dev/null
+++ b/functions/ocsp.php
@@ -0,0 +1,101 @@
+<!--
+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 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+function ocsp_stapling($host, $port){
+ $result = "";
+ $output = shell_exec('echo | timeout 5 openssl s_client -connect "' . escapeshellcmd($host) . ':' . escapeshellcmd($port) . '" -tlsextdebug -status 2>&1 | sed -n "/OCSP response:/,/---/p"');
+ 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();
+ $output = preg_replace("/[[:blank:]]+/"," ", $output);
+ $stapling_status_lines = explode("\n", $output);
+ $stapling_status_lines = array_map('trim', $stapling_status_lines);
+ foreach($stapling_status_lines as $line) {
+ if(endsWith($line, ":") == false) {
+ list($k, $v) = explode(":", $line);
+ $lines[trim($k)] = trim($v);
+ }
+ }
+ $result = array("working" => 1,
+ "Cert Status" => $lines["Cert Status"],
+ "This Update" => $lines["This Update"],
+ "Next Update" => $lines["Next Update"],
+ "Responder ID" => $lines["Responder Id"],
+ "Hash Algorithm" => $lines["Hash Algorithm"],
+ "Signature Algorithm" => $lines["Signature Algorithm"],
+ "Issuer Name Hash" => $lines["Issuer Name Hash"]);
+ }
+ 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');
+
+//echo 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).'" 2>&1');
+
+ $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) . '" 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) . '" 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);
+ $lines[trim($k)] = trim($v);
+ }
+ }
+
+ $result = array("This Update" => $lines["This Update"],
+ "Next Update" => $lines["Next Update"],
+ "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;
+}
+
+?> \ No newline at end of file
diff --git a/functions/parse_certificate.php b/functions/parse_certificate.php
new file mode 100644
index 0000000..1bdfedd
--- /dev/null
+++ b/functions/parse_certificate.php
@@ -0,0 +1,651 @@
+<!--
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+
+ 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;
+ }
+
+ echo "</td><td>";
+ switch ($key) {
+ case 'C':
+ echo htmlspecialchars($value);
+ echo ' <img src="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 "</table>";
+ return;
+ } else {
+ $cert_data = openssl_x509_parse($raw_cert_data);
+ }
+ if (empty($cert_data)) {
+ echo "Data not valid.";
+ continue;
+ }
+ ?>
+ <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, $port) ) {
+ 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>";
+ }
+ } 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>';
+ }
+// 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>';
+ } else {
+ echo '<td><h1><span class="text-danger glyphicon glyphicon-remove"></span>&nbsp;</h1></td>';
+ }
+ } 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>';
+ }
+// 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>';
+ }
+ } else {
+ echo "<td></td>";
+ }
+ 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>";
+ }
+ 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="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";
+ }
+
+
+ }
+ if (!empty($cert_data['extensions']['subjectAltName'])) {
+ ?>
+ <tr>
+ <td>Subject Alternative Names</td>
+ <td>
+ <?php
+ foreach ( explode("DNS:", $cert_data['extensions']['subjectAltName']) as $altName ) {
+ if ( !empty(str_replace(',', " ", "$altName"))) {
+ echo htmlspecialchars(str_replace(',', " ", "$altName"));
+ echo "<br>";
+ }
+ }
+ ?>
+ </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="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>
+ <?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) ) {
+
+ $ocsp_result = ocsp_verify($raw_cert_data, $raw_next_cert_data);
+ if ($ocsp_result["ocsp_verify_status"] == "good") {
+ echo '<span class="text-success glyphicon glyphicon-ok-sign"></span> ';
+ echo '<span class="text-success">';
+ echo htmlspecialchars($ocsp_uri);
+ echo "<br>This update: " . htmlspecialchars($ocsp_result["This Update"]) . " - ";
+ echo "<br>Next update: " . htmlspecialchars($ocsp_result["Next Update"]) . "</span>";
+ } else if ( $ocsp_result["ocsp_verify_status"] == "revoked") {
+ echo '<span class="text-danger glyphicon glyphicon-remove-sign"></span> - ';
+ echo '<span class="text-danger">';
+ echo htmlspecialchars($ocsp_uri);
+ echo "<br>This update: " . htmlspecialchars($ocsp_result["This Update"]);
+ echo "<br>Next update: " . htmlspecialchars($ocsp_result["Next Update"]) . "</span>";
+ } else {
+ echo '<span class="text-danger glyphicon glyphicon-question-sign"></span>';
+ echo '<span class="text-danger">';
+
+ 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 '<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>
+ <?php
+
+
+ $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>
+ <?php
+ }
+ ?>
+ </tbody>
+ </table>
+ <?php
+ }
+
+?> \ No newline at end of file
diff --git a/functions/textual.php b/functions/textual.php
new file mode 100644
index 0000000..4287283
--- /dev/null
+++ b/functions/textual.php
@@ -0,0 +1,30 @@
+<!--
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+function startsWith($haystack, $needle) {
+ // search backwards starting from haystack length characters from the end
+ return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
+}
+function endsWith($haystack, $needle) {
+ // search forward starting from end minus needle length characters
+ if(!empty($haystack)) {
+ return $needle === "" || strpos($haystack, $needle, strlen($haystack) - strlen($needle)) !== FALSE;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/functions/variables.php b/functions/variables.php
new file mode 100644
index 0000000..479dccd
--- /dev/null
+++ b/functions/variables.php
@@ -0,0 +1,24 @@
+<!--
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+
+$random_blurp = rand(1000,99999);
+
+# 2014-11-10 (nov) from wikipedia
+$ev_oids = array("1.3.6.1.4.1.34697.2.1", "1.3.6.1.4.1.34697.2.2", "1.3.6.1.4.1.34697.2.3", "1.3.6.1.4.1.34697.2.4", "1.2.40.0.17.1.22", "2.16.578.1.26.1.3.3", "1.3.6.1.4.1.17326.10.14.2.1.2", "1.3.6.1.4.1.17326.10.8.12.1.2", "1.3.6.1.4.1.6449.1.2.1.5.1", "2.16.840.1.114412.2.1", "2.16.840.1.114412.1.3.0.2", "2.16.528.1.1001.1.1.1.12.6.1.1.1", "2.16.840.1.114028.10.1.2", "0.4.0.2042.1.4", "0.4.0.2042.1.5", "1.3.6.1.4.1.13177.10.1.3.10", "1.3.6.1.4.1.14370.1.6", "1.3.6.1.4.1.4146.1.1", "2.16.840.1.114413.1.7.23.3", "1.3.6.1.4.1.14777.6.1.1", "2.16.792.1.2.1.1.5.7.1.9", "1.3.6.1.4.1.22234.2.5.2.3.1", "1.3.6.1.4.1.782.1.2.1.8.1", "1.3.6.1.4.1.8024.0.2.100.1.2", "1.2.392.200091.100.721.1", "2.16.840.1.114414.1.7.23.3", "1.3.6.1.4.1.23223.2", "1.3.6.1.4.1.23223.1.1.1", "2.16.756.1.83.21.0", "2.16.756.1.89.1.2.1.1", "2.16.840.1.113733.1.7.48.1", "2.16.840.1.114404.1.1.2.4.1", "2.16.840.1.113733.1.7.23.6", "1.3.6.1.4.1.6334.1.100.1", "2.16.840.1.114171.500.9", "1.3.6.1.4.1.36305.2");
+
+?> \ No newline at end of file
diff --git a/functions/verify_certifitcate.php b/functions/verify_certifitcate.php
new file mode 100644
index 0000000..95a4a9f
--- /dev/null
+++ b/functions/verify_certifitcate.php
@@ -0,0 +1,80 @@
+<!--
+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 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<?php
+function verify_certificate_hostname($raw_cert, $host, $port) {
+ $cert_data = openssl_x509_parse($raw_cert);
+ if ($cert_data['subject']['CN']) {
+ $cert_host_names = [];
+ $cert_host_names[] = $cert_data['subject']['CN'];
+ if ($cert_data['extensions']['subjectAltName']) {
+ foreach ( explode("DNS:", $cert_data['extensions']['subjectAltName']) as $altName ) {
+ foreach (explode(",", $altName) as $key => $value) {
+ if ( !empty(str_replace(',', "", "$value"))) {
+ $cert_host_names[] = str_replace(" ", "", str_replace(',', "", "$value"));
+ }
+ }
+ }
+ }
+ foreach ($cert_host_names as $key => $hostname) {
+ if (strpos($hostname, "*.") === 0) {
+// wildcard hostname from cert
+ if (explode(".", $host, 2)[1] == explode(".", $hostname, 2)[1] ) {
+// split cert name and host name on . and compare everything after the first dot
+ return true;
+ }
+ }
+// no wildcard, just regular match
+ if ($host == $hostname) {
+ return true;
+ }
+ }
+// no match
+ return false;
+ }
+}
+
+
+
+function verify_cert_issuer_by_subject_hash($raw_cert_data, $raw_next_cert_data) {
+ global $random_blurp;
+ $tmp_dir = "/tmp/";
+ 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');
+
+//echo 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).'" 2>&1');
+
+ $cert_issuer_hash = shell_exec('openssl x509 -noout -issuer_hash -in '.$tmp_dir.$random_blurp.'.cert_client.pem 2>&1');
+ $issuer_subject_hash = shell_exec('openssl x509 -noout -subject_hash -in '.$tmp_dir.$random_blurp.'.cert_issuer.pem 2>&1');
+
+ unlink($tmp_dir.$random_blurp.'.cert_client.pem');
+ unlink($tmp_dir.$random_blurp.'.cert_issuer.pem');
+ if ( $cert_issuer_hash == $issuer_subject_hash ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function cert_signature_algorithm($raw_cert_data) {
+ $cert_read = openssl_x509_read($raw_cert_data);
+ openssl_x509_export($cert_read, $out, FALSE);
+ $signature_algorithm = null;
+ if(preg_match('/^\s+Signature Algorithm:\s*(.*)\s*$/m', $out, $match)) $signature_algorithm = $match[1];
+ return($signature_algorithm);
+}
+
+?> \ No newline at end of file