- add full support for the id-ce-authorityKeyIdentifier and id-ce-subjectKeyIdentifier extensions via setKeyIdentifier() function

git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@210 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
Jim Wigginton 2012-04-16 04:35:37 +00:00
parent 3f9aa1ad6a
commit 960dd01fe1

View File

@ -192,6 +192,17 @@ class File_X509 {
*/ */
var $serialNumber; var $serialNumber;
/**
* Key Identifier
*
* See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and
* {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}.
*
* @var String
* @access private
*/
var $keyIdentifier;
/** /**
* Default Constructor. * Default Constructor.
* *
@ -1474,7 +1485,13 @@ class File_X509 {
case isset($this->currentCert['tbsCertificate']): case isset($this->currentCert['tbsCertificate']):
// self-signed cert // self-signed cert
if ($this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']) { if ($this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']) {
$signingCert = $this->currentCert; // working cert $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
switch (true) {
case !is_array($authorityKey):
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
$signingCert = $this->currentCert; // working cert
}
} }
if (!empty($this->CAs)) { if (!empty($this->CAs)) {
@ -1483,8 +1500,14 @@ class File_X509 {
// if not, we'll conditionally return an error // if not, we'll conditionally return an error
$ca = $this->CAs[$i]; $ca = $this->CAs[$i];
if ($this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { if ($this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
$signingCert = $ca; // working cert $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
break; $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
switch (true) {
case !is_array($authorityKey):
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
$signingCert = $ca; // working cert
break 2;
}
} }
} }
if (count($this->CAs) == $i && ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) { if (count($this->CAs) == $i && ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) {
@ -1708,14 +1731,18 @@ class File_X509 {
* @access public * @access public
* @return Boolean * @return Boolean
*/ */
function getDN($string = false) function getDN($string = false, $dn = NULL)
{ {
if (!isset($dn)) {
$dn = $this->currentCert['tbsCertificate']['subject'];
}
if (!$string) { if (!$string) {
return $this->currentCert['tbsCertificate']['subject']; return $dn;
} }
$start = true; $start = true;
foreach ($this->currentCert['tbsCertificate']['subject']['rdnSequence'] as $field) { foreach ($dn['rdnSequence'] as $field) {
$type = $field[0]['type']; $type = $field[0]['type'];
$value = $field[0]['value']; $value = $field[0]['value'];
@ -1879,11 +1906,10 @@ class File_X509 {
$this->currentCert['tbsCertificate']['validity']['notAfter']['utcTime'] = $this->endDate; $this->currentCert['tbsCertificate']['validity']['notAfter']['utcTime'] = $this->endDate;
unset($this->currentCert['tbsCertificate']['validity']['notAfter']['generalTime']); unset($this->currentCert['tbsCertificate']['validity']['notAfter']['generalTime']);
} }
if (!empty($this->dn)) { if (!empty($subject->dn)) {
$this->currentCert['tbsCertificate']['subject'] = $this->dn; $this->currentCert['tbsCertificate']['subject'] = $subject->dn;
} }
$this->removeExtension('id-ce-authorityKeyIdentifier'); $this->removeExtension('id-ce-authorityKeyIdentifier');
} else { } else {
$startDate = empty($this->startDate) ? $this->startDate : @date('M j H:i:s Y T'); $startDate = empty($this->startDate) ? $this->startDate : @date('M j H:i:s Y T');
$endDate = empty($this->endDate) ? $this->endDate : @date('M j H:i:s Y T', strtotime('+1 year')); $endDate = empty($this->endDate) ? $this->endDate : @date('M j H:i:s Y T', strtotime('+1 year'));
@ -1893,12 +1919,12 @@ class File_X509 {
'tbsCertificate' => 'tbsCertificate' =>
array( array(
'version' => 'v3', 'version' => 'v3',
'serialNumber' => $this->serialNumber, // $this->setserialNumber() 'serialNumber' => $serialNumber, // $this->setserialNumber()
'signature' => $signatureAlgorithm, 'signature' => $signatureAlgorithm,
'issuer' => false, // this is going to be overwritten later 'issuer' => false, // this is going to be overwritten later
'validity' => array( 'validity' => array(
'notBefore' => array('utcTime' => $this->startDate), // $this->setStartDate() 'notBefore' => array('utcTime' => $startDate), // $this->setStartDate()
'notAfter' => array('utcTime' => $this->endDate) // $this->setEndDate() 'notAfter' => array('utcTime' => $endDate) // $this->setEndDate()
), ),
'subject' => $subject->dn, 'subject' => $subject->dn,
'subjectPublicKeyInfo' => $subject->publicKey->getPublicKey() 'subjectPublicKeyInfo' => $subject->publicKey->getPublicKey()
@ -1910,6 +1936,36 @@ class File_X509 {
$this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn;
if (isset($issuer->keyIdentifier)) {
$extensions = &$this->currentCert['tbsCertificate']['extensions'];
$extensions[] = array(
'extnId' => 'id-ce-authorityKeyIdentifier',
'critical' => false,
'extnValue'=> array(
//'authorityCertIssuer' => array(
// array(
// 'directoryName' => $issuer->dn
// )
//),
'keyIdentifier' => $issuer->keyIdentifier
)
);
//if (isset($issuer->serialNumber)) {
// $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
//}
unset($extensions);
}
if (isset($subject->keyIdentifier)) {
$this->removeExtension('id-ce-subjectKeyIdentifier');
$this->currentCert['tbsCertificate']['extensions'][] = array(
'extnId' => 'id-ce-subjectKeyIdentifier',
'critical' => false,
'extnValue'=> $subject->keyIdentifier
);
}
// resync $this->signatureSubject
$this->loadX509($this->saveX509($this->currentCert)); $this->loadX509($this->saveX509($this->currentCert));
$result = $this->_sign($issuer->privateKey, $signatureAlgorithm); $result = $this->_sign($issuer->privateKey, $signatureAlgorithm);
@ -1995,8 +2051,10 @@ class File_X509 {
*/ */
function removeExtension($id) function removeExtension($id)
{ {
if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { switch (true) {
return false; case !is_array($this->currentCert):
case !isset($this->currentCert['tbsCertificate']['extensions']):
return false;
} }
$result = false; $result = false;
@ -2022,13 +2080,19 @@ class File_X509 {
* @access public * @access public
* @return Mixed * @return Mixed
*/ */
function getExtension($id) function getExtension($id, $cert = NULL)
{ {
if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { if (!isset($cert)) {
return false; $cert = $this->currentCert;
} }
foreach ($this->currentCert['tbsCertificate']['extensions'] as $key => $value) { switch (true) {
case !is_array($cert):
case !isset($cert['tbsCertificate']['extensions']):
return false;
}
foreach ($cert['tbsCertificate']['extensions'] as $key => $value) {
if ($value['extnId'] == $id) { if ($value['extnId'] == $id) {
return $value['extnValue']; return $value['extnValue'];
} }
@ -2043,17 +2107,40 @@ class File_X509 {
* @access public * @access public
* @return Array * @return Array
*/ */
function getExtensions() function getExtensions($cert = NULL)
{ {
if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { if (!isset($cert)) {
return false; $cert = $this->currentCert;
}
switch (true) {
case !is_array($cert):
case !isset($cert['tbsCertificate']['extensions']):
return array();
} }
$extensions = array(); $extensions = array();
foreach ($this->currentCert['tbsCertificate']['extensions'] as $extension) { foreach ($cert['tbsCertificate']['extensions'] as $extension) {
$extensions[] = $extension['extnId']; $extensions[] = $extension['extnId'];
} }
return $extensions; return $extensions;
} }
/**
* Sets the authority key identifier
*
* This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions.
*
* @param String $value
* @access public
*/
function setKeyIdentifier($value)
{
if (empty($value)) {
unset($this->keyIdentifier);
} else {
$this->keyIdentifier = base64_encode($value);
}
}
} }