Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
66.67% covered (warning)
66.67%
2 / 3
CRAP
86.96% covered (warning)
86.96%
20 / 23
OpenSslProcessPkcs7Reader
0.00% covered (danger)
0.00%
0 / 1
66.67% covered (warning)
66.67%
2 / 3
7.11
86.96% covered (warning)
86.96%
20 / 23
 __construct
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 3
 readUnverified
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 readUsingOnlyTrustedCerts
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
15 / 15
1<?php
2
3namespace Proton\IosReceiptParser\ASN1;
4
5use Symfony\Component\Process\Process;
6
7final class OpenSslProcessPkcs7Reader implements Pkcs7Reader
8{
9    public function __construct()
10    {
11        if (!class_exists(Process::class)) {
12            throw new \RuntimeException('You need to install symfony/process to use ' . self::class);
13        }
14    }
15
16    public function readUnverified(string $ber): string
17    {
18        return (new Process([
19            'openssl',
20            'cms',
21            '-verify',
22           '-noverify',
23            // Openssl DER parsing is permissive enough to allow for BER input
24            '-inform', 'der',
25        ]))
26            ->setInput($ber)
27            ->mustRun()
28            ->getOutput();
29    }
30
31    public function readUsingOnlyTrustedCerts(string $ber, string ...$certificates): string
32    {
33        $args = [
34            'openssl',
35            'cms',
36            '-verify',
37            // Ignore whatever certificate was inside
38            '-nointern',
39            // Since we're supplying our own certificates (which are likely to be self-signed) and ignoring bundled,
40            // there is no need to verify the certificate's signatures
41            '-noverify',
42            // Openssl DER parsing is permissive enough to allow for BER input
43            '-inform', 'der',
44        ];
45
46        $tmpfiles = [];
47
48        foreach ($certificates as $certificate) {
49            if (strlen($certificate) > 255) {
50                $tmpfile = tempnam(sys_get_temp_dir(), 'cert');
51                file_put_contents($tmpfile, $certificate);
52
53                $tmpfiles[] = $certificate = $tmpfile;
54            }
55
56            $args[] = '-certfile';
57            $args[] = $certificate;
58        }
59
60        try {
61            return (new Process($args))
62                ->setInput($ber)
63                ->mustRun()
64                ->getOutput();
65        } finally {
66            foreach ($tmpfiles as $tmpfile) {
67                @unlink($tmpfile);
68            }
69        }
70    }
71}