GitHub Access Token became invalid

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

Holder::entityName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\X509\AttributeCertificate;
6
7
use Sop\ASN1\Element;
8
use Sop\ASN1\Type\Constructed\Sequence;
9
use Sop\ASN1\Type\Tagged\ImplicitlyTaggedType;
10
use Sop\X509\Certificate\Certificate;
11
use Sop\X509\GeneralName\DirectoryName;
12
use Sop\X509\GeneralName\GeneralName;
13
use Sop\X509\GeneralName\GeneralNames;
14
15
/**
16
 * Implements *Holder* ASN.1 type.
17
 *
18
 * @see https://tools.ietf.org/html/rfc5755#section-4.1
19
 */
20
class Holder
21
{
22
    /**
23
     * Holder PKC's issuer and serial.
24
     *
25
     * @var null|IssuerSerial
26
     */
27
    protected $_baseCertificateID;
28
29
    /**
30
     * Holder PKC's subject.
31
     *
32
     * @var null|GeneralNames
33
     */
34
    protected $_entityName;
35
36
    /**
37
     * Linked object.
38
     *
39
     * @var null|ObjectDigestInfo
40
     */
41
    protected $_objectDigestInfo;
42
43
    /**
44
     * Constructor.
45
     *
46
     * @param null|IssuerSerial $issuer_serial
47
     * @param null|GeneralNames $entity_name
48
     */
49 21
    public function __construct(?IssuerSerial $issuer_serial = null,
50
        ?GeneralNames $entity_name = null)
51
    {
52 21
        $this->_baseCertificateID = $issuer_serial;
53 21
        $this->_entityName = $entity_name;
54 21
    }
55
56
    /**
57
     * Initialize from a holder's public key certificate.
58
     *
59
     * @param Certificate $cert
60
     *
61
     * @return self
62 1
     */
63
    public static function fromPKC(Certificate $cert): self
64 1
    {
65
        return new self(IssuerSerial::fromPKC($cert));
66
    }
67
68
    /**
69
     * Initialize from ASN.1.
70
     *
71
     * @param Sequence $seq
72 7
     */
73
    public static function fromASN1(Sequence $seq): self
74 7
    {
75 7
        $cert_id = null;
76 7
        $entity_name = null;
77 7
        $digest_info = null;
78 7
        if ($seq->hasTagged(0)) {
79 7
            $cert_id = IssuerSerial::fromASN1(
80 7
                $seq->getTagged(0)->asImplicit(Element::TYPE_SEQUENCE)
81 7
                    ->asSequence());
82
        }
83 7
        if ($seq->hasTagged(1)) {
84 3
            $entity_name = GeneralNames::fromASN1(
85 3
                $seq->getTagged(1)->asImplicit(Element::TYPE_SEQUENCE)
86 3
                    ->asSequence());
87 3
        }
88
        if ($seq->hasTagged(2)) {
89 7
            $digest_info = ObjectDigestInfo::fromASN1(
90 1
                $seq->getTagged(2)->asImplicit(Element::TYPE_SEQUENCE)
91 1
                    ->asSequence());
92 1
        }
93 1
        $obj = new self($cert_id, $entity_name);
94
        $obj->_objectDigestInfo = $digest_info;
95 7
        return $obj;
96 7
    }
97 7
98
    /**
99
     * Get self with base certificate ID.
100
     *
101
     * @param IssuerSerial $issuer
102
     *
103
     * @return self
104
     */
105
    public function withBaseCertificateID(IssuerSerial $issuer): self
106 1
    {
107
        $obj = clone $this;
108 1
        $obj->_baseCertificateID = $issuer;
109 1
        return $obj;
110 1
    }
111
112
    /**
113
     * Get self with entity name.
114
     *
115
     * @param GeneralNames $names
116
     *
117
     * @return self
118
     */
119 1
    public function withEntityName(GeneralNames $names): self
120
    {
121 1
        $obj = clone $this;
122 1
        $obj->_entityName = $names;
123 1
        return $obj;
124
    }
125
126
    /**
127
     * Get self with object digest info.
128
     *
129
     * @param ObjectDigestInfo $odi
130
     *
131
     * @return self
132 2
     */
133
    public function withObjectDigestInfo(ObjectDigestInfo $odi): self
134 2
    {
135 2
        $obj = clone $this;
136 2
        $obj->_objectDigestInfo = $odi;
137
        return $obj;
138
    }
139
140
    /**
141
     * Check whether base certificate ID is present.
142
     *
143
     * @return bool
144 2
     */
145
    public function hasBaseCertificateID(): bool
146 2
    {
147
        return isset($this->_baseCertificateID);
148
    }
149
150
    /**
151
     * Get base certificate ID.
152
     *
153
     * @throws \LogicException If not set
154
     *
155 2
     * @return IssuerSerial
156
     */
157 2
    public function baseCertificateID(): IssuerSerial
158 1
    {
159
        if (!$this->hasBaseCertificateID()) {
160 1
            throw new \LogicException('baseCertificateID not set.');
161
        }
162
        return $this->_baseCertificateID;
163
    }
164
165
    /**
166
     * Check whether entity name is present.
167
     *
168 2
     * @return bool
169
     */
170 2
    public function hasEntityName(): bool
171
    {
172
        return isset($this->_entityName);
173
    }
174
175
    /**
176
     * Get entity name.
177
     *
178
     * @throws \LogicException If not set
179 2
     *
180
     * @return GeneralNames
181 2
     */
182 1
    public function entityName(): GeneralNames
183
    {
184 1
        if (!$this->hasEntityName()) {
185
            throw new \LogicException('entityName not set.');
186
        }
187
        return $this->_entityName;
188
    }
189
190
    /**
191
     * Check whether object digest info is present.
192 2
     *
193
     * @return bool
194 2
     */
195
    public function hasObjectDigestInfo(): bool
196
    {
197
        return isset($this->_objectDigestInfo);
198
    }
199
200
    /**
201
     * Get object digest info.
202
     *
203 2
     * @throws \LogicException If not set
204
     *
205 2
     * @return ObjectDigestInfo
206 1
     */
207
    public function objectDigestInfo(): ObjectDigestInfo
208 1
    {
209
        if (!$this->hasObjectDigestInfo()) {
210
            throw new \LogicException('objectDigestInfo not set.');
211
        }
212
        return $this->_objectDigestInfo;
213
    }
214
215
    /**
216 20
     * Generate ASN.1 structure.
217
     *
218 20
     * @return Sequence
219 20
     */
220 20
    public function toASN1(): Sequence
221 20
    {
222
        $elements = [];
223 20
        if (isset($this->_baseCertificateID)) {
224 4
            $elements[] = new ImplicitlyTaggedType(0,
225 4
                $this->_baseCertificateID->toASN1());
226
        }
227 20
        if (isset($this->_entityName)) {
228 1
            $elements[] = new ImplicitlyTaggedType(1,
229 1
                $this->_entityName->toASN1());
230
        }
231 20
        if (isset($this->_objectDigestInfo)) {
232
            $elements[] = new ImplicitlyTaggedType(2,
233
                $this->_objectDigestInfo->toASN1());
234
        }
235
        return new Sequence(...$elements);
236
    }
237
238
    /**
239
     * Check whether Holder identifies given certificate.
240 19
     *
241
     * @param Certificate $cert
242
     *
243 19
     * @return bool
244 1
     */
245
    public function identifiesPKC(Certificate $cert): bool
246
    {
247 18
        // if neither baseCertificateID nor entityName are present
248 18
        if (!$this->_baseCertificateID && !$this->_entityName) {
249 3
            return false;
250
        }
251
        // if baseCertificateID is present, but doesn't match
252 15
        if ($this->_baseCertificateID &&
253 1
            !$this->_baseCertificateID->identifiesPKC($cert)) {
254
            return false;
255 14
        }
256
        // if entityName is present, but doesn't match
257
        if ($this->_entityName && !$this->_checkEntityName($cert)) {
258
            return false;
259
        }
260
        return true;
261
    }
262
263
    /**
264 4
     * Check whether entityName matches the given certificate.
265
     *
266 4
     * @param Certificate $cert
267 4
     *
268 4
     * @return bool
269 4
     */
270 2
    private function _checkEntityName(Certificate $cert): bool
271
    {
272 2
        $name = $this->_entityName->firstDN();
273 2
        if ($cert->tbsCertificate()->subject()->equals($name)) {
274 2
            return true;
275 2
        }
276 1
        $exts = $cert->tbsCertificate()->extensions();
277
        if ($exts->hasSubjectAlternativeName()) {
278
            $ext = $exts->subjectAlternativeName();
279 1
            if ($this->_checkEntityAlternativeNames($ext->names())) {
280
                return true;
281
            }
282
        }
283
        return false;
284
    }
285
286
    /**
287
     * Check whether any of the subject alternative names match entityName.
288 2
     *
289
     * @param GeneralNames $san
290
     *
291 2
     * @return bool
292 2
     */
293 2
    private function _checkEntityAlternativeNames(GeneralNames $san): bool
294 2
    {
295
        // only directory names supported for now
296
        $name = $this->_entityName->firstDN();
297 1
        foreach ($san->allOf(GeneralName::TAG_DIRECTORY_NAME) as $dn) {
298
            if ($dn instanceof DirectoryName && $dn->dn()->equals($name)) {
299
                return true;
300
            }
301
        }
302
        return false;
303
    }
304
}
305