]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Magic signature discovery and envelope changes
authorMikael Nordfeldth <mmn@hethane.se>
Sun, 4 Oct 2015 15:26:35 +0000 (17:26 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Sun, 4 Oct 2015 15:26:35 +0000 (17:26 +0200)
plugins/Diaspora/DiasporaPlugin.php
plugins/OStatus/OStatusPlugin.php
plugins/OStatus/lib/magicenvelope.php

index 68f23a438231bdf8369c6f5a4c6f15836c1383b7..75dba7384a487a87e7849d163f02807bc0b9947b 100644 (file)
@@ -56,6 +56,29 @@ class DiasporaPlugin extends Plugin
                                     strtolower($magicsig->toFingerprint()));
     }
 
+    public function onMagicsigPublicKeyFromXRD(XML_XRD $xrd, &$pubkey)
+    {
+        // See if we have a Diaspora public key in the XRD response
+        $link = $xrd->get(self::REL_PUBLIC_KEY, 'RSA');
+        if (!is_null($link)) {
+            // If we do, decode it so we have the PKCS1 format (starts with -----BEGIN PUBLIC KEY-----)
+            $pkcs1 = base64_decode($link->href);
+            $magicsig = new Magicsig(Magicsig::DEFAULT_SIGALG); // Diaspora uses RSA-SHA256 (we do too)
+            try {
+                // Try to load the public key so we can get it in the standard Magic signature format
+                $magicsig->loadPublicKeyPKCS1($pkcs1);
+                // We found it and will now store it in $pubkey in a proper format!
+                // This is how it would be found in a well implemented XRD according to the standard.
+                $pubkey = 'data:application/magic-public-key,'.$magicsig->toString();
+                common_debug('magic-public-key found in diaspora-public-key: '.$pubkey);
+                return false;
+            } catch (ServerException $e) {
+                common_log(LOG_WARNING, $e->getMessage());
+            }
+        }
+        return true;
+    }
+
     public function onPluginVersion(array &$versions)
     {
         $versions[] = array('name' => 'Diaspora',
@@ -144,6 +167,7 @@ class DiasporaPlugin extends Plugin
          * Encrypt the “outer aes key bundle” with Bob’s RSA public key.
          * I shall refer to this as the “encrypted outer aes key bundle”.
          */
+        common_debug('Diaspora creating "outer aes key bundle", will require magic-public-key');
         $key_fetcher = new MagicEnvelope();
         $remote_keys = $key_fetcher->getKeyPair($target, true); // actually just gets the public key
         $enc_outer = $remote_keys->publicKey->encrypt($outer_bundle);
@@ -216,7 +240,7 @@ class DiasporaPlugin extends Plugin
         // 202 Accepted is what we get from Diaspora for example
         if (!in_array($response->getStatus(), array(200, 202))) {
             common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s',
-                                $user->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
+                                $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus(), $response->getBody()));
             return true;
         }
 
index d1eea869a7569e56aef96746ea78d38689cc0abe..86befd58cd54278c768caf9a5f65ee483585e3c3 100644 (file)
@@ -1381,7 +1381,7 @@ class OStatusPlugin extends Plugin
             return false;
         }
         if ($response->getStatus() === 422) {
-            common_debug(sprintf('Salmon (from profile %d) endpoint %s returned status %s. We assume it is a Diaspora seed, will adapt and try again if that plugin is enabled!'));
+            common_debug(sprintf('Salmon (from profile %d) endpoint %s returned status %s. We assume it is a Diaspora seed; will adapt and try again if that plugin is enabled!', $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus()));
             return true;
         }
 
@@ -1389,7 +1389,7 @@ class OStatusPlugin extends Plugin
         // 202 Accepted is what we get from Diaspora for example
         if (!in_array($response->getStatus(), array(200, 202))) {
             common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s',
-                                $user->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
+                                $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus(), $response->getBody()));
             return true;
         }
 
index e96862bbadc0d03a7d7f221a8d2b07c63672bfb9..6786bfa298a650e34ef4e3e1fd6478ebe31a6190 100644 (file)
@@ -78,14 +78,16 @@ class MagicEnvelope
      * @param boolean $discovery    Network discovery if no local cache?
      */
     public function getKeyPair(Profile $profile, $discovery=false) {
-        $magicsig = Magicsig::getKV('user_id', $profile->id);
+        if (!$profile->isLocal()) common_debug('Getting magic-public-key for non-local profile id=='.$profile->getID());
+        $magicsig = Magicsig::getKV('user_id', $profile->getID());
 
         if ($discovery && !$magicsig instanceof Magicsig) {
+            if (!$profile->isLocal()) common_debug('magic-public-key not found, will do discovery for profile id=='.$profile->getID());
             // Throws exception on failure, but does not try to _load_ the keypair string.
             $keypair = $this->discoverKeyPair($profile);
 
             $magicsig = new Magicsig();
-            $magicsig->user_id = $profile->id;
+            $magicsig->user_id = $profile->getID();
             $magicsig->importKeys($keypair);
             // save the public key for this profile in our database.
             // TODO: If the profile generates a new key remotely, we must be able to replace
@@ -113,28 +115,41 @@ class MagicEnvelope
     {
         $signer_uri = $profile->getUri();
         if (empty($signer_uri)) {
-            throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->id));
+            throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->getID()));
         }
 
         $disco = new Discovery();
 
         // Throws exception on lookup problems
-        $xrd = $disco->lookup($signer_uri);
+        try {
+            $xrd = $disco->lookup($signer_uri);
+        } catch (Exception $e) {
+            // Diaspora seems to require us to request the acct: uri
+            $xrd = $disco->lookup($profile->getAcctUri());
+        }
 
-        $link = $xrd->get(Magicsig::PUBLICKEYREL);
-        if (is_null($link)) {
-            // TRANS: Exception.
-            throw new Exception(_m('Unable to locate signer public key.'));
+        common_debug('Will try to find magic-public-key from XRD of profile id=='.$profile->getID());
+        $pubkey = null;
+        if (Event::handle('MagicsigPublicKeyFromXRD', array($xrd, &$pubkey))) {
+            $link = $xrd->get(Magicsig::PUBLICKEYREL);
+            if (is_null($link)) {
+                // TRANS: Exception.
+                throw new Exception(_m('Unable to locate signer public key.'));
+            }
+            $pubkey = $link->href;
+        }
+        if (empty($pubkey)) {
+            throw new ServerException('Empty Magicsig public key. A bug?');
         }
 
         // We have a public key element, let's hope it has proper key data.
         $keypair = false;
-        $parts = explode(',', $link->href);
+        $parts = explode(',', $pubkey);
         if (count($parts) == 2) {
             $keypair = $parts[1];
         } else {
             // Backwards compatibility check for separator bug in 0.9.0
-            $parts = explode(';', $link->href);
+            $parts = explode(';', $pubkey);
             if (count($parts) == 2) {
                 $keypair = $parts[1];
             }