3 namespace Friendica\Util;
5 use Friendica\Util\JsonLD;
6 use Friendica\Util\DateTimeFormat;
7 use Friendica\Protocol\ActivityPub;
10 * @brief Implements JSON-LD signatures
12 * Ported from Osada: https://framagit.org/macgirvin/osada
16 public static function isSigned($data)
18 return !empty($data['signature']);
21 public static function getSigner($data)
23 if (!self::isSigned($data)) {
28 $creator = $data['signature']['creator'];
29 $actor = JsonLD::fetchElement($data, 'actor', 'id');
31 $url = (strpos($creator, '#') ? substr($creator, 0, strpos($creator, '#')) : $creator);
33 $profile = ActivityPub::fetchprofile($url);
34 if (!empty($profile)) {
35 logger('Taking key from creator ' . $creator, LOGGER_DEBUG);
36 } elseif ($url != $actor) {
37 $profile = ActivityPub::fetchprofile($actor);
38 if (empty($profile)) {
41 logger('Taking key from actor ' . $actor, LOGGER_DEBUG);
45 $actor = JsonLD::fetchElement($data, 'actor', 'id');
50 $profile = ActivityPub::fetchprofile($actor);
51 if (empty($profile['pubkey'])) {
54 $pubkey = $profile['pubkey'];
56 $ohash = self::hash(self::signable_options($data['signature']));
57 $dhash = self::hash(self::signable_data($data));
59 $x = Crypto::rsaVerify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
60 logger('LD-verify: ' . intval($x));
69 public static function sign($data, $owner)
72 'type' => 'RsaSignature2017',
73 'nonce' => random_string(64),
74 'creator' => $owner['url'] . '#main-key',
75 'created' => DateTimeFormat::utcNow(DateTimeFormat::ATOM)
78 $ohash = self::hash(self::signable_options($options));
79 $dhash = self::hash(self::signable_data($data));
80 $options['signatureValue'] = base64_encode(Crypto::rsaSign($ohash . $dhash, $owner['uprvkey']));
82 return array_merge($data, ['signature' => $options]);
86 private static function signable_data($data)
88 unset($data['signature']);
93 private static function signable_options($options)
95 $newopts = ['@context' => 'https://w3id.org/identity/v1'];
96 if (!empty($options)) {
97 foreach ($options as $k => $v) {
98 if (!in_array($k, ['type', 'id', 'signatureValue'])) {
106 private static function hash($obj)
108 return hash('sha256', JsonLD::normalize($obj));