Completed
Push — master ( 3f4b39...daa8e9 )
by Kirill
10:57
created

HasSignature   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 80
rs 10
c 0
b 0
f 0
wmc 5
lcom 1
cbo 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A digest() 0 6 1
A getSerialNumber() 0 6 1
B sign() 0 25 2
A getFilename() 0 4 1
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 message digest by GOST Р 34.11-94.
19
     *
20
     * @param array $values List arguments
21
     *
22
     * @return string
23
     */
24
    private function digest(array $values): string
25
    {
26
        ksort($values);
27
28
        return hash('gost-crypto', implode('', $values), true);
29
    }
30
31
    /**
32
     * Get serial number of X509.
33
     *
34
     * @param  string  $path
35
     * @return string
36
     */
37
    private function getSerialNumber(string $path): string
38
    {
39
        $text = openssl_x509_parse('file://'.realpath($path));
40
41
        return $text['serialNumber'];
42
    }
43
44
    /**
45
     * Calculate signature from digest message.
46
     *
47
     * @param array|string $message
48
     * @return string
49
     */
50
    private function sign($message): string
51
    {
52
        static $cmdLineSign = <<<'CMD'
53
openssl smime -sign -signer %signer% -engine gost -gost89 -binary -noattr -nocerts -outform DER -in %in% -out %out%
54
CMD;
55
        static $cmdLineAsn = 'openssl asn1parse -inform DER -in %in%';
56
57
        if (is_array($message)) {
58
            $message = $this->digest($message);
59
        }
60
61
        fwrite($_ = tmpfile(), $message);
62
63
        shell_exec(interpolate($cmdLineSign, [
64
            'in' => $this->getFilename($_),
65
            'out' => $this->getFilename($__ = tmpfile()),
66
            'signer' => $this->pemFile,
0 ignored issues
show
Bug introduced by
The property pemFile does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
67
        ]));
68
69
        $output = shell_exec(interpolate($cmdLineAsn, [
70
            'in' => $this->getFilename($__),
71
        ]));
72
73
        return hex2bin(trim(substr($output, -129)));
74
    }
75
76
    /**
77
     * Get file name from a file resource.
78
     *
79
     * @param resource $resource
80
     * @return string
81
     */
82
    private function getFilename($resource): string
83
    {
84
        return stream_get_meta_data($resource)['uri'];
85
    }
86
}
87