GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Failed
Push — master ( 405cf3...79c9ba )
by Joni
04:48
created

ValidatorState::pathLength()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\X509\CertificationPath\PathValidation;
6
7
use Sop\ASN1\Element;
8
use Sop\CryptoTypes\AlgorithmIdentifier\Feature\AlgorithmIdentifierType;
9
use Sop\CryptoTypes\Asymmetric\PublicKeyInfo;
10
use Sop\X501\ASN1\Name;
11
use Sop\X509\Certificate\Certificate;
12
use Sop\X509\CertificationPath\Policy\PolicyNode;
13
use Sop\X509\CertificationPath\Policy\PolicyTree;
14
15
/**
16
 * State class for the certification path validation process.
17
 *
18
 * @see https://tools.ietf.org/html/rfc5280#section-6.1.1
19
 * @see https://tools.ietf.org/html/rfc5280#section-6.1.2
20
 */
21
class ValidatorState
22
{
23
    /**
24
     * Length of the certification path (n).
25
     *
26
     * @var int
27
     */
28
    protected $_pathLength;
29
30
    /**
31
     * Current index in the certification path in the range of 1..n (i).
32
     *
33
     * @var int
34
     */
35
    protected $_index;
36
37
    /**
38
     * Valid policy tree (valid_policy_tree).
39
     *
40
     * A tree of certificate policies with their optional qualifiers.
41
     * Each of the leaves of the tree represents a valid policy at this stage in
42
     * the certification path validation.
43
     * Once the tree is set to NULL, policy processing ceases.
44
     *
45
     * @var null|PolicyTree
46
     */
47
    protected $_validPolicyTree;
48
49
    /**
50
     * Permitted subtrees (permitted_subtrees).
51
     *
52
     * A set of root names for each name type defining a set of subtrees within
53
     * which all subject names in subsequent certificates in the certification
54
     * path must fall.
55
     *
56
     * @var mixed
57
     */
58
    protected $_permittedSubtrees;
59
60
    /**
61
     * Excluded subtrees (excluded_subtrees).
62
     *
63
     * A set of root names for each name type defining a set of subtrees within
64
     * which no subject name in subsequent certificates in the certification
65
     * path may fall.
66
     *
67
     * @var mixed
68
     */
69
    protected $_excludedSubtrees;
70
71
    /**
72
     * Explicit policy (explicit_policy).
73
     *
74
     * An integer that indicates if a non-NULL valid_policy_tree is required.
75
     *
76
     * @var int
77
     */
78
    protected $_explicitPolicy;
79
80
    /**
81
     * Inhibit anyPolicy (inhibit_anyPolicy).
82
     *
83
     * An integer that indicates whether the anyPolicy policy identifier is
84
     * considered a match.
85
     *
86
     * @var int
87
     */
88
    protected $_inhibitAnyPolicy;
89
90
    /**
91
     * Policy mapping (policy_mapping).
92
     *
93
     * An integer that indicates if policy mapping is permitted.
94
     *
95
     * @var int
96
     */
97
    protected $_policyMapping;
98
99
    /**
100
     * Working public key algorithm (working_public_key_algorithm).
101
     *
102
     * The digital signature algorithm used to verify the signature of a
103
     * certificate.
104
     *
105
     * @var AlgorithmIdentifierType
106
     */
107
    protected $_workingPublicKeyAlgorithm;
108
109
    /**
110
     * Working public key (working_public_key).
111
     *
112
     * The public key used to verify the signature of a certificate.
113
     *
114
     * @var PublicKeyInfo
115
     */
116
    protected $_workingPublicKey;
117
118
    /**
119
     * Working public key parameters (working_public_key_parameters).
120
     *
121
     * Parameters associated with the current public key that may be required to
122
     * verify a signature.
123
     *
124
     * @var null|Element
125
     */
126
    protected $_workingPublicKeyParameters;
127
128
    /**
129
     * Working issuer name (working_issuer_name).
130
     *
131
     * The issuer distinguished name expected in the next certificate in the
132
     * chain.
133
     *
134
     * @var Name
135
     */
136
    protected $_workingIssuerName;
137
138
    /**
139
     * Maximum certification path length (max_path_length).
140
     *
141
     * @var int
142
     */
143
    protected $_maxPathLength;
144
145
    /**
146
     * Constructor.
147
     */
148 47
    protected function __construct()
149
    {
150 47
    }
151
152
    /**
153
     * Initialize variables according to RFC 5280 6.1.2.
154
     *
155
     * @see https://tools.ietf.org/html/rfc5280#section-6.1.2
156
     *
157
     * @param PathValidationConfig $config
158
     * @param Certificate          $trust_anchor Trust anchor certificate
159
     * @param int                  $n            Number of certificates
160
     *                                           in the certification path
161 47
     *
162
     * @return self
163
     */
164 47
    public static function initialize(PathValidationConfig $config,
165 47
        Certificate $trust_anchor, int $n): self
166 47
    {
167 47
        $state = new self();
168 47
        $state->_pathLength = $n;
169 47
        $state->_index = 1;
170 47
        $state->_validPolicyTree = new PolicyTree(PolicyNode::anyPolicyNode());
171 47
        $state->_permittedSubtrees = null;
172 47
        $state->_excludedSubtrees = null;
173 47
        $state->_explicitPolicy = $config->explicitPolicy() ? 0 : $n + 1;
174 47
        $state->_inhibitAnyPolicy = $config->anyPolicyInhibit() ? 0 : $n + 1;
175 47
        $state->_policyMapping = $config->policyMappingInhibit() ? 0 : $n + 1;
176 47
        $state->_workingPublicKeyAlgorithm = $trust_anchor->signatureAlgorithm();
177 47
        $tbsCert = $trust_anchor->tbsCertificate();
178 47
        $state->_workingPublicKey = $tbsCert->subjectPublicKeyInfo();
179 47
        $state->_workingPublicKeyParameters = self::getAlgorithmParameters(
180 47
            $state->_workingPublicKey->algorithmIdentifier());
181
        $state->_workingIssuerName = $tbsCert->issuer();
182
        $state->_maxPathLength = $config->maxLength();
183
        return $state;
184
    }
185
186
    /**
187
     * Get self with current certification path index set.
188
     *
189 44
     * @param int $index
190
     *
191 44
     * @return self
192 44
     */
193 44
    public function withIndex(int $index): self
194
    {
195
        $state = clone $this;
196
        $state->_index = $index;
197
        return $state;
198
    }
199
200
    /**
201
     * Get self with valid_policy_tree.
202 14
     *
203
     * @param PolicyTree $policy_tree
204 14
     *
205 14
     * @return self
206 14
     */
207
    public function withValidPolicyTree(PolicyTree $policy_tree): self
208
    {
209
        $state = clone $this;
210
        $state->_validPolicyTree = $policy_tree;
211
        return $state;
212
    }
213
214 36
    /**
215
     * Get self with valid_policy_tree set to null.
216 36
     *
217 36
     * @return self
218 36
     */
219
    public function withoutValidPolicyTree(): self
220
    {
221
        $state = clone $this;
222
        $state->_validPolicyTree = null;
223
        return $state;
224
    }
225
226
    /**
227 30
     * Get self with explicit_policy.
228
     *
229 30
     * @param int $num
230 30
     *
231 30
     * @return self
232
     */
233
    public function withExplicitPolicy(int $num): self
234
    {
235
        $state = clone $this;
236
        $state->_explicitPolicy = $num;
237
        return $state;
238
    }
239
240 23
    /**
241
     * Get self with inhibit_anyPolicy.
242 23
     *
243 23
     * @param int $num
244 23
     *
245
     * @return self
246
     */
247
    public function withInhibitAnyPolicy(int $num): self
248
    {
249
        $state = clone $this;
250
        $state->_inhibitAnyPolicy = $num;
251
        return $state;
252
    }
253 21
254
    /**
255 21
     * Get self with policy_mapping.
256 21
     *
257 21
     * @param int $num
258
     *
259
     * @return self
260
     */
261
    public function withPolicyMapping(int $num): self
262
    {
263
        $state = clone $this;
264
        $state->_policyMapping = $num;
265
        return $state;
266 42
    }
267
268 42
    /**
269 42
     * Get self with working_public_key_algorithm.
270 42
     *
271
     * @param AlgorithmIdentifierType $algo
272
     *
273
     * @return self
274
     */
275
    public function withWorkingPublicKeyAlgorithm(AlgorithmIdentifierType $algo): self
276
    {
277
        $state = clone $this;
278
        $state->_workingPublicKeyAlgorithm = $algo;
279 42
        return $state;
280
    }
281 42
282 42
    /**
283 42
     * Get self with working_public_key.
284
     *
285
     * @param PublicKeyInfo $pubkey_info
286
     *
287
     * @return self
288
     */
289
    public function withWorkingPublicKey(PublicKeyInfo $pubkey_info): self
290
    {
291
        $state = clone $this;
292 42
        $state->_workingPublicKey = $pubkey_info;
293
        return $state;
294 42
    }
295 42
296 42
    /**
297
     * Get self with working_public_key_parameters.
298
     *
299
     * @param null|Element $params
300
     *
301
     * @return self
302
     */
303
    public function withWorkingPublicKeyParameters(?Element $params = null): self
304
    {
305 42
        $state = clone $this;
306
        $state->_workingPublicKeyParameters = $params;
307 42
        return $state;
308 42
    }
309 42
310
    /**
311
     * Get self with working_issuer_name.
312
     *
313
     * @param Name $issuer
314
     *
315
     * @return self
316
     */
317
    public function withWorkingIssuerName(Name $issuer): self
318 28
    {
319
        $state = clone $this;
320 28
        $state->_workingIssuerName = $issuer;
321 28
        return $state;
322 28
    }
323
324
    /**
325
     * Get self with max_path_length.
326
     *
327
     * @param int $length
328
     *
329
     * @return self
330 1
     */
331
    public function withMaxPathLength(int $length): self
332 1
    {
333
        $state = clone $this;
334
        $state->_maxPathLength = $length;
335
        return $state;
336
    }
337
338
    /**
339
     * Get the certification path length (n).
340 15
     *
341
     * @return int
342 15
     */
343
    public function pathLength(): int
344
    {
345
        return $this->_pathLength;
346
    }
347
348
    /**
349
     * Get the current index in certification path in the range of 1..n.
350 35
     *
351
     * @return int
352 35
     */
353
    public function index(): int
354
    {
355
        return $this->_index;
356
    }
357
358
    /**
359
     * Check whether valid_policy_tree is present.
360
     *
361 15
     * @return bool
362
     */
363 15
    public function hasValidPolicyTree(): bool
364 1
    {
365
        return isset($this->_validPolicyTree);
366 14
    }
367
368
    /**
369
     * Get valid_policy_tree.
370
     *
371
     * @throws \LogicException If not set
372
     *
373
     * @return PolicyTree
374 35
     */
375
    public function validPolicyTree(): PolicyTree
376 35
    {
377
        if (!$this->hasValidPolicyTree()) {
378
            throw new \LogicException('valid_policy_tree not set.');
379
        }
380
        return $this->_validPolicyTree;
381
    }
382
383
    /**
384 35
     * Get permitted_subtrees.
385
     *
386 35
     * @return mixed
387
     */
388
    public function permittedSubtrees()
389
    {
390
        return $this->_permittedSubtrees;
391
    }
392
393
    /**
394 43
     * Get excluded_subtrees.
395
     *
396 43
     * @return mixed
397
     */
398
    public function excludedSubtrees()
399
    {
400
        return $this->_excludedSubtrees;
401
    }
402
403
    /**
404 26
     * Get explicit_policy.
405
     *
406 26
     * @return int
407
     */
408
    public function explicitPolicy(): int
409
    {
410
        return $this->_explicitPolicy;
411
    }
412
413
    /**
414 23
     * Get inhibit_anyPolicy.
415
     *
416 23
     * @return int
417
     */
418
    public function inhibitAnyPolicy(): int
419
    {
420
        return $this->_inhibitAnyPolicy;
421
    }
422
423
    /**
424 1
     * Get policy_mapping.
425
     *
426 1
     * @return int
427
     */
428
    public function policyMapping(): int
429
    {
430
        return $this->_policyMapping;
431
    }
432
433
    /**
434 44
     * Get working_public_key_algorithm.
435
     *
436 44
     * @return AlgorithmIdentifierType
437
     */
438
    public function workingPublicKeyAlgorithm(): AlgorithmIdentifierType
439
    {
440
        return $this->_workingPublicKeyAlgorithm;
441
    }
442
443
    /**
444 1
     * Get working_public_key.
445
     *
446 1
     * @return PublicKeyInfo
447
     */
448
    public function workingPublicKey(): PublicKeyInfo
449
    {
450
        return $this->_workingPublicKey;
451
    }
452
453
    /**
454 43
     * Get working_public_key_parameters.
455
     *
456 43
     * @return null|Element
457
     */
458
    public function workingPublicKeyParameters(): ?Element
459
    {
460
        return $this->_workingPublicKeyParameters;
461
    }
462
463
    /**
464 31
     * Get working_issuer_name.
465
     *
466 31
     * @return Name
467
     */
468
    public function workingIssuerName(): Name
469
    {
470
        return $this->_workingIssuerName;
471
    }
472
473
    /**
474 43
     * Get maximum certification path length.
475
     *
476 43
     * @return int
477
     */
478
    public function maxPathLength(): int
479
    {
480
        return $this->_maxPathLength;
481
    }
482
483
    /**
484
     * Check whether processing the final certificate of the certification path.
485 28
     *
486
     * @return bool
487 28
     */
488 28
    public function isFinal(): bool
489 28
    {
490
        return $this->_index === $this->_pathLength;
491
    }
492
493
    /**
494
     * Get the path validation result.
495
     *
496
     * @param Certificate[] $certificates Certificates in a certification path
497
     *
498 47
     * @return PathValidationResult
499
     */
500 47
    public function getResult(array $certificates): PathValidationResult
501 47
    {
502
        return new PathValidationResult($certificates, $this->_validPolicyTree,
503
            $this->_workingPublicKey, $this->_workingPublicKeyAlgorithm,
504
            $this->_workingPublicKeyParameters);
505
    }
506
507
    /**
508
     * Get ASN.1 parameters from algorithm identifier.
509
     *
510
     * @param AlgorithmIdentifierType $algo
511
     *
512
     * @return null|Element ASN.1 element or null if parameters are omitted
513
     */
514
    public static function getAlgorithmParameters(AlgorithmIdentifierType $algo): ?Element
515
    {
516
        $seq = $algo->toASN1();
517
        return $seq->has(1) ? $seq->at(1)->asElement() : null;
518
    }
519
}
520