]> git.mxchange.org Git - friendica.git/blob - src/Util/LDSignature.php
Refactor namespaces
[friendica.git] / src / Util / LDSignature.php
1 <?php
2
3 namespace Friendica\Util;
4
5 use Friendica\Core\Logger;
6 use Friendica\Model\APContact;
7
8 /**
9  * @brief Implements JSON-LD signatures
10  *
11  * Ported from Osada: https://framagit.org/macgirvin/osada
12  */
13 class LDSignature
14 {
15         public static function isSigned($data)
16         {
17                 return !empty($data['signature']);
18         }
19
20         public static function getSigner($data)
21         {
22                 if (!self::isSigned($data)) {
23                         return false;
24                 }
25
26                 $actor = JsonLD::fetchElement($data, 'actor', 'id');
27                 if (empty($actor) || !is_string($actor)) {
28                         return false;
29                 }
30
31                 $profile = APContact::getByURL($actor);
32                 if (empty($profile['pubkey'])) {
33                         return false;
34                 }
35                 $pubkey = $profile['pubkey'];
36
37                 $ohash = self::hash(self::signableOptions($data['signature']));
38                 $dhash = self::hash(self::signableData($data));
39
40                 $x = Crypto::rsaVerify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
41                 Logger::log('LD-verify: ' . intval($x));
42
43                 if (empty($x)) {
44                         return false;
45                 } else {
46                         return $actor;
47                 }
48         }
49
50         public static function sign($data, $owner)
51         {
52                 $options = [
53                         'type' => 'RsaSignature2017',
54                         'nonce' => Strings::getRandomHex(64),
55                         'creator' => $owner['url'] . '#main-key',
56                         'created' => DateTimeFormat::utcNow(DateTimeFormat::ATOM)
57                 ];
58
59                 $ohash = self::hash(self::signableOptions($options));
60                 $dhash = self::hash(self::signableData($data));
61                 $options['signatureValue'] = base64_encode(Crypto::rsaSign($ohash . $dhash, $owner['uprvkey']));
62
63                 return array_merge($data, ['signature' => $options]);
64         }
65
66         private static function signableData($data)
67         {
68                 unset($data['signature']);
69                 return $data;
70         }
71
72         private static function signableOptions($options)
73         {
74                 $newopts = ['@context' => 'https://w3id.org/identity/v1'];
75
76                 unset($options['type']);
77                 unset($options['id']);
78                 unset($options['signatureValue']);
79
80                 return array_merge($newopts, $options);
81         }
82
83         private static function hash($obj)
84         {
85                 return hash('sha256', JsonLD::normalize($obj));
86         }
87 }