1616 * @coversDefaultClass \Activitypub\Signature
1717 */
1818class Test_Signature extends \WP_UnitTestCase {
19+
20+ /**
21+ * The public key in PKCS#1 format.
22+ *
23+ * @var string
24+ */
25+ private $ pkcs1_key = '-----BEGIN RSA PUBLIC KEY-----
26+ MIIBCgKCAQEAtAVnFFbWG+6NBFKhMZdt59Gx2/vKxWxbxOAYyi/ypZ/9aDY6C/UB
27+ Rei8SqnhKcKXQaiSwme/wpqgCdkrf53H85OioBitCEvKNA6uDxkCtcdgtQ3X55QD
28+ XmatWd32ln6elRmKG45U9R386j82OHzff8Ju65QxGL1LlyCKQ/XFx/pgvblF3cGj
29+ shk0dhNcyGAztODN5HFp9Qzf9d7+gi+xdKeGNhXBAulXoaDzx8FvLEXNfPJb3jUM
30+ 1Ug0STFsiICcf7VxmQow6N6d0+HtWxrdtjUBdXrPxz998Ns/cu9jjg06d+XV3TcS
31+ U+AOldmGLJuB/AWV/+F9c9DlczqmnXqd1QIDAQAB
32+ -----END RSA PUBLIC KEY-----
33+ ' ;
34+
35+ /**
36+ * The public key in X.509 format.
37+ *
38+ * @var string
39+ */
40+ private $ x509_key = '-----BEGIN PUBLIC KEY-----
41+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19218d19uYisOYUZ3oqN
42+ wSRyixAX8V1JHJSngbjAjZr1vYcwMte8CPqqELbNwtQWAMy42UnQpyIqgvLpOaVr
43+ vQWjUuR+7i8wETrVNJq8JQNNCiQ+8+I4TPcGyZDBclHkLtKiCoBtjUH0itVh4Sg0
44+ KQLSb8ZHu9lGh8TJMcLXVUdVkvkUjqHl6I5BoftMVDSKQF+V4X8Qyk7qP7wU8mpE
45+ +O6RuhUpZ3QXM+dBIalyey8NKLf2yN6CmKyW1220wdNupOYHbc8DSYEq6NDQZfZb
46+ yP2KLHN3rdNwsnlAP02Ws1qroBivHSV71KLebQUDU2KpDLKQF2Ix6X47IBFOXnb9
47+ FwIDAQAB
48+ -----END PUBLIC KEY-----
49+ ' ;
50+
51+ /**
52+ * The public key in EC format.
53+ *
54+ * @var string
55+ */
56+ private $ ec_key = '-----BEGIN PUBLIC KEY-----
57+ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/jw3kftaHGIB2OTKTYFUTTqyzDs0
58+ eWKe+6k1Kh6HSrinXriBLbIhMPY9pQsvqkeT6wW975NDn7+8awb8kHRmIg==
59+ -----END PUBLIC KEY-----
60+ ' ;
61+
62+ /**
63+ * The public key in PKCS#8 format.
64+ *
65+ * @var string
66+ */
67+ private $ pkcs8_key = '-----BEGIN PUBLIC KEY-----
68+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8dfWmTltr09m49uyESj
69+ x6UnQ9G/iVq+3dJbUdCdVEPR256UD6DLHE8uM4DgXhtoLVrBcvTAl9h0nRGX4uVN
70+ 5jE+pTh47B9IUim0bVw2sOBNwPCTUuKbMVx3Cso/6UxJsot41q7+FHIxcAurDxfR
71+ xfJkf+1ecYSb5czoeOG+NUcTEQv1LQntAOJ1ngrmjKyL4UlKZgcs2TfueqlK1v2t
72+ Gw4ylFOQYRx1Nj5YttQAuXc+VpGfztyRK90R74WkE/N6miOoDHcvc+7AeW4zyWsh
73+ ZfLXCbngI45TVhUr3ljxWs1Ykc8d4Xt3JrtcUzltbc6nWS0vstcUmxTLTRURn3SX
74+ 4wIDAQAB
75+ -----END PUBLIC KEY-----
76+ ' ;
77+
1978 /**
2079 * Tear down.
2180 */
@@ -113,11 +172,11 @@ public function test_signature_legacy() {
113172 }
114173
115174 /**
116- * Test signature consistancy .
175+ * Test signature consistency .
117176 *
118177 * @covers ::get_keypair_for
119178 */
120- public function test_signature_consistancy () {
179+ public function test_signature_consistency () {
121180 // Check user.
122181 $ user = Actors::get_by_id ( 1 );
123182
@@ -148,7 +207,7 @@ public function test_signature_consistancy() {
148207 *
149208 * @covers ::get_keypair_for
150209 */
151- public function test_signature_consistancy2 () {
210+ public function test_signature_consistency2 () {
152211 $ user = Actors::get_by_id ( 1 );
153212
154213 $ key_pair = Signature::get_keypair_for ( $ user ->get__id () );
@@ -168,4 +227,123 @@ public function test_signature_consistancy2() {
168227 $ this ->assertEquals ( $ key_pair ['public_key ' ], $ public_key );
169228 $ this ->assertEquals ( $ key_pair ['private_key ' ], $ private_key );
170229 }
230+
231+ /**
232+ * Test handling of different public key formats.
233+ *
234+ * @covers ::get_remote_key
235+ */
236+ public function test_key_format_handling () {
237+ $ expected = '-----BEGIN PUBLIC KEY-----
238+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtAVnFFbWG+6NBFKhMZdt
239+ 59Gx2/vKxWxbxOAYyi/ypZ/9aDY6C/UBRei8SqnhKcKXQaiSwme/wpqgCdkrf53H
240+ 85OioBitCEvKNA6uDxkCtcdgtQ3X55QDXmatWd32ln6elRmKG45U9R386j82OHzf
241+ f8Ju65QxGL1LlyCKQ/XFx/pgvblF3cGjshk0dhNcyGAztODN5HFp9Qzf9d7+gi+x
242+ dKeGNhXBAulXoaDzx8FvLEXNfPJb3jUM1Ug0STFsiICcf7VxmQow6N6d0+HtWxrd
243+ tjUBdXrPxz998Ns/cu9jjg06d+XV3TcSU+AOldmGLJuB/AWV/+F9c9DlczqmnXqd
244+ 1QIDAQAB
245+ -----END PUBLIC KEY-----
246+ ' ;
247+
248+ \add_filter ( 'pre_get_remote_metadata_by_actor ' , array ( $ this , 'pre_get_remote_metadata_by_actor ' ), 10 , 2 );
249+
250+ // X.509 key should remain unchanged.
251+ $ result = Signature::get_remote_key ( 'https://example.com/author/x509 ' );
252+ $ key_resource = \openssl_pkey_get_details ( $ result );
253+ $ this ->assertNotFalse ( $ key_resource );
254+ $ this ->assertSame ( $ this ->x509_key , $ key_resource ['key ' ] );
255+
256+ // PKCS#1 key should be converted to X.509 format.
257+ $ result = Signature::get_remote_key ( 'https://example.com/author/pkcs1 ' );
258+ $ key_resource = \openssl_pkey_get_details ( $ result );
259+ $ this ->assertNotFalse ( $ key_resource );
260+ $ this ->assertSame ( $ expected , $ key_resource ['key ' ] );
261+
262+ // EC key should be handled correctly.
263+ $ result = Signature::get_remote_key ( 'https://example.com/author/ec ' );
264+ $ key_resource = \openssl_pkey_get_details ( $ result );
265+ $ this ->assertNotFalse ( $ key_resource );
266+
267+ // PKCS#8 key should be handled correctly.
268+ $ result = Signature::get_remote_key ( 'https://example.com/author/pkcs8 ' );
269+ $ key_resource = \openssl_pkey_get_details ( $ result );
270+ $ this ->assertNotFalse ( $ key_resource );
271+
272+ // Test with invalid key.
273+ $ result = Signature::get_remote_key ( 'https://example.com/author/invalid ' );
274+ $ this ->assertWPError ( $ result );
275+
276+ \remove_filter ( 'pre_get_remote_metadata_by_actor ' , array ( $ this , 'pre_get_remote_metadata_by_actor ' ) );
277+ }
278+
279+ /**
280+ * Pre get remote metadata by actor.
281+ *
282+ * @param mixed $value The value.
283+ * @param string $url The URL.
284+ * @return array|\WP_Error
285+ */
286+ public function pre_get_remote_metadata_by_actor ( $ value , $ url ) {
287+ if ( 'https://example.com/author/x509 ' === $ url ) {
288+ return array (
289+ 'name ' => 'Test Actor ' ,
290+ 'url ' => 'https://example.com/author/x509 ' ,
291+ 'publicKey ' => array (
292+ 'id ' => 'https://example.com/author#main-key ' ,
293+ 'owner ' => 'https://example.com/author ' ,
294+ 'publicKeyPem ' => $ this ->x509_key ,
295+ ),
296+ );
297+ }
298+
299+ if ( 'https://example.com/author/pkcs1 ' === $ url ) {
300+ return array (
301+ 'name ' => 'Test Actor ' ,
302+ 'url ' => 'https://example.com/author/pkcs1 ' ,
303+ 'publicKey ' => array (
304+ 'id ' => 'https://example.com/author#main-key ' ,
305+ 'owner ' => 'https://example.com/author ' ,
306+ 'publicKeyPem ' => $ this ->pkcs1_key ,
307+ ),
308+ );
309+ }
310+
311+ if ( 'https://example.com/author/ec ' === $ url ) {
312+ return array (
313+ 'name ' => 'Test Actor ' ,
314+ 'url ' => 'https://example.com/author/ec ' ,
315+ 'publicKey ' => array (
316+ 'id ' => 'https://example.com/author#main-key ' ,
317+ 'owner ' => 'https://example.com/author ' ,
318+ 'publicKeyPem ' => $ this ->ec_key ,
319+ ),
320+ );
321+ }
322+
323+ if ( 'https://example.com/author/pkcs8 ' === $ url ) {
324+ return array (
325+ 'name ' => 'Test Actor ' ,
326+ 'url ' => 'https://example.com/author/pkcs8 ' ,
327+ 'publicKey ' => array (
328+ 'id ' => 'https://example.com/author#main-key ' ,
329+ 'owner ' => 'https://example.com/author ' ,
330+ 'publicKeyPem ' => $ this ->pkcs8_key ,
331+ ),
332+ );
333+ }
334+
335+ if ( 'https://example.com/author/invalid ' === $ url ) {
336+ return array (
337+ 'name ' => 'Test Actor ' ,
338+ 'url ' => 'https://example.com/author/invalid ' ,
339+ 'publicKey ' => array (
340+ 'id ' => 'https://example.com/author#main-key ' ,
341+ 'owner ' => 'https://example.com/author ' ,
342+ 'publicKeyPem ' => 'INVALID KEY DATA ' ,
343+ ),
344+ );
345+ }
346+
347+ return new \WP_Error ( 'invalid_url ' , $ url );
348+ }
171349}
0 commit comments