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.

CertificateBundle::contains()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\X509\Certificate;
6
7
use Sop\CryptoEncoding\PEM;
8
use Sop\CryptoEncoding\PEMBundle;
9
10
/**
11
 * Implements a list of certificates.
12
 */
13
class CertificateBundle implements \Countable, \IteratorAggregate
14
{
15
    /**
16
     * Certificates.
17
     *
18
     * @var Certificate[]
19
     */
20
    protected $_certs;
21
22
    /**
23
     * Mapping from public key id to array of certificates.
24
     *
25
     * @var null|(Certificate[])[]
26
     */
27
    private $_keyIdMap;
28
29
    /**
30
     * Constructor.
31
     *
32
     * @param Certificate ...$certs Certificate objects
33
     */
34 17
    public function __construct(Certificate ...$certs)
35
    {
36 17
        $this->_certs = $certs;
37 17
    }
38
39
    /**
40
     * Reset internal cached variables on clone.
41
     */
42 1
    public function __clone()
43
    {
44 1
        $this->_keyIdMap = null;
45 1
    }
46
47
    /**
48
     * Initialize from PEMs.
49
     *
50
     * @param PEM ...$pems PEM objects
51
     *
52
     * @return self
53
     */
54 2
    public static function fromPEMs(PEM ...$pems): self
55
    {
56 2
        $certs = array_map(
57
            function ($pem) {
58 2
                return Certificate::fromPEM($pem);
59 2
            }, $pems);
60 2
        return new self(...$certs);
61
    }
62
63
    /**
64
     * Initialize from PEM bundle.
65
     *
66
     * @param PEMBundle $pem_bundle
67
     *
68
     * @return self
69
     */
70 1
    public static function fromPEMBundle(PEMBundle $pem_bundle): self
71
    {
72 1
        return self::fromPEMs(...$pem_bundle->all());
73
    }
74
75
    /**
76
     * Get self with certificates added.
77
     *
78
     * @param Certificate ...$cert
79
     *
80
     * @return self
81
     */
82 1
    public function withCertificates(Certificate ...$cert): self
83
    {
84 1
        $obj = clone $this;
85 1
        $obj->_certs = array_merge($obj->_certs, $cert);
86 1
        return $obj;
87
    }
88
89
    /**
90
     * Get self with certificates from PEMBundle added.
91
     *
92
     * @param PEMBundle $pem_bundle
93
     *
94
     * @return self
95
     */
96 1
    public function withPEMBundle(PEMBundle $pem_bundle): self
97
    {
98 1
        $certs = $this->_certs;
99 1
        foreach ($pem_bundle as $pem) {
100 1
            $certs[] = Certificate::fromPEM($pem);
101
        }
102 1
        return new self(...$certs);
103
    }
104
105
    /**
106
     * Get self with single certificate from PEM added.
107
     *
108
     * @param PEM $pem
109
     *
110
     * @return self
111
     */
112 1
    public function withPEM(PEM $pem): self
113
    {
114 1
        $certs = $this->_certs;
115 1
        $certs[] = Certificate::fromPEM($pem);
116 1
        return new self(...$certs);
117
    }
118
119
    /**
120
     * Check whether bundle contains a given certificate.
121
     *
122
     * @param Certificate $cert
123
     *
124
     * @return bool
125
     */
126 3
    public function contains(Certificate $cert): bool
127
    {
128 3
        $id = self::_getCertKeyId($cert);
129 3
        $map = $this->_getKeyIdMap();
130 3
        if (!isset($map[$id])) {
131 1
            return false;
132
        }
133 2
        foreach ($map[$id] as $c) {
134
            /** @var Certificate $c */
135 2
            if ($cert->equals($c)) {
136 2
                return true;
137
            }
138
        }
139 1
        return false;
140
    }
141
142
    /**
143
     * Get all certificates that have given subject key identifier.
144
     *
145
     * @param string $id
146
     *
147
     * @return Certificate[]
148
     */
149 11
    public function allBySubjectKeyIdentifier(string $id): array
150
    {
151 11
        $map = $this->_getKeyIdMap();
152 11
        if (!isset($map[$id])) {
153 7
            return [];
154
        }
155 9
        return $map[$id];
156
    }
157
158
    /**
159
     * Get all certificates in a bundle.
160
     *
161
     * @return Certificate[]
162
     */
163 1
    public function all(): array
164
    {
165 1
        return $this->_certs;
166
    }
167
168
    /**
169
     * @see \Countable::count()
170
     *
171
     * @return int
172
     */
173 4
    public function count(): int
174
    {
175 4
        return count($this->_certs);
176
    }
177
178
    /**
179
     * Get iterator for certificates.
180
     *
181
     * @see \IteratorAggregate::getIterator()
182
     *
183
     * @return \ArrayIterator
184
     */
185 1
    public function getIterator(): \ArrayIterator
186
    {
187 1
        return new \ArrayIterator($this->_certs);
188
    }
189
190
    /**
191
     * Get certificate mapping by public key id.
192
     *
193
     * @return (Certificate[])[]
194
     */
195 14
    private function _getKeyIdMap(): array
196
    {
197
        // lazily build mapping
198 14
        if (!isset($this->_keyIdMap)) {
199 13
            $this->_keyIdMap = [];
200 13
            foreach ($this->_certs as $cert) {
201 13
                $id = self::_getCertKeyId($cert);
202 13
                if (!isset($this->_keyIdMap[$id])) {
203 13
                    $this->_keyIdMap[$id] = [];
204
                }
205 13
                array_push($this->_keyIdMap[$id], $cert);
206
            }
207
        }
208 14
        return $this->_keyIdMap;
209
    }
210
211
    /**
212
     * Get public key id for the certificate.
213
     *
214
     * @param Certificate $cert
215
     *
216
     * @return string
217
     */
218 13
    private static function _getCertKeyId(Certificate $cert): string
219
    {
220 13
        $exts = $cert->tbsCertificate()->extensions();
221 13
        if ($exts->hasSubjectKeyIdentifier()) {
222 11
            return $exts->subjectKeyIdentifier()->keyIdentifier();
223
        }
224 2
        return $cert->tbsCertificate()->subjectPublicKeyInfo()->keyIdentifier();
225
    }
226
}
227