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

Certificate::_hasEqualSubject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\X509\Certificate;
6
7
use Sop\ASN1\Type\Constructed\Sequence;
8
use Sop\ASN1\Type\UnspecifiedType;
9
use Sop\CryptoBridge\Crypto;
10
use Sop\CryptoEncoding\PEM;
11
use Sop\CryptoTypes\AlgorithmIdentifier\AlgorithmIdentifier;
12
use Sop\CryptoTypes\AlgorithmIdentifier\Feature\SignatureAlgorithmIdentifier;
13
use Sop\CryptoTypes\Asymmetric\PublicKeyInfo;
14
use Sop\CryptoTypes\Signature\Signature;
15
16
/**
17
 * Implements <i>Certificate</i> ASN.1 type.
18
 *
19
 * @see https://tools.ietf.org/html/rfc5280#section-4.1
20
 */
21
class Certificate
22
{
23
    /**
24
     * "To be signed" certificate information.
25
     *
26
     * @var TBSCertificate
27
     */
28
    protected $_tbsCertificate;
29
30
    /**
31
     * Signature algorithm.
32
     *
33
     * @var SignatureAlgorithmIdentifier
34
     */
35
    protected $_signatureAlgorithm;
36
37
    /**
38
     * Signature value.
39
     *
40
     * @var Signature
41
     */
42
    protected $_signatureValue;
43
44
    /**
45
     * Constructor.
46
     *
47
     * @param TBSCertificate               $tbsCert
48
     * @param SignatureAlgorithmIdentifier $algo
49
     * @param Signature                    $signature
50
     */
51 30
    public function __construct(TBSCertificate $tbsCert,
52
        SignatureAlgorithmIdentifier $algo, Signature $signature)
53
    {
54 30
        $this->_tbsCertificate = $tbsCert;
55 30
        $this->_signatureAlgorithm = $algo;
56 30
        $this->_signatureValue = $signature;
57 30
    }
58
59
    /**
60
     * Get certificate as a PEM formatted string.
61
     *
62
     * @return string
63
     */
64 1
    public function __toString(): string
65
    {
66 1
        return $this->toPEM()->string();
67
    }
68
69
    /**
70
     * Initialize from ASN.1.
71
     *
72
     * @param Sequence $seq
73
     *
74
     * @return self
75
     */
76 18
    public static function fromASN1(Sequence $seq): self
77
    {
78 18
        $tbsCert = TBSCertificate::fromASN1($seq->at(0)->asSequence());
79 18
        $algo = AlgorithmIdentifier::fromASN1($seq->at(1)->asSequence());
80 18
        if (!$algo instanceof SignatureAlgorithmIdentifier) {
81 1
            throw new \UnexpectedValueException(
82 1
                'Unsupported signature algorithm ' . $algo->oid() . '.');
83
        }
84 17
        $signature = Signature::fromSignatureData(
85 17
            $seq->at(2)->asBitString()->string(), $algo);
86 17
        return new self($tbsCert, $algo, $signature);
87
    }
88
89
    /**
90
     * Initialize from DER.
91
     *
92
     * @param string $data
93
     *
94
     * @return self
95
     */
96 16
    public static function fromDER(string $data): self
97
    {
98 16
        return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence());
99
    }
100
101
    /**
102
     * Initialize from PEM.
103
     *
104
     * @param PEM $pem
105
     *
106
     * @throws \UnexpectedValueException
107
     *
108
     * @return self
109
     */
110 17
    public static function fromPEM(PEM $pem): self
111
    {
112 17
        if (PEM::TYPE_CERTIFICATE != $pem->type()) {
113 1
            throw new \UnexpectedValueException('Invalid PEM type.');
114
        }
115 16
        return self::fromDER($pem->data());
116
    }
117
118
    /**
119
     * Get certificate information.
120
     *
121
     * @return TBSCertificate
122
     */
123 88
    public function tbsCertificate(): TBSCertificate
124
    {
125 88
        return $this->_tbsCertificate;
126
    }
127
128
    /**
129
     * Get signature algorithm.
130
     *
131
     * @return SignatureAlgorithmIdentifier
132
     */
133 49
    public function signatureAlgorithm(): SignatureAlgorithmIdentifier
134
    {
135 49
        return $this->_signatureAlgorithm;
136
    }
137
138
    /**
139
     * Get signature value.
140
     *
141
     * @return Signature
142
     */
143 2
    public function signatureValue(): Signature
144
    {
145 2
        return $this->_signatureValue;
146
    }
147
148
    /**
149
     * Check whether certificate is self-issued.
150
     *
151
     * @return bool
152
     */
153 48
    public function isSelfIssued(): bool
154
    {
155 48
        return $this->_tbsCertificate->subject()->equals(
156 48
            $this->_tbsCertificate->issuer());
157
    }
158
159
    /**
160
     * Check whether certificate is semantically equal to another.
161
     *
162
     * @param Certificate $cert Certificate to compare to
163
     *
164
     * @return bool
165
     */
166 17
    public function equals(Certificate $cert): bool
167
    {
168 17
        return $this->_hasEqualSerialNumber($cert) &&
169 17
             $this->_hasEqualPublicKey($cert) && $this->_hasEqualSubject($cert);
170
    }
171
172
    /**
173
     * Generate ASN.1 structure.
174
     *
175
     * @return Sequence
176
     */
177 5
    public function toASN1(): Sequence
178
    {
179 5
        return new Sequence($this->_tbsCertificate->toASN1(),
180 5
            $this->_signatureAlgorithm->toASN1(),
181 5
            $this->_signatureValue->bitString());
182
    }
183
184
    /**
185
     * Get certificate as a DER.
186
     *
187
     * @return string
188
     */
189 3
    public function toDER(): string
190
    {
191 3
        return $this->toASN1()->toDER();
192
    }
193
194
    /**
195
     * Get certificate as a PEM.
196
     *
197
     * @return PEM
198
     */
199 3
    public function toPEM(): PEM
200
    {
201 3
        return new PEM(PEM::TYPE_CERTIFICATE, $this->toDER());
202
    }
203
204
    /**
205
     * Verify certificate signature.
206
     *
207
     * @param PublicKeyInfo $pubkey_info Issuer's public key
208
     * @param null|Crypto   $crypto      Crypto engine, use default if not set
209
     *
210
     * @return bool True if certificate signature is valid
211
     */
212 44
    public function verify(PublicKeyInfo $pubkey_info, ?Crypto $crypto = null): bool
213
    {
214 44
        $crypto = $crypto ?? Crypto::getDefault();
215 44
        $data = $this->_tbsCertificate->toASN1()->toDER();
216 44
        return $crypto->verify($data, $this->_signatureValue, $pubkey_info,
217 44
            $this->_signatureAlgorithm);
218
    }
219
220
    /**
221
     * Check whether certificate has serial number equal to another.
222
     *
223
     * @param Certificate $cert
224
     *
225
     * @return bool
226
     */
227 17
    private function _hasEqualSerialNumber(Certificate $cert): bool
228
    {
229 17
        $sn1 = $this->_tbsCertificate->serialNumber();
230 17
        $sn2 = $cert->_tbsCertificate->serialNumber();
231 17
        return $sn1 == $sn2;
232
    }
233
234
    /**
235
     * Check whether certificate has public key equal to another.
236
     *
237
     * @param Certificate $cert
238
     *
239
     * @return bool
240
     */
241 16
    private function _hasEqualPublicKey(Certificate $cert): bool
242
    {
243 16
        $kid1 = $this->_tbsCertificate->subjectPublicKeyInfo()->keyIdentifier();
244 16
        $kid2 = $cert->_tbsCertificate->subjectPublicKeyInfo()->keyIdentifier();
245 16
        return $kid1 == $kid2;
246
    }
247
248
    /**
249
     * Check whether certificate has subject equal to another.
250
     *
251
     * @param Certificate $cert
252
     *
253
     * @return bool
254
     */
255 7
    private function _hasEqualSubject(Certificate $cert): bool
256
    {
257 7
        $dn1 = $this->_tbsCertificate->subject();
258 7
        $dn2 = $cert->_tbsCertificate->subject();
259 7
        return $dn1->equals($dn2);
260
    }
261
}
262