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.
Completed
Push — master ( eef5cb...fe4976 )
by Joni
06:29
created

PathValidator::_calculatePolicyIntersection()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 19
ccs 8
cts 8
cp 1
rs 9.4285
cc 3
eloc 8
nc 3
nop 1
crap 3
1
<?php
2
3
namespace X509\CertificationPath\PathValidation;
4
5
use CryptoUtil\Crypto\Crypto;
6
use X509\Certificate\Certificate;
7
use X509\Certificate\Extension\CertificatePolicy\PolicyInformation;
8
use X509\Certificate\Extension\Extension;
9
use X509\Certificate\TBSCertificate;
10
use X509\CertificationPath\Exception\PathValidationException;
11
12
13
/**
14
 * Implements certification path validation.
15
 *
16
 * @link https://tools.ietf.org/html/rfc5280#section-6
17
 */
18
class PathValidator
19
{
20
	/**
21
	 * Crypto engine.
22
	 *
23
	 * @var Crypto $_crypto
24
	 */
25
	protected $_crypto;
26
	
27
	/**
28
	 * Path validation configuration.
29
	 *
30
	 * @var PathValidationConfig $_config
31
	 */
32
	protected $_config;
33
	
34
	/**
35
	 * Certification path.
36
	 *
37
	 * @var Certificate[] $_certificates
38
	 */
39
	protected $_certificates;
40
	
41
	/**
42
	 * Certification path trust anchor.
43
	 *
44
	 * @var Certificate $_trustAnchor
45
	 */
46
	protected $_trustAnchor;
47
	
48
	/**
49
	 * Constructor
50
	 *
51
	 * @param Crypto $crypto
52
	 * @param PathValidationConfig $config
53
	 * @param Certificate ...$certificates
54
	 */
55 46
	public function __construct(Crypto $crypto, PathValidationConfig $config, 
56
			Certificate ...$certificates) {
57 46
		if (!count($certificates)) {
58 1
			throw new \LogicException("No certificates.");
59
		}
60 45
		$this->_crypto = $crypto;
61 45
		$this->_config = $config;
62 45
		$this->_certificates = $certificates;
63
		// if trust anchor is explicitly given in configuration
64 45
		if ($config->hasTrustAnchor()) {
65 1
			$this->_trustAnchor = $config->trustAnchor();
66 1
		} else {
67 44
			$this->_trustAnchor = $certificates[0];
68
		}
69 45
	}
70
	
71
	/**
72
	 * Validate certification path.
73
	 *
74
	 * @throws PathValidationException
75
	 * @return PathValidationResult
76
	 */
77 45
	public function validate() {
78 45
		$n = count($this->_certificates);
79 45
		$state = ValidatorState::initialize($this->_config, $this->_trustAnchor, 
80 45
			$n);
81 45
		for ($i = 0; $i < $n; ++$i) {
82 44
			$state = $state->withIndex($i + 1);
83 44
			$cert = $this->_certificates[$i];
84
			// process certificate (section 6.1.3.)
85 44
			$state = $this->_processCertificate($state, $cert);
86 43
			if (!$state->isFinal()) {
87
				// prepare next certificate (section 6.1.4.)
88 43
				$state = $this->_prepareNext($state, $cert);
89 39
			}
90 39
		}
91 31
		if (!isset($cert)) {
92 1
			throw new \LogicException("No certificates.");
93
		}
94
		// wrap-up (section 6.1.5.)
95 30
		$state = $this->_wrapUp($state, $cert);
96
		// return outputs
97 28
		return $state->getResult($this->_certificates);
98
	}
99
	
100
	/**
101
	 * Apply basic certificate processing according to RFC 5280 section 6.1.3.
102
	 *
103
	 * @link https://tools.ietf.org/html/rfc5280#section-6.1.3
104
	 * @param ValidatorState $state
105
	 * @param Certificate $cert
106
	 * @throws PathValidationException
107
	 * @return ValidatorState
108
	 */
109 44
	private function _processCertificate(ValidatorState $state, 
110
			Certificate $cert) {
111
		// (a.1) verify signature
112 44
		$this->_verifySignature($state, $cert);
113
		// (a.2) check validity period
114 44
		$this->_checkValidity($cert);
115
		// (a.3) check that certificate is not revoked
116 43
		$this->_checkRevocation($cert);
0 ignored issues
show
Unused Code introduced by
The call to the method X509\CertificationPath\P...tor::_checkRevocation() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
117
		// (a.4) check issuer
118 43
		$this->_checkIssuer($state, $cert);
119
		// (b)(c) if certificate is self-issued and it is not
120
		// the final certificate in the path, skip this step
121 43
		if (!($cert->isSelfIssued() && !$state->isFinal())) {
122
			// (b) check permitted subtrees
123 35
			$this->_checkPermittedSubtrees($state, $cert);
0 ignored issues
show
Unused Code introduced by
The call to the method X509\CertificationPath\P...heckPermittedSubtrees() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
124
			// (c) check excluded subtrees
125 35
			$this->_checkExcludedSubtrees($state, $cert);
0 ignored issues
show
Unused Code introduced by
The call to the method X509\CertificationPath\P...checkExcludedSubtrees() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
126 35
		}
127 43
		$extensions = $cert->tbsCertificate()->extensions();
128 43
		if ($extensions->hasCertificatePolicies()) {
129
			// (d) process policy information
130 26
			if ($state->hasValidPolicyTree()) {
131 14
				$state = $state->validPolicyTree()->processPolicies($state, 
132 14
					$cert);
133 14
			}
134 26
		} else {
135
			// (e) certificate policies extension not present,
136
			// set the valid_policy_tree to NULL
137 31
			$state = $state->withoutValidPolicyTree();
138
		}
139
		// (f) check that explicit_policy > 0 or valid_policy_tree is set
140 43
		if (!($state->explicitPolicy() > 0 || $state->hasValidPolicyTree())) {
141 3
			throw new PathValidationException("No valid policies.");
142
		}
143 43
		return $state;
144
	}
145
	
146
	/**
147
	 * Apply preparation for the certificate i+1 according to rfc5280 section
148
	 * 6.1.4.
149
	 *
150
	 * @link https://tools.ietf.org/html/rfc5280#section-6.1.4
151
	 * @param ValidatorState $state
152
	 * @param Certificate $cert
153
	 * @return ValidatorState
154
	 */
155 43
	private function _prepareNext(ValidatorState $state, Certificate $cert) {
156
		// (a)(b) if policy mappings extension is present
157 43
		$state = $this->_preparePolicyMappings($state, $cert);
158
		// (c) assign working_issuer_name
159 42
		$state = $state->withWorkingIssuerName(
160 42
			$cert->tbsCertificate()
161 42
				->subject());
162
		// (d)(e)(f)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
163 42
		$state = $this->_setPublicKeyState($state, $cert);
164
		// (g) if name constraints extension is present
165 42
		$state = $this->_prepareNameConstraints($state, $cert);
166
		// (h) if certificate is not self-issued
167 42
		if (!$cert->isSelfIssued()) {
168 21
			$state = $this->_prepareNonSelfIssued($state);
169 21
		}
170
		// (i) if policy constraints extension is present
171 42
		$state = $this->_preparePolicyConstraints($state, $cert);
172
		// (j) if inhibit any policy extension is present
173 42
		$state = $this->_prepareInhibitAnyPolicy($state, $cert);
174
		// (k) check basic constraints
175 42
		$this->_processBasicContraints($cert);
176
		// (l) verify max_path_length
177 40
		$state = $this->_verifyMaxPathLength($state, $cert);
178
		// (m) check pathLenContraint
179 40
		$state = $this->_processPathLengthContraint($state, $cert);
180
		// (n) check key usage
181 40
		$this->_checkKeyUsage($cert);
182
		// (o) process relevant extensions
183 39
		$state = $this->_processExtensions($state, $cert);
184 39
		return $state;
185
	}
186
	
187
	/**
188
	 * Apply wrap-up procedure according to RFC 5280 section 6.1.5.
189
	 *
190
	 * @link https://tools.ietf.org/html/rfc5280#section-6.1.5
191
	 * @param ValidatorState $state
192
	 * @param Certificate $cert
193
	 * @throws PathValidationException
194
	 */
195 30
	private function _wrapUp(ValidatorState $state, Certificate $cert) {
196 30
		$tbs_cert = $cert->tbsCertificate();
197 30
		$extensions = $tbs_cert->extensions();
198
		// (a)
199 30
		if ($state->explicitPolicy() > 0) {
200 26
			$state = $state->withExplicitPolicy($state->explicitPolicy() - 1);
201 26
		}
202
		// (b)
203 30
		if ($extensions->hasPolicyConstraints()) {
204 13
			$ext = $extensions->policyConstraints();
205 13
			if ($ext->hasRequireExplicitPolicy() &&
206 13
				 $ext->requireExplicitPolicy() == 0) {
207 1
				$state = $state->withExplicitPolicy(0);
208 1
			}
209 13
		}
210
		// (c)(d)(e)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
211 30
		$state = $this->_setPublicKeyState($state, $cert);
212
		// (f) process relevant extensions
213 30
		$state = $this->_processExtensions($state, $cert);
214
		// (g) intersection of valid_policy_tree and the initial-policy-set
215 30
		$state = $this->_calculatePolicyIntersection($state);
216
		// check that explicit_policy > 0 or valid_policy_tree is set
217 30
		if (!($state->explicitPolicy() > 0 || $state->hasValidPolicyTree())) {
218 2
			throw new PathValidationException("No valid policies.");
219
		}
220
		// path validation succeeded
221 28
		return $state;
222
	}
223
	
224
	/**
225
	 * Update working_public_key, working_public_key_parameters and
226
	 * working_public_key_algorithm state variables from certificate.
227
	 *
228
	 * @param ValidatorState $state
229
	 * @param Certificate $cert
230
	 * @return ValidatorState
231
	 */
232 42
	private function _setPublicKeyState(ValidatorState $state, Certificate $cert) {
233 42
		$pk_info = $cert->tbsCertificate()->subjectPublicKeyInfo();
234
		// assign working_public_key
235 42
		$state = $state->withWorkingPublicKey($pk_info);
236
		// assign working_public_key_parameters
237 42
		$params = ValidatorState::getAlgorithmParameters(
238 42
			$pk_info->algorithmIdentifier());
239 42
		if (null !== $params) {
240 42
			$state = $state->withWorkingPublicKeyParameters($params);
241 42
		} else {
242
			// if algorithms differ, set parameters to null
243 1
			if ($pk_info->algorithmIdentifier()->oid() !==
244 1
				 $state->workingPublicKeyAlgorithm()->oid()) {
245 1
				$state = $state->withWorkingPublicKeyParameters(null);
246 1
			}
247
		}
248
		// assign working_public_key_algorithm
249 42
		$state = $state->withWorkingPublicKeyAlgorithm(
250 42
			$pk_info->algorithmIdentifier());
251 42
		return $state;
252
	}
253
	
254
	/**
255
	 * Verify certificate signature.
256
	 *
257
	 * @param ValidatorState $state
258
	 * @param Certificate $cert
259
	 * @throws PathValidationException
260
	 */
261 44
	private function _verifySignature(ValidatorState $state, Certificate $cert) {
262
		try {
263 44
			$valid = $cert->verify($this->_crypto, $state->workingPublicKey());
264 44
		} catch (\RuntimeException $e) {
265 1
			throw new PathValidationException(
266 1
				"Failed to verify signature: " . $e->getMessage(), null, $e);
267
		}
268 44
		if (!$valid) {
269 2
			throw new PathValidationException(
270 2
				"Certificate signature doesn't match.");
271
		}
272 44
	}
273
	
274
	/**
275
	 * Check certificate validity.
276
	 *
277
	 * @param Certificate $cert
278
	 * @throws PathValidationException
279
	 */
280 44
	private function _checkValidity(Certificate $cert) {
281 44
		$refdt = $this->_config->dateTime();
282 44
		$validity = $cert->tbsCertificate()->validity();
283 44
		if ($validity->notBefore()
284 44
			->dateTime()
285 44
			->diff($refdt)->invert) {
286 1
			throw new PathValidationException(
287 1
				"Certificate validity period has not started.");
288
		}
289 43
		if ($refdt->diff($validity->notAfter()
290 43
			->dateTime())->invert) {
291 1
			throw new PathValidationException("Certificate has expired.");
292
		}
293 43
	}
294
	
295
	/**
296
	 * Check certificate revocation.
297
	 *
298
	 * @param Certificate $cert
299
	 */
300 43
	private function _checkRevocation(Certificate $cert) {
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
301
		// @todo Implement CRL handling
302 43
	}
303
	
304
	/**
305
	 * Check certificate issuer.
306
	 *
307
	 * @param ValidatorState $state
308
	 * @param Certificate $cert
309
	 * @throws PathValidationException
310
	 */
311 43
	private function _checkIssuer(ValidatorState $state, Certificate $cert) {
312 43
		if (!$cert->tbsCertificate()
313 43
			->issuer()
314 43
			->equals($state->workingIssuerName())) {
315 1
			throw new PathValidationException("Certification issuer mismatch.");
316
		}
317 43
	}
318
	
319
	/**
320
	 *
321
	 * @param ValidatorState $state
322
	 * @param Certificate $cert
323
	 */
324 35
	private function _checkPermittedSubtrees(ValidatorState $state, 
325
			Certificate $cert) {
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
326
		// @todo Implement
327 35
		$state->permittedSubtrees();
0 ignored issues
show
Unused Code introduced by
The call to the method X509\CertificationPath\P...te::permittedSubtrees() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
328 35
	}
329
	
330
	/**
331
	 *
332
	 * @param ValidatorState $state
333
	 * @param Certificate $cert
334
	 */
335 35
	private function _checkExcludedSubtrees(ValidatorState $state, 
336
			Certificate $cert) {
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
337
		// @todo Implement
338 35
		$state->excludedSubtrees();
0 ignored issues
show
Unused Code introduced by
The call to the method X509\CertificationPath\P...ate::excludedSubtrees() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
339 35
	}
340
	
341
	/**
342
	 * Apply policy mappings handling for the preparation step.
343
	 *
344
	 * @param ValidatorState $state
345
	 * @param Certificate $cert
346
	 * @throws PathValidationException
347
	 * @return ValidatorState
348
	 */
349 43
	private function _preparePolicyMappings(ValidatorState $state, 
350
			Certificate $cert) {
351 43
		$extensions = $cert->tbsCertificate()->extensions();
352 43
		if ($extensions->hasPolicyMappings()) {
353
			// (a) verify that anyPolicy mapping is not used
354 4
			if ($extensions->policyMappings()->hasAnyPolicyMapping()) {
355 1
				throw new PathValidationException("anyPolicy mapping found.");
356
			}
357
			// (b) process policy mappings
358 3
			if ($state->hasValidPolicyTree()) {
359 3
				$state = $state->validPolicyTree()->processMappings($state, 
360 3
					$cert);
361 3
			}
362 3
		}
363 42
		return $state;
364
	}
365
	
366
	/**
367
	 * Apply name constraints handling for the preparation step.
368
	 *
369
	 * @param ValidatorState $state
370
	 * @param Certificate $cert
371
	 * @return ValidatorState
372
	 */
373 42
	private function _prepareNameConstraints(ValidatorState $state, 
374
			Certificate $cert) {
375 42
		$extensions = $cert->tbsCertificate()->extensions();
376 42
		if ($extensions->hasNameConstraints()) {
377 1
			$state = $this->_processNameConstraints($state, $cert);
378 1
		}
379 42
		return $state;
380
	}
381
	
382
	/**
383
	 * Apply preparation for a non-self-signed certificate.
384
	 *
385
	 * @param ValidatorState $state
386
	 * @return ValidatorState
387
	 */
388 21
	private function _prepareNonSelfIssued(ValidatorState $state) {
389
		// (h.1)
390 21
		if ($state->explicitPolicy() > 0) {
391 20
			$state = $state->withExplicitPolicy($state->explicitPolicy() - 1);
392 20
		}
393
		// (h.2)
394 21
		if ($state->policyMapping() > 0) {
395 20
			$state = $state->withPolicyMapping($state->policyMapping() - 1);
396 20
		}
397
		// (h.3)
398 21
		if ($state->inhibitAnyPolicy() > 0) {
399 21
			$state = $state->withInhibitAnyPolicy(
400 21
				$state->inhibitAnyPolicy() - 1);
401 21
		}
402 21
		return $state;
403
	}
404
	
405
	/**
406
	 * Apply policy constraints handling for the preparation step.
407
	 *
408
	 * @param ValidatorState $state
409
	 * @param Certificate $cert
410
	 * @return ValidatorState
411
	 */
412 42
	private function _preparePolicyConstraints(ValidatorState $state, 
413
			Certificate $cert) {
414 42
		$extensions = $cert->tbsCertificate()->extensions();
415 42
		if (!$extensions->hasPolicyConstraints()) {
416 41
			return $state;
417
		}
418 2
		$ext = $extensions->policyConstraints();
419
		// (i.1)
420 2
		if ($ext->hasRequireExplicitPolicy() &&
421 2
			 $ext->requireExplicitPolicy() < $state->explicitPolicy()) {
422 2
			$state = $state->withExplicitPolicy($ext->requireExplicitPolicy());
423 2
		}
424
		// (i.2)
425 2
		if ($ext->hasInhibitPolicyMapping() &&
426 2
			 $ext->inhibitPolicyMapping() < $state->policyMapping()) {
427 1
			$state = $state->withPolicyMapping($ext->inhibitPolicyMapping());
428 1
		}
429 2
		return $state;
430
	}
431
	
432
	/**
433
	 * Apply inhibit any-policy handling for the preparation step.
434
	 *
435
	 * @param ValidatorState $state
436
	 * @param Certificate $cert
437
	 * @return ValidatorState
438
	 */
439 42
	private function _prepareInhibitAnyPolicy(ValidatorState $state, 
440
			Certificate $cert) {
441 42
		$extensions = $cert->tbsCertificate()->extensions();
442 42
		if ($extensions->hasInhibitAnyPolicy()) {
443 2
			$ext = $extensions->inhibitAnyPolicy();
444 2
			if ($ext->skipCerts() < $state->inhibitAnyPolicy()) {
445 2
				$state = $state->withInhibitAnyPolicy($ext->skipCerts());
446 2
			}
447 2
		}
448 42
		return $state;
449
	}
450
	
451
	/**
452
	 * Verify maximum certification path length for the preparation step.
453
	 *
454
	 * @param ValidatorState $state
455
	 * @param Certificate $cert
456
	 * @throws PathValidationException
457
	 * @return ValidatorState
458
	 */
459 40
	private function _verifyMaxPathLength(ValidatorState $state, 
460
			Certificate $cert) {
461 40
		if (!$cert->isSelfIssued()) {
462 21
			if ($state->maxPathLength() <= 0) {
463 2
				throw new PathValidationException(
464 2
					"Certification path length exceeded.");
465
			}
466 19
			$state = $state->withMaxPathLength($state->maxPathLength() - 1);
467 19
		}
468 40
		return $state;
469
	}
470
	
471
	/**
472
	 * Check key usage extension for the preparation step.
473
	 *
474
	 * @param Certificate $cert
475
	 * @throws PathValidationException
476
	 */
477 40
	private function _checkKeyUsage(Certificate $cert) {
478 40
		$extensions = $cert->tbsCertificate()->extensions();
479 40
		if ($extensions->hasKeyUsage()) {
480 20
			$ext = $extensions->keyUsage();
481 20
			if (!$ext->isKeyCertSign()) {
482 1
				throw new PathValidationException("keyCertSign usage not set.");
483
			}
484 19
		}
485 39
	}
486
	
487
	/**
488
	 *
489
	 * @param ValidatorState $state
490
	 * @param Certificate $cert
491
	 * @return ValidatorState
492
	 */
493 1
	private function _processNameConstraints(ValidatorState $state, 
494
			Certificate $cert) {
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
495
		// @todo Implement
496 1
		return $state;
497
	}
498
	
499
	/**
500
	 * Process basic constraints extension.
501
	 *
502
	 * @param Certificate $cert
503
	 * @throws PathValidationException
504
	 */
505 42
	private function _processBasicContraints(Certificate $cert) {
506 42
		if ($cert->tbsCertificate()->version() == TBSCertificate::VERSION_3) {
507 39
			$extensions = $cert->tbsCertificate()->extensions();
508 39
			if (!$extensions->hasBasicConstraints()) {
509 1
				throw new PathValidationException(
510 1
					"v3 certificate must have basicConstraints extension.");
511
			}
512
			// verify that cA is set to TRUE
513 38
			if (!$extensions->basicConstraints()->isCA()) {
514 1
				throw new PathValidationException(
515 1
					"Certificate is not a CA certificate.");
516
			}
517 37
		}
518 40
	}
519
	
520
	/**
521
	 * Process pathLenConstraint.
522
	 *
523
	 * @param ValidatorState $state
524
	 * @param Certificate $cert
525
	 * @return ValidatorState
526
	 */
527 40
	private function _processPathLengthContraint(ValidatorState $state, 
528
			Certificate $cert) {
529 40
		$extensions = $cert->tbsCertificate()->extensions();
530 40
		if ($extensions->hasBasicConstraints()) {
531 37
			$ext = $extensions->basicConstraints();
532 37
			if ($ext->hasPathLen()) {
533 26
				if ($ext->pathLen() < $state->maxPathLength()) {
534 9
					$state = $state->withMaxPathLength($ext->pathLen());
535 9
				}
536 26
			}
537 37
		}
538 40
		return $state;
539
	}
540
	
541
	/**
542
	 *
543
	 * @param ValidatorState $state
544
	 * @param Certificate $cert
545
	 * @return ValidatorState
546
	 */
547 39
	private function _processExtensions(ValidatorState $state, Certificate $cert) {
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
548
		// @todo Implement
549 39
		return $state;
550
	}
551
	
552
	/**
553
	 *
554
	 * @param ValidatorState $state
555
	 * @return ValidatorState
556
	 */
557 30
	private function _calculatePolicyIntersection(ValidatorState $state) {
558
		// (i) If the valid_policy_tree is NULL, the intersection is NULL
559 30
		if (!$state->hasValidPolicyTree()) {
560 21
			return $state;
561
		}
562
		// (ii) If the valid_policy_tree is not NULL and
563
		// the user-initial-policy-set is any-policy, the intersection
564
		// is the entire valid_policy_tree
565 9
		$initial_policies = $this->_config->policySet();
566 9
		if (in_array(PolicyInformation::OID_ANY_POLICY, $initial_policies)) {
567 3
			return $state;
568
		}
569
		// (iii) If the valid_policy_tree is not NULL and the
570
		// user-initial-policy-set is not any-policy, calculate
571
		// the intersection of the valid_policy_tree and the
572
		// user-initial-policy-set as follows
573 6
		return $state->validPolicyTree()->calculateIntersection($state, 
574 6
			$initial_policies);
575
	}
576
}
577