2022-10-20 20:06:50 +03:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Webmasterskaya\CryptoPro;
|
|
|
|
|
|
2022-10-24 20:03:09 +03:00
|
|
|
|
use Webmasterskaya\CryptoPro\Constants\OIDsDictionary;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Helpers\ArrayHelper;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Helpers\CertificateHelper;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Helpers\ErrorMessageHelper;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Tags\IssuerTagsTranslations;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Tags\SubjectTagsTranslations;
|
|
|
|
|
use Webmasterskaya\CryptoPro\Tags\TagsTranslationsInterface;
|
|
|
|
|
|
2022-10-20 20:06:50 +03:00
|
|
|
|
class Certificate
|
|
|
|
|
{
|
2022-10-21 17:17:51 +03:00
|
|
|
|
|
|
|
|
|
public $_cadesCertificate;
|
|
|
|
|
public $name;
|
|
|
|
|
public $issuerName;
|
|
|
|
|
public $subjectName;
|
|
|
|
|
public $thumbprint;
|
|
|
|
|
public $validFrom;
|
|
|
|
|
public $validTo;
|
|
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
|
\CPCertificate $cadesCertificate,
|
|
|
|
|
string $name,
|
|
|
|
|
string $issuerName,
|
|
|
|
|
string $subjectName,
|
|
|
|
|
string $thumbprint,
|
|
|
|
|
string $validFrom,
|
|
|
|
|
string $validTo
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
$this->_cadesCertificate = $cadesCertificate;
|
|
|
|
|
$this->name = $name;
|
|
|
|
|
$this->issuerName = $issuerName;
|
|
|
|
|
$this->subjectName = $subjectName;
|
|
|
|
|
$this->thumbprint = $thumbprint;
|
|
|
|
|
$this->validFrom = $validFrom;
|
|
|
|
|
$this->validTo = $validTo;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 20:06:50 +03:00
|
|
|
|
/**
|
|
|
|
|
* возвращает флаг действительности сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return bool
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function isValid()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
$isValid = $this->_cadesCertificate->IsValid();
|
|
|
|
|
$isValid = (bool) $isValid->get_Result();
|
|
|
|
|
}
|
|
|
|
|
catch (\Throwable $e)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при проверке сертификата'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $isValid;
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает указанное внутренее свойство у сертификата в формате Cades
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @param string $propName наименование свойства
|
|
|
|
|
*
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return mixed
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
2022-10-24 20:03:09 +03:00
|
|
|
|
public function getCadesProp(string $propName)
|
2022-10-20 20:06:50 +03:00
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (method_exists($this->_cadesCertificate, 'get_' . $propName))
|
|
|
|
|
{
|
|
|
|
|
$propertyValue = call_user_func([$this->_cadesCertificate, 'get_' . $propName]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (\Throwable $e)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при обращении к свойству сертификата'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $propertyValue;
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает сертификат в формате base64
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function exportBase64()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает информацию об алгоритме сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return AlgorithmInfoInterface
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function getAlgorithm()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
$cadesPublicKey = $this->_cadesCertificate->PublicKey();
|
|
|
|
|
$cadesPublicKeyAlgorithm = $cadesPublicKey->get_Algorithm();
|
|
|
|
|
$algorithmInfo = new class(
|
|
|
|
|
$cadesPublicKeyAlgorithm->get_FriendlyName(),
|
|
|
|
|
$cadesPublicKeyAlgorithm->get_Value()) extends AbstractAlgorithmInfo {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
catch (\Throwable $e)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при получении алгоритма'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $algorithmInfo;
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает расшифрованную информацию о владельце сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return array|array[]
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function getOwnerInfo()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
return $this->getInfo(SubjectTagsTranslations::class, 'SubjectName');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $tags
|
|
|
|
|
* @param string $entitiesPath
|
|
|
|
|
*
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return array|array[]
|
|
|
|
|
*/
|
|
|
|
|
protected function getInfo(string $tags, string $entitiesPath)
|
|
|
|
|
{
|
|
|
|
|
if (!is_subclass_of($tags, TagsTranslationsInterface::class))
|
|
|
|
|
{
|
|
|
|
|
throw new \TypeError(
|
|
|
|
|
sprintf(
|
|
|
|
|
'Argument 1 passed to %s::getInfo() must be an instance of \Webmasterskaya\CryptoPro\Tags\TagsTranslationsInterface, instance of %s given.',
|
|
|
|
|
get_called_class(), $tags
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
$entities = $this->getCadesProp($entitiesPath);
|
|
|
|
|
}
|
|
|
|
|
catch (\Throwable $e)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при извлечении информации из сертификата'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CertificateHelper::parseCertInfo($tags, $entities);
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает расшифрованную информацию об издателе сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return array|array[]
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function getIssuerInfo()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
return $this->getInfo(IssuerTagsTranslations::class, 'IssuerName');
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает ОИД'ы сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @return array
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function getExtendedKeyUsage()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
$OIDs = [];
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
$cadesExtendedKeysUsage = $this->_cadesCertificate->ExtendedKeyUsage();
|
|
|
|
|
$cadesExtendedKeysUsage = $cadesExtendedKeysUsage->get_EKUs();
|
|
|
|
|
$cadesExtendedKeysUsageCount = $cadesExtendedKeysUsage->get_Count();
|
|
|
|
|
|
|
|
|
|
if ($cadesExtendedKeysUsageCount > 0)
|
|
|
|
|
{
|
|
|
|
|
while ($cadesExtendedKeysUsageCount)
|
|
|
|
|
{
|
|
|
|
|
$cadesExtendedKeyUsage = $cadesExtendedKeysUsage->get_Item($cadesExtendedKeysUsageCount);
|
|
|
|
|
$OIDs[] = $cadesExtendedKeyUsage->get_OID();
|
|
|
|
|
|
|
|
|
|
$cadesExtendedKeysUsageCount--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (\Throwable $e)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(ErrorMessageHelper::getErrorMessage($e, "Ошибка при получении ОИД'ов"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $OIDs;
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* возвращает расшифрованные ОИД'ы
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @return array
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
|
|
|
|
public function getDecodedExtendedKeyUsage()
|
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
$certOIDs = $this->getExtendedKeyUsage();
|
|
|
|
|
|
|
|
|
|
$decodedOIDs = [];
|
|
|
|
|
|
|
|
|
|
foreach ($certOIDs as $OID)
|
|
|
|
|
{
|
|
|
|
|
$decodedOIDs[$OID] = OIDsDictionary::MAP[$OID] ?? null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $decodedOIDs;
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* проверяет наличие ОИД'а (ОИД'ов) у сертификата
|
|
|
|
|
*
|
2022-10-24 20:03:09 +03:00
|
|
|
|
* @param string|array $OIDs
|
|
|
|
|
*
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @return bool
|
2022-10-20 20:06:50 +03:00
|
|
|
|
*/
|
2022-10-24 20:03:09 +03:00
|
|
|
|
public function hasExtendedKeyUsage($OIDs)
|
2022-10-20 20:06:50 +03:00
|
|
|
|
{
|
2022-10-24 20:03:09 +03:00
|
|
|
|
$certOIDs = $this->getExtendedKeyUsage();
|
|
|
|
|
|
|
|
|
|
if (is_string($OIDs))
|
|
|
|
|
{
|
|
|
|
|
$OIDs = [$OIDs];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_array($OIDs))
|
|
|
|
|
{
|
|
|
|
|
$OIDs = (array) $OIDs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ArrayHelper::every($OIDs, function ($oidToCheck) use ($certOIDs) {
|
|
|
|
|
return in_array($oidToCheck, $certOIDs);
|
|
|
|
|
});
|
2022-10-20 20:06:50 +03:00
|
|
|
|
}
|
|
|
|
|
}
|