1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace X509\AttributeCertificate; |
4
|
|
|
|
5
|
|
|
use ASN1\Element; |
6
|
|
|
use ASN1\Type\Constructed\Sequence; |
7
|
|
|
use ASN1\Type\Primitive\Integer; |
8
|
|
|
use X509\Certificate\Certificate; |
9
|
|
|
use X509\Certificate\TBSCertificate; |
10
|
|
|
use X509\Certificate\UniqueIdentifier; |
11
|
|
|
use X509\GeneralName\DirectoryName; |
12
|
|
|
use X509\GeneralName\GeneralNames; |
13
|
|
|
|
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Implements <i>IssuerSerial</i> ASN.1 type. |
17
|
|
|
* |
18
|
|
|
* @link https://tools.ietf.org/html/rfc5755#section-4.1 |
19
|
|
|
*/ |
20
|
|
|
class IssuerSerial |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* Issuer name. |
24
|
|
|
* |
25
|
|
|
* @var GeneralNames $_issuer |
26
|
|
|
*/ |
27
|
|
|
protected $_issuer; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Serial number. |
31
|
|
|
* |
32
|
|
|
* @var string|int $_serial |
33
|
|
|
*/ |
34
|
|
|
protected $_serial; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Issuer unique ID. |
38
|
|
|
* |
39
|
|
|
* @var UniqueIdentifier|null $_issuerUID |
40
|
|
|
*/ |
41
|
|
|
protected $_issuerUID; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Constructor |
45
|
|
|
* |
46
|
|
|
* @param GeneralNames $issuer |
47
|
|
|
* @param string|int $serial |
48
|
|
|
* @param UniqueIdentifier|null $uid |
49
|
13 |
|
*/ |
50
|
|
|
public function __construct(GeneralNames $issuer, $serial, |
51
|
13 |
|
UniqueIdentifier $uid = null) { |
52
|
13 |
|
$this->_issuer = $issuer; |
53
|
13 |
|
$this->_serial = $serial; |
54
|
13 |
|
$this->_issuerUID = $uid; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Initialize from ASN.1. |
59
|
|
|
* |
60
|
|
|
* @param Sequence $seq |
61
|
|
|
* @return self |
62
|
9 |
|
*/ |
63
|
9 |
View Code Duplication |
public static function fromASN1(Sequence $seq) { |
|
|
|
|
64
|
9 |
|
$issuer = GeneralNames::fromASN1($seq->at(0)->asSequence()); |
65
|
9 |
|
$serial = $seq->at(1) |
66
|
9 |
|
->asInteger() |
67
|
9 |
|
->number(); |
68
|
9 |
|
$uid = null; |
69
|
1 |
|
if ($seq->has(2, Element::TYPE_BIT_STRING)) { |
70
|
1 |
|
$uid = UniqueIdentifier::fromASN1($seq->at(2)->asBitString()); |
71
|
9 |
|
} |
72
|
|
|
return new self($issuer, $serial, $uid); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Initialize from a public key certificate. |
77
|
|
|
* |
78
|
|
|
* @param Certificate $cert |
79
|
|
|
* @return self |
80
|
1 |
|
*/ |
81
|
1 |
|
public static function fromPKC(Certificate $cert) { |
82
|
1 |
|
$tbsCert = $cert->tbsCertificate(); |
83
|
1 |
|
$issuer = new GeneralNames(new DirectoryName($tbsCert->issuer())); |
84
|
1 |
|
$serial = $tbsCert->serialNumber(); |
85
|
1 |
|
$uid = $tbsCert->hasIssuerUniqueID() ? $tbsCert->issuerUniqueID() : null; |
86
|
|
|
return new self($issuer, $serial, $uid); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Get issuer name. |
91
|
|
|
* |
92
|
|
|
* @return GeneralNames |
93
|
2 |
|
*/ |
94
|
2 |
|
public function issuer() { |
95
|
|
|
return $this->_issuer; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Get serial number. |
100
|
|
|
* |
101
|
|
|
* @return int|string |
102
|
2 |
|
*/ |
103
|
2 |
|
public function serial() { |
104
|
|
|
return $this->_serial; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Check whether issuer unique identifier is present. |
109
|
|
|
* |
110
|
|
|
* @return bool |
111
|
2 |
|
*/ |
112
|
2 |
|
public function hasIssuerUID() { |
113
|
|
|
return isset($this->_issuerUID); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get issuer unique identifier. |
118
|
|
|
* |
119
|
|
|
* @throws \LogicException |
120
|
|
|
* @return UniqueIdentifier |
121
|
2 |
|
*/ |
122
|
2 |
|
public function issuerUID() { |
123
|
1 |
|
if (!$this->hasIssuerUID()) { |
124
|
|
|
throw new \LogicException("issuerUID not set."); |
125
|
1 |
|
} |
126
|
|
|
return $this->_issuerUID; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Generate ASN.1 structure. |
131
|
|
|
* |
132
|
|
|
* @return Sequence |
133
|
15 |
|
*/ |
134
|
15 |
|
public function toASN1() { |
135
|
15 |
|
$elements = array($this->_issuer->toASN1(), new Integer($this->_serial)); |
136
|
1 |
|
if (isset($this->_issuerUID)) { |
137
|
1 |
|
$elements[] = $this->_issuerUID->toASN1(); |
138
|
15 |
|
} |
139
|
|
|
return new Sequence(...$elements); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Check whether this IssuerSerial identifies given certificate. |
144
|
|
|
* |
145
|
|
|
* @param Certificate $cert |
146
|
|
|
* @return boolean |
147
|
|
|
*/ |
148
|
|
|
public function identifiesPKC(Certificate $cert) { |
149
|
|
|
$tbs = $cert->tbsCertificate(); |
150
|
|
|
if (!$tbs->issuer()->equals($this->_issuer->firstDN())) { |
151
|
|
|
return false; |
152
|
|
|
} |
153
|
|
|
if (strval($tbs->serialNumber()) != strval($this->_serial)) { |
154
|
|
|
return false; |
155
|
|
|
} |
156
|
|
|
if ($this->_issuerUID && !$this->_checkUniqueID($cert)) { |
157
|
|
|
return false; |
158
|
|
|
} |
159
|
|
|
return true; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Check whether issuerUID matches given certificate. |
164
|
|
|
* |
165
|
|
|
* @param Certificate $cert |
166
|
|
|
* @return boolean |
167
|
|
|
*/ |
168
|
|
|
private function _checkUniqueID(Certificate $cert) { |
169
|
|
|
if (!$cert->tbsCertificate()->hasIssuerUniqueID()) { |
170
|
|
|
return false; |
171
|
|
|
} |
172
|
|
|
$uid = $cert->tbsCertificate() |
173
|
|
|
->issuerUniqueID() |
174
|
|
|
->string(); |
175
|
|
|
if ($this->_issuerUID->string() != $uid) { |
176
|
|
|
return false; |
177
|
|
|
} |
178
|
|
|
return true; |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.