Skip to content

Commit de7575b

Browse files
Mihkel Kivisildmrts
authored andcommitted
Add customizable hash algorithm for generating certificate ID
WE2-1022 Co-authored-by: Kai Hölscher [email protected] Signed-off-by: Mihkel Kivisild <[email protected]>
1 parent e1eec7a commit de7575b

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

src/ocsp/Ocsp.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use phpseclib3\File\X509;
3232
use web_eid\web_eid_authtoken_validation_php\ocsp\exceptions\OcspCertificateException;
3333
use web_eid\web_eid_authtoken_validation_php\util\AsnUtil;
34+
use web_eid\web_eid_authtoken_validation_php\util\HashAlgorithm;
3435

3536
class Ocsp
3637
{
@@ -65,7 +66,8 @@ class Ocsp
6566
*/
6667
public function generateCertificateId(
6768
X509 $certificate,
68-
X509 $issuerCertificate
69+
X509 $issuerCertificate,
70+
HashAlgorithm $hashAlgorithm = HashAlgorithm::SHA1
6971
): array {
7072
AsnUtil::loadOIDs();
7173

@@ -87,9 +89,7 @@ public function generateCertificateId(
8789
);
8890
}
8991

90-
$certificateId["serialNumber"] = clone $certificate->getCurrentCert()[
91-
"tbsCertificate"
92-
]["serialNumber"];
92+
$certificateId["serialNumber"] = clone $certificate->getCurrentCert()["tbsCertificate"]["serialNumber"];
9393

9494
// issuer name
9595
if (
@@ -109,7 +109,7 @@ public function generateCertificateId(
109109
"subject"
110110
];
111111
$issuerEncoded = ASN1::encodeDER($issuer, Name::MAP);
112-
$certificateId["issuerNameHash"] = hash("sha1", $issuerEncoded, true);
112+
$certificateId["issuerNameHash"] = hash($hashAlgorithm->value, $issuerEncoded, true);
113113

114114
// issuer public key
115115
if (
@@ -129,12 +129,12 @@ public function generateCertificateId(
129129
"subjectPublicKeyInfo"
130130
]["subjectPublicKey"];
131131
$certificateId["issuerKeyHash"] = hash(
132-
"sha1",
132+
$hashAlgorithm->value,
133133
AsnUtil::extractKeyData($publicKey),
134134
true
135135
);
136136

137-
$certificateId["hashAlgorithm"]["algorithm"] = Asn1::getOID("id-sha1");
137+
$certificateId["hashAlgorithm"]["algorithm"] = Asn1::getOID("id-" . $hashAlgorithm->value);
138138

139139
return $certificateId;
140140
}

src/util/AsnUtil.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@ public static function isSignatureInAsn1Format(string $signature): bool
4343

4444
// ASN.1 format: 0x30 b1 0x02 b2 r 0x02 b3 s.
4545
// Note: unpack() returns an array indexed from 1, not 0.
46-
if(!isset($sigByteArray[1]) ||
46+
if (
47+
!isset($sigByteArray[1]) ||
4748
!isset($sigByteArray[2]) ||
4849
!isset($sigByteArray[3]) ||
49-
!isset($sigByteArray[4])) {
50+
!isset($sigByteArray[4])
51+
) {
5052
return false;
5153
}
5254
$b1 = $sigByteArray[2];
5355
$b2 = $sigByteArray[4];
54-
if(!isset($sigByteArray[5 + $b2]) ||
55-
!isset($sigByteArray[6 + $b2])) {
56+
if (
57+
!isset($sigByteArray[5 + $b2]) ||
58+
!isset($sigByteArray[6 + $b2])
59+
) {
5660
return false;
5761
}
5862
$b3 = $sigByteArray[6 + $b2];
@@ -108,6 +112,13 @@ public static function loadOIDs(): void
108112
ASN1::loadOIDs([
109113
"id-pkix-ocsp-nonce" => self::ID_PKIX_OCSP_NONCE,
110114
"id-sha1" => "1.3.14.3.2.26",
115+
'id-sha256' => '2.16.840.1.101.3.4.2.1',
116+
'id-sha384' => '2.16.840.1.101.3.4.2.2',
117+
'id-sha512' => '2.16.840.1.101.3.4.2.3',
118+
'id-sha224' => '2.16.840.1.101.3.4.2.4',
119+
'id-sha512/224' => '2.16.840.1.101.3.4.2.5',
120+
'id-sha512/256' => '2.16.840.1.101.3.4.2.6',
121+
'id-mgf1' => '1.2.840.113549.1.1.8',
111122
"sha256WithRSAEncryption" => "1.2.840.113549.1.1.11",
112123
"qcStatements(3)" => "1.3.6.1.5.5.7.1.3",
113124
"street" => "2.5.4.9",

src/util/HashAlgorithm.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace web_eid\web_eid_authtoken_validation_php\util;
4+
5+
enum HashAlgorithm: string
6+
{
7+
case SHA1 = "sha1";
8+
case SHA256 = "sha256";
9+
case SHA384 = "sha384";
10+
case SHA512 = "sha512";
11+
case SHA224 = "sha224";
12+
case SHA512_224 = "sha512/224";
13+
case SHA512_256 = "sha512/256";
14+
case MGF1 = "mgf1";
15+
}

tests/ocsp/OcspTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use PHPUnit\Framework\TestCase;
3131
use web_eid\web_eid_authtoken_validation_php\ocsp\certificate\CertificateLoader;
3232
use web_eid\web_eid_authtoken_validation_php\ocsp\exceptions\OcspCertificateException;
33+
use web_eid\web_eid_authtoken_validation_php\util\HashAlgorithm;
3334

3435
class OcspTest extends TestCase
3536
{
@@ -43,6 +44,19 @@ public function testWhenGenerateCertificateIdIsSuccess(): void
4344
$this->assertEquals([168, 74, 106, 99, 4, 125, 221, 186, 230, 209, 57, 183, 166, 69, 101, 239, 243, 168, 236, 161], array_values(unpack('C*', $result['issuerKeyHash'])));
4445
}
4546

47+
public function testWhenGenerateCertificateIdWithSha256IsSuccess(): void
48+
{
49+
$result = (new Ocsp)->generateCertificateId(
50+
(new CertificateLoader)->fromFile(__DIR__ . '/../_resources/revoked.crt')->getCert(),
51+
(new CertificateLoader)->fromFile(__DIR__ . '/../_resources/revoked.issuer.crt')->getCert(),
52+
HashAlgorithm::SHA256
53+
);
54+
55+
$this->assertEquals("2.16.840.1.101.3.4.2.1", $result['hashAlgorithm']['algorithm']);
56+
$this->assertEquals([95, 66, 108, 14, 230, 221, 220, 19, 204, 150, 46, 50, 249, 230, 243, 173, 85, 145, 220, 162, 11, 98, 80, 34, 131, 168, 252, 178, 130, 128, 58, 168], array_values(unpack('C*', $result['issuerNameHash'])));
57+
$this->assertEquals([171, 181, 182, 119, 64, 116, 118, 100, 255, 11, 197, 252, 216, 32, 39, 48, 158, 67, 174, 62, 32, 137, 104, 62, 240, 236, 220, 228, 44, 99, 167, 49], array_values(unpack('C*', $result['issuerKeyHash'])));
58+
}
59+
4660
public function testWhenMissingSerialNumberInSubjectCertificateThrow(): void
4761
{
4862

0 commit comments

Comments
 (0)