mirror of
https://github.com/danog/tgseclib.git
synced 2024-11-27 04:34:45 +01:00
Merge branch 'authority-info-access-2.0' into authority-info-access-master
This commit is contained in:
commit
6c4a108a92
@ -243,6 +243,14 @@ class X509
|
|||||||
*/
|
*/
|
||||||
private static $oidsLoaded = false;
|
private static $oidsLoaded = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursion Limit
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
static $recur_limit = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
@ -1083,6 +1091,113 @@ class X509
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a URL
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @access private
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
static function _fetchURL($url)
|
||||||
|
{
|
||||||
|
$parts = parse_url($url);
|
||||||
|
$data = '';
|
||||||
|
switch ($parts['scheme']) {
|
||||||
|
case 'http':
|
||||||
|
$fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
|
||||||
|
if (!$fsock) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
|
||||||
|
fputs($fsock, "Host: $parts[host]\r\n\r\n");
|
||||||
|
$line = fgets($fsock, 1024);
|
||||||
|
if (strlen($line) < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
|
||||||
|
if ($temp[1] != '200') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the rest of the headers in the http response
|
||||||
|
while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!feof($fsock)) {
|
||||||
|
$data.= fread($fsock, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
//case 'ftp':
|
||||||
|
//case 'ldap':
|
||||||
|
//default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an intermediate cert as identified via authority info access extension
|
||||||
|
*
|
||||||
|
* See https://tools.ietf.org/html/rfc4325 for more info
|
||||||
|
*
|
||||||
|
* @param bool $caonly
|
||||||
|
* @param int $count
|
||||||
|
* @access private
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function _testForIntermediate($caonly, $count)
|
||||||
|
{
|
||||||
|
$opts = $this->getExtension('id-pe-authorityInfoAccess');
|
||||||
|
if (!is_array($opts)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($opts as $opt) {
|
||||||
|
if ($opt['accessMethod'] == 'id-ad-caIssuers') {
|
||||||
|
// accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
|
||||||
|
// etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
|
||||||
|
// discusses
|
||||||
|
if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
|
||||||
|
$url = $opt['accessLocation']['uniformResourceIdentifier'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cert = static::_fetchURL($url);
|
||||||
|
if (!is_string($cert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = new static();
|
||||||
|
$parent->CAs = $this->CAs;
|
||||||
|
/*
|
||||||
|
"Conforming applications that support HTTP or FTP for accessing
|
||||||
|
certificates MUST be able to accept .cer files and SHOULD be able
|
||||||
|
to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
|
||||||
|
|
||||||
|
A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
|
||||||
|
|
||||||
|
These are currently unsupported
|
||||||
|
*/
|
||||||
|
if (!is_array($parent->loadX509($cert))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->CAs[] = $parent->currentCert;
|
||||||
|
//$this->loadCA($cert);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a signature
|
* Validate a signature
|
||||||
*
|
*
|
||||||
@ -1099,11 +1214,30 @@ class X509
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function validateSignature($caonly = true)
|
public function validateSignature($caonly = true)
|
||||||
|
{
|
||||||
|
return $this->_validateSignatureCountable($caonly, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a signature
|
||||||
|
*
|
||||||
|
* Performs said validation whilst keeping track of how many times validation method is called
|
||||||
|
*
|
||||||
|
* @param bool $caonly
|
||||||
|
* @param int $count
|
||||||
|
* @access private
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function _validateSignatureCountable($caonly, $count)
|
||||||
{
|
{
|
||||||
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
|
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($count == self::$recur_limit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
"emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
|
"emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
|
||||||
-- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
|
-- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
|
||||||
@ -1149,10 +1283,10 @@ class X509
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($this->CAs) == $i && $caonly) {
|
if (count($this->CAs) == $i && $caonly) {
|
||||||
return false;
|
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||||
}
|
}
|
||||||
} elseif (!isset($signingCert) || $caonly) {
|
} elseif (!isset($signingCert) || $caonly) {
|
||||||
return false;
|
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||||
}
|
}
|
||||||
return $this->validateSignatureHelper(
|
return $this->validateSignatureHelper(
|
||||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||||
@ -1260,6 +1394,21 @@ class X509
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the recursion limit
|
||||||
|
*
|
||||||
|
* When validating a signature it may be necessary to download intermediate certs from URI's.
|
||||||
|
* An intermediate cert that linked to itself would result in an infinite loop so to prevent
|
||||||
|
* that we set a recursion limit. A negative number means that there is no recursion limit.
|
||||||
|
*
|
||||||
|
* @param int $count
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
static function setRecurLimit($count)
|
||||||
|
{
|
||||||
|
self::$recur_limit = $count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reformat public keys
|
* Reformat public keys
|
||||||
*
|
*
|
||||||
|
@ -629,4 +629,76 @@ Fqfy+n5VpXOdrjic4yZ52yS5sUaq05s6ZZvnmdU=
|
|||||||
// Output new certificate.
|
// Output new certificate.
|
||||||
$newcert->saveX509($crt);
|
$newcert->saveX509($crt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAuthorityInfoAccess()
|
||||||
|
{
|
||||||
|
$x509 = new X509();
|
||||||
|
$x509->loadCA('-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||||
|
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
||||||
|
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||||
|
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
||||||
|
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
||||||
|
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
||||||
|
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
||||||
|
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
||||||
|
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
||||||
|
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
||||||
|
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
||||||
|
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
||||||
|
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
||||||
|
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
||||||
|
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
||||||
|
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
||||||
|
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
||||||
|
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
||||||
|
-----END CERTIFICATE-----');
|
||||||
|
$x509->loadX509('-----BEGIN CERTIFICATE-----
|
||||||
|
MIIG3TCCBcWgAwIBAgIQAtB7LVsRCmgbyWiiw7Sf5jANBgkqhkiG9w0BAQsFADBN
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
|
||||||
|
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTcwOTEzMDAwMDAwWhcN
|
||||||
|
MTkwOTEzMTIwMDAwWjBqMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
|
||||||
|
bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
|
||||||
|
aW9uMRQwEgYDVQQDEwtvdXRsb29rLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||||
|
ADCCAQoCggEBAIz2tovvgBmK4sOHgpyzCdtXrI0XOujctf6LHMj16wzUnMEatioS
|
||||||
|
tH0Pz0dKkCr/0yd9qtXbGhD1o6WhFsd7k651K9MZ98+uQ29SzTIAl6y1gkaBbp4h
|
||||||
|
MFXcE5EpRNHHmK8t2OR7hzmrvvNr6OTYv7BhVCw9pSrQqEFNno0K2TQRhAD9uzrL
|
||||||
|
OY+rBBVedCXWXH7uhZoZ6joUU7CEA5pPMzKPL1ro+Eorc8vt5FYOC+oAT587+b1M
|
||||||
|
z+jbZVQlq0qaMkBKRtUIII78MYY0n8DopGqHyzwqWoGySHJNC8256q+MwsZQvvQ3
|
||||||
|
vmy/rf61h2sg1tU0s7O88Yufxp0LSaMMzZcCAwEAAaOCA5owggOWMB8GA1UdIwQY
|
||||||
|
MBaAFA+AYRyCMWHVLyjnjUY4tCzhxtniMB0GA1UdDgQWBBT7hLoZ/03rqwcslIc2
|
||||||
|
0k0z2R+vNTCCAdwGA1UdEQSCAdMwggHPggtvdXRsb29rLmNvbYIWKi5jbG8uZm9v
|
||||||
|
dHByaW50ZG5zLmNvbYIWKi5ucmIuZm9vdHByaW50ZG5zLmNvbYIgYXR0YWNobWVu
|
||||||
|
dC5vdXRsb29rLm9mZmljZXBwZS5uZXSCG2F0dGFjaG1lbnQub3V0bG9vay5saXZl
|
||||||
|
Lm5ldIIdYXR0YWNobWVudC5vdXRsb29rLm9mZmljZS5uZXSCHWNjcy5sb2dpbi5t
|
||||||
|
aWNyb3NvZnRvbmxpbmUuY29tgiFjY3Mtc2RmLmxvZ2luLm1pY3Jvc29mdG9ubGlu
|
||||||
|
ZS5jb22CC2hvdG1haWwuY29tgg0qLmhvdG1haWwuY29tggoqLmxpdmUuY29tghZt
|
||||||
|
YWlsLnNlcnZpY2VzLmxpdmUuY29tgg1vZmZpY2UzNjUuY29tgg8qLm9mZmljZTM2
|
||||||
|
NS5jb22CFyoub3V0bG9vay5vZmZpY2UzNjUuY29tgg0qLm91dGxvb2suY29tghYq
|
||||||
|
LmludGVybmFsLm91dGxvb2suY29tggwqLm9mZmljZS5jb22CEm91dGxvb2sub2Zm
|
||||||
|
aWNlLmNvbYIUc3Vic3RyYXRlLm9mZmljZS5jb22CGHN1YnN0cmF0ZS1zZGYub2Zm
|
||||||
|
aWNlLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
||||||
|
AQUFBwMCMGsGA1UdHwRkMGIwL6AtoCuGKWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
|
||||||
|
bS9zc2NhLXNoYTItZzEuY3JsMC+gLaArhilodHRwOi8vY3JsNC5kaWdpY2VydC5j
|
||||||
|
b20vc3NjYS1zaGEyLWcxLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgG
|
||||||
|
CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAEC
|
||||||
|
AjB8BggrBgEFBQcBAQRwMG4wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj
|
||||||
|
ZXJ0LmNvbTBGBggrBgEFBQcwAoY6aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t
|
||||||
|
L0RpZ2lDZXJ0U0hBMlNlY3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQA3zjN7I6jTeL+08nhG5eAY0q4pLY40bCQHqONBLSI3
|
||||||
|
uRmQFUfrQOPYBqLC1QU+J2Z2HcX7YiqE3WAR3ODS9g2BAVXkKOQKNBnr2hKwueOz
|
||||||
|
qPwyvTyzcIQYUw+SrTX+bfJwYMTmZvtP9S7/pB1jPhrV7YGsD55AI9bGa9cmH7VQ
|
||||||
|
OiL1p5Qovg5KRsldoZeC04OF/UQIR1fv47VGptsHHGypvSo1JinJFQMXylqLIrUW
|
||||||
|
lV66p3Ui7pFABGc/Lv7nOyANXfLugBO8MyzydGA4NRGiS2MbGpswPCg154pWausU
|
||||||
|
M0qaEPsM2o3CSTfxSJQQIyEe+izV3UQqYSyWkNqCCFPN
|
||||||
|
-----END CERTIFICATE-----');
|
||||||
|
|
||||||
|
X509::setRecurLimit(0);
|
||||||
|
$this->assertFalse($x509->validateSignature());
|
||||||
|
|
||||||
|
X509::setRecurLimit(5);
|
||||||
|
$this->assertTrue($x509->validateSignature());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user