Extensions   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 413
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 37
lcom 1
cbo 3
dl 0
loc 413
ccs 99
cts 99
cp 1
rs 9.44
c 0
b 0
f 0

34 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
A fromASN1() 0 8 1
A toASN1() 0 9 1
A withExtensions() 0 8 2
A has() 0 4 1
A get() 0 7 2
A hasAuthorityKeyIdentifier() 0 4 1
A authorityKeyIdentifier() 0 6 1
A hasSubjectKeyIdentifier() 0 4 1
A subjectKeyIdentifier() 0 7 1
A hasKeyUsage() 0 4 1
A keyUsage() 0 6 1
A hasCertificatePolicies() 0 4 1
A certificatePolicies() 0 6 1
A hasPolicyMappings() 0 4 1
A policyMappings() 0 6 1
A hasSubjectAlternativeName() 0 4 1
A subjectAlternativeName() 0 6 1
A hasIssuerAlternativeName() 0 4 1
A issuerAlternativeName() 0 6 1
A hasBasicConstraints() 0 4 1
A basicConstraints() 0 6 1
A hasNameConstraints() 0 4 1
A nameConstraints() 0 6 1
A hasPolicyConstraints() 0 4 1
A policyConstraints() 0 6 1
A hasExtendedKeyUsage() 0 4 1
A extendedKeyUsage() 0 6 1
A hasCRLDistributionPoints() 0 4 1
A crlDistributionPoints() 0 6 1
A hasInhibitAnyPolicy() 0 4 1
A inhibitAnyPolicy() 0 6 1
A count() 0 4 1
A getIterator() 0 4 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace X509\Certificate;
6
7
use ASN1\Type\UnspecifiedType;
8
use ASN1\Type\Constructed\Sequence;
9
use X509\Certificate\Extension as Ext;
10
11
/**
12
 * Implements <i>Extensions</i> ASN.1 type.
13
 *
14
 * Several convenience methods are provided to fetch commonly used
15
 * standard extensions. Others can be accessed using <code>get($oid)</code>.
16
 *
17
 * @link https://tools.ietf.org/html/rfc5280#section-4.1.2.9
18
 */
19
class Extensions implements \Countable, \IteratorAggregate
20
{
21
    /**
22
     * Extensions.
23
     *
24
     * @var Extension\Extension[] $_extensions
25
     */
26
    protected $_extensions;
27
    
28
    /**
29
     * Constructor.
30
     *
31
     * @param Ext\Extension ...$extensions Extension objects
32
     */
33 65
    public function __construct(Ext\Extension ...$extensions)
34
    {
35 65
        $this->_extensions = array();
36 65
        foreach ($extensions as $ext) {
37 40
            $this->_extensions[$ext->oid()] = $ext;
38
        }
39 65
    }
40
    
41
    /**
42
     * Initialize from ASN.1.
43
     *
44
     * @param Sequence $seq
45
     * @return self
46
     */
47 26
    public static function fromASN1(Sequence $seq): Extensions
48
    {
49 26
        $extensions = array_map(
50 26
            function (UnspecifiedType $el) {
51 23
                return Ext\Extension::fromASN1($el->asSequence());
52 26
            }, $seq->elements());
53 26
        return new self(...$extensions);
54
    }
55
    
56
    /**
57
     * Generate ASN.1 structure.
58
     *
59
     * @return Sequence
60
     */
61 66
    public function toASN1(): Sequence
62
    {
63 66
        $elements = array_values(
64 66
            array_map(
65 66
                function ($ext) {
66 60
                    return $ext->toASN1();
67 66
                }, $this->_extensions));
68 66
        return new Sequence(...$elements);
69
    }
70
    
71
    /**
72
     * Get self with extensions added.
73
     *
74
     * @param Ext\Extension ...$exts One or more extensions to add
75
     * @return self
76
     */
77 5
    public function withExtensions(Ext\Extension ...$exts): Extensions
78
    {
79 5
        $obj = clone $this;
80 5
        foreach ($exts as $ext) {
81 5
            $obj->_extensions[$ext->oid()] = $ext;
82
        }
83 5
        return $obj;
84
    }
85
    
86
    /**
87
     * Check whether extension is present.
88
     *
89
     * @param string $oid Extensions OID
90
     * @return bool
91
     */
92 108
    public function has(string $oid): bool
93
    {
94 108
        return isset($this->_extensions[$oid]);
95
    }
96
    
97
    /**
98
     * Get extension by OID.
99
     *
100
     * @param string $oid
101
     * @throws \LogicException If extension is not present
102
     * @return Extension\Extension
103
     */
104 86
    public function get(string $oid): Ext\Extension
105
    {
106 86
        if (!$this->has($oid)) {
107 1
            throw new \LogicException("No extension by OID $oid.");
108
        }
109 85
        return $this->_extensions[$oid];
110
    }
111
    
112
    /**
113
     * Check whether 'Authority Key Identifier' extension is present.
114
     *
115
     * @return bool
116
     */
117 10
    public function hasAuthorityKeyIdentifier(): bool
118
    {
119 10
        return $this->has(Ext\Extension::OID_AUTHORITY_KEY_IDENTIFIER);
120
    }
121
    
122
    /**
123
     * Get 'Authority Key Identifier' extension.
124
     *
125
     * @throws \LogicException If extension is not present
126
     * @return \X509\Certificate\Extension\AuthorityKeyIdentifierExtension
127
     */
128 11
    public function authorityKeyIdentifier(): Ext\AuthorityKeyIdentifierExtension
129
    {
130
        /** @var Extension\AuthorityKeyIdentifierExtension $keyIdentifier */
131 11
        $keyIdentifier = $this->get(Ext\Extension::OID_AUTHORITY_KEY_IDENTIFIER);
132 11
        return $keyIdentifier;
133
    }
134
    
135
    /**
136
     * Check whether 'Subject Key Identifier' extension is present.
137
     *
138
     * @return bool
139
     */
140 14
    public function hasSubjectKeyIdentifier(): bool
141
    {
142 14
        return $this->has(Ext\Extension::OID_SUBJECT_KEY_IDENTIFIER);
143
    }
144
    
145
    /**
146
     * Get 'Subject Key Identifier' extension.
147
     *
148
     * @throws \LogicException If extension is not present
149
     * @return \X509\Certificate\Extension\SubjectKeyIdentifierExtension
150
     */
151 13
    public function subjectKeyIdentifier(): Ext\SubjectKeyIdentifierExtension
152
    {
153
        /** @var Extension\SubjectKeyIdentifierExtension $subjectKeyIdentifier */
154 13
        $subjectKeyIdentifier = $this->get(
155 13
            Ext\Extension::OID_SUBJECT_KEY_IDENTIFIER);
156 13
        return $subjectKeyIdentifier;
157
    }
158
    
159
    /**
160
     * Check whether 'Key Usage' extension is present.
161
     *
162
     * @return bool
163
     */
164 41
    public function hasKeyUsage(): bool
165
    {
166 41
        return $this->has(Ext\Extension::OID_KEY_USAGE);
167
    }
168
    
169
    /**
170
     * Get 'Key Usage' extension.
171
     *
172
     * @throws \LogicException If extension is not present
173
     * @return \X509\Certificate\Extension\KeyUsageExtension
174
     */
175 21
    public function keyUsage(): Ext\KeyUsageExtension
176
    {
177
        /** @var Extension\KeyUsageExtension $keyUsage */
178 21
        $keyUsage = $this->get(Ext\Extension::OID_KEY_USAGE);
179 21
        return $keyUsage;
180
    }
181
    
182
    /**
183
     * Check whether 'Certificate Policies' extension is present.
184
     *
185
     * @return bool
186
     */
187 44
    public function hasCertificatePolicies(): bool
188
    {
189 44
        return $this->has(Ext\Extension::OID_CERTIFICATE_POLICIES);
190
    }
191
    
192
    /**
193
     * Get 'Certificate Policies' extension.
194
     *
195
     * @throws \LogicException If extension is not present
196
     * @return \X509\Certificate\Extension\CertificatePoliciesExtension
197
     */
198 16
    public function certificatePolicies(): Ext\CertificatePoliciesExtension
199
    {
200
        /** @var Extension\CertificatePoliciesExtension $certPolicies */
201 16
        $certPolicies = $this->get(Ext\Extension::OID_CERTIFICATE_POLICIES);
202 16
        return $certPolicies;
203
    }
204
    
205
    /**
206
     * Check whether 'Policy Mappings' extension is present.
207
     *
208
     * @return bool
209
     */
210 44
    public function hasPolicyMappings(): bool
211
    {
212 44
        return $this->has(Ext\Extension::OID_POLICY_MAPPINGS);
213
    }
214
    
215
    /**
216
     * Get 'Policy Mappings' extension.
217
     *
218
     * @throws \LogicException If extension is not present
219
     * @return \X509\Certificate\Extension\PolicyMappingsExtension
220
     */
221 5
    public function policyMappings(): Ext\PolicyMappingsExtension
222
    {
223
        /** @var Extension\PolicyMappingsExtension $policyMappings */
224 5
        $policyMappings = $this->get(Ext\Extension::OID_POLICY_MAPPINGS);
225 5
        return $policyMappings;
226
    }
227
    
228
    /**
229
     * Check whether 'Subject Alternative Name' extension is present.
230
     *
231
     * @return bool
232
     */
233 3
    public function hasSubjectAlternativeName(): bool
234
    {
235 3
        return $this->has(Ext\Extension::OID_SUBJECT_ALT_NAME);
236
    }
237
    
238
    /**
239
     * Get 'Subject Alternative Name' extension.
240
     *
241
     * @throws \LogicException If extension is not present
242
     * @return \X509\Certificate\Extension\SubjectAlternativeNameExtension
243
     */
244 4
    public function subjectAlternativeName(): Ext\SubjectAlternativeNameExtension
245
    {
246
        /** @var Extension\SubjectAlternativeNameExtension $subjectAltName */
247 4
        $subjectAltName = $this->get(Ext\Extension::OID_SUBJECT_ALT_NAME);
248 4
        return $subjectAltName;
249
    }
250
    
251
    /**
252
     * Check whether 'Issuer Alternative Name' extension is present.
253
     *
254
     * @return bool
255
     */
256 1
    public function hasIssuerAlternativeName(): bool
257
    {
258 1
        return $this->has(Ext\Extension::OID_ISSUER_ALT_NAME);
259
    }
260
    
261
    /**
262
     * Get 'Issuer Alternative Name' extension.
263
     *
264
     * @return \X509\Certificate\Extension\IssuerAlternativeNameExtension
265
     */
266 1
    public function issuerAlternativeName(): Ext\IssuerAlternativeNameExtension
267
    {
268
        /** @var Extension\IssuerAlternativeNameExtension $issuerAltName */
269 1
        $issuerAltName = $this->get(Ext\Extension::OID_ISSUER_ALT_NAME);
270 1
        return $issuerAltName;
271
    }
272
    
273
    /**
274
     * Check whether 'Basic Constraints' extension is present.
275
     *
276
     * @return bool
277
     */
278 43
    public function hasBasicConstraints(): bool
279
    {
280 43
        return $this->has(Ext\Extension::OID_BASIC_CONSTRAINTS);
281
    }
282
    
283
    /**
284
     * Get 'Basic Constraints' extension.
285
     *
286
     * @throws \LogicException If extension is not present
287
     * @return \X509\Certificate\Extension\BasicConstraintsExtension
288
     */
289 40
    public function basicConstraints(): Ext\BasicConstraintsExtension
290
    {
291
        /** @var Extension\BasicConstraintsExtension $basicConstraints */
292 40
        $basicConstraints = $this->get(Ext\Extension::OID_BASIC_CONSTRAINTS);
293 40
        return $basicConstraints;
294
    }
295
    
296
    /**
297
     * Check whether 'Name Constraints' extension is present.
298
     *
299
     * @return bool
300
     */
301 43
    public function hasNameConstraints(): bool
302
    {
303 43
        return $this->has(Ext\Extension::OID_NAME_CONSTRAINTS);
304
    }
305
    
306
    /**
307
     * Get 'Name Constraints' extension.
308
     *
309
     * @throws \LogicException If extension is not present
310
     * @return \X509\Certificate\Extension\NameConstraintsExtension
311
     */
312 1
    public function nameConstraints(): Ext\NameConstraintsExtension
313
    {
314
        /** @var Extension\NameConstraintsExtension $nameConstraints */
315 1
        $nameConstraints = $this->get(Ext\Extension::OID_NAME_CONSTRAINTS);
316 1
        return $nameConstraints;
317
    }
318
    
319
    /**
320
     * Check whether 'Policy Constraints' extension is present.
321
     *
322
     * @return bool
323
     */
324 43
    public function hasPolicyConstraints(): bool
325
    {
326 43
        return $this->has(Ext\Extension::OID_POLICY_CONSTRAINTS);
327
    }
328
    
329
    /**
330
     * Get 'Policy Constraints' extension.
331
     *
332
     * @throws \LogicException If extension is not present
333
     * @return \X509\Certificate\Extension\PolicyConstraintsExtension
334
     */
335 16
    public function policyConstraints(): Ext\PolicyConstraintsExtension
336
    {
337
        /** @var Extension\PolicyConstraintsExtension $policyConstraints */
338 16
        $policyConstraints = $this->get(Ext\Extension::OID_POLICY_CONSTRAINTS);
339 16
        return $policyConstraints;
340
    }
341
    
342
    /**
343
     * Check whether 'Extended Key Usage' extension is present.
344
     *
345
     * @return bool
346
     */
347 1
    public function hasExtendedKeyUsage(): bool
348
    {
349 1
        return $this->has(Ext\Extension::OID_EXT_KEY_USAGE);
350
    }
351
    
352
    /**
353
     * Get 'Extended Key Usage' extension.
354
     *
355
     * @throws \LogicException If extension is not present
356
     * @return \X509\Certificate\Extension\ExtendedKeyUsageExtension
357
     */
358 1
    public function extendedKeyUsage(): Ext\ExtendedKeyUsageExtension
359
    {
360
        /** @var Extension\ExtendedKeyUsageExtension $keyUsage */
361 1
        $keyUsage = $this->get(Ext\Extension::OID_EXT_KEY_USAGE);
362 1
        return $keyUsage;
363
    }
364
    
365
    /**
366
     * Check whether 'CRL Distribution Points' extension is present.
367
     *
368
     * @return bool
369
     */
370 1
    public function hasCRLDistributionPoints(): bool
371
    {
372 1
        return $this->has(Ext\Extension::OID_CRL_DISTRIBUTION_POINTS);
373
    }
374
    
375
    /**
376
     * Get 'CRL Distribution Points' extension.
377
     *
378
     * @throws \LogicException If extension is not present
379
     * @return \X509\Certificate\Extension\CRLDistributionPointsExtension
380
     */
381 1
    public function crlDistributionPoints(): Ext\CRLDistributionPointsExtension
382
    {
383
        /** @var Extension\CRLDistributionPointsExtension $crlDist */
384 1
        $crlDist = $this->get(Ext\Extension::OID_CRL_DISTRIBUTION_POINTS);
385 1
        return $crlDist;
386
    }
387
    
388
    /**
389
     * Check whether 'Inhibit anyPolicy' extension is present.
390
     *
391
     * @return bool
392
     */
393 43
    public function hasInhibitAnyPolicy(): bool
394
    {
395 43
        return $this->has(Ext\Extension::OID_INHIBIT_ANY_POLICY);
396
    }
397
    
398
    /**
399
     * Get 'Inhibit anyPolicy' extension.
400
     *
401
     * @throws \LogicException If extension is not present
402
     * @return \X509\Certificate\Extension\InhibitAnyPolicyExtension
403
     */
404 3
    public function inhibitAnyPolicy(): Ext\InhibitAnyPolicyExtension
405
    {
406
        /** @var Extension\InhibitAnyPolicyExtension $inhibitAny */
407 3
        $inhibitAny = $this->get(Ext\Extension::OID_INHIBIT_ANY_POLICY);
408 3
        return $inhibitAny;
409
    }
410
    
411
    /**
412
     *
413
     * @see \Countable::count()
414
     * @return int
415
     */
416 77
    public function count(): int
417
    {
418 77
        return count($this->_extensions);
419
    }
420
    
421
    /**
422
     * Get iterator for extensions.
423
     *
424
     * @see \IteratorAggregate::getIterator()
425
     * @return \Traversable
426
     */
427 1
    public function getIterator(): \Traversable
428
    {
429 1
        return new \ArrayIterator($this->_extensions);
430
    }
431
}
432