1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace SimpleSAML\XMLSecurity\Test\Alg\Signature; |
6
|
|
|
|
7
|
|
|
use PHPUnit\Framework\TestCase; |
8
|
|
|
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory; |
9
|
|
|
use SimpleSAML\XMLSecurity\Constants as C; |
10
|
|
|
use SimpleSAML\XMLSecurity\Key\PrivateKey; |
11
|
|
|
use SimpleSAML\XMLSecurity\Key\PublicKey; |
12
|
|
|
use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; |
13
|
|
|
|
14
|
|
|
use function bin2hex; |
15
|
|
|
use function hex2bin; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Tests for SimpleSAML\XMLSecurity\Alg\Signature\RSA. |
19
|
|
|
* |
20
|
|
|
* @package SimpleSAML\XMLSecurity\Alg |
21
|
|
|
*/ |
22
|
|
|
final class RSASignatureTest extends TestCase |
23
|
|
|
{ |
24
|
|
|
/** @var string */ |
25
|
|
|
protected const PLAINTEXT = 'plaintext'; |
26
|
|
|
|
27
|
|
|
/** @var \SimpleSAML\XMLSecurity\Key\PrivateKey */ |
28
|
|
|
protected static PrivateKey $privateKey; |
29
|
|
|
|
30
|
|
|
/** @var \SimpleSAML\XMLSecurity\Key\PublicKey */ |
31
|
|
|
protected static PublicKey $publicKey; |
32
|
|
|
|
33
|
|
|
/** @var \SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory */ |
34
|
|
|
protected static SignatureAlgorithmFactory $factory; |
35
|
|
|
|
36
|
|
|
|
37
|
|
|
public static function setUpBeforeClass(): void |
38
|
|
|
{ |
39
|
|
|
self::$publicKey = PEMCertificatesMock::getPublicKey(PEMCertificatesMock::PUBLIC_KEY); |
40
|
|
|
self::$privateKey = PEMCertificatesMock::getPrivateKey(PEMCertificatesMock::PRIVATE_KEY); |
41
|
|
|
self::$factory = new SignatureAlgorithmFactory([]); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Test RSA signing. |
47
|
|
|
*/ |
48
|
|
|
public function testSign(): void |
49
|
|
|
{ |
50
|
|
|
// test RSA-SHA1 |
51
|
|
|
if (boolval(OPENSSL_VERSION_NUMBER >= hexdec('0x30000000')) === false) { |
52
|
|
|
// OpenSSL 3.0 disabled SHA1 support |
53
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA1, self::$privateKey); |
54
|
|
|
$this->assertEquals( |
55
|
|
|
'75780000a403f4280d361c246a1c23e650d59c8cabbe4064e1848bace35ba8931a7c397caacf8af36c10ead3bed5252109a' . |
56
|
|
|
'3c12a54b3f867950ae75ea29864babef465eabdda826d81c367583725012dfa68a1b51119425e3e6e9490c778db81b5be93' . |
57
|
|
|
'7ae35f4b1393944b7260d4ebd3c100bf59ae42d4506c82cae6550d68b8', |
58
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
59
|
|
|
); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
// test RSA-SHA224 |
63
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA224, self::$privateKey); |
64
|
|
|
$this->assertEquals( |
65
|
|
|
'9f4bda98aefef8d289595e24663c02108d5273208eb9e530a5a2518082b9e357146517cb630dbaba5f9db7ac297e8b9b1b9248b' . |
66
|
|
|
'c4b2fbdf009450f4a0759080055b8d3b944d1781fcb03b1fe5039d59a293c54a3e5e8288ecfab9c3a3127f22816753e4aae835d' . |
67
|
|
|
'e395d52f30768d1d5003e3b124272e89a401909d34c24b9b8f', |
68
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
69
|
|
|
); |
70
|
|
|
|
71
|
|
|
// test RSA-SHA256 |
72
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA256, self::$privateKey); |
73
|
|
|
$this->assertEquals( |
74
|
|
|
'397f0972d3d52b354298e8f1803efe6b6a77c2213605ab88ff3a38a336e14673c59f69103c1377c5ddf8f9314409ecd865f48b5' . |
75
|
|
|
'63af2e9ad31121846b0f565fa01898d9ab438ea5278734200400e62cc2bdd31ba86c7b98f8c51dbb22241fbe0535fe2291e9421' . |
76
|
|
|
'5450ca7fbe4cc8d18420cacce720ac39e09397019c67b8bb2e', |
77
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
78
|
|
|
); |
79
|
|
|
|
80
|
|
|
// test RSA-SHA384 |
81
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA384, self::$privateKey); |
82
|
|
|
$this->assertEquals( |
83
|
|
|
'6f281ee29c08fa72aaf4f01b095f004608ed82351a160db91933f24118837d43864449862a60eda305d68169a7af12ebe1055b8' . |
84
|
|
|
'1e5e6a5effca3fd26f0f0db879d83c28a2ef833c021f1b523be2e6947749dbd7daf2d405e341858e95293c724244fc36fccfc05' . |
85
|
|
|
'27ce1d33e4ff9152e8fbe71eafa0867d076315cb8eb41a5fe5', |
86
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
87
|
|
|
); |
88
|
|
|
|
89
|
|
|
// test RSA-SHA512 |
90
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA512, self::$privateKey); |
91
|
|
|
$this->assertEquals( |
92
|
|
|
'ce7c0840a26d6bb15e2d386aef8338fff631ca4f1fda22d21b19ee928ed87c7de9ea94f546bcace5dc8cd640a164667686cf836' . |
93
|
|
|
'bbcbce0f5bbd7c33d9e4262499a8c5c7d8159d090dd4c02fc49eab7e4522ba46258e50ee3278792bba13321780c64980fdd5034' . |
94
|
|
|
'f79285c07c5f765637950877feb03f94420799bb67b7b9a2ac', |
95
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
96
|
|
|
); |
97
|
|
|
|
98
|
|
|
// test RSA-RIPEMD160 |
99
|
|
|
if (boolval(OPENSSL_VERSION_NUMBER >= hexdec('0x30000000')) === false) { |
100
|
|
|
// OpenSSL 3.0 disabled RIPEMD160 support |
101
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_RIPEMD160, self::$privateKey); |
102
|
|
|
$this->assertEquals( |
103
|
|
|
'783d2c86bf73b02838be76f832fe1c75e03e9c3ad9055d19737a342c59385744b2332f65f1eac5f5dd0fb88ae7d145ac16d' . |
104
|
|
|
'3e83916a3be078e426a5ef5ed034a7f69f65ef5e62f6aecac9a896fa9edf473e482fd84ccc93c6677f146bf490af320ae41' . |
105
|
|
|
'f4a3fb0fa859e68c130a6d321ead6eb0167d1da24a49d97c030d3e8554', |
106
|
|
|
bin2hex($rsa->sign(self::PLAINTEXT)), |
107
|
|
|
); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Test RSA signature verification. |
114
|
|
|
*/ |
115
|
|
|
public function testVerify(): void |
116
|
|
|
{ |
117
|
|
|
// test RSA-SHA1 |
118
|
|
|
if (boolval(OPENSSL_VERSION_NUMBER >= hexdec('0x30000000')) === false) { |
119
|
|
|
// OpenSSL 3.0 disabled SHA1 support |
120
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA1, self::$publicKey); |
121
|
|
|
$this->assertTrue($rsa->verify( |
122
|
|
|
self::PLAINTEXT, |
123
|
|
|
hex2bin( |
124
|
|
|
'75780000a403f4280d361c246a1c23e650d59c8cabbe4064e1848bace35ba8931a7c397caacf8af36c10ead3bed5252' . |
125
|
|
|
'109a3c12a54b3f867950ae75ea29864babef465eabdda826d81c367583725012dfa68a1b51119425e3e6e9490c778db' . |
126
|
|
|
'81b5be937ae35f4b1393944b7260d4ebd3c100bf59ae42d4506c82cae6550d68b8', |
127
|
|
|
), |
128
|
|
|
)); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
// test RSA-SHA224 |
132
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA224, self::$publicKey); |
133
|
|
|
$this->assertTrue($rsa->verify( |
134
|
|
|
self::PLAINTEXT, |
135
|
|
|
hex2bin( |
136
|
|
|
'9f4bda98aefef8d289595e24663c02108d5273208eb9e530a5a2518082b9e357146517cb630dbaba5f9db7ac297e8b9b1b9' . |
137
|
|
|
'248bc4b2fbdf009450f4a0759080055b8d3b944d1781fcb03b1fe5039d59a293c54a3e5e8288ecfab9c3a3127f22816753e' . |
138
|
|
|
'4aae835de395d52f30768d1d5003e3b124272e89a401909d34c24b9b8f', |
139
|
|
|
), |
140
|
|
|
)); |
141
|
|
|
|
142
|
|
|
// test RSA-SHA256 |
143
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA256, self::$publicKey); |
144
|
|
|
$this->assertTrue($rsa->verify( |
145
|
|
|
self::PLAINTEXT, |
146
|
|
|
hex2bin( |
147
|
|
|
'397f0972d3d52b354298e8f1803efe6b6a77c2213605ab88ff3a38a336e14673c59f69103c1377c5ddf8f9314409ecd865f' . |
148
|
|
|
'48b563af2e9ad31121846b0f565fa01898d9ab438ea5278734200400e62cc2bdd31ba86c7b98f8c51dbb22241fbe0535fe2' . |
149
|
|
|
'291e94215450ca7fbe4cc8d18420cacce720ac39e09397019c67b8bb2e', |
150
|
|
|
), |
151
|
|
|
)); |
152
|
|
|
|
153
|
|
|
// test RSA-SHA384 |
154
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA384, self::$publicKey); |
155
|
|
|
$this->assertTrue($rsa->verify( |
156
|
|
|
self::PLAINTEXT, |
157
|
|
|
hex2bin( |
158
|
|
|
'6f281ee29c08fa72aaf4f01b095f004608ed82351a160db91933f24118837d43864449862a60eda305d68169a7af12ebe10' . |
159
|
|
|
'55b81e5e6a5effca3fd26f0f0db879d83c28a2ef833c021f1b523be2e6947749dbd7daf2d405e341858e95293c724244fc3' . |
160
|
|
|
'6fccfc0527ce1d33e4ff9152e8fbe71eafa0867d076315cb8eb41a5fe5', |
161
|
|
|
), |
162
|
|
|
)); |
163
|
|
|
|
164
|
|
|
// test RSA-SHA512 |
165
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA512, self::$publicKey); |
166
|
|
|
$this->assertTrue($rsa->verify( |
167
|
|
|
self::PLAINTEXT, |
168
|
|
|
hex2bin( |
169
|
|
|
'ce7c0840a26d6bb15e2d386aef8338fff631ca4f1fda22d21b19ee928ed87c7de9ea94f546bcace5dc8cd640a164667686c' . |
170
|
|
|
'f836bbcbce0f5bbd7c33d9e4262499a8c5c7d8159d090dd4c02fc49eab7e4522ba46258e50ee3278792bba13321780c6498' . |
171
|
|
|
'0fdd5034f79285c07c5f765637950877feb03f94420799bb67b7b9a2ac', |
172
|
|
|
), |
173
|
|
|
)); |
174
|
|
|
|
175
|
|
|
// test RSA-RIPEMD160 |
176
|
|
|
if (boolval(OPENSSL_VERSION_NUMBER >= hexdec('0x30000000')) === false) { |
177
|
|
|
// OpenSSL 3.0 disabled RIPEMD160 support |
178
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_RIPEMD160, self::$publicKey); |
179
|
|
|
$this->assertTrue($rsa->verify( |
180
|
|
|
self::PLAINTEXT, |
181
|
|
|
hex2bin( |
182
|
|
|
'783d2c86bf73b02838be76f832fe1c75e03e9c3ad9055d19737a342c59385744b2332f65f1eac5f5dd0fb88ae7d145a' . |
183
|
|
|
'c16d3e83916a3be078e426a5ef5ed034a7f69f65ef5e62f6aecac9a896fa9edf473e482fd84ccc93c6677f146bf490a' . |
184
|
|
|
'f320ae41f4a3fb0fa859e68c130a6d321ead6eb0167d1da24a49d97c030d3e8554', |
185
|
|
|
), |
186
|
|
|
)); |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Test that verification fails properly. |
193
|
|
|
*/ |
194
|
|
|
public function testVerificationFailure(): void |
195
|
|
|
{ |
196
|
|
|
// test wrong plaintext |
197
|
|
|
$rsa = self::$factory->getAlgorithm(C::SIG_RSA_SHA1, self::$publicKey); |
198
|
|
|
$this->assertFalse($rsa->verify( |
199
|
|
|
self::PLAINTEXT . '.', |
200
|
|
|
'002e8007f09d327b48a7393c9e3666c0d0d73a437804d6e71191bc227546d62351cda58173d69dd792c783337c4ed903a59' . |
201
|
|
|
'b6fdfd221a0dd22e8632e66c020e1c07400b02625fcdb3821495593e0e0a776a616a2cdf268b3070f7d02e78fdc531c0275' . |
202
|
|
|
'9ad1fc292ee2f77dcb8a0232cb32e8808c57cb592329d48168bc73936d468421a83446a429cd03bd82aa4a099c2585e0ee6' . |
203
|
|
|
'0e8afc9b7731d07b00ac8e9f8e7e8c0f526506520c717af5926395b49e6644015e166b462649f65a7d9728ce8872d3b6b02' . |
204
|
|
|
'19550b4944cb6286e1278908c516be2391928df8d81298e619d0a8711c58e79e5536d7c39fa1b1ffc81d96be6e1b733a824' . |
205
|
|
|
'8d5fee2866c7f6e48', |
206
|
|
|
)); |
207
|
|
|
|
208
|
|
|
// test wrong signature |
209
|
|
|
$this->assertFalse($rsa->verify( |
210
|
|
|
self::PLAINTEXT, |
211
|
|
|
'002e8007f09d327b48a7393c9e3666c0d0d73a437804d6e71191bc227546d62351cda58173d69dd792c783337c4ed903a59' . |
212
|
|
|
'b6fdfd221a0dd22e8632e66c020e1c07400b02625fcdb3821495593e0e0a776a616a2cdf268b3070f7d02e78fdc531c0275' . |
213
|
|
|
'9ad1fc292ee2f77dcb8a0232cb32e8808c57cb592329d48168bc73936d468421a83446a429cd03bd82aa4a099c2585e0ee6' . |
214
|
|
|
'0e8afc9b7731d07b00ac8e9f8e7e8c0f526506520c717af5926395b49e6644015e166b462649f65a7d9728ce8872d3b6b02' . |
215
|
|
|
'19550b4944cb6286e1278908c516be2391928df8d81298e619d0a8711c58e79e5536d7c39fa1b1ffc81d96be6e1b733a824' . |
216
|
|
|
'8d5fee2866c7f6e48', |
217
|
|
|
)); |
218
|
|
|
|
219
|
|
|
// test wrong key |
220
|
|
|
$rsa = self::$factory->getAlgorithm( |
221
|
|
|
C::SIG_RSA_SHA1, |
222
|
|
|
PEMCertificatesMock::getPublicKey(PEMCertificatesMock::OTHER_PUBLIC_KEY), |
223
|
|
|
); |
224
|
|
|
$this->assertFalse($rsa->verify( |
225
|
|
|
self::PLAINTEXT, |
226
|
|
|
'002e8007f09d327b48a7393c9e3666c0d0d73a437804d6e71191bc227546d62351cda58173d69dd792c783337c4ed903a59' . |
227
|
|
|
'b6fdfd221a0dd22e8632e66c020e1c07400b02625fcdb3821495593e0e0a776a616a2cdf268b3070f7d02e78fdc531c0275' . |
228
|
|
|
'9ad1fc292ee2f77dcb8a0232cb32e8808c57cb592329d48168bc73936d468421a83446a429cd03bd82aa4a099c2585e0ee6' . |
229
|
|
|
'0e8afc9b7731d07b00ac8e9f8e7e8c0f526506520c717af5926395b49e6644015e166b462649f65a7d9728ce8872d3b6b02' . |
230
|
|
|
'19550b4944cb6286e1278908c516be2391928df8d81298e619d0a8711c58e79e5536d7c39fa1b1ffc81d96be6e1b733a824' . |
231
|
|
|
'8d5fee2866c7f6e48', |
232
|
|
|
)); |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|