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 ( f72a3e...f130a4 )
by Freek
01:36
created

Certificate::convertPkcs72Pem()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 8.1155
c 0
b 0
f 0
cc 8
nc 6
nop 1
1
<?php
2
3
namespace Spatie\CertificateChain;
4
5
use phpseclib\File\ASN1;
6
use phpseclib\File\X509;
7
use Spatie\CertificateChain\Exceptions\CouldNotLoadCertificate;
8
use Spatie\CertificateChain\Exceptions\CouldNotCreateCertificate;
9
10
class Certificate
11
{
12
    /**
13
     * @param string
14
     */
15
    protected $contents;
16
17
    /**
18
     * @param string $inputFile
19
     *
20
     * @return static
21
     */
22
    public static function loadFromFile(string $inputFile)
23
    {
24
        $contents = @file_get_contents($inputFile);
25
26
        if ($contents === false) {
27
            throw CouldNotLoadCertificate::cannotGetContents($inputFile);
28
        }
29
30
        return new static($contents);
31
    }
32
33
    /**
34
     * @param string $url
35
     *
36
     * @return static
37
     */
38
    public static function loadFromUrl(string $url)
39
    {
40
        return static::loadFromFile($url);
41
    }
42
43
    public function __construct(string $contents)
44
    {
45
        $certificate = $contents;
46
47
        // If we are missing the pem certificate header, try to convert it to a pem format first
48
        if (! empty($contents) && strpos($contents, '-----BEGIN CERTIFICATE-----') === false) {
49
            // Extract from either a PKCS#7 format or DER formatted contents
50
            $certificate = self::convertPkcs72Pem($contents) ?? self::convertDer2Pem($contents);
51
        }
52
53
        $this->guardAgainstInvalidContents($certificate, $contents);
54
55
        $this->contents = $certificate;
56
    }
57
58
    /**
59
     * Get the URL of the parent certificate.
60
     */
61
    public function getParentCertificateUrl(): string
62
    {
63
        $x509 = new X509();
64
65
        $certProperties = $x509->loadX509($this->contents);
66
67
        if (empty($certProperties['tbsCertificate']['extensions'])) {
68
            return '';
69
        }
70
71
        foreach ($certProperties['tbsCertificate']['extensions'] as $extension) {
72
            if ($extension['extnId'] == 'id-pe-authorityInfoAccess') {
73
                foreach ($extension['extnValue'] as $extnValue) {
74
                    if ($extnValue['accessMethod'] == 'id-ad-caIssuers') {
75
                        return $extnValue['accessLocation']['uniformResourceIdentifier'];
76
                    }
77
                }
78
            }
79
        }
80
81
        return '';
82
    }
83
84
    public function fetchParentCertificate(): self
85
    {
86
        return static::loadFromUrl($this->getParentCertificateUrl());
87
    }
88
89
    public function hasParentInTrustChain(): bool
90
    {
91
        return ! $this->getParentCertificateUrl() == '';
92
    }
93
94
    public function getContents(): string
95
    {
96
        $x509 = new X509();
97
98
        return $x509->saveX509($x509->loadX509($this->contents)).PHP_EOL;
99
    }
100
101
    protected function guardAgainstInvalidContents(string $content, string $original)
102
    {
103
        if (! (new X509())->loadX509($content)) {
104
            throw CouldNotCreateCertificate::invalidContent($original);
105
        }
106
    }
107
108
    protected function convertPkcs72Pem(string $pkcs7)
109
    {
110
        $asn = new ASN1();
111
        $decoded = $asn->decodeBER($pkcs7);
112
        $data = $decoded[0]['content'] ?? [];
113
114
        // Make sure we are dealing with actual data
115
        if (empty($data)) {
116
            return;
117
        }
118
119
        // Make sure this is an PKCS#7 signedData object
120
        if ($data[0]['type'] === ASN1::TYPE_OBJECT_IDENTIFIER && $data[0]['content'] === '1.2.840.113549.1.7.2') {
121
            // Loop over all the content in the signedData object
122
            foreach ($data[1]['content'] as $pkcs7SignedData) {
123
                // Find all sequences of data
124
                if ($pkcs7SignedData['type'] === ASN1::TYPE_SEQUENCE) {
125
                    // Extract the sequence identifier if possible
126
                    $identifier = $pkcs7SignedData['content'][2] ?? '';
127
128
                    // Make sure the sequence is a PKCS#7 data object we are dealing with
129
                    if ($identifier['type'] === ASN1::TYPE_SEQUENCE && $identifier['content'][0]['content'] === '1.2.840.113549.1.7.1') {
130
                        // Extract the certificate data
131
                        $certificate = $pkcs7SignedData['content'][3];
132
133
                        // Extract the raw certificate data from the PKCS#7 string
134
                        $rawCert = substr($pkcs7, $certificate['start'] + $certificate['headerlength'], $certificate['length'] - $certificate['headerlength']);
135
136
                        // Return the PEM encoded certificate
137
                        return $this->convertDer2Pem($rawCert);
138
                    }
139
                }
140
            }
141
        }
142
    }
143
144
    protected function convertDer2Pem(string $der_data, $type = 'CERTIFICATE'): string
145
    {
146
        $pem = chunk_split(base64_encode($der_data), 64, "\n");
147
148
        return "-----BEGIN {$type}-----\n{$pem}-----END {$type}-----\n";
149
    }
150
}
151