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
Pull Request — master (#117)
by
unknown
01:06
created

SslCertificate::createForCertificateString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\SslCertificate;
4
5
use Carbon\Carbon;
6
use Spatie\Macroable\Macroable;
7
8
class SslCertificate
9
{
10
    use Macroable;
11
12
    /** @var array */
13
    protected $rawCertificateFields = [];
14
15
    /** @var string */
16
    protected $fingerprint = '';
17
18
    /** @var string */
19
    private $fingerprintSha256 = '';
20
21
    /** @var string */
22
    private $remoteAddress = '';
23
24
    public static function download(): Downloader
25
    {
26
        return new Downloader();
27
    }
28
29
    public static function createForHostName(string $url, int $timeout = 30): self
30
    {
31
        return Downloader::downloadCertificateFromUrl($url, $timeout);
32
    }
33
34
    public static function createForCertificateString(string $certificateString): self
35
    {
36
        return Local::certificateAsString($certificateString);
37
    }
38
39
    public function __construct(
40
        array $rawCertificateFields,
41
        string $fingerprint = '',
42
        string $fingerprintSha256 = '',
43
        string $remoteAddress = '')
44
    {
45
        $this->rawCertificateFields = $rawCertificateFields;
46
47
        $this->fingerprint = $fingerprint;
48
49
        $this->fingerprintSha256 = $fingerprintSha256;
50
51
        $this->remoteAddress = $remoteAddress;
52
    }
53
54
    public function getRawCertificateFields(): array
55
    {
56
        return $this->rawCertificateFields;
57
    }
58
59
    public function getIssuer(): string
60
    {
61
        return $this->rawCertificateFields['issuer']['CN'] ?? '';
62
    }
63
64
    public function getDomain(): string
65
    {
66
        if (! array_key_exists('CN', $this->rawCertificateFields['subject'])) {
67
            return '';
68
        }
69
70
        if (is_string($this->rawCertificateFields['subject']['CN'])) {
71
            return $this->rawCertificateFields['subject']['CN'];
72
        }
73
74
        if (is_array($this->rawCertificateFields['subject']['CN'])) {
75
            return $this->rawCertificateFields['subject']['CN'][0];
76
        }
77
78
        return '';
79
    }
80
81
    public function getSignatureAlgorithm(): string
82
    {
83
        return $this->rawCertificateFields['signatureTypeSN'] ?? '';
84
    }
85
86
    public function getFingerprint(): string
87
    {
88
        return $this->fingerprint;
89
    }
90
91
    /**
92
     * @return string
93
     */
94
    public function getFingerprintSha256(): string
95
    {
96
        return $this->fingerprintSha256;
97
    }
98
99
    public function getAdditionalDomains(): array
100
    {
101
        $additionalDomains = explode(', ', $this->rawCertificateFields['extensions']['subjectAltName'] ?? '');
102
103
        return array_map(function (string $domain) {
104
            return str_replace('DNS:', '', $domain);
105
        }, $additionalDomains);
106
    }
107
108
    public function validFromDate(): Carbon
109
    {
110
        return Carbon::createFromTimestampUTC($this->rawCertificateFields['validFrom_time_t']);
111
    }
112
113
    public function expirationDate(): Carbon
114
    {
115
        return Carbon::createFromTimestampUTC($this->rawCertificateFields['validTo_time_t']);
116
    }
117
118
    public function isExpired(): bool
119
    {
120
        return $this->expirationDate()->isPast();
121
    }
122
123
    public function isValid(string $url = null)
124
    {
125
        if (! Carbon::now()->between($this->validFromDate(), $this->expirationDate())) {
126
            return false;
127
        }
128
129
        if (! empty($url)) {
130
            return $this->appliesToUrl($url ?? $this->getDomain());
131
        }
132
133
        return true;
134
    }
135
136
    public function isSelfSigned(): bool
137
    {
138
        return $this->getIssuer() === $this->getDomain();
139
    }
140
141
    public function usesSha1Hash(): bool
142
    {
143
        $certificateFields = $this->getRawCertificateFields();
144
145
        if ($certificateFields['signatureTypeSN'] === 'RSA-SHA1') {
146
            return true;
147
        }
148
149
        if ($certificateFields['signatureTypeLN'] === 'sha1WithRSAEncryption') {
150
            return true;
151
        }
152
153
        return false;
154
    }
155
156
    public function isValidUntil(Carbon $carbon, string $url = null): bool
157
    {
158
        if ($this->expirationDate()->lte($carbon)) {
159
            return false;
160
        }
161
162
        return $this->isValid($url);
163
    }
164
165
    public function daysUntilExpirationDate(): int
166
    {
167
        $endDate = $this->expirationDate();
168
169
        $interval = Carbon::now()->diff($endDate);
170
171
        return (int) $interval->format('%r%a');
172
    }
173
174
    public function getDomains(): array
175
    {
176
        $allDomains = $this->getAdditionalDomains();
177
        $allDomains[] = $this->getDomain();
178
        $uniqueDomains = array_unique($allDomains);
179
180
        return array_values(array_filter($uniqueDomains));
181
    }
182
183
    public function appliesToUrl(string $url): bool
184
    {
185
        if (filter_var($url, FILTER_VALIDATE_IP)) {
186
            $host = $url;
187
        } else {
188
            $host = (new Url($url))->getHostName();
189
        }
190
191
        $certificateHosts = $this->getDomains();
192
193
        foreach ($certificateHosts as $certificateHost) {
194
            $certificateHost = str_replace('ip address:', '', strtolower($certificateHost));
195
            if ($host === $certificateHost) {
196
                return true;
197
            }
198
199
            if ($this->wildcardHostCoversHost($certificateHost, $host)) {
200
                return true;
201
            }
202
        }
203
204
        return false;
205
    }
206
207
    protected function wildcardHostCoversHost(string $wildcardHost, string $host): bool
208
    {
209
        if ($host === $wildcardHost) {
210
            return true;
211
        }
212
213
        if (! starts_with($wildcardHost, '*')) {
214
            return false;
215
        }
216
217
        if (substr_count($wildcardHost, '.') < substr_count($host, '.')) {
218
            return false;
219
        }
220
221
        $wildcardHostWithoutWildcard = substr($wildcardHost, 1);
222
223
        $hostWithDottedPrefix = ".{$host}";
224
225
        return ends_with($hostWithDottedPrefix, $wildcardHostWithoutWildcard);
226
    }
227
228
    public function getRawCertificateFieldsJson(): string
229
    {
230
        return json_encode($this->getRawCertificateFields());
231
    }
232
233
    public function getHash(): string
234
    {
235
        return md5($this->getRawCertificateFieldsJson());
236
    }
237
238
    public function getRemoteAddress(): string
239
    {
240
        return $this->remoteAddress;
241
    }
242
243
    public function __toString(): string
244
    {
245
        return $this->getRawCertificateFieldsJson();
246
    }
247
248
    public function containsDomain(string $domain): bool
249
    {
250
        $certificateHosts = $this->getDomains();
251
252
        foreach ($certificateHosts as $certificateHost) {
253
            if ($certificateHost == $domain) {
254
                return true;
255
            }
256
257
            if (ends_with($domain, '.'.$certificateHost)) {
258
                return true;
259
            }
260
        }
261
262
        return false;
263
    }
264
265
    public function isPreCertificate(): bool
266
    {
267
        if (! array_key_exists('extensions', $this->rawCertificateFields)) {
268
            return false;
269
        }
270
271
        if (! array_key_exists('ct_precert_poison', $this->rawCertificateFields['extensions'])) {
272
            return false;
273
        }
274
275
        return true;
276
    }
277
}
278