Completed
Push — master ( daa8e9...6018cf )
by Kirill
12:53
created

HasSignature::getFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Personnage\Tinkoff\SDK\E2Card;
4
5
use function Personnage\Tinkoff\SDK\interpolate;
6
7
trait HasSignature
8
{
9
    private $cmdLineSign = <<<CMD
10
openssl smime -sign -signer %signer% -engine gost -gost89 -binary -noattr -nocerts -outform DER -in %in% -out %out%
11
CMD;
12
13
    private $cmdLineAsn = <<<CMD
14
openssl asn1parse -inform DER -in %in%
15
CMD;
16
17
    /**
18
     * Get path to X509 file.
19
     *
20
     * @return mixed
21
     */
22
    abstract public function getPemFile();
23
24
    /**
25
     * Get message digest by GOST Р 34.11-94.
26
     *
27
     * @param array $values List arguments
28
     *
29
     * @return string
30
     */
31
    private function digest(array $values): string
32
    {
33
        ksort($values);
34
35
        return hash('gost-crypto', implode('', $values), true);
36
    }
37
38
    /**
39
     * Get serial number of X509.
40
     *
41
     * @return string
42
     */
43
    private function getSerialNumber(): string
44
    {
45
        $text = openssl_x509_parse('file://'.$this->getPemFile());
46
47
        return $text['serialNumber'];
48
    }
49
50
    /**
51
     * Calculate signature from digest message.
52
     *
53
     * @param  array|string $message
54
     * @return string
55
     */
56
    private function sign($message): string
57
    {
58
        $filename = function ($resource): string {
59
            return stream_get_meta_data($resource)['uri'];
60
        };
61
62
        if (is_array($message)) {
63
            $message = $this->digest($message);
64
        }
65
66
        fwrite($_ = tmpfile(), $message);
67
68
        static $smime = <<<'CMD'
69
openssl smime -sign -signer %signer% -engine gost -gost89 -binary -noattr -nocerts -outform DER -in %in% -out %out%
70
CMD;
71
        shell_exec(interpolate($smime, [
72
            'in' => $filename($_),
73
            'out' => $filename($__ = tmpfile()),
74
            'signer' => $this->getPemFile(),
75
        ]));
76
77
        $output = shell_exec('openssl asn1parse -inform DER -in ' . $filename($__));
78
79
        return hex2bin(trim(substr($output, -129)));
80
    }
81
}
82