<?php

class Requests_SSL
{
    public static function verify_certificate($host, $cert)
    {
        $parts = explode('.', $host);
        if (ip2long($host) === false) {
            $parts[0] = '*';
        }
        $wildcard = implode('.', $parts);
        $has_dns_alt = false;
        if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
            $altnames = explode(',', $cert['extensions']['subjectAltName']);
            foreach ($altnames as $altname) {
                $altname = trim($altname);
                if (strpos($altname, 'DNS:') !== 0) {
                    continue;
                }
                $has_dns_alt = true;
                $altname = trim(substr($altname, 4));
                if (self::match_domain($host, $altname) === true) {
                    return true;
                }
            }
        }
        if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
            if (self::match_domain($host, $cert['subject']['CN']) === true) {
                return true;
            }
        }
        return false;
    }
    public static function verify_reference_name($reference)
    {
        $parts = explode('.', $reference);
        $first = array_shift($parts);
        if (strpos($first, '*') !== false) {
            if ($first !== '*') {
                return false;
            }
            if (count($parts) < 2) {
                return false;
            }
        }
        foreach ($parts as $part) {
            if (strpos($part, '*') !== false) {
                return false;
            }
        }
        return true;
    }
    public static function match_domain($host, $reference)
    {
        if (self::verify_reference_name($reference) !== true) {
            return false;
        }
        if ($host === $reference) {
            return true;
        }
        if (ip2long($host) === false) {
            $parts = explode('.', $host);
            $parts[0] = '*';
            $wildcard = implode('.', $parts);
            if ($wildcard === $reference) {
                return true;
            }
        }
        return false;
    }
}