X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FDiaspora%2FDiasporaPlugin.php;h=c054d3b767658cfd32cd5629e428569bb402bb62;hb=4211206e3be06baa6c63af8c9fc819db3020d559;hp=68f23a438231bdf8369c6f5a4c6f15836c1383b7;hpb=2aed59a02af83af0021db6464bd3cd3626c09b71;p=quix0rs-gnu-social.git diff --git a/plugins/Diaspora/DiasporaPlugin.php b/plugins/Diaspora/DiasporaPlugin.php index 68f23a4382..c054d3b767 100644 --- a/plugins/Diaspora/DiasporaPlugin.php +++ b/plugins/Diaspora/DiasporaPlugin.php @@ -33,9 +33,6 @@ if (!defined('GNUSOCIAL')) { exit(1); } // Depends on OStatus of course. addPlugin('OStatus'); -//Since Magicsig hasn't loaded yet -require_once('Crypt/AES.php'); - class DiasporaPlugin extends Plugin { const REL_SEED_LOCATION = 'http://joindiaspora.com/seed_location'; @@ -46,7 +43,7 @@ class DiasporaPlugin extends Plugin { // So far we've only handled RSA keys, but it can change in the future, // so be prepared. And remember to change the statically assigned type attribute below! - assert($magicsig->publicKey instanceof Crypt_RSA); + assert($magicsig->publicKey instanceof \phpseclib\Crypt\RSA); $xrd->links[] = new XML_XRD_Element_Link(self::REL_PUBLIC_KEY, base64_encode($magicsig->exportPublicKey()), 'RSA'); @@ -56,10 +53,33 @@ 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', - 'version' => '0.1', + 'version' => '0.2', 'author' => 'Mikael Nordfeldth', 'homepage' => 'https://gnu.io/social', // TRANS: Plugin description. @@ -81,16 +101,20 @@ class DiasporaPlugin extends Plugin /** * https://wiki.diasporafoundation.org/Federation_protocol_overview + * http://www.rubydoc.info/github/Raven24/diaspora-federation/master/DiasporaFederation/Salmon/EncryptedSlap * * Constructing the encryption header */ + // For some reason diaspora wants the salmon slap in a header. + $xs->elementStart('diaspora', array('xmlns'=>'https://joindiaspora.com/protocol')); + /** * Choose an AES key and initialization vector, suitable for the * aes-256-cbc cipher. I shall refer to this as the “inner key” * and the “inner initialization vector (iv)”. */ - $inner_key = new Crypt_AES(CRYPT_AES_MODE_CBC); + $inner_key = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CBC); $inner_key->setKeyLength(256); // set length to 256 bits (could be calculated, but let's be sure) $inner_key->setKey(common_random_rawstr(32)); // 32 bytes from a (pseudo) random source $inner_key->setIV(common_random_rawstr(16)); // 16 bytes is the block length @@ -116,7 +140,7 @@ class DiasporaPlugin extends Plugin * for the aes-256-cbc cipher. I shall refer to this as the * “outer key” and the “outer initialization vector (iv)”. */ - $outer_key = new Crypt_AES(CRYPT_AES_MODE_CBC); + $outer_key = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CBC); $outer_key->setKeyLength(256); // set length to 256 bits (could be calculated, but let's be sure) $outer_key->setKey(common_random_rawstr(32)); // 32 bytes from a (pseudo) random source $outer_key->setIV(common_random_rawstr(16)); // 16 bytes is the block length @@ -126,7 +150,7 @@ class DiasporaPlugin extends Plugin * and “outer iv” (using the aes-256-cbc cipher). This encrypted * blob shall be referred to as “the ciphertext”. */ - $ciphertext = $outer_key->encrypt($decrypted_header); + $ciphertext = $outer_key->encrypt($decrypted_header, \phpseclib\Crypt\RSA::PADDING_PKCS1); /** * Construct the following JSON object, which shall be referred to @@ -144,9 +168,10 @@ 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); + $enc_outer = $remote_keys->publicKey->encrypt($outer_bundle, \phpseclib\Crypt\RSA::PADDING_PKCS1); /** * Construct the following JSON object, which I shall refer to as @@ -176,7 +201,10 @@ class DiasporaPlugin extends Plugin * chose earlier. * 2. Base64-encode the encrypted payload message. */ - $payload = $inner_key->encrypt($magic_env->getData()); + $payload = $inner_key->encrypt($magic_env->getData(), \phpseclib\Crypt\RSA::PADDING_PKCS1); + //FIXME: This means we don't actually put an in the payload, + // since Diaspora has its own update method! Silly me. Read up on: + // https://wiki.diasporafoundation.org/Federation_Message_Semantics $magic_env->signMessage(base64_encode($payload), 'application/xml'); @@ -190,12 +218,19 @@ class DiasporaPlugin extends Plugin $xs->element('me:sig', null, $magic_env->getSignature()); $xs->elementEnd('me:env'); + $xs->elementEnd('entry'); + return false; } public function onSalmonSlap($endpoint_uri, MagicEnvelope $magic_env, Profile $target=null) { - $envxml = $magic_env->toXML($target, 'diaspora'); + try { + $envxml = $magic_env->toXML($target, 'diaspora'); + } catch (Exception $e) { + common_log(LOG_ERR, sprintf('Could not generate Magic Envelope XML (diaspora flavour) for profile id=='.$target->getID().': '.$e->getMessage())); + return false; + } // Diaspora wants another POST format (base64url-encoded POST variable 'xml') $headers = array('Content-Type: application/x-www-form-urlencoded'); @@ -207,7 +242,7 @@ class DiasporaPlugin extends Plugin $client = new HTTPClient(); $client->setBody('xml=' . Magicsig::base64_url_encode($envxml)); $response = $client->post($endpoint_uri, $headers); - } catch (HTTP_Request2_Exception $e) { + } catch (Exception $e) { common_log(LOG_ERR, "Diaspora-flavoured Salmon post to $endpoint_uri failed: " . $e->getMessage()); return false; } @@ -216,7 +251,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; }