From 752b5fe28464c7f1dec79132b6ef74ae71420d8b Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 20 Sep 2018 21:45:23 +0000 Subject: [PATCH] Outgoing posts are now signed --- src/Protocol/ActivityPub.php | 22 +++++++-- src/Util/LDSignature.php | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 src/Util/LDSignature.php diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index d952f4de8f..6f5fdedc95 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -20,6 +20,7 @@ use Friendica\Util\Crypto; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Util\JsonLD; +use Friendica\Util\LDSignature; /** * @brief ActivityPub Protocol class @@ -273,7 +274,10 @@ class ActivityPub $data = array_merge($data, ActivityPub::createPermissionBlockForItem($item)); $data['object'] = self::createNote($item); - return $data; + + $owner = User::getOwnerDataById($item['uid']); + + return LDSignature::sign($data, $owner); } public static function createObjectFromItemID($item_id) @@ -369,7 +373,9 @@ class ActivityPub 'to' => $profile['url']]; logger('Sending activity ' . $activity . ' to ' . $target . ' for user ' . $uid, LOGGER_DEBUG); - return HTTPSignature::transmit($data, $profile['inbox'], $uid); + + $signed = LDSignature::sign($data, $owner); + return HTTPSignature::transmit($signed, $profile['inbox'], $uid); } public static function transmitContactAccept($target, $id, $uid) @@ -387,7 +393,9 @@ class ActivityPub 'to' => $profile['url']]; logger('Sending accept to ' . $target . ' for user ' . $uid . ' with id ' . $id, LOGGER_DEBUG); - return HTTPSignature::transmit($data, $profile['inbox'], $uid); + + $signed = LDSignature::sign($data, $owner); + return HTTPSignature::transmit($signed, $profile['inbox'], $uid); } public static function transmitContactReject($target, $id, $uid) @@ -405,7 +413,9 @@ class ActivityPub 'to' => $profile['url']]; logger('Sending reject to ' . $target . ' for user ' . $uid . ' with id ' . $id, LOGGER_DEBUG); - return HTTPSignature::transmit($data, $profile['inbox'], $uid); + + $signed = LDSignature::sign($data, $owner); + return HTTPSignature::transmit($signed, $profile['inbox'], $uid); } public static function transmitContactUndo($target, $uid) @@ -425,7 +435,9 @@ class ActivityPub 'to' => $profile['url']]; logger('Sending undo to ' . $target . ' for user ' . $uid . ' with id ' . $id, LOGGER_DEBUG); - return HTTPSignature::transmit($data, $profile['inbox'], $uid); + + $signed = LDSignature::sign($data, $owner); + return HTTPSignature::transmit($signed, $profile['inbox'], $uid); } /** diff --git a/src/Util/LDSignature.php b/src/Util/LDSignature.php new file mode 100644 index 0000000000..7288b584c7 --- /dev/null +++ b/src/Util/LDSignature.php @@ -0,0 +1,92 @@ + 'RsaSignature2017', + 'nonce' => random_string(64), + 'creator' => $owner['url'] . '#main-key', + 'created' => DateTimeFormat::utcNow() + ]; + + $ohash = self::hash(self::signable_options($options)); + $dhash = self::hash(self::signable_data($data)); + $options['signatureValue'] = base64_encode(Crypto::rsaSign($ohash . $dhash, $owner['uprvkey'])); + + return array_merge($data, ['signature' => $options]); + } + + + private static function signable_data($data) + { + $newdata = []; + if (!empty($data)) { + foreach ($data as $k => $v) { + if (!in_array($k, ['signature'])) { + $newdata[$k] = $v; + } + } + } + return $newdata; + } + + + private static function signable_options($options) + { + $newopts = ['@context' => 'https://w3id.org/identity/v1']; + if (!empty($options)) { + foreach ($options as $k => $v) { + if (!in_array($k, ['type','id','signatureValue'])) { + $newopts[$k] = $v; + } + } + } + return $newopts; + } + + private static function hash($obj) + { + return hash('sha256', JsonLD::normalize($obj)); + } +}