Skip to content

Commit

Permalink
refactor for pull request
Browse files Browse the repository at this point in the history
  • Loading branch information
Falseclock committed Dec 8, 2020
1 parent 180c27d commit 191d9f8
Show file tree
Hide file tree
Showing 18 changed files with 197 additions and 24 deletions.
1 change: 0 additions & 1 deletion src/Maps/OCSPRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace Falseclock\AdvancedCMS\Maps;

use Adapik\CMS\Maps\Signature;
use FG\ASN1\Identifier;

abstract class OCSPRequest
Expand Down
42 changes: 42 additions & 0 deletions src/Maps/Signature.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* Signature
*
* @author Nurlan Mukhanov <nurike@gmail.com>
* @copyright 2020 Nurlan Mukhanov
* @license https://en.wikipedia.org/wiki/MIT_License MIT License
* @link https://github.com/Falseclock/AdvancedCMS
*/

namespace Falseclock\AdvancedCMS\Maps;

use Adapik\CMS\Maps\AlgorithmIdentifier;
use Adapik\CMS\Maps\Certificate;
use FG\ASN1\Identifier;

abstract class Signature
{
/**
* Signature ::= SEQUENCE {
* signatureAlgorithm AlgorithmIdentifier,
* signature BIT STRING,
* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
* }
*/
const MAP = [
'type' => Identifier::SEQUENCE,
'children' => [
'signatureAlgorithm' => AlgorithmIdentifier::MAP,
'signature' => ['type' => Identifier::BITSTRING],
'certs' => [
'constant' => 0,
'explicit' => true,
'optional' => true,
'min' => 1,
'max' => -1,
'type' => Identifier::SEQUENCE,
'children' => Certificate::MAP
],
],
];
}
54 changes: 49 additions & 5 deletions src/OCSPRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
use Adapik\CMS\Certificate;
use Adapik\CMS\CMSBase;
use Adapik\CMS\Exception\FormatException;
use Adapik\CMS\Signature;
use Exception;
use FG\ASN1\Exception\ParserException;
use FG\ASN1\ExplicitlyTaggedObject;
use FG\ASN1\Universal\BitString;
use FG\ASN1\Universal\Integer;
use FG\ASN1\Universal\NullObject;
use FG\ASN1\Universal\ObjectIdentifier;
Expand Down Expand Up @@ -46,7 +46,7 @@ class OCSPRequest extends CMSBase
* @return OCSPRequest
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\OCSPRequest::class, Sequence::class));
}
Expand All @@ -58,6 +58,7 @@ public static function createFromContent(string $content): self
*
* @return OCSPRequest
* @throws FormatException
* @throws ParserException
*/
public static function createSimple(Certificate $publicCertificate, Certificate $intermediateCertificate, string $hashAlgorithmOID = Algorithm::OID_SHA1): self
{
Expand Down Expand Up @@ -86,10 +87,9 @@ public static function createSimple(Certificate $publicCertificate, Certificate
]
),
# issuerNameHash
Algorithm::hashValue($hashAlgorithmOID, $intermediateCertificate->getSubject()->getBinary()),
OctetString::createFromString(self::getNameHash($hashAlgorithmOID, $intermediateCertificate)),
# issuerKeyHash
Algorithm::hashValue($hashAlgorithmOID, $intermediateCertificate->getPublicKey()->getKey()->getBinary()),
# serialNumber
OctetString::createFromString(self::getKeyHash($hashAlgorithmOID, $intermediateCertificate)), # serialNumber
Integer::create($publicCertificate->getSerial())
]
)
Expand Down Expand Up @@ -148,4 +148,48 @@ public function getOptionalSignature(): ?Signature

return null;
}

/**
* @param string $algorithmOID
* @param Certificate $certificate
* @return string
* @throws FormatException
* @throws ParserException
*/
private static function getNameHash(string $algorithmOID, Certificate $certificate): string
{
$binary = $certificate->getBinary();
/** @var Sequence $certificate */
$certificate = Sequence::fromBinary($binary);
return Algorithm::hashValue($algorithmOID, self::_getTBSCertificate($certificate)->getChildren()[5]->getBinary());
}

/**
* @param string $algorithmOID
* @param Certificate $certificate
* @return string
* @throws FormatException
* @throws ParserException
*/
private static function getKeyHash(string $algorithmOID, Certificate $certificate): string
{
$binary = $certificate->getBinary();
/** @var Sequence $certificate */
$certificate = Sequence::fromBinary($binary);
$child = self::_getTBSCertificate($certificate)->getChildren()[6];
/** @var BitString $octet */
$octet = $child->findChildrenByType(BitString::class)[0];

return Algorithm::hashValue($algorithmOID, hex2bin($octet->getStringValue()));
}

/**
* @param Sequence $certificate
* @return Sequence
* @throws Exception
*/
private static function _getTBSCertificate(Sequence $certificate): Sequence
{
return $certificate->findChildrenByType(Sequence::class)[0];
}
}
2 changes: 1 addition & 1 deletion src/OCSPResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class OCSPResponse extends CMSBase
* @return OCSPResponse
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\OCSPResponse::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/OCSPResponseStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class OCSPResponseStatus extends CMSBase
* @return OCSPResponseStatus
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\OCSPResponseStatus::class, Enumerated::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/PKIStatusInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class PKIStatusInfo extends CMSBase
* @return PKIStatusInfo
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\PKIStatusInfo::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Request extends CMSBase
* @return Request
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\Request::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ResponseBytes.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ResponseBytes extends CMSBase
* @return ResponseBytes
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\ResponseBytes::class, Sequence::class));
}
Expand Down
83 changes: 83 additions & 0 deletions src/Signature.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* Signature
*
* @author Nurlan Mukhanov <nurike@gmail.com>
* @copyright 2020 Nurlan Mukhanov
* @license https://en.wikipedia.org/wiki/MIT_License MIT License
* @link https://github.com/Falseclock/AdvancedCMS
*/

namespace Falseclock\AdvancedCMS;

use Adapik\CMS\AlgorithmIdentifier;
use Adapik\CMS\Certificate;
use Adapik\CMS\CMSBase;
use Adapik\CMS\Exception\FormatException;
use FG\ASN1\Exception\ParserException;
use FG\ASN1\ExplicitlyTaggedObject;
use FG\ASN1\Universal\BitString;
use FG\ASN1\Universal\Sequence;

/**
* Class Signature
*
* @see Maps\Signature
* @package Adapik\CMS
*/
class Signature extends CMSBase
{
/**
* @var Sequence
*/
protected $object;

/**
* @param string $content
* @return Signature
* @throws FormatException
*/
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\Signature::class, Sequence::class));
}

/**
* @return AlgorithmIdentifier
*/
public function getSignatureAlgorithm(): AlgorithmIdentifier
{
$signatureAlgorithm = $this->object->getChildren()[0];

return new AlgorithmIdentifier($signatureAlgorithm);
}

/**
* @return BitString
* @throws ParserException
*/
public function getSignature(): BitString
{
$binary = $this->object->getChildren()[1]->getBinary();

return BitString::fromBinary($binary);
}

/**
* @return Certificate[]
*/
public function getCerts(): array
{
$certificates = [];

if (count($this->object->getChildren()) == 3) {
/** @var ExplicitlyTaggedObject $certs */
$certs = $this->object->getChildren()[2];

foreach ($certs->getChildren() as $cert) {
$certificates[] = new Certificate($cert->getChildren()[0]);
}
}
return $certificates;
}
}
3 changes: 2 additions & 1 deletion src/SignedData.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Falseclock\AdvancedCMS;

use Adapik\CMS\CMSBase;
use Adapik\CMS\Exception\FormatException;
use Exception;
use FG\ASN1\ExplicitlyTaggedObject;
Expand All @@ -31,7 +32,7 @@ class SignedData extends \Adapik\CMS\SignedData
* @return SignedData
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, \Adapik\CMS\Maps\SignedData::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/SignedDataContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function getSignerInfoSet(): array
}

/**
* @return EncapsulatedContentInfo
* @return EncapsulatedContentInfo|\Adapik\CMS\EncapsulatedContentInfo
* @throws Exception
*/
public function getEncapsulatedContentInfo(): EncapsulatedContentInfo
Expand Down
5 changes: 3 additions & 2 deletions src/SignerInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Falseclock\AdvancedCMS;

use Adapik\CMS\CMSBase;
use Adapik\CMS\Exception\FormatException;
use Adapik\CMS\UnsignedAttribute;
use Exception;
Expand All @@ -32,7 +33,7 @@ class SignerInfo extends \Adapik\CMS\SignerInfo
* @return SignerInfo
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, \Adapik\CMS\Maps\SignerInfo::class, Sequence::class));
}
Expand Down Expand Up @@ -65,7 +66,7 @@ public function addUnsignedAttribute(UnsignedAttribute $newAttribute): SignerInf
* @return UnsignedAttributes|null
* @throws Exception
*/
public function getUnsignedAttributes(): ?UnsignedAttributes
public function getUnsignedAttributes(): ?\Adapik\CMS\UnsignedAttributes
{
$unsignedAttributes = $this->findUnsignedAttributes();

Expand Down
2 changes: 1 addition & 1 deletion src/TBSRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class TBSRequest extends CMSBase
* @return TBSRequest
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\TBSRequest::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/TimeStampRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class TimeStampRequest extends CMSBase
* @return TimeStampRequest
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\TimeStampRequest::class, Sequence::class));
}
Expand Down
2 changes: 1 addition & 1 deletion src/TimeStampResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class TimeStampResponse extends CMSBase
* @return TimeStampResponse
* @throws FormatException
*/
public static function createFromContent(string $content): self
public static function createFromContent(string $content): CMSBase
{
return new self(self::makeFromContent($content, Maps\TimeStampResponse::class, Sequence::class));
}
Expand Down
9 changes: 6 additions & 3 deletions tests/OCSPRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use Adapik\CMS\AlgorithmIdentifier;
use Adapik\CMS\Certificate;
use Adapik\CMS\GeneralName;
use Adapik\CMS\Signature;
use Falseclock\AdvancedCMS\OCSPRequest;
use Falseclock\AdvancedCMS\OCSPResponse;
use Falseclock\AdvancedCMS\Signature;
use Falseclock\AdvancedCMS\SignedData;
use Falseclock\AdvancedCMS\TBSRequest;
use FG\ASN1\Universal\BitString;
Expand Down Expand Up @@ -38,9 +38,12 @@ public function testRevoked()
$OCSPResponse = OCSPResponse::createFromContent($result);
self::assertInstanceOf(OCSPResponse::class, $OCSPResponse);

$responses = $OCSPResponse->getBasicOCSPResponse()->getTbsResponseData()->getResponses();
$basicOCSPResponse = $OCSPResponse->getBasicOCSPResponse();
$tbsResponseData = $basicOCSPResponse->getTbsResponseData();
$responses = $tbsResponseData->getResponses();
foreach ($responses as $response) {
self::assertTrue($response->getCertStatus()->isRevoked());
$status = $response->getCertStatus();
self::assertTrue($status->isRevoked());
}

break;
Expand Down
2 changes: 0 additions & 2 deletions tests/SignerInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ public function testForBaseFork()
);

$OCSPResponse->getBasicOCSPResponse();

return;
}

public function testNoUnsigned()
Expand Down
4 changes: 3 additions & 1 deletion tests/fixtures/intermediateCertificate.pem
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
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
-----BEGIN CERTIFICATE-----
MIIHfzCCBWegAwIBAgIUNXb1sxtaaCGhb++rEhLJTZONx+4wDQYJKoZIhvcNAQELBQAwgaIxRTBDBgNVBAMMPNCd0JXQk9CG0JfQk9CGINCa0KPTmNCb0JDQndCU0KvQoNCj0KjQqyDQntCg0KLQkNCb0KvSmiAoUlNBKTFMMEoGA1UECgxD0KDQnNCaIMKr0JzQldCc0JvQldCa0JXQotCi0IbQmiDQotCV0KXQndCY0JrQkNCb0KvSmiDSmtCr0JfQnNCV0KLCuzELMAkGA1UEBhMCS1owHhcNMTgwODA4MDQyNjM2WhcNMjUwNjI1MDQyNjM2WjBSMQswCQYDVQQGEwJLWjFDMEEGA1UEAww60rDQm9Ci0KLQq9KaINCa0KPTmNCb0JDQndCU0KvQoNCj0KjQqyDQntCg0KLQkNCb0KvSmiAoUlNBKTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK5bzHPV9MZLVWM/05m2xSs5DZ1+WQ6kTe+PMY2hOb/527+ep9IdvlAxtzQlvbr6Q6I8Jg9FYOWFQddQEqMoeipsaT8vb7F569VIp4M3BLs91+L1xJVhRholgonWrjd9n3N06pEvgiXOD2BxlWpPInxVNvTLRIuDjsO65KOeyZeBzLnPhUaELG9TcPnvZt9doucaC88caS9RFRNRDm03yfuB+LJE+5nuX+sycMVLkAKI0AHu4Icdl6DikqP2l/MB3BScnQ7CzzTCKn5puq6R06VuOV9ELhCab8JSF2vzr4eQuHAHLXz61/LN22vFINGMGb8LsS4SkCAz/30sYnTCsDlcAMiQi2Fd9HbcBMHElXwQsoN/5OWlqH4CtmR55umePvbCwCRmZF12m66JK/J69CDj55YqEDLhqmIn+BhVMv1ZVpWpy3Dkr4trH3agyXkOF0jj9bWs4Yn5gSEyjcLWRb9XveYtDiB9JpBn7WRGsdwSdzothpN8VcT9LOSJh4JKy87WIk9kLgwuTKsmezV9EOJPXRGBAamxAGLxNTPFe0Ar6jPqQX0tDJjGrIBq0LG9tpGCejEuKkFSuiLziU/yCqjlDU+R8xUWMKsoM6R0ELx5ZLfDxlXMCvZtRelsGynnL9ktjbkflkDyNmlNkH94S+jqItAuMB+J6BW5H9+Pql1VAgMBAAGjggH6MIIB9jANBgNVHQ4EBgQEW2p0ETCB4gYDVR0jBIHaMIHXgBTUpRhp74s/Ff3qrb1H4JSBawZqO6GBqKSBpTCBojFFMEMGA1UEAww80J3QldCT0IbQl9CT0IYg0JrQo9OY0JvQkNCd0JTQq9Cg0KPQqNCrINCe0KDQotCQ0JvQq9KaIChSU0EpMUwwSgYDVQQKDEPQoNCc0JogwqvQnNCV0JzQm9CV0JrQldCi0KLQhtCaINCi0JXQpdCd0JjQmtCQ0JvQq9KaINKa0KvQl9Cc0JXQosK7MQswCQYDVQQGEwJLWoIUVKUYae+LPxX96q29R+CUgWsGajswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwQAYIKwYBBQUHAQEENDAyMDAGCCsGAQUFBzAChiRodHRwOi8vcm9vdC5nb3Yua3ovY2VydC9yb290X3JzYS5jZXIwOQYDVR0gBDIwMDAuBgcqgw4DAwEBMCMwIQYIKwYBBQUHAgEWFWh0dHA6Ly9wa2kuZ292Lmt6L2NwczBiBgNVHR8EWzBZMFegVaBThlFodHRwOi8vY3JsLnJvb3QuZ292Lmt6L3JzYS5jcmwKICAgICAgICAgICAgICAgVVJMPWh0dHA6Ly9jcmwxLnJvb3QuZ292Lmt6L3JzYS5jcmwwDQYJKoZIhvcNAQELBQADggIBAA3cfGtNWdxzjG1a70HEGVUvMsyCUQmGhDGy2KFsg7DKaDAevI3IRyeaLxhOEHdif4ocsxnuPr0a7QPcysvfFa6yTvlj2aIm3qXY/La+LlOljNCoj3EEzjFSySUhAv1NAvnlmuY+jqW0Z0LkLiV2QP+XlCeVjAmSWnur5SLlbDUe35yYB3XGJ8Ul74Cx7fWJDdT2Trgh5hTSNPVP4rIlLNNOHUcXuWtABVV8Fstr9w3C+iulKvabQaJWhMupsGD17lRUWmTMkRQC99L6yIlO5PHRxrDc2NGNn/nMJXzrVtOPRiJE2JhOg1d85DQCrNAIUtWg2av3qbFdkeXPCXt9xBeBPkpHA7gCtYf8a/HM8dwYvrXaJbZYKgh10/3V1+vC94qHpTk7C03z2MVTtiLZtzxqn3N1eZMr89Bq4HPTPMjQCg7p3J9asM4qMvWYD4ljU6ppvTPyo8lU096qA5j7HxR5BsIhKlAVhMgklhIwwC2w4iLyNj7jsePDt3KAe3X1tLNgpYXzry61CgzMVSSdciVzmW+/HJHy5Z5ZSa8ApD0u2uNyusyvG2uc4ut03AAEgkaUfgj3BJwoRz4eLPHQj7vaHsaOP9GXV2zA3rGMMpZ3ZXrtlhnBWsYklosfSaWrOdAB9Kp4o3w5RpVRWUj3ARDa3W9zO4jYFiG82r7Shu50
-----END CERTIFICATE-----

0 comments on commit 191d9f8

Please sign in to comment.