Completed
Pull Request — master (#24)
by
unknown
03:06
created

testWSESignatureWithPrivateKeyPassword()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php declare(strict_types = 1);
2
3
namespace SlevomatEET\Cryptography;
4
5
use SlevomatEET\Formatter;
6
7
class CryptographyServiceTest extends \PHPUnit\Framework\TestCase
8
{
9
10
	const EXPECTED_PKP = 'a0asEiJhFCBlVtptSspKvEZhcrvnzF7SQ55C4DhnStnSu1b37GUI2+Dlme9P94UCPZ1oCUPJdsYOBZ3IX6aEgEe0FJKXYX0kXraYCJKIo3g64wRchE7iblIOBCK1uHh8qqHA66Isnhb6hqBOOdlt2aWO/0jCzlfeQr0axpPF1mohMnP3h3ICaxZh0dnMdju5OmMrq+91PL5T9KkR7bfGHqAoWJ0kmxY/mZumtRfGil2/xf7I5pdVeYXPgDO/Tojzm6J95n68fPDOXTDrTzKYmqDjpg3kmWepLNQKFXRmkQrkBLToJWG1LDUDm3UTTmPWzq4c0XnGcXJDZglxfolGpA==';
11
	const EXPECTED_BKP = '9356D566-A3E48838-FB403790-D201244E-95DCBD92';
12
	const PRIVATE_KEY_WITHOUT_PASSWORD_PATH = __DIR__ . '/../../../cert/EET_CA1_Playground-CZ00000019.key';
13
	const PRIVATE_KEY_WITH_PASSWORD_PATH = __DIR__ . '/../../../cert/EET_CA1_Playground_With_Password-CZ00000019.key';
14
	const PUBLIC_KEY_PATH = __DIR__ . '/../../../cert/EET_CA1_Playground-CZ00000019.pub';
15
	const INVALID_KEY_PATH = __DIR__ . '/invalid-certificate.pem';
16
17
	public function testGetCodes()
18
	{
19
		$data = $this->getReceiptData();
20
		$crypto = $this->createCryptographyServiceWithoutPassword();
21
22
		$expectedPkp = base64_decode(self::EXPECTED_PKP);
23
		$pkpCode = $crypto->getPkpCode($data);
24
		self::assertSame($expectedPkp, $pkpCode);
25
		self::assertSame(self::EXPECTED_BKP, $crypto->getBkpCode($pkpCode));
26
	}
27
28
	/**
29
	 * @dataProvider provideInvalidKeyPaths
30
	 */
31
	public function testInvalidKeyPaths(string $privateKeyPath, string $publicKeyPath, string $expectedExceptionType)
32
	{
33
		try {
34
			new CryptographyService($privateKeyPath, $publicKeyPath);
35
			$this->fail('Exception ' . $expectedExceptionType . ' expected');
36
		} catch (\PHPUnit\Framework\AssertionFailedError $exception) {
37
			throw $exception;
38
		} catch (\Throwable $exception) {
39
			$this->assertInstanceOf($expectedExceptionType, $exception);
40
		}
41
	}
42
43
	/**
44
	 * @return array[]
45
	 */
46
	public function provideInvalidKeyPaths(): array
47
	{
48
		return [
49
			[self::PRIVATE_KEY_WITHOUT_PASSWORD_PATH, './foo/path', PublicKeyFileNotFoundException::class],
50
			['./foo/path', self::PUBLIC_KEY_PATH, PrivateKeyFileNotFoundException::class],
51
		];
52
	}
53
54
	public function testInvalidPrivateKeyInPkpCalculation()
55
	{
56
		$cryptoService = new CryptographyService(
57
			self::INVALID_KEY_PATH,
58
			self::PUBLIC_KEY_PATH
59
		);
60
61
		try {
62
			$cryptoService->getPkpCode($this->getReceiptData());
63
			$this->fail();
64
65
		} catch (PrivateKeyFileException $e) {
66
			$this->assertSame(self::INVALID_KEY_PATH, $e->getPrivateKeyFile());
67
		}
68
	}
69
70
	/**
71
	 * @runInSeparateProcess
72
	 */
73
	public function testExceptions2()
74
	{
75
		include __DIR__ . '/OpenSslFunctionsMock.php';
76
77
		$cryptoService = $cryptoService = $this->createCryptographyServiceWithoutPassword();
78
79
		try {
80
			$cryptoService->getPkpCode($this->getReceiptData());
81
			$this->fail();
82
83
		} catch (SigningFailedException $e) {
84
			$this->assertSame(array_values($this->getReceiptData()), $e->getData());
85
		}
86
	}
87
88
	public function testWSESignatureWithoutPrivateKeyPassword()
89
	{
90
		$request = $this->getRequestData();
91
		$crypto = $this->createCryptographyServiceWithoutPassword();
92
93
		$this->assertNotEmpty($crypto->addWSESignature($request));
94
	}
95
96
	public function testWSESignatureWithPrivateKeyPassword()
97
	{
98
		$request = $this->getRequestData();
99
		$crypto = $this->createCryptographyServiceWithPassword('eet');
100
101
		$this->assertNotEmpty($crypto->addWSESignature($request));
102
	}
103
104
	public function testWSESignatureWithInvalidPrivateKeyPassword()
105
	{
106
		$request = $this->getRequestData();
107
		$crypto = $this->createCryptographyServiceWithPassword('invalid');
108
109
		$this->expectException(\PHPUnit\Framework\Error\Error::class);
110
		$this->expectExceptionMessage('openssl_sign(): supplied key param cannot be coerced into a private key');
111
		$crypto->addWSESignature($request);
112
	}
113
114
	public function testWSESignatureWithInvalidPublicKey()
115
	{
116
		$request = $this->getRequestData();
117
		$crypto = $cryptoService = new CryptographyService(
0 ignored issues
show
Unused Code introduced by
$cryptoService is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
118
			self::PRIVATE_KEY_WITHOUT_PASSWORD_PATH,
119
			self::INVALID_KEY_PATH
120
		);
121
122
		$this->expectException(PublicKeyFileException::class);
123
		$this->expectExceptionMessage('Public key could not be loaded from file \'/var/www/eet-client/tests/SlevomatEET/Cryptography/invalid-certificate.pem');
124
		$crypto->addWSESignature($request);
125
	}
126
127
	private function getReceiptData(): array
128
	{
129
		return [
130
			'dic_popl' => 'CZ00000019',
131
			'id_provoz' => '273',
132
			'id_pokl' => '/5546/RO24',
133
			'porad_cis' => '0/6460/ZQ42',
134
			'dat_trzby' => Formatter::formatDateTime(new \DateTimeImmutable('2016-08-05 00:30:12', new \DateTimeZone('Europe/Prague'))),
135
			'celk_trzba' => Formatter::formatAmount(3411300),
136
		];
137
	}
138
139
	private function getRequestData(): string
140
	{
141
		$requestTemplate = file_get_contents(__DIR__ . '/CZ00000019.fixture.3.1.xml');
142
143
		$data = $this->getReceiptData();
144
		$data += [
145
			'pkp' => self::EXPECTED_PKP,
146
			'bkp' => self::EXPECTED_BKP,
147
		];
148
149
		$patterns = array_map(function (string $dataKey): string {
150
			return sprintf('~{%s}~', $dataKey);
151
		}, array_keys($data));
152
		$replacements = array_values($data);
153
154
		$request = preg_replace($patterns, $replacements, $requestTemplate);
155
156
		return $request;
157
	}
158
159
	private function createCryptographyServiceWithoutPassword(): CryptographyService
160
	{
161
		return new CryptographyService(self::PRIVATE_KEY_WITHOUT_PASSWORD_PATH, self::PUBLIC_KEY_PATH);
162
	}
163
164
	private function createCryptographyServiceWithPassword(string $password): CryptographyService
165
	{
166
		return new CryptographyService(
167
			self::PRIVATE_KEY_WITH_PASSWORD_PATH,
168
			self::PUBLIC_KEY_PATH,
169
			$password
170
		);
171
	}
172
173
}
174