<?php defined('ABSPATH') or die("you do not have access to this page!"); if (!class_exists('rsssl_certificate')) { class rsssl_certificate { private static $_this; function __construct() { if (isset(self::$_this)) { wp_die(sprintf(__('%s is a singleton class and you cannot create a second instance.', 'really-simple-ssl'), get_class($this))); } self::$_this = $this; } static function this() { return self::$_this; } public function is_valid() { $domain = site_url(); $parse = parse_url($domain); $domain = $parse['host']; if (function_exists('stream_context_get_params')) { $certinfo = $this->get_certinfo($domain); if (!$certinfo) { RSSSL()->really_simple_ssl->trace_log("- SSL certificate not valid"); return false; } $domain_valid = $this->is_domain_valid($certinfo, $domain); if (!$domain_valid) { RSSSL()->really_simple_ssl->trace_log("- Domain on certificate does not match website's domain"); } $date_valid = $this->is_date_valid($certinfo); if (!$date_valid) { RSSSL()->really_simple_ssl->trace_log("- Date on certificate expired or not valid"); } if ($domain_valid && $date_valid) { return true; } } return false; } public function is_domain_valid($certinfo, $domain) { $certificate_common_names = isset($certinfo['subject']['CN']) ? $certinfo['subject']['CN'] : false; $certificate_alternative_names = isset($certinfo['extensions']['subjectAltName']) ? $certinfo['extensions']['subjectAltName'] : false; $pos_cn = strpos($certificate_common_names, $domain); $pos_an = strpos($certificate_alternative_names, $domain); if ($pos_cn !== false || $pos_an !== false) { return true; } $cert_domains = array(); if ($this->is_wildcard()) { $certificate_alternative_names = isset($certinfo['extensions']['subjectAltName']) ? explode(', ', $certinfo['extensions']['subjectAltName']) : false; $cert_domains[] = trim(str_replace('*', '', $certificate_common_names)); foreach ($certificate_alternative_names as $subjectAltName) { $cert_domains[] = trim(str_replace('*', '', $subjectAltName)); } foreach ($cert_domains as $cert_domain) { if (strpos($domain, $cert_domain) !== false) { return true; } } } return false; } public function detection_failed() { $certinfo = get_transient('rsssl_certinfo'); if ($certinfo && $certinfo === 'no-response') { return true; } return false; } public function is_date_valid($certinfo) { $start_date = isset($certinfo['validFrom_time_t']) ? $certinfo['validFrom_time_t'] : false; $end_date = isset($certinfo['validTo_time_t']) ? $certinfo['validTo_time_t'] : false; $current_date = time(); if ($current_date > $start_date && $current_date < $end_date) { return true; } return false; } public function expiry_date_nice() { $valid = RSSSL()->rsssl_certificate->is_valid(); $certinfo = get_transient('rsssl_certinfo'); $end_date = isset($certinfo['validTo_time_t']) ? $certinfo['validTo_time_t'] : false; $expiry_date = !empty($end_date) ? date(get_option('date_format'), $end_date) : false; return $expiry_date; } public function about_to_expire() { $valid = $this->is_valid(); if (!$valid) { return true; } $certinfo = get_transient('rsssl_certinfo'); $end_date = isset($certinfo['validTo_time_t']) ? $certinfo['validTo_time_t'] : false; $expiry_days_time = strtotime('+' . rsssl_le_manual_generation_renewal_check . ' days'); if ($expiry_days_time < $end_date) { return false; } else { return true; } } public function is_wildcard() { $domain = network_site_url(); $certinfo = $this->get_certinfo($domain); $certificate_common_name = isset($certinfo['subject']['CN']) ? $certinfo['subject']['CN'] : false; $subjectAltNames = isset($certinfo['extensions']['subjectAltName']) ? explode(', ', $certinfo['extensions']['subjectAltName']) : false; if (strpos($certificate_common_name, '*')) { return true; } if (is_array($subjectAltNames)) { foreach ($subjectAltNames as $subjectAltName) { if (strpos($subjectAltName, '*') !== false) { return true; } } } return false; } public function get_certinfo($url) { $certinfo = get_transient('rsssl_certinfo'); if ($certinfo === 'no-response') { return false; } if (!$certinfo || RSSSL()->really_simple_ssl->is_settings_page()) { $url = 'https://' . str_replace(array('https://', 'http://'), '', $url); $original_parse = parse_url($url, PHP_URL_HOST); if ($original_parse) { $get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE))); if ($get) { set_error_handler(array($this, 'custom_error_handling')); $read = stream_socket_client("ssl://" . $original_parse . ":443", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $get); restore_error_handler(); if (!$read) { $certinfo = 'no-response'; } if ($errno == 0 && $read) { $cert = stream_context_get_params($read); if (isset($cert['options']['ssl']['peer_certificate'])) { $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); } else { $certinfo = 'no-response'; } } } } set_transient('rsssl_certinfo', $certinfo, DAY_IN_SECONDS); } if ($certinfo === 'not-valid') { return false; } if (!empty($certinfo)) { return $certinfo; } return false; } public function custom_error_handling($errno, $errstr, $errfile, $errline, $errcontext = array()) { return true; } } }