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
Branch php72 (a7f01e)
by Joni
04:53
created
lib/X509/CertificationPath/Policy/PolicyTree.php 2 patches
Indentation   +392 added lines, -392 removed lines patch added patch discarded remove patch
@@ -10,410 +10,410 @@
 block discarded – undo
10 10
 
11 11
 class PolicyTree
12 12
 {
13
-    /**
14
-     * Root node at depth zero.
15
-     *
16
-     * @var null|PolicyNode
17
-     */
18
-    protected $_root;
13
+	/**
14
+	 * Root node at depth zero.
15
+	 *
16
+	 * @var null|PolicyNode
17
+	 */
18
+	protected $_root;
19 19
 
20
-    /**
21
-     * Constructor.
22
-     *
23
-     * @param PolicyNode $root Initial root node
24
-     */
25
-    public function __construct(PolicyNode $root)
26
-    {
27
-        $this->_root = $root;
28
-    }
20
+	/**
21
+	 * Constructor.
22
+	 *
23
+	 * @param PolicyNode $root Initial root node
24
+	 */
25
+	public function __construct(PolicyNode $root)
26
+	{
27
+		$this->_root = $root;
28
+	}
29 29
 
30
-    /**
31
-     * Process policy information from the certificate.
32
-     *
33
-     * Certificate policies extension must be present.
34
-     *
35
-     * @param ValidatorState $state
36
-     * @param Certificate    $cert
37
-     *
38
-     * @return ValidatorState
39
-     */
40
-    public function processPolicies(ValidatorState $state,
41
-        Certificate $cert): ValidatorState
42
-    {
43
-        $policies = $cert->tbsCertificate()->extensions()->certificatePolicies();
44
-        $tree = clone $this;
45
-        // (d.1) for each policy P not equal to anyPolicy
46
-        foreach ($policies as $policy) {
47
-            if ($policy->isAnyPolicy()) {
48
-                $tree->_processAnyPolicy($policy, $cert, $state);
49
-            } else {
50
-                $tree->_processPolicy($policy, $state);
51
-            }
52
-        }
53
-        // if whole tree is pruned
54
-        if (!$tree->_pruneTree($state->index() - 1)) {
55
-            return $state->withoutValidPolicyTree();
56
-        }
57
-        return $state->withValidPolicyTree($tree);
58
-    }
30
+	/**
31
+	 * Process policy information from the certificate.
32
+	 *
33
+	 * Certificate policies extension must be present.
34
+	 *
35
+	 * @param ValidatorState $state
36
+	 * @param Certificate    $cert
37
+	 *
38
+	 * @return ValidatorState
39
+	 */
40
+	public function processPolicies(ValidatorState $state,
41
+		Certificate $cert): ValidatorState
42
+	{
43
+		$policies = $cert->tbsCertificate()->extensions()->certificatePolicies();
44
+		$tree = clone $this;
45
+		// (d.1) for each policy P not equal to anyPolicy
46
+		foreach ($policies as $policy) {
47
+			if ($policy->isAnyPolicy()) {
48
+				$tree->_processAnyPolicy($policy, $cert, $state);
49
+			} else {
50
+				$tree->_processPolicy($policy, $state);
51
+			}
52
+		}
53
+		// if whole tree is pruned
54
+		if (!$tree->_pruneTree($state->index() - 1)) {
55
+			return $state->withoutValidPolicyTree();
56
+		}
57
+		return $state->withValidPolicyTree($tree);
58
+	}
59 59
 
60
-    /**
61
-     * Process policy mappings from the certificate.
62
-     *
63
-     * @param ValidatorState $state
64
-     * @param Certificate    $cert
65
-     *
66
-     * @return ValidatorState
67
-     */
68
-    public function processMappings(ValidatorState $state,
69
-        Certificate $cert): ValidatorState
70
-    {
71
-        $tree = clone $this;
72
-        if ($state->policyMapping() > 0) {
73
-            $tree->_applyMappings($cert, $state);
74
-        } elseif (0 == $state->policyMapping()) {
75
-            $tree->_deleteMappings($cert, $state);
76
-        }
77
-        // if whole tree is pruned
78
-        if (!$tree->_root) {
79
-            return $state->withoutValidPolicyTree();
80
-        }
81
-        return $state->withValidPolicyTree($tree);
82
-    }
60
+	/**
61
+	 * Process policy mappings from the certificate.
62
+	 *
63
+	 * @param ValidatorState $state
64
+	 * @param Certificate    $cert
65
+	 *
66
+	 * @return ValidatorState
67
+	 */
68
+	public function processMappings(ValidatorState $state,
69
+		Certificate $cert): ValidatorState
70
+	{
71
+		$tree = clone $this;
72
+		if ($state->policyMapping() > 0) {
73
+			$tree->_applyMappings($cert, $state);
74
+		} elseif (0 == $state->policyMapping()) {
75
+			$tree->_deleteMappings($cert, $state);
76
+		}
77
+		// if whole tree is pruned
78
+		if (!$tree->_root) {
79
+			return $state->withoutValidPolicyTree();
80
+		}
81
+		return $state->withValidPolicyTree($tree);
82
+	}
83 83
 
84
-    /**
85
-     * Calculate policy intersection as specified in Wrap-Up Procedure 6.1.5.g.
86
-     *
87
-     * @param ValidatorState $state
88
-     * @param array          $policies
89
-     *
90
-     * @return ValidatorState
91
-     */
92
-    public function calculateIntersection(ValidatorState $state,
93
-        array $policies): ValidatorState
94
-    {
95
-        $tree = clone $this;
96
-        $valid_policy_node_set = $tree->_validPolicyNodeSet();
97
-        // 2. If the valid_policy of any node in the valid_policy_node_set
98
-        // is not in the user-initial-policy-set and is not anyPolicy,
99
-        // delete this node and all its children.
100
-        $valid_policy_node_set = array_filter($valid_policy_node_set,
101
-            function (PolicyNode $node) use ($policies) {
102
-                if ($node->isAnyPolicy()) {
103
-                    return true;
104
-                }
105
-                if (in_array($node->validPolicy(), $policies)) {
106
-                    return true;
107
-                }
108
-                $node->remove();
109
-                return false;
110
-            });
111
-        // array of valid policy OIDs
112
-        $valid_policy_set = array_map(
113
-            function (PolicyNode $node) {
114
-                return $node->validPolicy();
115
-            }, $valid_policy_node_set);
116
-        // 3. If the valid_policy_tree includes a node of depth n with
117
-        // the valid_policy anyPolicy and the user-initial-policy-set
118
-        // is not any-policy
119
-        foreach ($tree->_nodesAtDepth($state->index()) as $node) {
120
-            if ($node->hasParent() && $node->isAnyPolicy()) {
121
-                // a. Set P-Q to the qualifier_set in the node of depth n
122
-                // with valid_policy anyPolicy.
123
-                $pq = $node->qualifiers();
124
-                // b. For each P-OID in the user-initial-policy-set that is not
125
-                // the valid_policy of a node in the valid_policy_node_set,
126
-                // create a child node whose parent is the node of depth n-1
127
-                // with the valid_policy anyPolicy.
128
-                $poids = array_diff($policies, $valid_policy_set);
129
-                foreach ($tree->_nodesAtDepth($state->index() - 1) as $parent) {
130
-                    if ($parent->isAnyPolicy()) {
131
-                        // Set the values in the child node as follows:
132
-                        // set the valid_policy to P-OID, set the qualifier_set
133
-                        // to P-Q, and set the expected_policy_set to {P-OID}.
134
-                        foreach ($poids as $poid) {
135
-                            $parent->addChild(new PolicyNode($poid, $pq, [$poid]));
136
-                        }
137
-                        break;
138
-                    }
139
-                }
140
-                // c. Delete the node of depth n with the
141
-                // valid_policy anyPolicy.
142
-                $node->remove();
143
-            }
144
-        }
145
-        // 4. If there is a node in the valid_policy_tree of depth n-1 or less
146
-        // without any child nodes, delete that node. Repeat this step until
147
-        // there are no nodes of depth n-1 or less without children.
148
-        if (!$tree->_pruneTree($state->index() - 1)) {
149
-            return $state->withoutValidPolicyTree();
150
-        }
151
-        return $state->withValidPolicyTree($tree);
152
-    }
84
+	/**
85
+	 * Calculate policy intersection as specified in Wrap-Up Procedure 6.1.5.g.
86
+	 *
87
+	 * @param ValidatorState $state
88
+	 * @param array          $policies
89
+	 *
90
+	 * @return ValidatorState
91
+	 */
92
+	public function calculateIntersection(ValidatorState $state,
93
+		array $policies): ValidatorState
94
+	{
95
+		$tree = clone $this;
96
+		$valid_policy_node_set = $tree->_validPolicyNodeSet();
97
+		// 2. If the valid_policy of any node in the valid_policy_node_set
98
+		// is not in the user-initial-policy-set and is not anyPolicy,
99
+		// delete this node and all its children.
100
+		$valid_policy_node_set = array_filter($valid_policy_node_set,
101
+			function (PolicyNode $node) use ($policies) {
102
+				if ($node->isAnyPolicy()) {
103
+					return true;
104
+				}
105
+				if (in_array($node->validPolicy(), $policies)) {
106
+					return true;
107
+				}
108
+				$node->remove();
109
+				return false;
110
+			});
111
+		// array of valid policy OIDs
112
+		$valid_policy_set = array_map(
113
+			function (PolicyNode $node) {
114
+				return $node->validPolicy();
115
+			}, $valid_policy_node_set);
116
+		// 3. If the valid_policy_tree includes a node of depth n with
117
+		// the valid_policy anyPolicy and the user-initial-policy-set
118
+		// is not any-policy
119
+		foreach ($tree->_nodesAtDepth($state->index()) as $node) {
120
+			if ($node->hasParent() && $node->isAnyPolicy()) {
121
+				// a. Set P-Q to the qualifier_set in the node of depth n
122
+				// with valid_policy anyPolicy.
123
+				$pq = $node->qualifiers();
124
+				// b. For each P-OID in the user-initial-policy-set that is not
125
+				// the valid_policy of a node in the valid_policy_node_set,
126
+				// create a child node whose parent is the node of depth n-1
127
+				// with the valid_policy anyPolicy.
128
+				$poids = array_diff($policies, $valid_policy_set);
129
+				foreach ($tree->_nodesAtDepth($state->index() - 1) as $parent) {
130
+					if ($parent->isAnyPolicy()) {
131
+						// Set the values in the child node as follows:
132
+						// set the valid_policy to P-OID, set the qualifier_set
133
+						// to P-Q, and set the expected_policy_set to {P-OID}.
134
+						foreach ($poids as $poid) {
135
+							$parent->addChild(new PolicyNode($poid, $pq, [$poid]));
136
+						}
137
+						break;
138
+					}
139
+				}
140
+				// c. Delete the node of depth n with the
141
+				// valid_policy anyPolicy.
142
+				$node->remove();
143
+			}
144
+		}
145
+		// 4. If there is a node in the valid_policy_tree of depth n-1 or less
146
+		// without any child nodes, delete that node. Repeat this step until
147
+		// there are no nodes of depth n-1 or less without children.
148
+		if (!$tree->_pruneTree($state->index() - 1)) {
149
+			return $state->withoutValidPolicyTree();
150
+		}
151
+		return $state->withValidPolicyTree($tree);
152
+	}
153 153
 
154
-    /**
155
-     * Get policies at given policy tree depth.
156
-     *
157
-     * @param int $i Depth in range 1..n
158
-     *
159
-     * @return PolicyInformation[]
160
-     */
161
-    public function policiesAtDepth(int $i): array
162
-    {
163
-        $policies = [];
164
-        foreach ($this->_nodesAtDepth($i) as $node) {
165
-            $policies[] = new PolicyInformation(
166
-                $node->validPolicy(), ...$node->qualifiers());
167
-        }
168
-        return $policies;
169
-    }
154
+	/**
155
+	 * Get policies at given policy tree depth.
156
+	 *
157
+	 * @param int $i Depth in range 1..n
158
+	 *
159
+	 * @return PolicyInformation[]
160
+	 */
161
+	public function policiesAtDepth(int $i): array
162
+	{
163
+		$policies = [];
164
+		foreach ($this->_nodesAtDepth($i) as $node) {
165
+			$policies[] = new PolicyInformation(
166
+				$node->validPolicy(), ...$node->qualifiers());
167
+		}
168
+		return $policies;
169
+	}
170 170
 
171
-    /**
172
-     * Process single policy information.
173
-     *
174
-     * @param PolicyInformation $policy
175
-     * @param ValidatorState    $state
176
-     */
177
-    protected function _processPolicy(PolicyInformation $policy,
178
-        ValidatorState $state): void
179
-    {
180
-        $p_oid = $policy->oid();
181
-        $i = $state->index();
182
-        $match_count = 0;
183
-        // (d.1.i) for each node of depth i-1 in the valid_policy_tree...
184
-        foreach ($this->_nodesAtDepth($i - 1) as $node) {
185
-            // ...where P-OID is in the expected_policy_set
186
-            if ($node->hasExpectedPolicy($p_oid)) {
187
-                $node->addChild(new PolicyNode(
188
-                    $p_oid, $policy->qualifiers(), [$p_oid]));
189
-                ++$match_count;
190
-            }
191
-        }
192
-        // (d.1.ii) if there was no match in step (i)...
193
-        if (!$match_count) {
194
-            // ...and the valid_policy_tree includes a node of depth i-1 with
195
-            // the valid_policy anyPolicy
196
-            foreach ($this->_nodesAtDepth($i - 1) as $node) {
197
-                if ($node->isAnyPolicy()) {
198
-                    $node->addChild(new PolicyNode(
199
-                        $p_oid, $policy->qualifiers(), [$p_oid]));
200
-                }
201
-            }
202
-        }
203
-    }
171
+	/**
172
+	 * Process single policy information.
173
+	 *
174
+	 * @param PolicyInformation $policy
175
+	 * @param ValidatorState    $state
176
+	 */
177
+	protected function _processPolicy(PolicyInformation $policy,
178
+		ValidatorState $state): void
179
+	{
180
+		$p_oid = $policy->oid();
181
+		$i = $state->index();
182
+		$match_count = 0;
183
+		// (d.1.i) for each node of depth i-1 in the valid_policy_tree...
184
+		foreach ($this->_nodesAtDepth($i - 1) as $node) {
185
+			// ...where P-OID is in the expected_policy_set
186
+			if ($node->hasExpectedPolicy($p_oid)) {
187
+				$node->addChild(new PolicyNode(
188
+					$p_oid, $policy->qualifiers(), [$p_oid]));
189
+				++$match_count;
190
+			}
191
+		}
192
+		// (d.1.ii) if there was no match in step (i)...
193
+		if (!$match_count) {
194
+			// ...and the valid_policy_tree includes a node of depth i-1 with
195
+			// the valid_policy anyPolicy
196
+			foreach ($this->_nodesAtDepth($i - 1) as $node) {
197
+				if ($node->isAnyPolicy()) {
198
+					$node->addChild(new PolicyNode(
199
+						$p_oid, $policy->qualifiers(), [$p_oid]));
200
+				}
201
+			}
202
+		}
203
+	}
204 204
 
205
-    /**
206
-     * Process anyPolicy policy information.
207
-     *
208
-     * @param PolicyInformation $policy
209
-     * @param Certificate       $cert
210
-     * @param ValidatorState    $state
211
-     */
212
-    protected function _processAnyPolicy(PolicyInformation $policy,
213
-        Certificate $cert, ValidatorState $state): void
214
-    {
215
-        $i = $state->index();
216
-        // if (a) inhibit_anyPolicy is greater than 0 or
217
-        // (b) i<n and the certificate is self-issued
218
-        if (!($state->inhibitAnyPolicy() > 0 ||
219
-            ($i < $state->pathLength() && $cert->isSelfIssued()))) {
220
-            return;
221
-        }
222
-        // for each node in the valid_policy_tree of depth i-1
223
-        foreach ($this->_nodesAtDepth($i - 1) as $node) {
224
-            // for each value in the expected_policy_set
225
-            foreach ($node->expectedPolicies() as $p_oid) {
226
-                // that does not appear in a child node
227
-                if (!$node->hasChildWithValidPolicy($p_oid)) {
228
-                    $node->addChild(new PolicyNode(
229
-                        $p_oid, $policy->qualifiers(), [$p_oid]));
230
-                }
231
-            }
232
-        }
233
-    }
205
+	/**
206
+	 * Process anyPolicy policy information.
207
+	 *
208
+	 * @param PolicyInformation $policy
209
+	 * @param Certificate       $cert
210
+	 * @param ValidatorState    $state
211
+	 */
212
+	protected function _processAnyPolicy(PolicyInformation $policy,
213
+		Certificate $cert, ValidatorState $state): void
214
+	{
215
+		$i = $state->index();
216
+		// if (a) inhibit_anyPolicy is greater than 0 or
217
+		// (b) i<n and the certificate is self-issued
218
+		if (!($state->inhibitAnyPolicy() > 0 ||
219
+			($i < $state->pathLength() && $cert->isSelfIssued()))) {
220
+			return;
221
+		}
222
+		// for each node in the valid_policy_tree of depth i-1
223
+		foreach ($this->_nodesAtDepth($i - 1) as $node) {
224
+			// for each value in the expected_policy_set
225
+			foreach ($node->expectedPolicies() as $p_oid) {
226
+				// that does not appear in a child node
227
+				if (!$node->hasChildWithValidPolicy($p_oid)) {
228
+					$node->addChild(new PolicyNode(
229
+						$p_oid, $policy->qualifiers(), [$p_oid]));
230
+				}
231
+			}
232
+		}
233
+	}
234 234
 
235
-    /**
236
-     * Apply policy mappings to the policy tree.
237
-     *
238
-     * @param Certificate    $cert
239
-     * @param ValidatorState $state
240
-     */
241
-    protected function _applyMappings(Certificate $cert, ValidatorState $state): void
242
-    {
243
-        $policy_mappings = $cert->tbsCertificate()->extensions()->policyMappings();
244
-        // (6.1.4. b.1.) for each node in the valid_policy_tree of depth i...
245
-        foreach ($policy_mappings->flattenedMappings() as $idp => $sdps) {
246
-            $match_count = 0;
247
-            foreach ($this->_nodesAtDepth($state->index()) as $node) {
248
-                // ...where ID-P is the valid_policy
249
-                if ($node->validPolicy() == $idp) {
250
-                    // set expected_policy_set to the set of subjectDomainPolicy
251
-                    // values that are specified as equivalent to ID-P by
252
-                    // the policy mappings extension
253
-                    $node->setExpectedPolicies(...$sdps);
254
-                    ++$match_count;
255
-                }
256
-            }
257
-            // if no node of depth i in the valid_policy_tree has
258
-            // a valid_policy of ID-P...
259
-            if (!$match_count) {
260
-                $this->_applyAnyPolicyMapping($cert, $state, $idp, $sdps);
261
-            }
262
-        }
263
-    }
235
+	/**
236
+	 * Apply policy mappings to the policy tree.
237
+	 *
238
+	 * @param Certificate    $cert
239
+	 * @param ValidatorState $state
240
+	 */
241
+	protected function _applyMappings(Certificate $cert, ValidatorState $state): void
242
+	{
243
+		$policy_mappings = $cert->tbsCertificate()->extensions()->policyMappings();
244
+		// (6.1.4. b.1.) for each node in the valid_policy_tree of depth i...
245
+		foreach ($policy_mappings->flattenedMappings() as $idp => $sdps) {
246
+			$match_count = 0;
247
+			foreach ($this->_nodesAtDepth($state->index()) as $node) {
248
+				// ...where ID-P is the valid_policy
249
+				if ($node->validPolicy() == $idp) {
250
+					// set expected_policy_set to the set of subjectDomainPolicy
251
+					// values that are specified as equivalent to ID-P by
252
+					// the policy mappings extension
253
+					$node->setExpectedPolicies(...$sdps);
254
+					++$match_count;
255
+				}
256
+			}
257
+			// if no node of depth i in the valid_policy_tree has
258
+			// a valid_policy of ID-P...
259
+			if (!$match_count) {
260
+				$this->_applyAnyPolicyMapping($cert, $state, $idp, $sdps);
261
+			}
262
+		}
263
+	}
264 264
 
265
-    /**
266
-     * Apply anyPolicy mapping to the policy tree as specified in 6.1.4 (b)(1).
267
-     *
268
-     * @param Certificate    $cert
269
-     * @param ValidatorState $state
270
-     * @param string         $idp   OID of the issuer domain policy
271
-     * @param array          $sdps  Array of subject domain policy OIDs
272
-     */
273
-    protected function _applyAnyPolicyMapping(Certificate $cert,
274
-        ValidatorState $state, string $idp, array $sdps): void
275
-    {
276
-        // (6.1.4. b.1.) ...but there is a node of depth i with
277
-        // a valid_policy of anyPolicy
278
-        foreach ($this->_nodesAtDepth($state->index()) as $node) {
279
-            if ($node->isAnyPolicy()) {
280
-                // then generate a child node of the node of depth i-1
281
-                // that has a valid_policy of anyPolicy as follows...
282
-                foreach ($this->_nodesAtDepth($state->index() - 1) as $node) {
283
-                    if ($node->isAnyPolicy()) {
284
-                        // try to fetch qualifiers of anyPolicy certificate policy
285
-                        $qualifiers = [];
286
-                        try {
287
-                            $qualifiers = $cert->tbsCertificate()
288
-                                ->extensions()->certificatePolicies()
289
-                                ->anyPolicy()->qualifiers();
290
-                        } catch (\LogicException $e) {
291
-                            // if there's no policies or no qualifiers
292
-                        }
293
-                        $node->addChild(new PolicyNode($idp, $qualifiers, $sdps));
294
-                        // bail after first anyPolicy has been processed
295
-                        break;
296
-                    }
297
-                }
298
-                // bail after first anyPolicy has been processed
299
-                break;
300
-            }
301
-        }
302
-    }
265
+	/**
266
+	 * Apply anyPolicy mapping to the policy tree as specified in 6.1.4 (b)(1).
267
+	 *
268
+	 * @param Certificate    $cert
269
+	 * @param ValidatorState $state
270
+	 * @param string         $idp   OID of the issuer domain policy
271
+	 * @param array          $sdps  Array of subject domain policy OIDs
272
+	 */
273
+	protected function _applyAnyPolicyMapping(Certificate $cert,
274
+		ValidatorState $state, string $idp, array $sdps): void
275
+	{
276
+		// (6.1.4. b.1.) ...but there is a node of depth i with
277
+		// a valid_policy of anyPolicy
278
+		foreach ($this->_nodesAtDepth($state->index()) as $node) {
279
+			if ($node->isAnyPolicy()) {
280
+				// then generate a child node of the node of depth i-1
281
+				// that has a valid_policy of anyPolicy as follows...
282
+				foreach ($this->_nodesAtDepth($state->index() - 1) as $node) {
283
+					if ($node->isAnyPolicy()) {
284
+						// try to fetch qualifiers of anyPolicy certificate policy
285
+						$qualifiers = [];
286
+						try {
287
+							$qualifiers = $cert->tbsCertificate()
288
+								->extensions()->certificatePolicies()
289
+								->anyPolicy()->qualifiers();
290
+						} catch (\LogicException $e) {
291
+							// if there's no policies or no qualifiers
292
+						}
293
+						$node->addChild(new PolicyNode($idp, $qualifiers, $sdps));
294
+						// bail after first anyPolicy has been processed
295
+						break;
296
+					}
297
+				}
298
+				// bail after first anyPolicy has been processed
299
+				break;
300
+			}
301
+		}
302
+	}
303 303
 
304
-    /**
305
-     * Delete nodes as specified in 6.1.4 (b)(2).
306
-     *
307
-     * @param Certificate    $cert
308
-     * @param ValidatorState $state
309
-     */
310
-    protected function _deleteMappings(Certificate $cert,
311
-        ValidatorState $state): void
312
-    {
313
-        $idps = $cert->tbsCertificate()->extensions()
314
-            ->policyMappings()->issuerDomainPolicies();
315
-        // delete each node of depth i in the valid_policy_tree
316
-        // where ID-P is the valid_policy
317
-        foreach ($this->_nodesAtDepth($state->index()) as $node) {
318
-            if (in_array($node->validPolicy(), $idps)) {
319
-                $node->remove();
320
-            }
321
-        }
322
-        $this->_pruneTree($state->index() - 1);
323
-    }
304
+	/**
305
+	 * Delete nodes as specified in 6.1.4 (b)(2).
306
+	 *
307
+	 * @param Certificate    $cert
308
+	 * @param ValidatorState $state
309
+	 */
310
+	protected function _deleteMappings(Certificate $cert,
311
+		ValidatorState $state): void
312
+	{
313
+		$idps = $cert->tbsCertificate()->extensions()
314
+			->policyMappings()->issuerDomainPolicies();
315
+		// delete each node of depth i in the valid_policy_tree
316
+		// where ID-P is the valid_policy
317
+		foreach ($this->_nodesAtDepth($state->index()) as $node) {
318
+			if (in_array($node->validPolicy(), $idps)) {
319
+				$node->remove();
320
+			}
321
+		}
322
+		$this->_pruneTree($state->index() - 1);
323
+	}
324 324
 
325
-    /**
326
-     * Prune tree starting from given depth.
327
-     *
328
-     * @param int $depth
329
-     *
330
-     * @return int The number of nodes left in a tree
331
-     */
332
-    protected function _pruneTree(int $depth): int
333
-    {
334
-        for ($i = $depth; $i > 0; --$i) {
335
-            foreach ($this->_nodesAtDepth($i) as $node) {
336
-                if (!count($node)) {
337
-                    $node->remove();
338
-                }
339
-            }
340
-        }
341
-        // if root has no children left
342
-        if (!count($this->_root)) {
343
-            $this->_root = null;
344
-            return 0;
345
-        }
346
-        return $this->_root->nodeCount();
347
-    }
325
+	/**
326
+	 * Prune tree starting from given depth.
327
+	 *
328
+	 * @param int $depth
329
+	 *
330
+	 * @return int The number of nodes left in a tree
331
+	 */
332
+	protected function _pruneTree(int $depth): int
333
+	{
334
+		for ($i = $depth; $i > 0; --$i) {
335
+			foreach ($this->_nodesAtDepth($i) as $node) {
336
+				if (!count($node)) {
337
+					$node->remove();
338
+				}
339
+			}
340
+		}
341
+		// if root has no children left
342
+		if (!count($this->_root)) {
343
+			$this->_root = null;
344
+			return 0;
345
+		}
346
+		return $this->_root->nodeCount();
347
+	}
348 348
 
349
-    /**
350
-     * Get all nodes at given depth.
351
-     *
352
-     * @param int $i
353
-     *
354
-     * @return PolicyNode[]
355
-     */
356
-    protected function _nodesAtDepth(int $i): array
357
-    {
358
-        if (!$this->_root) {
359
-            return [];
360
-        }
361
-        $depth = 0;
362
-        $nodes = [$this->_root];
363
-        while ($depth < $i) {
364
-            $nodes = self::_gatherChildren(...$nodes);
365
-            if (!count($nodes)) {
366
-                break;
367
-            }
368
-            ++$depth;
369
-        }
370
-        return $nodes;
371
-    }
349
+	/**
350
+	 * Get all nodes at given depth.
351
+	 *
352
+	 * @param int $i
353
+	 *
354
+	 * @return PolicyNode[]
355
+	 */
356
+	protected function _nodesAtDepth(int $i): array
357
+	{
358
+		if (!$this->_root) {
359
+			return [];
360
+		}
361
+		$depth = 0;
362
+		$nodes = [$this->_root];
363
+		while ($depth < $i) {
364
+			$nodes = self::_gatherChildren(...$nodes);
365
+			if (!count($nodes)) {
366
+				break;
367
+			}
368
+			++$depth;
369
+		}
370
+		return $nodes;
371
+	}
372 372
 
373
-    /**
374
-     * Get the valid policy node set as specified in spec 6.1.5.(g)(iii)1.
375
-     *
376
-     * @return PolicyNode[]
377
-     */
378
-    protected function _validPolicyNodeSet(): array
379
-    {
380
-        // 1. Determine the set of policy nodes whose parent nodes have
381
-        // a valid_policy of anyPolicy. This is the valid_policy_node_set.
382
-        $set = [];
383
-        if (!$this->_root) {
384
-            return $set;
385
-        }
386
-        // for each node in a tree
387
-        $this->_root->walkNodes(
388
-            function (PolicyNode $node) use (&$set) {
389
-                $parents = $node->parents();
390
-                // node has parents
391
-                if (count($parents)) {
392
-                    // check that each ancestor is an anyPolicy node
393
-                    foreach ($parents as $ancestor) {
394
-                        if (!$ancestor->isAnyPolicy()) {
395
-                            return;
396
-                        }
397
-                    }
398
-                    $set[] = $node;
399
-                }
400
-            });
401
-        return $set;
402
-    }
373
+	/**
374
+	 * Get the valid policy node set as specified in spec 6.1.5.(g)(iii)1.
375
+	 *
376
+	 * @return PolicyNode[]
377
+	 */
378
+	protected function _validPolicyNodeSet(): array
379
+	{
380
+		// 1. Determine the set of policy nodes whose parent nodes have
381
+		// a valid_policy of anyPolicy. This is the valid_policy_node_set.
382
+		$set = [];
383
+		if (!$this->_root) {
384
+			return $set;
385
+		}
386
+		// for each node in a tree
387
+		$this->_root->walkNodes(
388
+			function (PolicyNode $node) use (&$set) {
389
+				$parents = $node->parents();
390
+				// node has parents
391
+				if (count($parents)) {
392
+					// check that each ancestor is an anyPolicy node
393
+					foreach ($parents as $ancestor) {
394
+						if (!$ancestor->isAnyPolicy()) {
395
+							return;
396
+						}
397
+					}
398
+					$set[] = $node;
399
+				}
400
+			});
401
+		return $set;
402
+	}
403 403
 
404
-    /**
405
-     * Gather all children of given nodes to a flattened array.
406
-     *
407
-     * @param PolicyNode ...$nodes
408
-     *
409
-     * @return PolicyNode[]
410
-     */
411
-    private static function _gatherChildren(PolicyNode ...$nodes): array
412
-    {
413
-        $children = [];
414
-        foreach ($nodes as $node) {
415
-            $children = array_merge($children, $node->children());
416
-        }
417
-        return $children;
418
-    }
404
+	/**
405
+	 * Gather all children of given nodes to a flattened array.
406
+	 *
407
+	 * @param PolicyNode ...$nodes
408
+	 *
409
+	 * @return PolicyNode[]
410
+	 */
411
+	private static function _gatherChildren(PolicyNode ...$nodes): array
412
+	{
413
+		$children = [];
414
+		foreach ($nodes as $node) {
415
+			$children = array_merge($children, $node->children());
416
+		}
417
+		return $children;
418
+	}
419 419
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\CertificationPath\Policy;
6 6
 
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
         // is not in the user-initial-policy-set and is not anyPolicy,
99 99
         // delete this node and all its children.
100 100
         $valid_policy_node_set = array_filter($valid_policy_node_set,
101
-            function (PolicyNode $node) use ($policies) {
101
+            function(PolicyNode $node) use ($policies) {
102 102
                 if ($node->isAnyPolicy()) {
103 103
                     return true;
104 104
                 }
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
             });
111 111
         // array of valid policy OIDs
112 112
         $valid_policy_set = array_map(
113
-            function (PolicyNode $node) {
113
+            function(PolicyNode $node) {
114 114
                 return $node->validPolicy();
115 115
             }, $valid_policy_node_set);
116 116
         // 3. If the valid_policy_tree includes a node of depth n with
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
         }
386 386
         // for each node in a tree
387 387
         $this->_root->walkNodes(
388
-            function (PolicyNode $node) use (&$set) {
388
+            function(PolicyNode $node) use (&$set) {
389 389
                 $parents = $node->parents();
390 390
                 // node has parents
391 391
                 if (count($parents)) {
Please login to merge, or discard this patch.
lib/X509/CertificationPath/Policy/PolicyNode.php 2 patches
Indentation   +240 added lines, -240 removed lines patch added patch discarded remove patch
@@ -16,267 +16,267 @@
 block discarded – undo
16 16
  */
17 17
 class PolicyNode implements \IteratorAggregate, \Countable
18 18
 {
19
-    /**
20
-     * Policy OID.
21
-     *
22
-     * @var string
23
-     */
24
-    protected $_validPolicy;
19
+	/**
20
+	 * Policy OID.
21
+	 *
22
+	 * @var string
23
+	 */
24
+	protected $_validPolicy;
25 25
 
26
-    /**
27
-     * List of qualifiers.
28
-     *
29
-     * @var PolicyQualifierInfo[]
30
-     */
31
-    protected $_qualifiers;
26
+	/**
27
+	 * List of qualifiers.
28
+	 *
29
+	 * @var PolicyQualifierInfo[]
30
+	 */
31
+	protected $_qualifiers;
32 32
 
33
-    /**
34
-     * List of expected policy OIDs.
35
-     *
36
-     * @var string[]
37
-     */
38
-    protected $_expectedPolicies;
33
+	/**
34
+	 * List of expected policy OIDs.
35
+	 *
36
+	 * @var string[]
37
+	 */
38
+	protected $_expectedPolicies;
39 39
 
40
-    /**
41
-     * List of child nodes.
42
-     *
43
-     * @var PolicyNode[]
44
-     */
45
-    protected $_children;
40
+	/**
41
+	 * List of child nodes.
42
+	 *
43
+	 * @var PolicyNode[]
44
+	 */
45
+	protected $_children;
46 46
 
47
-    /**
48
-     * Reference to the parent node.
49
-     *
50
-     * @var null|PolicyNode
51
-     */
52
-    protected $_parent;
47
+	/**
48
+	 * Reference to the parent node.
49
+	 *
50
+	 * @var null|PolicyNode
51
+	 */
52
+	protected $_parent;
53 53
 
54
-    /**
55
-     * Constructor.
56
-     *
57
-     * @param string                $valid_policy      Policy OID
58
-     * @param PolicyQualifierInfo[] $qualifiers
59
-     * @param string[]              $expected_policies
60
-     */
61
-    public function __construct(string $valid_policy, array $qualifiers,
62
-        array $expected_policies)
63
-    {
64
-        $this->_validPolicy = $valid_policy;
65
-        $this->_qualifiers = $qualifiers;
66
-        $this->_expectedPolicies = $expected_policies;
67
-        $this->_children = [];
68
-    }
54
+	/**
55
+	 * Constructor.
56
+	 *
57
+	 * @param string                $valid_policy      Policy OID
58
+	 * @param PolicyQualifierInfo[] $qualifiers
59
+	 * @param string[]              $expected_policies
60
+	 */
61
+	public function __construct(string $valid_policy, array $qualifiers,
62
+		array $expected_policies)
63
+	{
64
+		$this->_validPolicy = $valid_policy;
65
+		$this->_qualifiers = $qualifiers;
66
+		$this->_expectedPolicies = $expected_policies;
67
+		$this->_children = [];
68
+	}
69 69
 
70
-    /**
71
-     * Create initial node for the policy tree.
72
-     *
73
-     * @return self
74
-     */
75
-    public static function anyPolicyNode(): self
76
-    {
77
-        return new self(PolicyInformation::OID_ANY_POLICY, [],
78
-            [PolicyInformation::OID_ANY_POLICY]);
79
-    }
70
+	/**
71
+	 * Create initial node for the policy tree.
72
+	 *
73
+	 * @return self
74
+	 */
75
+	public static function anyPolicyNode(): self
76
+	{
77
+		return new self(PolicyInformation::OID_ANY_POLICY, [],
78
+			[PolicyInformation::OID_ANY_POLICY]);
79
+	}
80 80
 
81
-    /**
82
-     * Get the valid policy OID.
83
-     *
84
-     * @return string
85
-     */
86
-    public function validPolicy(): string
87
-    {
88
-        return $this->_validPolicy;
89
-    }
81
+	/**
82
+	 * Get the valid policy OID.
83
+	 *
84
+	 * @return string
85
+	 */
86
+	public function validPolicy(): string
87
+	{
88
+		return $this->_validPolicy;
89
+	}
90 90
 
91
-    /**
92
-     * Check whether node has anyPolicy as a valid policy.
93
-     *
94
-     * @return bool
95
-     */
96
-    public function isAnyPolicy(): bool
97
-    {
98
-        return PolicyInformation::OID_ANY_POLICY === $this->_validPolicy;
99
-    }
91
+	/**
92
+	 * Check whether node has anyPolicy as a valid policy.
93
+	 *
94
+	 * @return bool
95
+	 */
96
+	public function isAnyPolicy(): bool
97
+	{
98
+		return PolicyInformation::OID_ANY_POLICY === $this->_validPolicy;
99
+	}
100 100
 
101
-    /**
102
-     * Get the qualifier set.
103
-     *
104
-     * @return PolicyQualifierInfo[]
105
-     */
106
-    public function qualifiers(): array
107
-    {
108
-        return $this->_qualifiers;
109
-    }
101
+	/**
102
+	 * Get the qualifier set.
103
+	 *
104
+	 * @return PolicyQualifierInfo[]
105
+	 */
106
+	public function qualifiers(): array
107
+	{
108
+		return $this->_qualifiers;
109
+	}
110 110
 
111
-    /**
112
-     * Check whether node has OID as an expected policy.
113
-     *
114
-     * @param string $oid
115
-     *
116
-     * @return bool
117
-     */
118
-    public function hasExpectedPolicy(string $oid): bool
119
-    {
120
-        return in_array($oid, $this->_expectedPolicies);
121
-    }
111
+	/**
112
+	 * Check whether node has OID as an expected policy.
113
+	 *
114
+	 * @param string $oid
115
+	 *
116
+	 * @return bool
117
+	 */
118
+	public function hasExpectedPolicy(string $oid): bool
119
+	{
120
+		return in_array($oid, $this->_expectedPolicies);
121
+	}
122 122
 
123
-    /**
124
-     * Get the expected policy set.
125
-     *
126
-     * @return string[]
127
-     */
128
-    public function expectedPolicies(): array
129
-    {
130
-        return $this->_expectedPolicies;
131
-    }
123
+	/**
124
+	 * Get the expected policy set.
125
+	 *
126
+	 * @return string[]
127
+	 */
128
+	public function expectedPolicies(): array
129
+	{
130
+		return $this->_expectedPolicies;
131
+	}
132 132
 
133
-    /**
134
-     * Set expected policies.
135
-     *
136
-     * @param string ...$oids Policy OIDs
137
-     */
138
-    public function setExpectedPolicies(string ...$oids): void
139
-    {
140
-        $this->_expectedPolicies = $oids;
141
-    }
133
+	/**
134
+	 * Set expected policies.
135
+	 *
136
+	 * @param string ...$oids Policy OIDs
137
+	 */
138
+	public function setExpectedPolicies(string ...$oids): void
139
+	{
140
+		$this->_expectedPolicies = $oids;
141
+	}
142 142
 
143
-    /**
144
-     * Check whether node has a child node with given valid policy OID.
145
-     *
146
-     * @param string $oid
147
-     *
148
-     * @return bool
149
-     */
150
-    public function hasChildWithValidPolicy(string $oid): bool
151
-    {
152
-        foreach ($this->_children as $node) {
153
-            if ($node->validPolicy() == $oid) {
154
-                return true;
155
-            }
156
-        }
157
-        return false;
158
-    }
143
+	/**
144
+	 * Check whether node has a child node with given valid policy OID.
145
+	 *
146
+	 * @param string $oid
147
+	 *
148
+	 * @return bool
149
+	 */
150
+	public function hasChildWithValidPolicy(string $oid): bool
151
+	{
152
+		foreach ($this->_children as $node) {
153
+			if ($node->validPolicy() == $oid) {
154
+				return true;
155
+			}
156
+		}
157
+		return false;
158
+	}
159 159
 
160
-    /**
161
-     * Add child node.
162
-     *
163
-     * @param PolicyNode $node
164
-     *
165
-     * @return self
166
-     */
167
-    public function addChild(PolicyNode $node): self
168
-    {
169
-        $id = spl_object_hash($node);
170
-        $node->_parent = $this;
171
-        $this->_children[$id] = $node;
172
-        return $this;
173
-    }
160
+	/**
161
+	 * Add child node.
162
+	 *
163
+	 * @param PolicyNode $node
164
+	 *
165
+	 * @return self
166
+	 */
167
+	public function addChild(PolicyNode $node): self
168
+	{
169
+		$id = spl_object_hash($node);
170
+		$node->_parent = $this;
171
+		$this->_children[$id] = $node;
172
+		return $this;
173
+	}
174 174
 
175
-    /**
176
-     * Get the child nodes.
177
-     *
178
-     * @return PolicyNode[]
179
-     */
180
-    public function children(): array
181
-    {
182
-        return array_values($this->_children);
183
-    }
175
+	/**
176
+	 * Get the child nodes.
177
+	 *
178
+	 * @return PolicyNode[]
179
+	 */
180
+	public function children(): array
181
+	{
182
+		return array_values($this->_children);
183
+	}
184 184
 
185
-    /**
186
-     * Remove this node from the tree.
187
-     *
188
-     * @return self The removed node
189
-     */
190
-    public function remove(): self
191
-    {
192
-        if ($this->_parent) {
193
-            $id = spl_object_hash($this);
194
-            unset($this->_parent->_children[$id], $this->_parent);
195
-        }
196
-        return $this;
197
-    }
185
+	/**
186
+	 * Remove this node from the tree.
187
+	 *
188
+	 * @return self The removed node
189
+	 */
190
+	public function remove(): self
191
+	{
192
+		if ($this->_parent) {
193
+			$id = spl_object_hash($this);
194
+			unset($this->_parent->_children[$id], $this->_parent);
195
+		}
196
+		return $this;
197
+	}
198 198
 
199
-    /**
200
-     * Check whether node has a parent.
201
-     *
202
-     * @return bool
203
-     */
204
-    public function hasParent(): bool
205
-    {
206
-        return isset($this->_parent);
207
-    }
199
+	/**
200
+	 * Check whether node has a parent.
201
+	 *
202
+	 * @return bool
203
+	 */
204
+	public function hasParent(): bool
205
+	{
206
+		return isset($this->_parent);
207
+	}
208 208
 
209
-    /**
210
-     * Get the parent node.
211
-     *
212
-     * @return null|PolicyNode
213
-     */
214
-    public function parent(): ?PolicyNode
215
-    {
216
-        return $this->_parent;
217
-    }
209
+	/**
210
+	 * Get the parent node.
211
+	 *
212
+	 * @return null|PolicyNode
213
+	 */
214
+	public function parent(): ?PolicyNode
215
+	{
216
+		return $this->_parent;
217
+	}
218 218
 
219
-    /**
220
-     * Get chain of parent nodes from this node's parent to the root node.
221
-     *
222
-     * @return PolicyNode[]
223
-     */
224
-    public function parents(): array
225
-    {
226
-        if (!$this->_parent) {
227
-            return [];
228
-        }
229
-        $nodes = $this->_parent->parents();
230
-        $nodes[] = $this->_parent;
231
-        return array_reverse($nodes);
232
-    }
219
+	/**
220
+	 * Get chain of parent nodes from this node's parent to the root node.
221
+	 *
222
+	 * @return PolicyNode[]
223
+	 */
224
+	public function parents(): array
225
+	{
226
+		if (!$this->_parent) {
227
+			return [];
228
+		}
229
+		$nodes = $this->_parent->parents();
230
+		$nodes[] = $this->_parent;
231
+		return array_reverse($nodes);
232
+	}
233 233
 
234
-    /**
235
-     * Walk tree from this node, applying a callback for each node.
236
-     *
237
-     * Nodes are traversed depth-first and callback shall be applied post-order.
238
-     *
239
-     * @param callable $fn
240
-     */
241
-    public function walkNodes(callable $fn): void
242
-    {
243
-        foreach ($this->_children as $node) {
244
-            $node->walkNodes($fn);
245
-        }
246
-        $fn($this);
247
-    }
234
+	/**
235
+	 * Walk tree from this node, applying a callback for each node.
236
+	 *
237
+	 * Nodes are traversed depth-first and callback shall be applied post-order.
238
+	 *
239
+	 * @param callable $fn
240
+	 */
241
+	public function walkNodes(callable $fn): void
242
+	{
243
+		foreach ($this->_children as $node) {
244
+			$node->walkNodes($fn);
245
+		}
246
+		$fn($this);
247
+	}
248 248
 
249
-    /**
250
-     * Get the total number of nodes in a tree.
251
-     *
252
-     * @return int
253
-     */
254
-    public function nodeCount(): int
255
-    {
256
-        $c = 1;
257
-        foreach ($this->_children as $child) {
258
-            $c += $child->nodeCount();
259
-        }
260
-        return $c;
261
-    }
249
+	/**
250
+	 * Get the total number of nodes in a tree.
251
+	 *
252
+	 * @return int
253
+	 */
254
+	public function nodeCount(): int
255
+	{
256
+		$c = 1;
257
+		foreach ($this->_children as $child) {
258
+			$c += $child->nodeCount();
259
+		}
260
+		return $c;
261
+	}
262 262
 
263
-    /**
264
-     * Get the number of child nodes.
265
-     *
266
-     * @see \Countable::count()
267
-     */
268
-    public function count(): int
269
-    {
270
-        return count($this->_children);
271
-    }
263
+	/**
264
+	 * Get the number of child nodes.
265
+	 *
266
+	 * @see \Countable::count()
267
+	 */
268
+	public function count(): int
269
+	{
270
+		return count($this->_children);
271
+	}
272 272
 
273
-    /**
274
-     * Get iterator for the child nodes.
275
-     *
276
-     * @see \IteratorAggregate::getIterator()
277
-     */
278
-    public function getIterator(): \ArrayIterator
279
-    {
280
-        return new \ArrayIterator($this->_children);
281
-    }
273
+	/**
274
+	 * Get iterator for the child nodes.
275
+	 *
276
+	 * @see \IteratorAggregate::getIterator()
277
+	 */
278
+	public function getIterator(): \ArrayIterator
279
+	{
280
+		return new \ArrayIterator($this->_children);
281
+	}
282 282
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\CertificationPath\Policy;
6 6
 
Please login to merge, or discard this patch.
lib/X509/CertificationPath/CertificationPath.php 2 patches
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -24,178 +24,178 @@
 block discarded – undo
24 24
  */
25 25
 class CertificationPath implements \Countable, \IteratorAggregate
26 26
 {
27
-    /**
28
-     * Certification path.
29
-     *
30
-     * @var Certificate[]
31
-     */
32
-    protected $_certificates;
33
-
34
-    /**
35
-     * Constructor.
36
-     *
37
-     * @param Certificate ...$certificates Certificates from the trust anchor
38
-     *                                     to the target end-entity certificate
39
-     */
40
-    public function __construct(Certificate ...$certificates)
41
-    {
42
-        $this->_certificates = $certificates;
43
-    }
44
-
45
-    /**
46
-     * Initialize from a certificate chain.
47
-     *
48
-     * @param CertificateChain $chain
49
-     *
50
-     * @return self
51
-     */
52
-    public static function fromCertificateChain(CertificateChain $chain): self
53
-    {
54
-        return new self(...array_reverse($chain->certificates(), false));
55
-    }
56
-
57
-    /**
58
-     * Build certification path to given target.
59
-     *
60
-     * @param Certificate            $target        Target end-entity certificate
61
-     * @param CertificateBundle      $trust_anchors List of trust anchors
62
-     * @param null|CertificateBundle $intermediate  Optional intermediate certificates
63
-     *
64
-     * @return self
65
-     */
66
-    public static function toTarget(Certificate $target,
67
-        CertificateBundle $trust_anchors, ?CertificateBundle $intermediate = null): self
68
-    {
69
-        $builder = new CertificationPathBuilder($trust_anchors);
70
-        return $builder->shortestPathToTarget($target, $intermediate);
71
-    }
72
-
73
-    /**
74
-     * Build certification path from given trust anchor to target certificate,
75
-     * using intermediate certificates from given bundle.
76
-     *
77
-     * @param Certificate            $trust_anchor Trust anchor certificate
78
-     * @param Certificate            $target       Target end-entity certificate
79
-     * @param null|CertificateBundle $intermediate Optional intermediate certificates
80
-     *
81
-     * @return self
82
-     */
83
-    public static function fromTrustAnchorToTarget(Certificate $trust_anchor,
84
-        Certificate $target, ?CertificateBundle $intermediate = null): self
85
-    {
86
-        return self::toTarget($target, new CertificateBundle($trust_anchor),
87
-            $intermediate);
88
-    }
89
-
90
-    /**
91
-     * Get certificates.
92
-     *
93
-     * @return Certificate[]
94
-     */
95
-    public function certificates(): array
96
-    {
97
-        return $this->_certificates;
98
-    }
99
-
100
-    /**
101
-     * Get the trust anchor certificate from the path.
102
-     *
103
-     * @throws \LogicException If path is empty
104
-     *
105
-     * @return Certificate
106
-     */
107
-    public function trustAnchorCertificate(): Certificate
108
-    {
109
-        if (!count($this->_certificates)) {
110
-            throw new \LogicException('No certificates.');
111
-        }
112
-        return $this->_certificates[0];
113
-    }
114
-
115
-    /**
116
-     * Get the end-entity certificate from the path.
117
-     *
118
-     * @throws \LogicException If path is empty
119
-     *
120
-     * @return Certificate
121
-     */
122
-    public function endEntityCertificate(): Certificate
123
-    {
124
-        if (!count($this->_certificates)) {
125
-            throw new \LogicException('No certificates.');
126
-        }
127
-        return $this->_certificates[count($this->_certificates) - 1];
128
-    }
129
-
130
-    /**
131
-     * Get certification path as a certificate chain.
132
-     *
133
-     * @return CertificateChain
134
-     */
135
-    public function certificateChain(): CertificateChain
136
-    {
137
-        return new CertificateChain(...array_reverse($this->_certificates, false));
138
-    }
139
-
140
-    /**
141
-     * Check whether certification path starts with one ore more given
142
-     * certificates in parameter order.
143
-     *
144
-     * @param Certificate ...$certs Certificates
145
-     *
146
-     * @return true
147
-     */
148
-    public function startsWith(Certificate ...$certs): bool
149
-    {
150
-        $n = count($certs);
151
-        if ($n > count($this->_certificates)) {
152
-            return false;
153
-        }
154
-        for ($i = 0; $i < $n; ++$i) {
155
-            if (!$certs[$i]->equals($this->_certificates[$i])) {
156
-                return false;
157
-            }
158
-        }
159
-        return true;
160
-    }
161
-
162
-    /**
163
-     * Validate certification path.
164
-     *
165
-     * @param PathValidationConfig $config
166
-     * @param null|Crypto          $crypto Crypto engine, use default if not set
167
-     *
168
-     * @throws Exception\PathValidationException
169
-     *
170
-     * @return PathValidationResult
171
-     */
172
-    public function validate(PathValidationConfig $config,
173
-        ?Crypto $crypto = null): PathValidationResult
174
-    {
175
-        $crypto = $crypto ?? Crypto::getDefault();
176
-        $validator = new PathValidator($crypto, $config, ...$this->_certificates);
177
-        return $validator->validate();
178
-    }
179
-
180
-    /**
181
-     * @see \Countable::count()
182
-     *
183
-     * @return int
184
-     */
185
-    public function count(): int
186
-    {
187
-        return count($this->_certificates);
188
-    }
189
-
190
-    /**
191
-     * Get iterator for certificates.
192
-     *
193
-     * @see \IteratorAggregate::getIterator()
194
-     *
195
-     * @return \ArrayIterator
196
-     */
197
-    public function getIterator(): \ArrayIterator
198
-    {
199
-        return new \ArrayIterator($this->_certificates);
200
-    }
27
+	/**
28
+	 * Certification path.
29
+	 *
30
+	 * @var Certificate[]
31
+	 */
32
+	protected $_certificates;
33
+
34
+	/**
35
+	 * Constructor.
36
+	 *
37
+	 * @param Certificate ...$certificates Certificates from the trust anchor
38
+	 *                                     to the target end-entity certificate
39
+	 */
40
+	public function __construct(Certificate ...$certificates)
41
+	{
42
+		$this->_certificates = $certificates;
43
+	}
44
+
45
+	/**
46
+	 * Initialize from a certificate chain.
47
+	 *
48
+	 * @param CertificateChain $chain
49
+	 *
50
+	 * @return self
51
+	 */
52
+	public static function fromCertificateChain(CertificateChain $chain): self
53
+	{
54
+		return new self(...array_reverse($chain->certificates(), false));
55
+	}
56
+
57
+	/**
58
+	 * Build certification path to given target.
59
+	 *
60
+	 * @param Certificate            $target        Target end-entity certificate
61
+	 * @param CertificateBundle      $trust_anchors List of trust anchors
62
+	 * @param null|CertificateBundle $intermediate  Optional intermediate certificates
63
+	 *
64
+	 * @return self
65
+	 */
66
+	public static function toTarget(Certificate $target,
67
+		CertificateBundle $trust_anchors, ?CertificateBundle $intermediate = null): self
68
+	{
69
+		$builder = new CertificationPathBuilder($trust_anchors);
70
+		return $builder->shortestPathToTarget($target, $intermediate);
71
+	}
72
+
73
+	/**
74
+	 * Build certification path from given trust anchor to target certificate,
75
+	 * using intermediate certificates from given bundle.
76
+	 *
77
+	 * @param Certificate            $trust_anchor Trust anchor certificate
78
+	 * @param Certificate            $target       Target end-entity certificate
79
+	 * @param null|CertificateBundle $intermediate Optional intermediate certificates
80
+	 *
81
+	 * @return self
82
+	 */
83
+	public static function fromTrustAnchorToTarget(Certificate $trust_anchor,
84
+		Certificate $target, ?CertificateBundle $intermediate = null): self
85
+	{
86
+		return self::toTarget($target, new CertificateBundle($trust_anchor),
87
+			$intermediate);
88
+	}
89
+
90
+	/**
91
+	 * Get certificates.
92
+	 *
93
+	 * @return Certificate[]
94
+	 */
95
+	public function certificates(): array
96
+	{
97
+		return $this->_certificates;
98
+	}
99
+
100
+	/**
101
+	 * Get the trust anchor certificate from the path.
102
+	 *
103
+	 * @throws \LogicException If path is empty
104
+	 *
105
+	 * @return Certificate
106
+	 */
107
+	public function trustAnchorCertificate(): Certificate
108
+	{
109
+		if (!count($this->_certificates)) {
110
+			throw new \LogicException('No certificates.');
111
+		}
112
+		return $this->_certificates[0];
113
+	}
114
+
115
+	/**
116
+	 * Get the end-entity certificate from the path.
117
+	 *
118
+	 * @throws \LogicException If path is empty
119
+	 *
120
+	 * @return Certificate
121
+	 */
122
+	public function endEntityCertificate(): Certificate
123
+	{
124
+		if (!count($this->_certificates)) {
125
+			throw new \LogicException('No certificates.');
126
+		}
127
+		return $this->_certificates[count($this->_certificates) - 1];
128
+	}
129
+
130
+	/**
131
+	 * Get certification path as a certificate chain.
132
+	 *
133
+	 * @return CertificateChain
134
+	 */
135
+	public function certificateChain(): CertificateChain
136
+	{
137
+		return new CertificateChain(...array_reverse($this->_certificates, false));
138
+	}
139
+
140
+	/**
141
+	 * Check whether certification path starts with one ore more given
142
+	 * certificates in parameter order.
143
+	 *
144
+	 * @param Certificate ...$certs Certificates
145
+	 *
146
+	 * @return true
147
+	 */
148
+	public function startsWith(Certificate ...$certs): bool
149
+	{
150
+		$n = count($certs);
151
+		if ($n > count($this->_certificates)) {
152
+			return false;
153
+		}
154
+		for ($i = 0; $i < $n; ++$i) {
155
+			if (!$certs[$i]->equals($this->_certificates[$i])) {
156
+				return false;
157
+			}
158
+		}
159
+		return true;
160
+	}
161
+
162
+	/**
163
+	 * Validate certification path.
164
+	 *
165
+	 * @param PathValidationConfig $config
166
+	 * @param null|Crypto          $crypto Crypto engine, use default if not set
167
+	 *
168
+	 * @throws Exception\PathValidationException
169
+	 *
170
+	 * @return PathValidationResult
171
+	 */
172
+	public function validate(PathValidationConfig $config,
173
+		?Crypto $crypto = null): PathValidationResult
174
+	{
175
+		$crypto = $crypto ?? Crypto::getDefault();
176
+		$validator = new PathValidator($crypto, $config, ...$this->_certificates);
177
+		return $validator->validate();
178
+	}
179
+
180
+	/**
181
+	 * @see \Countable::count()
182
+	 *
183
+	 * @return int
184
+	 */
185
+	public function count(): int
186
+	{
187
+		return count($this->_certificates);
188
+	}
189
+
190
+	/**
191
+	 * Get iterator for certificates.
192
+	 *
193
+	 * @see \IteratorAggregate::getIterator()
194
+	 *
195
+	 * @return \ArrayIterator
196
+	 */
197
+	public function getIterator(): \ArrayIterator
198
+	{
199
+		return new \ArrayIterator($this->_certificates);
200
+	}
201 201
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\CertificationPath;
6 6
 
Please login to merge, or discard this patch.
lib/X509/CertificationPath/Exception/PathBuildingException.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\CertificationPath\Exception;
6 6
 
Please login to merge, or discard this patch.
lib/X509/CertificationPath/Exception/PathValidationException.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\CertificationPath\Exception;
6 6
 
Please login to merge, or discard this patch.
lib/X509/AttributeCertificate/Validation/ACValidationConfig.php 2 patches
Indentation   +100 added lines, -100 removed lines patch added patch discarded remove patch
@@ -12,114 +12,114 @@
 block discarded – undo
12 12
  */
13 13
 class ACValidationConfig
14 14
 {
15
-    /**
16
-     * Certification path of the AC holder.
17
-     *
18
-     * @var CertificationPath
19
-     */
20
-    protected $_holderPath;
15
+	/**
16
+	 * Certification path of the AC holder.
17
+	 *
18
+	 * @var CertificationPath
19
+	 */
20
+	protected $_holderPath;
21 21
 
22
-    /**
23
-     * Certification path of the AC issuer.
24
-     *
25
-     * @var CertificationPath
26
-     */
27
-    protected $_issuerPath;
22
+	/**
23
+	 * Certification path of the AC issuer.
24
+	 *
25
+	 * @var CertificationPath
26
+	 */
27
+	protected $_issuerPath;
28 28
 
29
-    /**
30
-     * Evaluation reference time.
31
-     *
32
-     * @var \DateTimeImmutable
33
-     */
34
-    protected $_evalTime;
29
+	/**
30
+	 * Evaluation reference time.
31
+	 *
32
+	 * @var \DateTimeImmutable
33
+	 */
34
+	protected $_evalTime;
35 35
 
36
-    /**
37
-     * Permitted targets.
38
-     *
39
-     * @var Target[]
40
-     */
41
-    protected $_targets;
36
+	/**
37
+	 * Permitted targets.
38
+	 *
39
+	 * @var Target[]
40
+	 */
41
+	protected $_targets;
42 42
 
43
-    /**
44
-     * Constructor.
45
-     *
46
-     * @param CertificationPath $holder_path Certification path of the AC holder
47
-     * @param CertificationPath $issuer_path Certification path of the AC issuer
48
-     */
49
-    public function __construct(CertificationPath $holder_path,
50
-        CertificationPath $issuer_path)
51
-    {
52
-        $this->_holderPath = $holder_path;
53
-        $this->_issuerPath = $issuer_path;
54
-        $this->_evalTime = new \DateTimeImmutable();
55
-        $this->_targets = [];
56
-    }
43
+	/**
44
+	 * Constructor.
45
+	 *
46
+	 * @param CertificationPath $holder_path Certification path of the AC holder
47
+	 * @param CertificationPath $issuer_path Certification path of the AC issuer
48
+	 */
49
+	public function __construct(CertificationPath $holder_path,
50
+		CertificationPath $issuer_path)
51
+	{
52
+		$this->_holderPath = $holder_path;
53
+		$this->_issuerPath = $issuer_path;
54
+		$this->_evalTime = new \DateTimeImmutable();
55
+		$this->_targets = [];
56
+	}
57 57
 
58
-    /**
59
-     * Get certification path of the AC's holder.
60
-     *
61
-     * @return CertificationPath
62
-     */
63
-    public function holderPath(): CertificationPath
64
-    {
65
-        return $this->_holderPath;
66
-    }
58
+	/**
59
+	 * Get certification path of the AC's holder.
60
+	 *
61
+	 * @return CertificationPath
62
+	 */
63
+	public function holderPath(): CertificationPath
64
+	{
65
+		return $this->_holderPath;
66
+	}
67 67
 
68
-    /**
69
-     * Get certification path of the AC's issuer.
70
-     *
71
-     * @return CertificationPath
72
-     */
73
-    public function issuerPath(): CertificationPath
74
-    {
75
-        return $this->_issuerPath;
76
-    }
68
+	/**
69
+	 * Get certification path of the AC's issuer.
70
+	 *
71
+	 * @return CertificationPath
72
+	 */
73
+	public function issuerPath(): CertificationPath
74
+	{
75
+		return $this->_issuerPath;
76
+	}
77 77
 
78
-    /**
79
-     * Get self with given evaluation reference time.
80
-     *
81
-     * @param \DateTimeImmutable $dt
82
-     *
83
-     * @return self
84
-     */
85
-    public function withEvaluationTime(\DateTimeImmutable $dt): self
86
-    {
87
-        $obj = clone $this;
88
-        $obj->_evalTime = $dt;
89
-        return $obj;
90
-    }
78
+	/**
79
+	 * Get self with given evaluation reference time.
80
+	 *
81
+	 * @param \DateTimeImmutable $dt
82
+	 *
83
+	 * @return self
84
+	 */
85
+	public function withEvaluationTime(\DateTimeImmutable $dt): self
86
+	{
87
+		$obj = clone $this;
88
+		$obj->_evalTime = $dt;
89
+		return $obj;
90
+	}
91 91
 
92
-    /**
93
-     * Get the evaluation reference time.
94
-     *
95
-     * @return \DateTimeImmutable
96
-     */
97
-    public function evaluationTime(): \DateTimeImmutable
98
-    {
99
-        return $this->_evalTime;
100
-    }
92
+	/**
93
+	 * Get the evaluation reference time.
94
+	 *
95
+	 * @return \DateTimeImmutable
96
+	 */
97
+	public function evaluationTime(): \DateTimeImmutable
98
+	{
99
+		return $this->_evalTime;
100
+	}
101 101
 
102
-    /**
103
-     * Get self with permitted targets.
104
-     *
105
-     * @param Target ...$targets
106
-     *
107
-     * @return self
108
-     */
109
-    public function withTargets(Target ...$targets): self
110
-    {
111
-        $obj = clone $this;
112
-        $obj->_targets = $targets;
113
-        return $obj;
114
-    }
102
+	/**
103
+	 * Get self with permitted targets.
104
+	 *
105
+	 * @param Target ...$targets
106
+	 *
107
+	 * @return self
108
+	 */
109
+	public function withTargets(Target ...$targets): self
110
+	{
111
+		$obj = clone $this;
112
+		$obj->_targets = $targets;
113
+		return $obj;
114
+	}
115 115
 
116
-    /**
117
-     * Get array of permitted targets.
118
-     *
119
-     * @return Target[]
120
-     */
121
-    public function targets(): array
122
-    {
123
-        return $this->_targets;
124
-    }
116
+	/**
117
+	 * Get array of permitted targets.
118
+	 *
119
+	 * @return Target[]
120
+	 */
121
+	public function targets(): array
122
+	{
123
+		return $this->_targets;
124
+	}
125 125
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\AttributeCertificate\Validation;
6 6
 
Please login to merge, or discard this patch.
X509/AttributeCertificate/Validation/Exception/ACValidationException.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\AttributeCertificate\Validation\Exception;
6 6
 
Please login to merge, or discard this patch.
lib/X509/AttributeCertificate/Validation/ACValidator.php 2 patches
Indentation   +172 added lines, -172 removed lines patch added patch discarded remove patch
@@ -21,186 +21,186 @@
 block discarded – undo
21 21
  */
22 22
 class ACValidator
23 23
 {
24
-    /**
25
-     * Attribute certificate.
26
-     *
27
-     * @var AttributeCertificate
28
-     */
29
-    protected $_ac;
24
+	/**
25
+	 * Attribute certificate.
26
+	 *
27
+	 * @var AttributeCertificate
28
+	 */
29
+	protected $_ac;
30 30
 
31
-    /**
32
-     * Validation configuration.
33
-     *
34
-     * @var ACValidationConfig
35
-     */
36
-    protected $_config;
31
+	/**
32
+	 * Validation configuration.
33
+	 *
34
+	 * @var ACValidationConfig
35
+	 */
36
+	protected $_config;
37 37
 
38
-    /**
39
-     * Crypto engine.
40
-     *
41
-     * @var Crypto
42
-     */
43
-    protected $_crypto;
38
+	/**
39
+	 * Crypto engine.
40
+	 *
41
+	 * @var Crypto
42
+	 */
43
+	protected $_crypto;
44 44
 
45
-    /**
46
-     * Constructor.
47
-     *
48
-     * @param AttributeCertificate $ac     Attribute certificate to validate
49
-     * @param ACValidationConfig   $config Validation configuration
50
-     * @param null|Crypto          $crypto Crypto engine, use default if not set
51
-     */
52
-    public function __construct(AttributeCertificate $ac,
53
-        ACValidationConfig $config, ?Crypto $crypto = null)
54
-    {
55
-        $this->_ac = $ac;
56
-        $this->_config = $config;
57
-        $this->_crypto = $crypto ?? Crypto::getDefault();
58
-    }
45
+	/**
46
+	 * Constructor.
47
+	 *
48
+	 * @param AttributeCertificate $ac     Attribute certificate to validate
49
+	 * @param ACValidationConfig   $config Validation configuration
50
+	 * @param null|Crypto          $crypto Crypto engine, use default if not set
51
+	 */
52
+	public function __construct(AttributeCertificate $ac,
53
+		ACValidationConfig $config, ?Crypto $crypto = null)
54
+	{
55
+		$this->_ac = $ac;
56
+		$this->_config = $config;
57
+		$this->_crypto = $crypto ?? Crypto::getDefault();
58
+	}
59 59
 
60
-    /**
61
-     * Validate attribute certificate.
62
-     *
63
-     * @throws ACValidationException If validation fails
64
-     *
65
-     * @return AttributeCertificate Validated AC
66
-     */
67
-    public function validate(): AttributeCertificate
68
-    {
69
-        $this->_validateHolder();
70
-        $issuer = $this->_verifyIssuer();
71
-        $this->_validateIssuerProfile($issuer);
72
-        $this->_validateTime();
73
-        $this->_validateTargeting();
74
-        return $this->_ac;
75
-    }
60
+	/**
61
+	 * Validate attribute certificate.
62
+	 *
63
+	 * @throws ACValidationException If validation fails
64
+	 *
65
+	 * @return AttributeCertificate Validated AC
66
+	 */
67
+	public function validate(): AttributeCertificate
68
+	{
69
+		$this->_validateHolder();
70
+		$issuer = $this->_verifyIssuer();
71
+		$this->_validateIssuerProfile($issuer);
72
+		$this->_validateTime();
73
+		$this->_validateTargeting();
74
+		return $this->_ac;
75
+	}
76 76
 
77
-    /**
78
-     * Validate AC holder's certification.
79
-     *
80
-     * @throws ACValidationException
81
-     *
82
-     * @return Certificate Certificate of the AC's holder
83
-     */
84
-    private function _validateHolder(): Certificate
85
-    {
86
-        $path = $this->_config->holderPath();
87
-        $config = PathValidationConfig::defaultConfig()
88
-            ->withMaxLength(count($path))
89
-            ->withDateTime($this->_config->evaluationTime());
90
-        try {
91
-            $holder = $path->validate($config, $this->_crypto)->certificate();
92
-        } catch (PathValidationException $e) {
93
-            throw new ACValidationException(
94
-                "Failed to validate holder PKC's certification path.", 0, $e);
95
-        }
96
-        if (!$this->_ac->isHeldBy($holder)) {
97
-            throw new ACValidationException("Name mismatch of AC's holder PKC.");
98
-        }
99
-        return $holder;
100
-    }
77
+	/**
78
+	 * Validate AC holder's certification.
79
+	 *
80
+	 * @throws ACValidationException
81
+	 *
82
+	 * @return Certificate Certificate of the AC's holder
83
+	 */
84
+	private function _validateHolder(): Certificate
85
+	{
86
+		$path = $this->_config->holderPath();
87
+		$config = PathValidationConfig::defaultConfig()
88
+			->withMaxLength(count($path))
89
+			->withDateTime($this->_config->evaluationTime());
90
+		try {
91
+			$holder = $path->validate($config, $this->_crypto)->certificate();
92
+		} catch (PathValidationException $e) {
93
+			throw new ACValidationException(
94
+				"Failed to validate holder PKC's certification path.", 0, $e);
95
+		}
96
+		if (!$this->_ac->isHeldBy($holder)) {
97
+			throw new ACValidationException("Name mismatch of AC's holder PKC.");
98
+		}
99
+		return $holder;
100
+	}
101 101
 
102
-    /**
103
-     * Verify AC's signature and issuer's certification.
104
-     *
105
-     * @throws ACValidationException
106
-     *
107
-     * @return Certificate Certificate of the AC's issuer
108
-     */
109
-    private function _verifyIssuer(): Certificate
110
-    {
111
-        $path = $this->_config->issuerPath();
112
-        $config = PathValidationConfig::defaultConfig()
113
-            ->withMaxLength(count($path))
114
-            ->withDateTime($this->_config->evaluationTime());
115
-        try {
116
-            $issuer = $path->validate($config, $this->_crypto)->certificate();
117
-        } catch (PathValidationException $e) {
118
-            throw new ACValidationException(
119
-                "Failed to validate issuer PKC's certification path.", 0, $e);
120
-        }
121
-        if (!$this->_ac->isIssuedBy($issuer)) {
122
-            throw new ACValidationException("Name mismatch of AC's issuer PKC.");
123
-        }
124
-        $pubkey_info = $issuer->tbsCertificate()->subjectPublicKeyInfo();
125
-        if (!$this->_ac->verify($pubkey_info, $this->_crypto)) {
126
-            throw new ACValidationException('Failed to verify signature.');
127
-        }
128
-        return $issuer;
129
-    }
102
+	/**
103
+	 * Verify AC's signature and issuer's certification.
104
+	 *
105
+	 * @throws ACValidationException
106
+	 *
107
+	 * @return Certificate Certificate of the AC's issuer
108
+	 */
109
+	private function _verifyIssuer(): Certificate
110
+	{
111
+		$path = $this->_config->issuerPath();
112
+		$config = PathValidationConfig::defaultConfig()
113
+			->withMaxLength(count($path))
114
+			->withDateTime($this->_config->evaluationTime());
115
+		try {
116
+			$issuer = $path->validate($config, $this->_crypto)->certificate();
117
+		} catch (PathValidationException $e) {
118
+			throw new ACValidationException(
119
+				"Failed to validate issuer PKC's certification path.", 0, $e);
120
+		}
121
+		if (!$this->_ac->isIssuedBy($issuer)) {
122
+			throw new ACValidationException("Name mismatch of AC's issuer PKC.");
123
+		}
124
+		$pubkey_info = $issuer->tbsCertificate()->subjectPublicKeyInfo();
125
+		if (!$this->_ac->verify($pubkey_info, $this->_crypto)) {
126
+			throw new ACValidationException('Failed to verify signature.');
127
+		}
128
+		return $issuer;
129
+	}
130 130
 
131
-    /**
132
-     * Validate AC issuer's profile.
133
-     *
134
-     * @see https://tools.ietf.org/html/rfc5755#section-4.5
135
-     *
136
-     * @param Certificate $cert
137
-     *
138
-     * @throws ACValidationException
139
-     */
140
-    private function _validateIssuerProfile(Certificate $cert): void
141
-    {
142
-        $exts = $cert->tbsCertificate()->extensions();
143
-        if ($exts->hasKeyUsage() && !$exts->keyUsage()->isDigitalSignature()) {
144
-            throw new ACValidationException(
145
-                "Issuer PKC's Key Usage extension doesn't permit" .
146
-                     ' verification of digital signatures.');
147
-        }
148
-        if ($exts->hasBasicConstraints() && $exts->basicConstraints()->isCA()) {
149
-            throw new ACValidationException('Issuer PKC must not be a CA.');
150
-        }
151
-    }
131
+	/**
132
+	 * Validate AC issuer's profile.
133
+	 *
134
+	 * @see https://tools.ietf.org/html/rfc5755#section-4.5
135
+	 *
136
+	 * @param Certificate $cert
137
+	 *
138
+	 * @throws ACValidationException
139
+	 */
140
+	private function _validateIssuerProfile(Certificate $cert): void
141
+	{
142
+		$exts = $cert->tbsCertificate()->extensions();
143
+		if ($exts->hasKeyUsage() && !$exts->keyUsage()->isDigitalSignature()) {
144
+			throw new ACValidationException(
145
+				"Issuer PKC's Key Usage extension doesn't permit" .
146
+					 ' verification of digital signatures.');
147
+		}
148
+		if ($exts->hasBasicConstraints() && $exts->basicConstraints()->isCA()) {
149
+			throw new ACValidationException('Issuer PKC must not be a CA.');
150
+		}
151
+	}
152 152
 
153
-    /**
154
-     * Validate AC's validity period.
155
-     *
156
-     * @throws ACValidationException
157
-     */
158
-    private function _validateTime(): void
159
-    {
160
-        $t = $this->_config->evaluationTime();
161
-        $validity = $this->_ac->acinfo()->validityPeriod();
162
-        if ($validity->notBeforeTime()->diff($t)->invert) {
163
-            throw new ACValidationException('Validity period has not started.');
164
-        }
165
-        if ($t->diff($validity->notAfterTime())->invert) {
166
-            throw new ACValidationException('Attribute certificate has expired.');
167
-        }
168
-    }
153
+	/**
154
+	 * Validate AC's validity period.
155
+	 *
156
+	 * @throws ACValidationException
157
+	 */
158
+	private function _validateTime(): void
159
+	{
160
+		$t = $this->_config->evaluationTime();
161
+		$validity = $this->_ac->acinfo()->validityPeriod();
162
+		if ($validity->notBeforeTime()->diff($t)->invert) {
163
+			throw new ACValidationException('Validity period has not started.');
164
+		}
165
+		if ($t->diff($validity->notAfterTime())->invert) {
166
+			throw new ACValidationException('Attribute certificate has expired.');
167
+		}
168
+	}
169 169
 
170
-    /**
171
-     * Validate AC's target information.
172
-     *
173
-     * @throws ACValidationException
174
-     */
175
-    private function _validateTargeting(): void
176
-    {
177
-        $exts = $this->_ac->acinfo()->extensions();
178
-        // if target information extension is not present
179
-        if (!$exts->has(Extension::OID_TARGET_INFORMATION)) {
180
-            return;
181
-        }
182
-        $ext = $exts->get(Extension::OID_TARGET_INFORMATION);
183
-        if ($ext instanceof TargetInformationExtension &&
184
-            !$this->_hasMatchingTarget($ext->targets())) {
185
-            throw new ACValidationException(
186
-                "Attribute certificate doesn't have a matching target.");
187
-        }
188
-    }
170
+	/**
171
+	 * Validate AC's target information.
172
+	 *
173
+	 * @throws ACValidationException
174
+	 */
175
+	private function _validateTargeting(): void
176
+	{
177
+		$exts = $this->_ac->acinfo()->extensions();
178
+		// if target information extension is not present
179
+		if (!$exts->has(Extension::OID_TARGET_INFORMATION)) {
180
+			return;
181
+		}
182
+		$ext = $exts->get(Extension::OID_TARGET_INFORMATION);
183
+		if ($ext instanceof TargetInformationExtension &&
184
+			!$this->_hasMatchingTarget($ext->targets())) {
185
+			throw new ACValidationException(
186
+				"Attribute certificate doesn't have a matching target.");
187
+		}
188
+	}
189 189
 
190
-    /**
191
-     * Check whether validation configuration has matching targets.
192
-     *
193
-     * @param Targets $targets Set of eligible targets
194
-     *
195
-     * @return bool
196
-     */
197
-    private function _hasMatchingTarget(Targets $targets): bool
198
-    {
199
-        foreach ($this->_config->targets() as $target) {
200
-            if ($targets->hasTarget($target)) {
201
-                return true;
202
-            }
203
-        }
204
-        return false;
205
-    }
190
+	/**
191
+	 * Check whether validation configuration has matching targets.
192
+	 *
193
+	 * @param Targets $targets Set of eligible targets
194
+	 *
195
+	 * @return bool
196
+	 */
197
+	private function _hasMatchingTarget(Targets $targets): bool
198
+	{
199
+		foreach ($this->_config->targets() as $target) {
200
+			if ($targets->hasTarget($target)) {
201
+				return true;
202
+			}
203
+		}
204
+		return false;
205
+	}
206 206
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\AttributeCertificate\Validation;
6 6
 
Please login to merge, or discard this patch.
lib/X509/AttributeCertificate/AttributeCertificateInfo.php 2 patches
Indentation   +446 added lines, -446 removed lines patch added patch discarded remove patch
@@ -22,450 +22,450 @@
 block discarded – undo
22 22
  */
23 23
 class AttributeCertificateInfo
24 24
 {
25
-    const VERSION_2 = 1;
26
-
27
-    /**
28
-     * AC version.
29
-     *
30
-     * @var int
31
-     */
32
-    protected $_version;
33
-
34
-    /**
35
-     * AC holder.
36
-     *
37
-     * @var Holder
38
-     */
39
-    protected $_holder;
40
-
41
-    /**
42
-     * AC issuer.
43
-     *
44
-     * @var AttCertIssuer
45
-     */
46
-    protected $_issuer;
47
-
48
-    /**
49
-     * Signature algorithm identifier.
50
-     *
51
-     * @var SignatureAlgorithmIdentifier
52
-     */
53
-    protected $_signature;
54
-
55
-    /**
56
-     * AC serial number as a base 10 integer.
57
-     *
58
-     * @var string
59
-     */
60
-    protected $_serialNumber;
61
-
62
-    /**
63
-     * Validity period.
64
-     *
65
-     * @var AttCertValidityPeriod
66
-     */
67
-    protected $_attrCertValidityPeriod;
68
-
69
-    /**
70
-     * Attributes.
71
-     *
72
-     * @var Attributes
73
-     */
74
-    protected $_attributes;
75
-
76
-    /**
77
-     * Issuer unique identifier.
78
-     *
79
-     * @var null|UniqueIdentifier
80
-     */
81
-    protected $_issuerUniqueID;
82
-
83
-    /**
84
-     * Extensions.
85
-     *
86
-     * @var Extensions
87
-     */
88
-    protected $_extensions;
89
-
90
-    /**
91
-     * Constructor.
92
-     *
93
-     * @param Holder                $holder   AC holder
94
-     * @param AttCertIssuer         $issuer   AC issuer
95
-     * @param AttCertValidityPeriod $validity Validity
96
-     * @param Attributes            $attribs  Attributes
97
-     */
98
-    public function __construct(Holder $holder, AttCertIssuer $issuer,
99
-        AttCertValidityPeriod $validity, Attributes $attribs)
100
-    {
101
-        $this->_version = self::VERSION_2;
102
-        $this->_holder = $holder;
103
-        $this->_issuer = $issuer;
104
-        $this->_attrCertValidityPeriod = $validity;
105
-        $this->_attributes = $attribs;
106
-        $this->_extensions = new Extensions();
107
-    }
108
-
109
-    /**
110
-     * Initialize from ASN.1.
111
-     *
112
-     * @param Sequence $seq
113
-     *
114
-     * @throws \UnexpectedValueException
115
-     *
116
-     * @return self
117
-     */
118
-    public static function fromASN1(Sequence $seq): self
119
-    {
120
-        $idx = 0;
121
-        $version = $seq->at($idx++)->asInteger()->intNumber();
122
-        if (self::VERSION_2 !== $version) {
123
-            throw new \UnexpectedValueException('Version must be 2.');
124
-        }
125
-        $holder = Holder::fromASN1($seq->at($idx++)->asSequence());
126
-        $issuer = AttCertIssuer::fromASN1($seq->at($idx++));
127
-        $signature = AlgorithmIdentifier::fromASN1($seq->at($idx++)->asSequence());
128
-        if (!$signature instanceof SignatureAlgorithmIdentifier) {
129
-            throw new \UnexpectedValueException(
130
-                'Unsupported signature algorithm ' . $signature->oid() . '.');
131
-        }
132
-        $serial = $seq->at($idx++)->asInteger()->number();
133
-        $validity = AttCertValidityPeriod::fromASN1($seq->at($idx++)->asSequence());
134
-        $attribs = Attributes::fromASN1($seq->at($idx++)->asSequence());
135
-        $obj = new self($holder, $issuer, $validity, $attribs);
136
-        $obj->_signature = $signature;
137
-        $obj->_serialNumber = $serial;
138
-        if ($seq->has($idx, Element::TYPE_BIT_STRING)) {
139
-            $obj->_issuerUniqueID = UniqueIdentifier::fromASN1(
140
-                $seq->at($idx++)->asBitString());
141
-        }
142
-        if ($seq->has($idx, Element::TYPE_SEQUENCE)) {
143
-            $obj->_extensions = Extensions::fromASN1(
144
-                $seq->at($idx++)->asSequence());
145
-        }
146
-        return $obj;
147
-    }
148
-
149
-    /**
150
-     * Get self with holder.
151
-     *
152
-     * @param Holder $holder
153
-     *
154
-     * @return self
155
-     */
156
-    public function withHolder(Holder $holder): self
157
-    {
158
-        $obj = clone $this;
159
-        $obj->_holder = $holder;
160
-        return $obj;
161
-    }
162
-
163
-    /**
164
-     * Get self with issuer.
165
-     *
166
-     * @param AttCertIssuer $issuer
167
-     *
168
-     * @return self
169
-     */
170
-    public function withIssuer(AttCertIssuer $issuer): self
171
-    {
172
-        $obj = clone $this;
173
-        $obj->_issuer = $issuer;
174
-        return $obj;
175
-    }
176
-
177
-    /**
178
-     * Get self with signature algorithm identifier.
179
-     *
180
-     * @param SignatureAlgorithmIdentifier $algo
181
-     *
182
-     * @return self
183
-     */
184
-    public function withSignature(SignatureAlgorithmIdentifier $algo): self
185
-    {
186
-        $obj = clone $this;
187
-        $obj->_signature = $algo;
188
-        return $obj;
189
-    }
190
-
191
-    /**
192
-     * Get self with serial number.
193
-     *
194
-     * @param int|string $serial Base 10 serial number
195
-     *
196
-     * @return self
197
-     */
198
-    public function withSerialNumber($serial): self
199
-    {
200
-        $obj = clone $this;
201
-        $obj->_serialNumber = strval($serial);
202
-        return $obj;
203
-    }
204
-
205
-    /**
206
-     * Get self with random positive serial number.
207
-     *
208
-     * @param int $size Number of random bytes
209
-     *
210
-     * @return self
211
-     */
212
-    public function withRandomSerialNumber(int $size = 16): self
213
-    {
214
-        // ensure that first byte is always non-zero and having first bit unset
215
-        $num = gmp_init(mt_rand(1, 0x7f), 10);
216
-        for ($i = 1; $i < $size; ++$i) {
217
-            $num <<= 8;
218
-            $num += mt_rand(0, 0xff);
219
-        }
220
-        return $this->withSerialNumber(gmp_strval($num, 10));
221
-    }
222
-
223
-    /**
224
-     * Get self with validity period.
225
-     *
226
-     * @param AttCertValidityPeriod $validity
227
-     *
228
-     * @return self
229
-     */
230
-    public function withValidity(AttCertValidityPeriod $validity): self
231
-    {
232
-        $obj = clone $this;
233
-        $obj->_attrCertValidityPeriod = $validity;
234
-        return $obj;
235
-    }
236
-
237
-    /**
238
-     * Get self with attributes.
239
-     *
240
-     * @param Attributes $attribs
241
-     *
242
-     * @return self
243
-     */
244
-    public function withAttributes(Attributes $attribs): self
245
-    {
246
-        $obj = clone $this;
247
-        $obj->_attributes = $attribs;
248
-        return $obj;
249
-    }
250
-
251
-    /**
252
-     * Get self with issuer unique identifier.
253
-     *
254
-     * @param UniqueIdentifier $uid
255
-     *
256
-     * @return self
257
-     */
258
-    public function withIssuerUniqueID(UniqueIdentifier $uid): self
259
-    {
260
-        $obj = clone $this;
261
-        $obj->_issuerUniqueID = $uid;
262
-        return $obj;
263
-    }
264
-
265
-    /**
266
-     * Get self with extensions.
267
-     *
268
-     * @param Extensions $extensions
269
-     *
270
-     * @return self
271
-     */
272
-    public function withExtensions(Extensions $extensions): self
273
-    {
274
-        $obj = clone $this;
275
-        $obj->_extensions = $extensions;
276
-        return $obj;
277
-    }
278
-
279
-    /**
280
-     * Get self with extensions added.
281
-     *
282
-     * @param Extension ...$exts One or more Extension objects
283
-     *
284
-     * @return self
285
-     */
286
-    public function withAdditionalExtensions(Extension ...$exts): self
287
-    {
288
-        $obj = clone $this;
289
-        $obj->_extensions = $obj->_extensions->withExtensions(...$exts);
290
-        return $obj;
291
-    }
292
-
293
-    /**
294
-     * Get version.
295
-     *
296
-     * @return int
297
-     */
298
-    public function version(): int
299
-    {
300
-        return $this->_version;
301
-    }
302
-
303
-    /**
304
-     * Get AC holder.
305
-     *
306
-     * @return Holder
307
-     */
308
-    public function holder(): Holder
309
-    {
310
-        return $this->_holder;
311
-    }
312
-
313
-    /**
314
-     * Get AC issuer.
315
-     *
316
-     * @return AttCertIssuer
317
-     */
318
-    public function issuer(): AttCertIssuer
319
-    {
320
-        return $this->_issuer;
321
-    }
322
-
323
-    /**
324
-     * Check whether signature is set.
325
-     *
326
-     * @return bool
327
-     */
328
-    public function hasSignature(): bool
329
-    {
330
-        return isset($this->_signature);
331
-    }
332
-
333
-    /**
334
-     * Get signature algorithm identifier.
335
-     *
336
-     * @throws \LogicException If not set
337
-     *
338
-     * @return SignatureAlgorithmIdentifier
339
-     */
340
-    public function signature(): SignatureAlgorithmIdentifier
341
-    {
342
-        if (!$this->hasSignature()) {
343
-            throw new \LogicException('signature not set.');
344
-        }
345
-        return $this->_signature;
346
-    }
347
-
348
-    /**
349
-     * Check whether serial number is present.
350
-     *
351
-     * @return bool
352
-     */
353
-    public function hasSerialNumber(): bool
354
-    {
355
-        return isset($this->_serialNumber);
356
-    }
357
-
358
-    /**
359
-     * Get AC serial number as a base 10 integer.
360
-     *
361
-     * @throws \LogicException If not set
362
-     *
363
-     * @return string
364
-     */
365
-    public function serialNumber(): string
366
-    {
367
-        if (!$this->hasSerialNumber()) {
368
-            throw new \LogicException('serialNumber not set.');
369
-        }
370
-        return $this->_serialNumber;
371
-    }
372
-
373
-    /**
374
-     * Get validity period.
375
-     *
376
-     * @return AttCertValidityPeriod
377
-     */
378
-    public function validityPeriod(): AttCertValidityPeriod
379
-    {
380
-        return $this->_attrCertValidityPeriod;
381
-    }
382
-
383
-    /**
384
-     * Get attributes.
385
-     *
386
-     * @return Attributes
387
-     */
388
-    public function attributes(): Attributes
389
-    {
390
-        return $this->_attributes;
391
-    }
392
-
393
-    /**
394
-     * Check whether issuer unique identifier is present.
395
-     *
396
-     * @return bool
397
-     */
398
-    public function hasIssuerUniqueID(): bool
399
-    {
400
-        return isset($this->_issuerUniqueID);
401
-    }
402
-
403
-    /**
404
-     * Get issuer unique identifier.
405
-     *
406
-     * @throws \LogicException If not set
407
-     *
408
-     * @return UniqueIdentifier
409
-     */
410
-    public function issuerUniqueID(): UniqueIdentifier
411
-    {
412
-        if (!$this->hasIssuerUniqueID()) {
413
-            throw new \LogicException('issuerUniqueID not set.');
414
-        }
415
-        return $this->_issuerUniqueID;
416
-    }
417
-
418
-    /**
419
-     * Get extensions.
420
-     *
421
-     * @return Extensions
422
-     */
423
-    public function extensions(): Extensions
424
-    {
425
-        return $this->_extensions;
426
-    }
427
-
428
-    /**
429
-     * Get ASN.1 structure.
430
-     *
431
-     * @return Sequence
432
-     */
433
-    public function toASN1(): Sequence
434
-    {
435
-        $elements = [new Integer($this->_version), $this->_holder->toASN1(),
436
-            $this->_issuer->toASN1(), $this->signature()->toASN1(),
437
-            new Integer($this->serialNumber()),
438
-            $this->_attrCertValidityPeriod->toASN1(),
439
-            $this->_attributes->toASN1(), ];
440
-        if (isset($this->_issuerUniqueID)) {
441
-            $elements[] = $this->_issuerUniqueID->toASN1();
442
-        }
443
-        if (count($this->_extensions)) {
444
-            $elements[] = $this->_extensions->toASN1();
445
-        }
446
-        return new Sequence(...$elements);
447
-    }
448
-
449
-    /**
450
-     * Create signed attribute certificate.
451
-     *
452
-     * @param SignatureAlgorithmIdentifier $algo         Signature algorithm
453
-     * @param PrivateKeyInfo               $privkey_info Private key
454
-     * @param null|Crypto                  $crypto       Crypto engine, use default if not set
455
-     *
456
-     * @return AttributeCertificate
457
-     */
458
-    public function sign(SignatureAlgorithmIdentifier $algo,
459
-        PrivateKeyInfo $privkey_info, ?Crypto $crypto = null): AttributeCertificate
460
-    {
461
-        $crypto = $crypto ?? Crypto::getDefault();
462
-        $aci = clone $this;
463
-        if (!isset($aci->_serialNumber)) {
464
-            $aci->_serialNumber = '0';
465
-        }
466
-        $aci->_signature = $algo;
467
-        $data = $aci->toASN1()->toDER();
468
-        $signature = $crypto->sign($data, $privkey_info, $algo);
469
-        return new AttributeCertificate($aci, $algo, $signature);
470
-    }
25
+	const VERSION_2 = 1;
26
+
27
+	/**
28
+	 * AC version.
29
+	 *
30
+	 * @var int
31
+	 */
32
+	protected $_version;
33
+
34
+	/**
35
+	 * AC holder.
36
+	 *
37
+	 * @var Holder
38
+	 */
39
+	protected $_holder;
40
+
41
+	/**
42
+	 * AC issuer.
43
+	 *
44
+	 * @var AttCertIssuer
45
+	 */
46
+	protected $_issuer;
47
+
48
+	/**
49
+	 * Signature algorithm identifier.
50
+	 *
51
+	 * @var SignatureAlgorithmIdentifier
52
+	 */
53
+	protected $_signature;
54
+
55
+	/**
56
+	 * AC serial number as a base 10 integer.
57
+	 *
58
+	 * @var string
59
+	 */
60
+	protected $_serialNumber;
61
+
62
+	/**
63
+	 * Validity period.
64
+	 *
65
+	 * @var AttCertValidityPeriod
66
+	 */
67
+	protected $_attrCertValidityPeriod;
68
+
69
+	/**
70
+	 * Attributes.
71
+	 *
72
+	 * @var Attributes
73
+	 */
74
+	protected $_attributes;
75
+
76
+	/**
77
+	 * Issuer unique identifier.
78
+	 *
79
+	 * @var null|UniqueIdentifier
80
+	 */
81
+	protected $_issuerUniqueID;
82
+
83
+	/**
84
+	 * Extensions.
85
+	 *
86
+	 * @var Extensions
87
+	 */
88
+	protected $_extensions;
89
+
90
+	/**
91
+	 * Constructor.
92
+	 *
93
+	 * @param Holder                $holder   AC holder
94
+	 * @param AttCertIssuer         $issuer   AC issuer
95
+	 * @param AttCertValidityPeriod $validity Validity
96
+	 * @param Attributes            $attribs  Attributes
97
+	 */
98
+	public function __construct(Holder $holder, AttCertIssuer $issuer,
99
+		AttCertValidityPeriod $validity, Attributes $attribs)
100
+	{
101
+		$this->_version = self::VERSION_2;
102
+		$this->_holder = $holder;
103
+		$this->_issuer = $issuer;
104
+		$this->_attrCertValidityPeriod = $validity;
105
+		$this->_attributes = $attribs;
106
+		$this->_extensions = new Extensions();
107
+	}
108
+
109
+	/**
110
+	 * Initialize from ASN.1.
111
+	 *
112
+	 * @param Sequence $seq
113
+	 *
114
+	 * @throws \UnexpectedValueException
115
+	 *
116
+	 * @return self
117
+	 */
118
+	public static function fromASN1(Sequence $seq): self
119
+	{
120
+		$idx = 0;
121
+		$version = $seq->at($idx++)->asInteger()->intNumber();
122
+		if (self::VERSION_2 !== $version) {
123
+			throw new \UnexpectedValueException('Version must be 2.');
124
+		}
125
+		$holder = Holder::fromASN1($seq->at($idx++)->asSequence());
126
+		$issuer = AttCertIssuer::fromASN1($seq->at($idx++));
127
+		$signature = AlgorithmIdentifier::fromASN1($seq->at($idx++)->asSequence());
128
+		if (!$signature instanceof SignatureAlgorithmIdentifier) {
129
+			throw new \UnexpectedValueException(
130
+				'Unsupported signature algorithm ' . $signature->oid() . '.');
131
+		}
132
+		$serial = $seq->at($idx++)->asInteger()->number();
133
+		$validity = AttCertValidityPeriod::fromASN1($seq->at($idx++)->asSequence());
134
+		$attribs = Attributes::fromASN1($seq->at($idx++)->asSequence());
135
+		$obj = new self($holder, $issuer, $validity, $attribs);
136
+		$obj->_signature = $signature;
137
+		$obj->_serialNumber = $serial;
138
+		if ($seq->has($idx, Element::TYPE_BIT_STRING)) {
139
+			$obj->_issuerUniqueID = UniqueIdentifier::fromASN1(
140
+				$seq->at($idx++)->asBitString());
141
+		}
142
+		if ($seq->has($idx, Element::TYPE_SEQUENCE)) {
143
+			$obj->_extensions = Extensions::fromASN1(
144
+				$seq->at($idx++)->asSequence());
145
+		}
146
+		return $obj;
147
+	}
148
+
149
+	/**
150
+	 * Get self with holder.
151
+	 *
152
+	 * @param Holder $holder
153
+	 *
154
+	 * @return self
155
+	 */
156
+	public function withHolder(Holder $holder): self
157
+	{
158
+		$obj = clone $this;
159
+		$obj->_holder = $holder;
160
+		return $obj;
161
+	}
162
+
163
+	/**
164
+	 * Get self with issuer.
165
+	 *
166
+	 * @param AttCertIssuer $issuer
167
+	 *
168
+	 * @return self
169
+	 */
170
+	public function withIssuer(AttCertIssuer $issuer): self
171
+	{
172
+		$obj = clone $this;
173
+		$obj->_issuer = $issuer;
174
+		return $obj;
175
+	}
176
+
177
+	/**
178
+	 * Get self with signature algorithm identifier.
179
+	 *
180
+	 * @param SignatureAlgorithmIdentifier $algo
181
+	 *
182
+	 * @return self
183
+	 */
184
+	public function withSignature(SignatureAlgorithmIdentifier $algo): self
185
+	{
186
+		$obj = clone $this;
187
+		$obj->_signature = $algo;
188
+		return $obj;
189
+	}
190
+
191
+	/**
192
+	 * Get self with serial number.
193
+	 *
194
+	 * @param int|string $serial Base 10 serial number
195
+	 *
196
+	 * @return self
197
+	 */
198
+	public function withSerialNumber($serial): self
199
+	{
200
+		$obj = clone $this;
201
+		$obj->_serialNumber = strval($serial);
202
+		return $obj;
203
+	}
204
+
205
+	/**
206
+	 * Get self with random positive serial number.
207
+	 *
208
+	 * @param int $size Number of random bytes
209
+	 *
210
+	 * @return self
211
+	 */
212
+	public function withRandomSerialNumber(int $size = 16): self
213
+	{
214
+		// ensure that first byte is always non-zero and having first bit unset
215
+		$num = gmp_init(mt_rand(1, 0x7f), 10);
216
+		for ($i = 1; $i < $size; ++$i) {
217
+			$num <<= 8;
218
+			$num += mt_rand(0, 0xff);
219
+		}
220
+		return $this->withSerialNumber(gmp_strval($num, 10));
221
+	}
222
+
223
+	/**
224
+	 * Get self with validity period.
225
+	 *
226
+	 * @param AttCertValidityPeriod $validity
227
+	 *
228
+	 * @return self
229
+	 */
230
+	public function withValidity(AttCertValidityPeriod $validity): self
231
+	{
232
+		$obj = clone $this;
233
+		$obj->_attrCertValidityPeriod = $validity;
234
+		return $obj;
235
+	}
236
+
237
+	/**
238
+	 * Get self with attributes.
239
+	 *
240
+	 * @param Attributes $attribs
241
+	 *
242
+	 * @return self
243
+	 */
244
+	public function withAttributes(Attributes $attribs): self
245
+	{
246
+		$obj = clone $this;
247
+		$obj->_attributes = $attribs;
248
+		return $obj;
249
+	}
250
+
251
+	/**
252
+	 * Get self with issuer unique identifier.
253
+	 *
254
+	 * @param UniqueIdentifier $uid
255
+	 *
256
+	 * @return self
257
+	 */
258
+	public function withIssuerUniqueID(UniqueIdentifier $uid): self
259
+	{
260
+		$obj = clone $this;
261
+		$obj->_issuerUniqueID = $uid;
262
+		return $obj;
263
+	}
264
+
265
+	/**
266
+	 * Get self with extensions.
267
+	 *
268
+	 * @param Extensions $extensions
269
+	 *
270
+	 * @return self
271
+	 */
272
+	public function withExtensions(Extensions $extensions): self
273
+	{
274
+		$obj = clone $this;
275
+		$obj->_extensions = $extensions;
276
+		return $obj;
277
+	}
278
+
279
+	/**
280
+	 * Get self with extensions added.
281
+	 *
282
+	 * @param Extension ...$exts One or more Extension objects
283
+	 *
284
+	 * @return self
285
+	 */
286
+	public function withAdditionalExtensions(Extension ...$exts): self
287
+	{
288
+		$obj = clone $this;
289
+		$obj->_extensions = $obj->_extensions->withExtensions(...$exts);
290
+		return $obj;
291
+	}
292
+
293
+	/**
294
+	 * Get version.
295
+	 *
296
+	 * @return int
297
+	 */
298
+	public function version(): int
299
+	{
300
+		return $this->_version;
301
+	}
302
+
303
+	/**
304
+	 * Get AC holder.
305
+	 *
306
+	 * @return Holder
307
+	 */
308
+	public function holder(): Holder
309
+	{
310
+		return $this->_holder;
311
+	}
312
+
313
+	/**
314
+	 * Get AC issuer.
315
+	 *
316
+	 * @return AttCertIssuer
317
+	 */
318
+	public function issuer(): AttCertIssuer
319
+	{
320
+		return $this->_issuer;
321
+	}
322
+
323
+	/**
324
+	 * Check whether signature is set.
325
+	 *
326
+	 * @return bool
327
+	 */
328
+	public function hasSignature(): bool
329
+	{
330
+		return isset($this->_signature);
331
+	}
332
+
333
+	/**
334
+	 * Get signature algorithm identifier.
335
+	 *
336
+	 * @throws \LogicException If not set
337
+	 *
338
+	 * @return SignatureAlgorithmIdentifier
339
+	 */
340
+	public function signature(): SignatureAlgorithmIdentifier
341
+	{
342
+		if (!$this->hasSignature()) {
343
+			throw new \LogicException('signature not set.');
344
+		}
345
+		return $this->_signature;
346
+	}
347
+
348
+	/**
349
+	 * Check whether serial number is present.
350
+	 *
351
+	 * @return bool
352
+	 */
353
+	public function hasSerialNumber(): bool
354
+	{
355
+		return isset($this->_serialNumber);
356
+	}
357
+
358
+	/**
359
+	 * Get AC serial number as a base 10 integer.
360
+	 *
361
+	 * @throws \LogicException If not set
362
+	 *
363
+	 * @return string
364
+	 */
365
+	public function serialNumber(): string
366
+	{
367
+		if (!$this->hasSerialNumber()) {
368
+			throw new \LogicException('serialNumber not set.');
369
+		}
370
+		return $this->_serialNumber;
371
+	}
372
+
373
+	/**
374
+	 * Get validity period.
375
+	 *
376
+	 * @return AttCertValidityPeriod
377
+	 */
378
+	public function validityPeriod(): AttCertValidityPeriod
379
+	{
380
+		return $this->_attrCertValidityPeriod;
381
+	}
382
+
383
+	/**
384
+	 * Get attributes.
385
+	 *
386
+	 * @return Attributes
387
+	 */
388
+	public function attributes(): Attributes
389
+	{
390
+		return $this->_attributes;
391
+	}
392
+
393
+	/**
394
+	 * Check whether issuer unique identifier is present.
395
+	 *
396
+	 * @return bool
397
+	 */
398
+	public function hasIssuerUniqueID(): bool
399
+	{
400
+		return isset($this->_issuerUniqueID);
401
+	}
402
+
403
+	/**
404
+	 * Get issuer unique identifier.
405
+	 *
406
+	 * @throws \LogicException If not set
407
+	 *
408
+	 * @return UniqueIdentifier
409
+	 */
410
+	public function issuerUniqueID(): UniqueIdentifier
411
+	{
412
+		if (!$this->hasIssuerUniqueID()) {
413
+			throw new \LogicException('issuerUniqueID not set.');
414
+		}
415
+		return $this->_issuerUniqueID;
416
+	}
417
+
418
+	/**
419
+	 * Get extensions.
420
+	 *
421
+	 * @return Extensions
422
+	 */
423
+	public function extensions(): Extensions
424
+	{
425
+		return $this->_extensions;
426
+	}
427
+
428
+	/**
429
+	 * Get ASN.1 structure.
430
+	 *
431
+	 * @return Sequence
432
+	 */
433
+	public function toASN1(): Sequence
434
+	{
435
+		$elements = [new Integer($this->_version), $this->_holder->toASN1(),
436
+			$this->_issuer->toASN1(), $this->signature()->toASN1(),
437
+			new Integer($this->serialNumber()),
438
+			$this->_attrCertValidityPeriod->toASN1(),
439
+			$this->_attributes->toASN1(), ];
440
+		if (isset($this->_issuerUniqueID)) {
441
+			$elements[] = $this->_issuerUniqueID->toASN1();
442
+		}
443
+		if (count($this->_extensions)) {
444
+			$elements[] = $this->_extensions->toASN1();
445
+		}
446
+		return new Sequence(...$elements);
447
+	}
448
+
449
+	/**
450
+	 * Create signed attribute certificate.
451
+	 *
452
+	 * @param SignatureAlgorithmIdentifier $algo         Signature algorithm
453
+	 * @param PrivateKeyInfo               $privkey_info Private key
454
+	 * @param null|Crypto                  $crypto       Crypto engine, use default if not set
455
+	 *
456
+	 * @return AttributeCertificate
457
+	 */
458
+	public function sign(SignatureAlgorithmIdentifier $algo,
459
+		PrivateKeyInfo $privkey_info, ?Crypto $crypto = null): AttributeCertificate
460
+	{
461
+		$crypto = $crypto ?? Crypto::getDefault();
462
+		$aci = clone $this;
463
+		if (!isset($aci->_serialNumber)) {
464
+			$aci->_serialNumber = '0';
465
+		}
466
+		$aci->_signature = $algo;
467
+		$data = $aci->toASN1()->toDER();
468
+		$signature = $crypto->sign($data, $privkey_info, $algo);
469
+		return new AttributeCertificate($aci, $algo, $signature);
470
+	}
471 471
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types = 1);
3
+declare(strict_types=1);
4 4
 
5 5
 namespace Sop\X509\AttributeCertificate;
6 6
 
Please login to merge, or discard this patch.