GitHub Access Token became invalid

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

withAdditionalExtensions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace X509\AttributeCertificate;
4
5
use ASN1\Element;
6
use ASN1\Type\Constructed\Sequence;
7
use ASN1\Type\Primitive\Integer;
8
use CryptoUtil\ASN1\AlgorithmIdentifier;
9
use CryptoUtil\ASN1\AlgorithmIdentifier\Feature\SignatureAlgorithmIdentifier;
10
use CryptoUtil\ASN1\PrivateKeyInfo;
11
use CryptoUtil\Crypto\Crypto;
12
use X509\Certificate\Extension\Extension;
13
use X509\Certificate\Extensions;
14
use X509\Certificate\UniqueIdentifier;
15
16
17
/**
18
 * Implements <i>AttributeCertificateInfo</i> ASN.1 type.
19
 *
20
 * @link https://tools.ietf.org/html/rfc5755#section-4.1
21
 */
22
class AttributeCertificateInfo
23
{
24
	const VERSION_2 = 1;
25
	
26
	/**
27
	 * AC version.
28
	 *
29
	 * @var int $_version
30
	 */
31
	protected $_version;
32
	
33
	/**
34
	 * AC holder.
35
	 *
36
	 * @var Holder $_holder
37
	 */
38
	protected $_holder;
39
	
40
	/**
41
	 * AC issuer.
42
	 *
43
	 * @var AttCertIssuer $_issuer
44
	 */
45
	protected $_issuer;
46
	
47
	/**
48
	 * Signature algorithm identifier.
49
	 *
50
	 * @var SignatureAlgorithmIdentifier $_signature
51
	 */
52
	protected $_signature;
53
	
54
	/**
55
	 * AC serial number.
56
	 *
57
	 * @var int|string $_serialNumber
58
	 */
59
	protected $_serialNumber;
60
	
61
	/**
62
	 * Validity period.
63
	 *
64
	 * @var AttCertValidityPeriod $_attrCertValidityPeriod
65
	 */
66
	protected $_attrCertValidityPeriod;
67
	
68
	/**
69
	 * Attributes.
70
	 *
71
	 * @var Attributes $_attributes
72
	 */
73
	protected $_attributes;
74
	
75
	/**
76
	 * Issuer unique identifier.
77
	 *
78
	 * @var UniqueIdentifier|null $_issuerUniqueID
79
	 */
80
	protected $_issuerUniqueID;
81
	
82
	/**
83
	 * Extensions.
84
	 *
85
	 * @var Extensions $_extensions
86
	 */
87
	protected $_extensions;
88
	
89
	/**
90
	 * Constructor
91
	 *
92
	 * @param Holder $holder AC holder
93
	 * @param AttCertIssuer $issuer AC issuer
94
	 * @param AttCertValidityPeriod $validity Validity
95
	 * @param Attributes $attribs Attributes
96
	 */
97 8
	public function __construct(Holder $holder, AttCertIssuer $issuer, 
98
			AttCertValidityPeriod $validity, Attributes $attribs) {
99 8
		$this->_version = self::VERSION_2;
100 8
		$this->_holder = $holder;
101 8
		$this->_issuer = $issuer;
102 8
		$this->_attrCertValidityPeriod = $validity;
103 8
		$this->_attributes = $attribs;
104 8
		$this->_extensions = new Extensions();
105 8
	}
106
	
107
	/**
108
	 * Initialize from ASN.1.
109
	 *
110
	 * @param Sequence $seq
111
	 * @throws \UnexpectedValueException
112
	 * @return self
113
	 */
114 7
	public static function fromASN1(Sequence $seq) {
115 7
		$version = $seq->at(0)
116 7
			->asInteger()
117 7
			->number();
118 7
		if ($version != self::VERSION_2) {
119 1
			throw new \UnexpectedValueException("Version must be 2.");
120
		}
121 6
		$holder = Holder::fromASN1($seq->at(1)->asSequence());
122 6
		$issuer = AttCertIssuer::fromASN1($seq->at(2));
123 6
		$signature = AlgorithmIdentifier::fromASN1($seq->at(3)->asSequence());
124 6
		if (!$signature instanceof SignatureAlgorithmIdentifier) {
125 1
			throw new \UnexpectedValueException(
126 1
				"Unsupported signature algorithm " . $signature->oid() . ".");
127
		}
128 5
		$serial = $seq->at(4)
129 5
			->asInteger()
130 5
			->number();
131 5
		$validity = AttCertValidityPeriod::fromASN1($seq->at(5)->asSequence());
132 5
		$attribs = Attributes::fromASN1($seq->at(6)->asSequence());
133 5
		$obj = new self($holder, $issuer, $validity, $attribs);
134 5
		$obj->_signature = $signature;
135 5
		$obj->_serialNumber = $serial;
136 5
		$idx = 7;
137 5
		if ($seq->has($idx, Element::TYPE_BIT_STRING)) {
138 1
			$obj->_issuerUniqueID = UniqueIdentifier::fromASN1(
139 1
				$seq->at($idx++)->asBitString());
140 1
		}
141 5
		if ($seq->has($idx, Element::TYPE_SEQUENCE)) {
142 3
			$obj->_extensions = Extensions::fromASN1(
143 3
				$seq->at($idx++)->asSequence());
144 3
		}
145 5
		return $obj;
146
	}
147
	
148
	/**
149
	 * Get self with holder.
150
	 *
151
	 * @param Holder $holder
152
	 * @return self
153
	 */
154 1
	public function withHolder(Holder $holder) {
155 1
		$obj = clone $this;
156 1
		$obj->_holder = $holder;
157 1
		return $obj;
158
	}
159
	
160
	/**
161
	 * Get self with issuer.
162
	 *
163
	 * @param AttCertIssuer $issuer
164
	 * @return self
165
	 */
166 1
	public function withIssuer(AttCertIssuer $issuer) {
167 1
		$obj = clone $this;
168 1
		$obj->_issuer = $issuer;
169 1
		return $obj;
170
	}
171
	
172
	/**
173
	 * Get self with signature algorithm identifier.
174
	 *
175
	 * @param SignatureAlgorithmIdentifier $algo
176
	 * @return self
177
	 */
178 3
	public function withSignature(SignatureAlgorithmIdentifier $algo) {
179 3
		$obj = clone $this;
180 3
		$obj->_signature = $algo;
181 3
		return $obj;
182
	}
183
	
184
	/**
185
	 * Get self with serial number.
186
	 *
187
	 * @param int|string $serial
188
	 * @return self
189
	 */
190 4
	public function withSerialNumber($serial) {
191 4
		$obj = clone $this;
192 4
		$obj->_serialNumber = $serial;
193 4
		return $obj;
194
	}
195
	
196
	/**
197
	 * Get self with random positive serial number.
198
	 *
199
	 * @param int $size Number of random bytes
200
	 * @return self
201
	 */
202 1 View Code Duplication
	public function withRandomSerialNumber($size = 16) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
		// ensure that first byte is always non-zero and having first bit unset
204 1
		$num = gmp_init(mt_rand(1, 0x7f), 10);
205 1
		for ($i = 1; $i < $size; ++$i) {
206 1
			$num <<= 8;
207 1
			$num += mt_rand(0, 0xff);
208 1
		}
209 1
		return $this->withSerialNumber(gmp_strval($num, 10));
210
	}
211
	
212
	/**
213
	 * Get self with validity period.
214
	 *
215
	 * @param AttCertValidityPeriod $validity
216
	 * @return self
217
	 */
218 1
	public function withValidity(AttCertValidityPeriod $validity) {
219 1
		$obj = clone $this;
220 1
		$obj->_attrCertValidityPeriod = $validity;
221 1
		return $obj;
222
	}
223
	
224
	/**
225
	 * Get self with attributes.
226
	 *
227
	 * @param Attributes $attribs
228
	 * @return self
229
	 */
230 1
	public function withAttributes(Attributes $attribs) {
231 1
		$obj = clone $this;
232 1
		$obj->_attributes = $attribs;
233 1
		return $obj;
234
	}
235
	
236
	/**
237
	 * Get self with issuer unique identifier.
238
	 *
239
	 * @param UniqueIdentifier $uid
240
	 * @return self
241
	 */
242 2
	public function withIssuerUniqueID(UniqueIdentifier $uid) {
243 2
		$obj = clone $this;
244 2
		$obj->_issuerUniqueID = $uid;
245 2
		return $obj;
246
	}
247
	
248
	/**
249
	 * Get self with extensions.
250
	 *
251
	 * @param Extensions $extensions
252
	 * @return self
253
	 */
254 2
	public function withExtensions(Extensions $extensions) {
255 2
		$obj = clone $this;
256 2
		$obj->_extensions = $extensions;
257 2
		return $obj;
258
	}
259
	
260
	/**
261
	 * Get self with extensions added.
262
	 *
263
	 * @param Extension ...$exts One or more Extension objects
264
	 * @return self
265
	 */
266 1
	public function withAdditionalExtensions(Extension ...$exts) {
267 1
		$obj = clone $this;
268 1
		$obj->_extensions = $obj->_extensions->withExtensions(...$exts);
269 1
		return $obj;
270
	}
271
	
272
	/**
273
	 * Get version.
274
	 *
275
	 * @return int
276
	 */
277 1
	public function version() {
278 1
		return $this->_version;
279
	}
280
	
281
	/**
282
	 * Get AC holder.
283
	 *
284
	 * @return Holder
285
	 */
286 1
	public function holder() {
287 1
		return $this->_holder;
288
	}
289
	
290
	/**
291
	 * Get AC issuer.
292
	 *
293
	 * @return AttCertIssuer
294
	 */
295 1
	public function issuer() {
296 1
		return $this->_issuer;
297
	}
298
	
299
	/**
300
	 * Check whether signature is set.
301
	 *
302
	 * @return bool
303
	 */
304 13
	public function hasSignature() {
305 13
		return isset($this->_signature);
306
	}
307
	
308
	/**
309
	 * Get signature algorithm identifier.
310
	 *
311
	 * @return SignatureAlgorithmIdentifier
312
	 */
313 13
	public function signature() {
314 13
		if (!$this->hasSignature()) {
315 1
			throw new \LogicException("signature not set.");
316
		}
317 12
		return $this->_signature;
318
	}
319
	
320
	/**
321
	 * Check whether serial number is present.
322
	 *
323
	 * @return bool
324
	 */
325 14
	public function hasSerialNumber() {
326 14
		return isset($this->_serialNumber);
327
	}
328
	
329
	/**
330
	 * Get AC serial number.
331
	 *
332
	 * @return int|string
333
	 */
334 14
	public function serialNumber() {
335 14
		if (!$this->hasSerialNumber()) {
336 1
			throw new \LogicException("serialNumber not set.");
337
		}
338 13
		return $this->_serialNumber;
339
	}
340
	
341
	/**
342
	 * Get validity period.
343
	 *
344
	 * @return AttCertValidityPeriod
345
	 */
346 1
	public function validityPeriod() {
347 1
		return $this->_attrCertValidityPeriod;
348
	}
349
	
350
	/**
351
	 * Get attributes.
352
	 *
353
	 * @return Attributes
354
	 */
355 1
	public function attributes() {
356 1
		return $this->_attributes;
357
	}
358
	
359
	/**
360
	 * Check whether issuer unique identifier is present.
361
	 *
362
	 * @return bool
363
	 */
364 2
	public function hasIssuerUniqueID() {
365 2
		return isset($this->_issuerUniqueID);
366
	}
367
	
368
	/**
369
	 * Get issuer unique identifier.
370
	 *
371
	 * @return UniqueIdentifier
372
	 */
373 2
	public function issuerUniqueID() {
374 2
		if (!$this->hasIssuerUniqueID()) {
375 1
			throw new \LogicException("issuerUniqueID not set.");
376
		}
377 1
		return $this->_issuerUniqueID;
378
	}
379
	
380
	/**
381
	 * Get extensions.
382
	 *
383
	 * @return Extensions
384
	 */
385 1
	public function extensions() {
386 1
		return $this->_extensions;
387
	}
388
	
389
	/**
390
	 * Get ASN.1 structure.
391
	 *
392
	 * @return Sequence
393
	 */
394 11
	public function toASN1() {
395 11
		$elements = array(new Integer($this->_version), 
396 11
			$this->_holder->toASN1(), $this->_issuer->toASN1(), 
397 11
			$this->signature()->toASN1(), new Integer($this->serialNumber()), 
398 11
			$this->_attrCertValidityPeriod->toASN1(), 
399 11
			$this->_attributes->toASN1());
400 11
		if (isset($this->_issuerUniqueID)) {
401 3
			$elements[] = $this->_issuerUniqueID->toASN1();
402 3
		}
403 11
		if (count($this->_extensions)) {
404 6
			$elements[] = $this->_extensions->toASN1();
405 6
		}
406 11
		return new Sequence(...$elements);
407
	}
408
	
409
	/**
410
	 * Create signed attribute certificate.
411
	 *
412
	 * @param Crypto $crypto
413
	 * @param SignatureAlgorithmIdentifier $algo Signature algorithm
414
	 * @param PrivateKeyInfo $privkey_info Private key
415
	 * @return AttributeCertificate
416
	 */
417 1
	public function sign(Crypto $crypto, SignatureAlgorithmIdentifier $algo, 
418
			PrivateKeyInfo $privkey_info) {
419 1
		$aci = clone $this;
420 1
		if (!isset($aci->_serialNumber)) {
421 1
			$aci->_serialNumber = 0;
422 1
		}
423 1
		$aci->_signature = $algo;
424 1
		$data = $aci->toASN1()->toDER();
425 1
		$signature = $crypto->sign($data, $privkey_info, $algo);
426 1
		return new AttributeCertificate($aci, $algo, $signature);
427
	}
428
}
429