1 | <?php |
||
2 | |||
3 | namespace Ocsp; |
||
4 | |||
5 | use Ocsp\Asn1\Der\Decoder as DerDecoder; |
||
6 | use Ocsp\Asn1\Element\Sequence; |
||
7 | use Ocsp\Exception\Asn1DecodingException; |
||
8 | |||
9 | /** |
||
10 | * Class to load and decode certificates in PEM (text) / DER (binary) formats. |
||
11 | */ |
||
12 | class CertificateLoader |
||
13 | { |
||
14 | /** |
||
15 | * The decoder to be used to decode the loaded certificate. |
||
16 | * |
||
17 | * @var \Ocsp\Asn1\Der\Decoder |
||
18 | */ |
||
19 | private $derDecoder; |
||
20 | |||
21 | /** |
||
22 | * Initialize the instance. |
||
23 | */ |
||
24 | 3 | public function __construct() |
|
25 | { |
||
26 | 3 | $this->derDecoder = new DerDecoder(); |
|
27 | } |
||
28 | |||
29 | /** |
||
30 | * Load a certificate from a file. |
||
31 | * |
||
32 | * @param string $path |
||
33 | * |
||
34 | * @throws \Ocsp\Exception\Asn1DecodingException |
||
35 | * |
||
36 | * @return \Ocsp\Asn1\Element\Sequence |
||
37 | */ |
||
38 | 1 | public function fromFile($path) |
|
39 | { |
||
40 | 1 | if (!is_string($path) || !is_file($path)) { |
|
0 ignored issues
–
show
introduced
by
![]() |
|||
41 | throw Asn1DecodingException::create(sprintf('Unable to find the file %s', $path)); |
||
42 | } |
||
43 | 1 | if (!is_readable($path)) { |
|
44 | throw Asn1DecodingException::create(sprintf('The file %s is not readable', $path)); |
||
45 | } |
||
46 | 1 | $contents = @file_get_contents($path); |
|
47 | 1 | if ($contents === false) { |
|
48 | throw Asn1DecodingException::create(sprintf('Unable to read the file %s', $path)); |
||
49 | } |
||
50 | |||
51 | 1 | return $this->fromString($contents); |
|
52 | } |
||
53 | |||
54 | /** |
||
55 | * Load a certificate from a string. |
||
56 | * |
||
57 | * @param string $data |
||
58 | * |
||
59 | * @throws \Ocsp\Exception\Asn1DecodingException |
||
60 | * |
||
61 | * @return \Ocsp\Asn1\Element\Sequence |
||
62 | */ |
||
63 | 3 | public function fromString($data) |
|
64 | { |
||
65 | 3 | $data = (string) $data; |
|
66 | 3 | if ($data === '') { |
|
67 | throw Asn1DecodingException::create('Empty certificate'); |
||
68 | } |
||
69 | 3 | $data = $this->ensureDer($data); |
|
70 | 3 | $certificate = $this->derDecoder->decodeElement($data); |
|
71 | 3 | if (!$certificate instanceof Sequence) { |
|
72 | throw Asn1DecodingException::create(); |
||
73 | } |
||
74 | |||
75 | 3 | return $certificate; |
|
76 | } |
||
77 | |||
78 | /** |
||
79 | * Convert (if necessary) a PEM-encoded certificate to DER format. |
||
80 | * Code from phpseclib, by TerraFrost and other phpseclib contributors (see https://github.com/phpseclib/phpseclib). |
||
81 | * |
||
82 | * @param string $data |
||
83 | * |
||
84 | * @return string |
||
85 | */ |
||
86 | 3 | protected function ensureDer($data) |
|
87 | { |
||
88 | 3 | $temp = preg_replace('/.*?^-+[^-]+-+[\r\n ]*$/ms', '', $data, 1); |
|
89 | 3 | $temp = preg_replace('/-+[^-]+-+/', '', $temp); |
|
90 | 3 | $temp = str_replace(["\r", "\n", ' '], '', $temp); |
|
91 | 3 | $temp = preg_match('/^[a-zA-Z\d\/+]*={0,2}$/', $temp) ? @base64_decode($temp, true) : false; |
|
92 | |||
93 | 3 | return $temp ?: $data; |
|
94 | } |
||
95 | } |
||
96 |