save
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Acme PHP project.
|
||||
*
|
||||
* (c) Titouan Galopin <galopintitouan@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AcmePhp\Ssl\Parser;
|
||||
|
||||
use AcmePhp\Ssl\Certificate;
|
||||
use AcmePhp\Ssl\Exception\CertificateParsingException;
|
||||
use AcmePhp\Ssl\ParsedCertificate;
|
||||
|
||||
/**
|
||||
* Parse certificate to extract metadata.
|
||||
*
|
||||
* @author Jérémy Derussé <jeremy@derusse.com>
|
||||
*/
|
||||
class CertificateParser
|
||||
{
|
||||
public function parse(Certificate $certificate): ParsedCertificate
|
||||
{
|
||||
$rawData = openssl_x509_parse($certificate->getPEM());
|
||||
|
||||
if (!\is_array($rawData)) {
|
||||
throw new CertificateParsingException(sprintf('Fail to parse certificate with error: %s', openssl_error_string()));
|
||||
}
|
||||
|
||||
if (!isset($rawData['subject']['CN'])) {
|
||||
throw new CertificateParsingException('Missing expected key "subject.cn" in certificate');
|
||||
}
|
||||
if (!isset($rawData['serialNumber'])) {
|
||||
throw new CertificateParsingException('Missing expected key "serialNumber" in certificate');
|
||||
}
|
||||
if (!isset($rawData['validFrom_time_t'])) {
|
||||
throw new CertificateParsingException('Missing expected key "validFrom_time_t" in certificate');
|
||||
}
|
||||
if (!isset($rawData['validTo_time_t'])) {
|
||||
throw new CertificateParsingException('Missing expected key "validTo_time_t" in certificate');
|
||||
}
|
||||
|
||||
$subjectAlternativeName = [];
|
||||
|
||||
if (isset($rawData['extensions']['subjectAltName'])) {
|
||||
$subjectAlternativeName = array_map(
|
||||
function ($item) {
|
||||
return explode(':', trim($item), 2)[1];
|
||||
},
|
||||
array_filter(
|
||||
explode(
|
||||
',',
|
||||
$rawData['extensions']['subjectAltName']
|
||||
),
|
||||
function ($item) {
|
||||
return false !== strpos($item, ':');
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new ParsedCertificate(
|
||||
$certificate,
|
||||
$rawData['subject']['CN'],
|
||||
isset($rawData['issuer']['CN']) ? $rawData['issuer']['CN'] : null,
|
||||
$rawData['subject'] === $rawData['issuer'],
|
||||
new \DateTime('@'.$rawData['validFrom_time_t']),
|
||||
new \DateTime('@'.$rawData['validTo_time_t']),
|
||||
$rawData['serialNumber'],
|
||||
$subjectAlternativeName
|
||||
);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Acme PHP project.
|
||||
*
|
||||
* (c) Titouan Galopin <galopintitouan@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AcmePhp\Ssl\Parser;
|
||||
|
||||
use AcmePhp\Ssl\Exception\KeyFormatException;
|
||||
use AcmePhp\Ssl\Exception\KeyParsingException;
|
||||
use AcmePhp\Ssl\Key;
|
||||
use AcmePhp\Ssl\ParsedKey;
|
||||
|
||||
/**
|
||||
* Parse keys to extract metadata.
|
||||
*
|
||||
* @author Titouan Galopin
|
||||
*/
|
||||
class KeyParser
|
||||
{
|
||||
public function parse(Key $key): ParsedKey
|
||||
{
|
||||
try {
|
||||
$resource = $key->getResource();
|
||||
} catch (KeyFormatException $e) {
|
||||
throw new KeyParsingException('Fail to load resource for key', 0, $e);
|
||||
}
|
||||
|
||||
$rawData = openssl_pkey_get_details($resource);
|
||||
|
||||
// PHP 8 automatically frees the key instance and deprecates the function
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
openssl_free_key($resource);
|
||||
}
|
||||
|
||||
if (!\is_array($rawData)) {
|
||||
throw new KeyParsingException(sprintf('Fail to parse key with error: %s', openssl_error_string()));
|
||||
}
|
||||
|
||||
foreach (['type', 'key', 'bits'] as $requiredKey) {
|
||||
if (!isset($rawData[$requiredKey])) {
|
||||
throw new KeyParsingException(sprintf('Missing expected key "%s" in OpenSSL key', $requiredKey));
|
||||
}
|
||||
}
|
||||
|
||||
$details = [];
|
||||
|
||||
if (OPENSSL_KEYTYPE_RSA === $rawData['type']) {
|
||||
$details = $rawData['rsa'];
|
||||
} elseif (OPENSSL_KEYTYPE_DSA === $rawData['type']) {
|
||||
$details = $rawData['dsa'];
|
||||
} elseif (OPENSSL_KEYTYPE_DH === $rawData['type']) {
|
||||
$details = $rawData['dh'];
|
||||
} elseif (OPENSSL_KEYTYPE_EC === $rawData['type']) {
|
||||
$details = $rawData['ec'];
|
||||
}
|
||||
|
||||
return new ParsedKey($key, $rawData['key'], $rawData['bits'], $rawData['type'], $details);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user