]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/Salmon.php
Merge pull request #13646 from annando/page-drop
[friendica.git] / src / Protocol / Salmon.php
index 98af26c15c3130b01e5a21aaca82565953b415a9..5047375ea0fb81c89caccb69a6cc1b87e6d25418 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @copyright Copyright (C) 2010-2022, the Friendica project
+ * @copyright Copyright (C) 2010-2023, the Friendica project
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -25,9 +25,11 @@ use Friendica\Core\Logger;
 use Friendica\DI;
 use Friendica\Network\HTTPClient\Client\HttpClientAccept;
 use Friendica\Network\Probe;
+use Friendica\Protocol\Salmon\Format\Magic;
 use Friendica\Util\Crypto;
 use Friendica\Util\Strings;
 use Friendica\Util\XML;
+use phpseclib3\Crypt\PublicKeyLoader;
 
 /**
  * Salmon Protocol class
@@ -40,10 +42,10 @@ class Salmon
        /**
         * @param string $uri     Uniform Resource Identifier
         * @param string $keyhash encoded key
-        * @return mixed
+        * @return string Key or empty string on any errors
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function getKey(string $uri, string $keyhash)
+       public static function getKey(string $uri, string $keyhash): string
        {
                $ret = [];
 
@@ -83,13 +85,13 @@ class Salmon
                Logger::notice('Key located', ['ret' => $ret]);
 
                if (count($ret) == 1) {
-                       // We only found one one key so we don't care if the hash matches.
-                       // If it's the wrong key we'll find out soon enough because
-                       // message verification will fail. This also covers some older
-                       // software which don't supply a keyhash. As long as they only
-                       // have one key we'll be right.
-
-                       return $ret[0];
+                       /* We only found one key so we don't care if the hash matches.
+                        * If it's the wrong key we'll find out soon enough because
+                        * message verification will fail. This also covers some older
+                        * software which don't supply a keyhash. As long as they only
+                        * have one key we'll be right.
+                        */
+                       return (string) $ret[0];
                } else {
                        foreach ($ret as $a) {
                                $hash = Strings::base64UrlEncode(hash('sha256', $a));
@@ -145,16 +147,20 @@ class Salmon
                $signature3  = Strings::base64UrlEncode(Crypto::rsaSign($data, $owner['sprvkey']));
 
                // At first try the non compliant method that works for GNU Social
-               $xmldata = ["me:env" => ["me:data" => $data,
-                               "@attributes" => ["type" => $data_type],
-                               "me:encoding" => $encoding,
-                               "me:alg" => $algorithm,
-                               "me:sig" => $signature,
-                               "@attributes2" => ["key_id" => $keyhash]]];
+               $xmldata = [
+                       'me:env' => [
+                               'me:data' => $data,
+                               '@attributes' => ['type' => $data_type],
+                               'me:encoding' => $encoding,
+                               'me:alg' => $algorithm,
+                               'me:sig' => $signature,
+                               '@attributes2' => ['key_id' => $keyhash],
+                       ]
+               ];
 
-               $namespaces = ["me" => "http://salmon-protocol.org/ns/magic-env"];
+               $namespaces = ['me' => ActivityNamespace::SALMON_ME];
 
-               $salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
+               $salmon = XML::fromArray($xmldata, $dummy, false, $namespaces);
 
                // slap them
                $postResult = DI::httpClient()->post($url, $salmon, [
@@ -170,16 +176,18 @@ class Salmon
                        Logger::notice('GNU Social salmon failed. Falling back to compliant mode');
 
                        // Now try the compliant mode that normally isn't used for GNU Social
-                       $xmldata = ["me:env" => ["me:data" => $data,
-                                       "@attributes" => ["type" => $data_type],
-                                       "me:encoding" => $encoding,
-                                       "me:alg" => $algorithm,
-                                       "me:sig" => $signature2,
-                                       "@attributes2" => ["key_id" => $keyhash]]];
-
-                       $namespaces = ["me" => "http://salmon-protocol.org/ns/magic-env"];
-
-                       $salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
+                       $xmldata = [
+                               'me:env' => [
+                                       'me:data' => $data,
+                                       '@attributes' => ['type' => $data_type],
+                                       'me:encoding' => $encoding,
+                                       'me:alg' => $algorithm,
+                                       'me:sig' => $signature2,
+                                       '@attributes2' => ['key_id' => $keyhash]
+                               ]
+                       ];
+
+                       $salmon = XML::fromArray($xmldata, $dummy, false, $namespaces);
 
                        // slap them
                        $postResult = DI::httpClient()->post($url, $salmon, [
@@ -193,16 +201,18 @@ class Salmon
                        Logger::notice('compliant salmon failed. Falling back to old status.net');
 
                        // Last try. This will most likely fail as well.
-                       $xmldata = ["me:env" => ["me:data" => $data,
-                                       "@attributes" => ["type" => $data_type],
-                                       "me:encoding" => $encoding,
-                                       "me:alg" => $algorithm,
-                                       "me:sig" => $signature3,
-                                       "@attributes2" => ["key_id" => $keyhash]]];
-
-                       $namespaces = ["me" => "http://salmon-protocol.org/ns/magic-env"];
-
-                       $salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
+                       $xmldata = [
+                               'me:env' => [
+                                       'me:data' => $data,
+                                       '@attributes' => ['type' => $data_type],
+                                       'me:encoding' => $encoding,
+                                       'me:alg' => $algorithm,
+                                       'me:sig' => $signature3,
+                                       '@attributes2' => ['key_id' => $keyhash],
+                               ]
+                       ];
+
+                       $salmon = XML::fromArray($xmldata, $dummy, false, $namespaces);
 
                        // slap them
                        $postResult = DI::httpClient()->post($url, $salmon, [
@@ -231,7 +241,19 @@ class Salmon
         */
        public static function salmonKey(string $pubkey): string
        {
-               Crypto::pemToMe($pubkey, $modulus, $exponent);
-               return 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true);
+               \phpseclib3\Crypt\RSA::addFileFormat(Magic::class);
+
+               return PublicKeyLoader::load($pubkey)->toString('Magic');
+       }
+
+       /**
+        * @param string $magic Magic key format starting with "RSA."
+        * @return string
+        */
+       public static function magicKeyToPem(string $magic): string
+       {
+               \phpseclib3\Crypt\RSA::addFileFormat(Magic::class);
+
+               return (string) PublicKeyLoader::load($magic);
        }
 }