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 ( 0989e1...73a8c5 )
by Joni
04:44
created

ACValidator::_verifyIssuer()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 19
rs 9.2
nc 4
cc 4
eloc 15
nop 0
1
<?php
2
3
namespace X509\AttributeCertificate\Validation;
4
5
use CryptoUtil\Crypto\Crypto;
6
use X509\AttributeCertificate\AttributeCertificate;
7
use X509\AttributeCertificate\Validation\Exception\ACValidationException;
8
use X509\Certificate\Certificate;
9
use X509\Certificate\Extension\Extension;
10
use X509\Certificate\Extension\Target\Target;
11
use X509\Certificate\Extension\Target\Targets;
12
use X509\Certificate\Extension\TargetInformationExtension;
13
use X509\CertificationPath\Exception\PathValidationException;
14
use X509\CertificationPath\PathValidation\PathValidationConfig;
15
16
17
/**
18
 * Implements attribute certificate validation conforming to RFC 5755.
19
 *
20
 * @link https://tools.ietf.org/html/rfc5755#section-5
21
 */
22
class ACValidator
23
{
24
	/**
25
	 * Attribute certificate.
26
	 *
27
	 * @var AttributeCertificate
28
	 */
29
	protected $_ac;
30
	
31
	/**
32
	 * Validation configuration.
33
	 *
34
	 * @var ACValidationConfig
35
	 */
36
	protected $_config;
37
	
38
	/**
39
	 * Crypto engine.
40
	 *
41
	 * @var Crypto
42
	 */
43
	protected $_crypto;
44
	
45
	/**
46
	 * Constructor.
47
	 *
48
	 * @param AttributeCertificate $ac Attribute certificate to validate
49
	 * @param ACValidationConfig $config Validation configuration
50
	 * @param Crypto $crypto Crypto engine
51
	 */
52
	public function __construct(AttributeCertificate $ac, 
53
			ACValidationConfig $config, Crypto $crypto) {
54
		$this->_ac = $ac;
55
		$this->_config = $config;
56
		$this->_crypto = $crypto;
57
	}
58
	
59
	/**
60
	 * Validate attribute certificate.
61
	 *
62
	 * @throws ACValidationException If validation fails
63
	 * @return AttributeCertificate Validated AC
64
	 */
65
	public function validate() {
66
		$this->_validateHolder();
67
		$issuer = $this->_verifyIssuer();
68
		$this->_validateIssuerProfile($issuer);
69
		$this->_validateTime();
70
		$this->_validateTargeting();
71
		return $this->_ac;
72
	}
73
	
74
	private function _validateHolder() {
75
		$path = $this->_config->holderPath();
76
		$config = PathValidationConfig::defaultConfig()->withMaxLength(
77
			count($path));
78
		try {
79
			$holder = $path->validate($this->_crypto, $config)->certificate();
80
		} catch (PathValidationException $e) {
81
			throw new ACValidationException(
82
				"Failed to validate holder PKC's certification path.", null, $e);
83
		}
84
		if (!$this->_ac->isHeldBy($holder)) {
85
			throw new ACValidationException("Name mismatch of AC's holder PKC.");
86
		}
87
		return $holder;
88
	}
89
	
90
	private function _verifyIssuer() {
91
		$path = $this->_config->issuerPath();
92
		$config = PathValidationConfig::defaultConfig()->withMaxLength(
93
			count($path));
94
		try {
95
			$issuer = $path->validate($this->_crypto, $config)->certificate();
96
		} catch (PathValidationException $e) {
97
			throw new ACValidationException(
98
				"Failed to validate issuer PKC's certification path.", null, $e);
99
		}
100
		if (!$this->_ac->isIssuedBy($issuer)) {
101
			throw new ACValidationException("Name mismatch of AC's issuer PKC.");
102
		}
103
		$pubkey_info = $issuer->tbsCertificate()->subjectPublicKeyInfo();
104
		if (!$this->_ac->verify($this->_crypto, $pubkey_info)) {
105
			throw new ACValidationException("Failed to verify signature.");
106
		}
107
		return $issuer;
108
	}
109
	
110
	private function _validateIssuerProfile(Certificate $cert) {
111
		$exts = $cert->tbsCertificate()->extensions();
112
		if ($exts->hasKeyUsage() && !$exts->keyUsage()->isDigitalSignature()) {
113
			throw new ACValidationException(
114
				"Issuer PKC's Key Usage extension doesn't permit" .
115
					 " verification of digital signatures.");
116
		}
117
		if ($exts->hasBasicConstraints() && $exts->basicConstraints()->isCA()) {
118
			throw new ACValidationException("Issuer PKC must not be a CA.");
119
		}
120
	}
121
	
122
	private function _validateTime() {
123
		$t = $this->_config->evaluationTime();
124
		$validity = $this->_ac->acinfo()->validityPeriod();
125
		if ($validity->notBeforeTime()->diff($t)->invert) {
126
			throw new ACValidationException("Validity period has not started.");
127
		}
128
		if ($t->diff($validity->notAfterTime())->invert) {
129
			throw new ACValidationException("Attribute certificate has expired.");
130
		}
131
	}
132
	
133
	private function _validateTargeting() {
134
		$exts = $this->_ac->acinfo()->extensions();
135
		// if target information extension is not present
136
		if (!$exts->has(Extension::OID_TARGET_INFORMATION)) {
137
			return;
138
		}
139
		$ext = $exts->get(Extension::OID_TARGET_INFORMATION);
140
		if ($ext instanceof TargetInformationExtension &&
141
			 !$this->_hasMatchingTarget($ext->targets())) {
142
			throw new ACValidationException(
143
				"Attribute certificate doesn't have a matching target.");
144
		}
145
	}
146
	
147
	private function _hasMatchingTarget(Targets $targets) {
148
		foreach ($this->_config->targets() as $target) {
149
			if ($targets->hasTarget($target)) {
150
				return true;
151
			}
152
		}
153
		return false;
154
	}
155
}
156