mirror of
https://github.com/danog/phpseclib.git
synced 2024-11-27 04:46:26 +01:00
- fix a bunch of E_NOTICEs, add support for the id-ce-certificatePolicies extension, add limited validation
git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@206 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
81beb6e2e2
commit
5cc327e0c3
@ -112,6 +112,38 @@ define('FILE_ASN1_TYPE_CHOICE', -1);
|
||||
define('FILE_ASN1_TYPE_ANY', -2);
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* ASN.1 Element
|
||||
*
|
||||
* Bypass normal encoding rules in File_ASN1::encodeDER()
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.3.0
|
||||
* @access public
|
||||
* @package File_ASN1
|
||||
*/
|
||||
class File_ASN1_Element {
|
||||
/**
|
||||
* Raw element value
|
||||
*
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $element;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param String $encoded
|
||||
* @return File_ASN1_Element
|
||||
* @access public
|
||||
*/
|
||||
function File_ASN1_Element($encoded)
|
||||
{
|
||||
$this->element = $encoded;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP ASN.1 Parser
|
||||
*
|
||||
@ -449,6 +481,10 @@ class File_ASN1 {
|
||||
case FILE_ASN1_TYPE_SEQUENCE:
|
||||
$map = array();
|
||||
|
||||
if (empty($decoded['content'])) {
|
||||
return $map;
|
||||
}
|
||||
|
||||
// ignore the min and max
|
||||
if (isset($mapping['min']) && isset($mapping['max'])) {
|
||||
$child = $mapping['children'];
|
||||
@ -460,6 +496,16 @@ class File_ASN1 {
|
||||
|
||||
$temp = $decoded['content'][$i = 0];
|
||||
foreach ($mapping['children'] as $key => $child) {
|
||||
if (!isset($child['optional']) && $child['type'] == FILE_ASN1_TYPE_CHOICE) {
|
||||
$map[$key] = $this->asn1map($temp, $child);
|
||||
$i++;
|
||||
if (count($decoded['content']) == $i) {
|
||||
break;
|
||||
}
|
||||
$temp = $decoded['content'][$i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($temp['constant'])) {
|
||||
$tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
|
||||
$childClass = isset($child['class']) ? $child['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
|
||||
@ -480,6 +526,11 @@ class File_ASN1 {
|
||||
$temp = $decoded['content'][$i];
|
||||
}
|
||||
} elseif (!isset($child['constant'])) {
|
||||
if ($child['type'] == FILE_ASN1_TYPE_CHOICE) {
|
||||
$map[$key] = $this->asn1map($temp, $child);
|
||||
$i++;
|
||||
continue;
|
||||
}
|
||||
// we could do this, as well:
|
||||
// $buffer = $this->asn1map($temp, $child); if (isset($buffer)) { $map[$key] = $buffer; }
|
||||
if ($child['type'] == $temp['type']) {
|
||||
@ -489,6 +540,16 @@ class File_ASN1 {
|
||||
break;
|
||||
}
|
||||
$temp = $decoded['content'][$i];
|
||||
} elseif ($child['type'] == FILE_ASN1_TYPE_CHOICE) {
|
||||
$candidate = $this->asn1map($temp, $child);
|
||||
if (!empty($candidate)) {
|
||||
$map[$key] = $candidate;
|
||||
$i++;
|
||||
if (count($decoded['content']) == $i) {
|
||||
break;
|
||||
}
|
||||
$temp = $decoded['content'][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,6 +584,12 @@ class File_ASN1 {
|
||||
for ($i = 0; $i < count($decoded['content']); $i++) {
|
||||
foreach ($mapping['children'] as $key => $child) {
|
||||
$temp = $decoded['content'][$i];
|
||||
|
||||
if (!isset($child['optional']) && $child['type'] == FILE_ASN1_TYPE_CHOICE) {
|
||||
$map[$key] = $this->asn1map($temp, $child);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($temp['constant'])) {
|
||||
$tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
|
||||
$childClass = isset($child['class']) ? $child['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
|
||||
@ -648,6 +715,10 @@ class File_ASN1 {
|
||||
*/
|
||||
function _encode_der($source, $mapping, $idx = NULL)
|
||||
{
|
||||
if (is_object($source) && strtolower(get_class($source)) == 'file_asn1_element') {
|
||||
return $source->element;
|
||||
}
|
||||
|
||||
if (isset($idx)) {
|
||||
$this->location[] = $idx;
|
||||
}
|
||||
@ -865,11 +936,15 @@ class File_ASN1 {
|
||||
$value = chr(40 * $parts[0] + $parts[1]);
|
||||
for ($i = 2; $i < count($parts); $i++) {
|
||||
$temp = '';
|
||||
while ($parts[$i]) {
|
||||
$temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
|
||||
$parts[$i] >>= 7;
|
||||
if (!$parts[$i]) {
|
||||
$temp = "\0";
|
||||
} else {
|
||||
while ($parts[$i]) {
|
||||
$temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
|
||||
$parts[$i] >>= 7;
|
||||
}
|
||||
$temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
|
||||
}
|
||||
$temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
|
||||
$value.= $temp;
|
||||
}
|
||||
break;
|
||||
@ -906,6 +981,7 @@ class File_ASN1 {
|
||||
case FILE_ASN1_TYPE_UTF8_STRING:
|
||||
case FILE_ASN1_TYPE_BMP_STRING:
|
||||
case FILE_ASN1_TYPE_IA5_STRING:
|
||||
case FILE_ASN1_TYPE_VISIBLE_STRING:
|
||||
$value = $source;
|
||||
break;
|
||||
case FILE_ASN1_TYPE_BOOLEAN:
|
||||
|
@ -11,6 +11,12 @@
|
||||
* The extensions are from {@link http://tools.ietf.org/html/rfc5280 RFC5280} and
|
||||
* {@link http://web.archive.org/web/19961027104704/http://www3.netscape.com/eng/security/cert-exts.html Netscape Certificate Extensions}.
|
||||
*
|
||||
* Note that loading an X.509 certificate and resaving it may invalidate the signature. The reason being that the signature is based on a
|
||||
* portion of the certificate that contains optional parameters with default values. ie. if the parameter isn't there the default value is
|
||||
* used. Problem is, if the parameter is there and it just so happens to have the default value there are two ways that that parameter can
|
||||
* be encoded. It can be encoded explicitly or left out all together. This would effect the signature value and thus may invalidate the
|
||||
* the certificate all together unless the certificate is re-signed.
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
@ -43,6 +49,24 @@
|
||||
*/
|
||||
include('File/ASN1.php');
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see File_X509::validate()
|
||||
*/
|
||||
/**
|
||||
* The current date does not fall between the certificate's notBefore and notAfter dates
|
||||
*/
|
||||
define('FILE_X509_VALIDATE_EXPIRATION', 0);
|
||||
/**
|
||||
* The certificate has not been signed by a recognized certificate authority
|
||||
*/
|
||||
define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1);
|
||||
/**
|
||||
* The certificate's signature could not be verified on account of it's using an unsupported algorithm
|
||||
*/
|
||||
define('FILE_X509_VALIDATE_UNSUPPORTED_ALGORITHM', 2);
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Pure-PHP X.509 Parser
|
||||
*
|
||||
@ -78,6 +102,10 @@ class File_X509 {
|
||||
var $IssuerAltName;
|
||||
var $PolicyMappings;
|
||||
var $NameConstraints;
|
||||
|
||||
var $CPSuri;
|
||||
var $UserNotice;
|
||||
|
||||
var $netscape_cert_type;
|
||||
var $netscape_comment;
|
||||
/**#@-*/
|
||||
@ -105,7 +133,7 @@ class File_X509 {
|
||||
* @var Array
|
||||
* @access private
|
||||
*/
|
||||
var $certificate;
|
||||
var $currentCert;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
@ -466,7 +494,7 @@ class File_X509 {
|
||||
'network-address' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'implicit' => trues
|
||||
'implicit' => true
|
||||
) + $NetworkAddress,
|
||||
'terminal-identifier' => array(
|
||||
'constant' => 1,
|
||||
@ -691,7 +719,7 @@ class File_X509 {
|
||||
'policyIdentifier' => $CertPolicyId,
|
||||
'policyQualifiers' => array(
|
||||
'type' => FILE_ASN1_TYPE_SEQUENCE,
|
||||
'min' => 1,
|
||||
'min' => 0,
|
||||
'max' => -1,
|
||||
'children' => $PolicyQualifierInfo
|
||||
)
|
||||
@ -803,6 +831,45 @@ class File_X509 {
|
||||
)
|
||||
);
|
||||
|
||||
$this->CPSuri = array('type' => FILE_ASN1_TYPE_IA5_STRING);
|
||||
|
||||
$DisplayText = array(
|
||||
'type' => FILE_ASN1_TYPE_CHOICE,
|
||||
'children' => array(
|
||||
'ia5String' => array('type' => FILE_ASN1_TYPE_IA5_STRING),
|
||||
'visibleString' => array('type' => FILE_ASN1_TYPE_VISIBLE_STRING),
|
||||
'bmpString' => array('type' => FILE_ASN1_TYPE_BMP_STRING),
|
||||
'utf8String' => array('type' => FILE_ASN1_TYPE_UTF8_STRING)
|
||||
)
|
||||
);
|
||||
|
||||
$NoticeReference = array(
|
||||
'type' => FILE_ASN1_TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'organization' => $DisplayText,
|
||||
'noticeNumbers' => array(
|
||||
'type' => FILE_ASN1_TYPE_SEQUENCE,
|
||||
'min' => 1,
|
||||
'max' => 200,
|
||||
'children' => array('type' => FILE_ASN1_TYPE_INTEGER)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->UserNotice = array(
|
||||
'type' => FILE_ASN1_TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'noticeRef' => array(
|
||||
'optional' => true,
|
||||
'implicit' => true
|
||||
) + $NoticeReference,
|
||||
'explicitText' => array(
|
||||
'optional' => true,
|
||||
'implicit' => true
|
||||
) + $DisplayText
|
||||
)
|
||||
);
|
||||
|
||||
// mapping is from <http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html>
|
||||
$this->netscape_cert_type = array(
|
||||
'type' => FILE_ASN1_TYPE_BIT_STRING,
|
||||
@ -978,6 +1045,7 @@ class File_X509 {
|
||||
*
|
||||
* @param String $cert
|
||||
* @access public
|
||||
* @return Array
|
||||
*/
|
||||
function loadX509($cert)
|
||||
{
|
||||
@ -993,19 +1061,54 @@ class File_X509 {
|
||||
$cert = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]#', '', $cert);
|
||||
$cert = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $cert) ? base64_decode($cert) : false;
|
||||
|
||||
if ($cert === false) {
|
||||
$this->currentCert = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$asn1->loadOIDs($this->oids);
|
||||
$decoded = $asn1->decodeBER($cert);
|
||||
$x509 = $asn1->asn1map($decoded[0], $this->Certificate);
|
||||
if (!isset($x509) || $x509 === false) {
|
||||
$this->currentCert = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($x509['tbsCertificate']['extensions']); $i++) {
|
||||
$id = $x509['tbsCertificate']['extensions'][$i]['extnId'];
|
||||
$value = base64_decode($x509['tbsCertificate']['extensions'][$i]['extnValue']);
|
||||
$decoded = $asn1->decodeBER($value);
|
||||
/* [extnValue] contains the DER encoding of an ASN.1 value
|
||||
corresponding to the extension type identified by extnID */
|
||||
$map = $this->_getMapping($id);
|
||||
if ($map !== false) {
|
||||
$x509['tbsCertificate']['extensions'][$i]['extnValue'] = $asn1->asn1map($decoded[0], $map);
|
||||
$this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||
|
||||
if (isset($x509['tbsCertificate']['extensions'])) {
|
||||
for ($i = 0; $i < count($x509['tbsCertificate']['extensions']); $i++) {
|
||||
$id = $x509['tbsCertificate']['extensions'][$i]['extnId'];
|
||||
$value = &$x509['tbsCertificate']['extensions'][$i]['extnValue'];
|
||||
$value = base64_decode($value);
|
||||
$decoded = $asn1->decodeBER($value);
|
||||
/* [extnValue] contains the DER encoding of an ASN.1 value
|
||||
corresponding to the extension type identified by extnID */
|
||||
$map = $this->_getMapping($id);
|
||||
if (!is_bool($map)) {
|
||||
$mapped = $asn1->asn1map($decoded[0], $map);
|
||||
$value = $mapped === false ? $decoded[0] : $mapped;
|
||||
|
||||
if ($id == 'id-ce-certificatePolicies') {
|
||||
for ($j = 0; $j < count($value); $j++) {
|
||||
if (!isset($value[$j]['policyQualifiers'])) {
|
||||
continue;
|
||||
}
|
||||
for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
|
||||
$subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
|
||||
$map = $this->_getMapping($subid);
|
||||
$subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
|
||||
if ($map !== false) {
|
||||
$decoded = $asn1->decodeBER($subvalue);
|
||||
$mapped = $asn1->asn1map($decoded[0], $map);
|
||||
$subvalue = $mapped === false ? $decoded[0] : $mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($map) {
|
||||
$value = base64_encode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1030,6 +1133,7 @@ class File_X509 {
|
||||
*
|
||||
* @param optional Array $cert
|
||||
* @access public
|
||||
* @return String
|
||||
*/
|
||||
function saveX509($cert)
|
||||
{
|
||||
@ -1062,20 +1166,50 @@ class File_X509 {
|
||||
|
||||
$asn1->loadFilters($filters);
|
||||
|
||||
$size = count($cert['tbsCertificate']['extensions']);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$id = $cert['tbsCertificate']['extensions'][$i]['extnId'];
|
||||
$value = $cert['tbsCertificate']['extensions'][$i]['extnValue'];
|
||||
/* [extnValue] contains the DER encoding of an ASN.1 value
|
||||
corresponding to the extension type identified by extnID */
|
||||
$map = $this->_getMapping($id);
|
||||
if (is_bool($map)) {
|
||||
if (!$map) {
|
||||
user_error($id . ' is not a currently supported extension', E_USER_NOTICE);
|
||||
if (isset($cert['tbsCertificate']['extensions'])) {
|
||||
$size = count($cert['tbsCertificate']['extensions']);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$id = $cert['tbsCertificate']['extensions'][$i]['extnId'];
|
||||
$value = &$cert['tbsCertificate']['extensions'][$i]['extnValue'];
|
||||
|
||||
switch ($id) {
|
||||
case 'id-ce-certificatePolicies':
|
||||
for ($j = 0; $j < count($value); $j++) {
|
||||
if (!isset($value[$j]['policyQualifiers'])) {
|
||||
continue;
|
||||
}
|
||||
for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
|
||||
$subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
|
||||
$map = $this->_getMapping($subid);
|
||||
$subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
|
||||
if ($map !== false) {
|
||||
// by default File_ASN1 will try to render qualifier as a FILE_ASN1_TYPE_IA5_STRING since it's
|
||||
// actual type is FILE_ASN1_TYPE_ANY
|
||||
$subvalue = new File_ASN1_Element($asn1->encodeDER($subvalue, $map));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string
|
||||
if (isset($value['authorityCertSerialNumber'])) {
|
||||
if ($value['authorityCertSerialNumber']->toBytes() == '') {
|
||||
$temp = chr((FILE_ASN1_CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0";
|
||||
$value['authorityCertSerialNumber'] = new File_ASN1_Element($temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* [extnValue] contains the DER encoding of an ASN.1 value
|
||||
corresponding to the extension type identified by extnID */
|
||||
$map = $this->_getMapping($id);
|
||||
if (is_bool($map)) {
|
||||
if (!$map) {
|
||||
user_error($id . ' is not a currently supported extension', E_USER_NOTICE);
|
||||
unset($cert['tbsCertificate']['extensions'][$i]);
|
||||
}
|
||||
} else {
|
||||
$value = base64_encode($asn1->encodeDER($value, $map));
|
||||
}
|
||||
unset($cert['tbsCertificate']['extensions'][$i]);
|
||||
} else {
|
||||
$cert['tbsCertificate']['extensions'][$i]['extnValue'] = base64_encode($asn1->encodeDER($value, $map));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1089,6 +1223,7 @@ class File_X509 {
|
||||
*
|
||||
* @param String $extnId
|
||||
* @access private
|
||||
* @return Mixed
|
||||
*/
|
||||
function _getMapping($extnId)
|
||||
{
|
||||
@ -1125,6 +1260,13 @@ class File_X509 {
|
||||
case 'netscape-comment':
|
||||
return $this->netscape_comment;
|
||||
|
||||
// since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets
|
||||
// back around to asn1map() and we don't want it decoded again.
|
||||
//case 'id-qt-cps':
|
||||
// return $this->CPSuri;
|
||||
case 'id-qt-unotice':
|
||||
return $this->UserNotice;
|
||||
|
||||
// the following OIDs are unsupported but we don't want them to give notices when calling saveX509().
|
||||
case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt
|
||||
case 'entrustVersInfo':
|
||||
@ -1139,4 +1281,111 @@ class File_X509 {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an X.509 certificate as a certificate authority
|
||||
*
|
||||
* @param String $cert
|
||||
* @access public
|
||||
*/
|
||||
function loadCA($cert)
|
||||
{
|
||||
$this->CAs[] = $this->loadX509($cert);
|
||||
unset($this->currentCert);
|
||||
unset($this->signatureSubject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an X.509 certificate
|
||||
*
|
||||
* Returns either an array containing non-fatal error codes or, if $criteria is passed as a parameter,
|
||||
* a boolean true / false. If there are fatal errors (such as the signature not matching) a false is
|
||||
* returned.
|
||||
*
|
||||
* @param optional Array $criteria
|
||||
* @access public
|
||||
* @return Mixed
|
||||
*/
|
||||
function validate($criteria = false)
|
||||
{
|
||||
if (!is_array($this->currentCert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$problems = array();
|
||||
|
||||
// self-signed cert
|
||||
if ($this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']) {
|
||||
$signingCert = $this->currentCert; // working cert
|
||||
}
|
||||
|
||||
if (!empty($this->CAs)) {
|
||||
for ($i = 0; $i < count($this->CAs); $i++) {
|
||||
// even if the cert is a self-signed one we still want to see if it's a CA;
|
||||
// if not, we'll conditionally return an error
|
||||
$ca = $this->CAs[$i];
|
||||
if ($this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
|
||||
$signingCert = $ca; // working cert
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count($this->CAs) == $i) {
|
||||
$problems[] = FILE_X509_VALIDATE_SIGNATURE_BY_CA;
|
||||
}
|
||||
} else {
|
||||
$problems[] = FILE_X509_VALIDATE_SIGNATURE_BY_CA;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case time() < @strtotime($this->currentCert['tbsCertificate']['notBefore']):
|
||||
case time() > @strtotime($this->currentCert['tbsCertificate']['notAfter']):
|
||||
$problems[] = FILE_X509_VALIDATE_EXPIRATION;
|
||||
}
|
||||
|
||||
switch ($signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm']) {
|
||||
case 'rsaEncryption':
|
||||
if (!class_exists('Crypt_RSA')) {
|
||||
require_once('Crypt/RSA.php');
|
||||
}
|
||||
$rsa = new Crypt_RSA();
|
||||
$rsa->loadKey($signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']);
|
||||
|
||||
$algo = $this->currentCert['signatureAlgorithm']['algorithm'];
|
||||
|
||||
switch ($algo) {
|
||||
case 'md2WithRSAEncryption':
|
||||
case 'md5WithRSAEncryption':
|
||||
case 'sha1WithRSAEncryption':
|
||||
case 'sha224WithRSAEncryption':
|
||||
case 'sha256WithRSAEncryption':
|
||||
case 'sha384WithRSAEncryption':
|
||||
case 'sha512WithRSAEncryption':
|
||||
$rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $algo));
|
||||
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
||||
|
||||
if (!@$rsa->verify($this->signatureSubject, substr(base64_decode($this->currentCert['signature']), 1))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$problems[] = FILE_X509_VALIDATE_UNSUPPORTED_ALGORITHM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$problems[] = FILE_X509_VALIDATE_UNSUPPORTED_ALGORITHM;
|
||||
}
|
||||
|
||||
return is_array($criteria) ? count(array_intersect($criteria, $problems)) == 0 : $problems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an X.509 certificate against a URL
|
||||
*
|
||||
* @param String $url
|
||||
* @access public
|
||||
* @return Boolean
|
||||
*/
|
||||
function validateURL($url)
|
||||
{
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user