1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace X509\Certificate\Extension\DistributionPoint; |
4
|
|
|
|
5
|
|
|
use ASN1\Element; |
6
|
|
|
use ASN1\Type\Constructed\Sequence; |
7
|
|
|
use ASN1\Type\Tagged\ExplicitlyTaggedType; |
8
|
|
|
use ASN1\Type\Tagged\ImplicitlyTaggedType; |
9
|
|
|
use X509\GeneralName\GeneralNames; |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Implements <i>DistributionPoint</i> ASN.1 type used by |
14
|
|
|
* 'CRL Distribution Points' certificate extension. |
15
|
|
|
* |
16
|
|
|
* @link https://tools.ietf.org/html/rfc5280#section-4.2.1.13 |
17
|
|
|
*/ |
18
|
|
|
class DistributionPoint |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Distribution point name. |
22
|
|
|
* |
23
|
|
|
* @var DistributionPointName $_distributionPoint |
24
|
|
|
*/ |
25
|
|
|
protected $_distributionPoint; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Revocation reason. |
29
|
|
|
* |
30
|
|
|
* @var ReasonFlags $_reasons |
31
|
|
|
*/ |
32
|
|
|
protected $_reasons; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* CRL issuer. |
36
|
|
|
* |
37
|
|
|
* @var GeneralNames $_issuer |
38
|
|
|
*/ |
39
|
|
|
protected $_issuer; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Constructor |
43
|
|
|
* |
44
|
|
|
* @param DistributionPointName $name |
45
|
|
|
* @param ReasonFlags $reasons |
46
|
|
|
* @param GeneralNames $issuer |
47
|
|
|
*/ |
48
|
13 |
|
public function __construct(DistributionPointName $name = null, |
49
|
|
|
ReasonFlags $reasons = null, GeneralNames $issuer = null) { |
50
|
13 |
|
$this->_distributionPoint = $name; |
51
|
13 |
|
$this->_reasons = $reasons; |
52
|
13 |
|
$this->_issuer = $issuer; |
53
|
13 |
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Initialize from ASN.1. |
57
|
|
|
* |
58
|
|
|
* @param Sequence $seq |
59
|
|
|
* @return self |
60
|
|
|
*/ |
61
|
8 |
|
public static function fromASN1(Sequence $seq) { |
62
|
8 |
|
$name = null; |
63
|
8 |
|
$reasons = null; |
64
|
8 |
|
$issuer = null; |
65
|
8 |
|
if ($seq->hasTagged(0)) { |
66
|
|
|
// promoted to explicit tagging because underlying type is CHOICE |
67
|
8 |
|
$name = DistributionPointName::fromTaggedType( |
68
|
8 |
|
$seq->getTagged(0) |
69
|
8 |
|
->asExplicit() |
70
|
8 |
|
->asTagged()); |
71
|
8 |
|
} |
72
|
8 |
|
if ($seq->hasTagged(1)) { |
73
|
7 |
|
$reasons = ReasonFlags::fromASN1( |
74
|
7 |
|
$seq->getTagged(1) |
75
|
7 |
|
->asImplicit(Element::TYPE_BIT_STRING) |
76
|
7 |
|
->asBitString()); |
77
|
7 |
|
} |
78
|
8 |
|
if ($seq->hasTagged(2)) { |
79
|
7 |
|
$issuer = GeneralNames::fromASN1( |
80
|
7 |
|
$seq->getTagged(2) |
81
|
7 |
|
->asImplicit(Element::TYPE_SEQUENCE) |
82
|
7 |
|
->asSequence()); |
83
|
7 |
|
} |
84
|
8 |
|
return new self($name, $reasons, $issuer); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Check whether distribution point name is set. |
89
|
|
|
* |
90
|
|
|
* @return bool |
91
|
|
|
*/ |
92
|
9 |
|
public function hasDistributionPointName() { |
93
|
9 |
|
return isset($this->_distributionPoint); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Get distribution point name. |
98
|
|
|
* |
99
|
|
|
* @throws \LogicException |
100
|
|
|
* @return DistributionPointName |
101
|
|
|
*/ |
102
|
9 |
|
public function distributionPointName() { |
103
|
9 |
|
if (!$this->hasDistributionPointName()) { |
104
|
1 |
|
throw new \LogicException("distributionPoint not set."); |
105
|
|
|
} |
106
|
8 |
|
return $this->_distributionPoint; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Check whether distribution point name is set and it's a full name. |
111
|
|
|
* |
112
|
|
|
* @return bool |
113
|
|
|
*/ |
114
|
3 |
|
public function hasFullName() { |
115
|
3 |
|
return $this->distributionPointName()->tag() == |
116
|
3 |
|
DistributionPointName::TAG_FULL_NAME; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Get full distribution point name. |
121
|
|
|
* |
122
|
|
|
* @throws \LogicException |
123
|
|
|
* @return FullName |
124
|
|
|
*/ |
125
|
3 |
|
public function fullName() { |
126
|
3 |
|
if (!$this->hasFullName()) { |
127
|
1 |
|
throw new \LogicException("fullName not set."); |
128
|
|
|
} |
129
|
2 |
|
return $this->_distributionPoint; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Check whether distribution point name is set and it's a relative name. |
134
|
|
|
* |
135
|
|
|
* @return bool |
136
|
|
|
*/ |
137
|
2 |
|
public function hasRelativeName() { |
138
|
2 |
|
return $this->distributionPointName()->tag() == |
139
|
2 |
|
DistributionPointName::TAG_RDN; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Get relative distribution point name. |
144
|
|
|
* |
145
|
|
|
* @throws \LogicException |
146
|
|
|
* @return RelativeName |
147
|
|
|
*/ |
148
|
2 |
|
public function relativeName() { |
149
|
2 |
|
if (!$this->hasRelativeName()) { |
150
|
1 |
|
throw new \LogicException("nameRelativeToCRLIssuer not set."); |
151
|
|
|
} |
152
|
1 |
|
return $this->_distributionPoint; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Check whether reasons flags is set. |
157
|
|
|
* |
158
|
|
|
* @return bool |
159
|
|
|
*/ |
160
|
5 |
|
public function hasReasons() { |
161
|
5 |
|
return isset($this->_reasons); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Get revocation reason flags. |
166
|
|
|
* |
167
|
|
|
* @throws \LogicException |
168
|
|
|
* @return ReasonFlags |
169
|
|
|
*/ |
170
|
5 |
|
public function reasons() { |
171
|
5 |
|
if (!$this->hasReasons()) { |
172
|
1 |
|
throw new \LogicException("reasons not set."); |
173
|
|
|
} |
174
|
4 |
|
return $this->_reasons; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Check whether cRLIssuer is set. |
179
|
|
|
* |
180
|
|
|
* @return bool |
181
|
|
|
*/ |
182
|
5 |
|
public function hasCRLIssuer() { |
183
|
5 |
|
return isset($this->_issuer); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Get CRL issuer. |
188
|
|
|
* |
189
|
|
|
* @throws \LogicException |
190
|
|
|
* @return GeneralNames |
191
|
|
|
*/ |
192
|
5 |
|
public function crlIssuer() { |
193
|
5 |
|
if (!$this->hasCRLIssuer()) { |
194
|
1 |
|
throw new \LogicException("crlIssuer not set."); |
195
|
|
|
} |
196
|
4 |
|
return $this->_issuer; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Generate ASN.1 structure. |
201
|
|
|
* |
202
|
|
|
* @return Sequence |
203
|
|
|
*/ |
204
|
5 |
View Code Duplication |
public function toASN1() { |
|
|
|
|
205
|
5 |
|
$elements = array(); |
206
|
5 |
|
if (isset($this->_distributionPoint)) { |
207
|
5 |
|
$elements[] = new ExplicitlyTaggedType(0, |
208
|
5 |
|
$this->_distributionPoint->toASN1()); |
209
|
5 |
|
} |
210
|
5 |
|
if (isset($this->_reasons)) { |
211
|
4 |
|
$elements[] = new ImplicitlyTaggedType(1, $this->_reasons->toASN1()); |
212
|
4 |
|
} |
213
|
5 |
|
if (isset($this->_issuer)) { |
214
|
4 |
|
$elements[] = new ImplicitlyTaggedType(2, $this->_issuer->toASN1()); |
215
|
4 |
|
} |
216
|
5 |
|
return new Sequence(...$elements); |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
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.