]> git.mxchange.org Git - friendica.git/blob - src/Util/LDSignature.php
6db66a52a5ecdb086c1a7ff0b8a5ad67af29613d
[friendica.git] / src / Util / LDSignature.php
1 <?php
2
3 namespace Friendica\Util;
4
5 use Friendica\Util\JsonLD;
6 use Friendica\Util\DateTimeFormat;
7 use Friendica\Protocol\ActivityPub;
8
9 class LDSignature
10 {
11         public static function isSigned($data)
12         {
13                 return !empty($data['signature']);
14         }
15
16         public static function getSigner($data)
17         {
18                 if (!self::isSigned($data)) {
19                         return false;
20                 }
21
22 /*
23                 $creator = $data['signature']['creator'];
24                 $actor = JsonLD::fetchElement($data, 'actor', 'id');
25
26                 $url = (strpos($creator, '#') ? substr($creator, 0, strpos($creator, '#')) : $creator);
27
28                 $profile = ActivityPub::fetchprofile($url);
29                 if (!empty($profile)) {
30                         logger('Taking key from creator ' . $creator, LOGGER_DEBUG);
31                 } elseif ($url != $actor) {
32                         $profile = ActivityPub::fetchprofile($actor);
33                         if (empty($profile)) {
34                                 return false;
35                         }
36                         logger('Taking key from actor ' . $actor, LOGGER_DEBUG);
37                 }
38
39 */
40                 $actor = JsonLD::fetchElement($data, 'actor', 'id');
41                 if (empty($actor)) {
42                         return false;
43                 }
44
45                 $profile = ActivityPub::fetchprofile($actor);
46                 if (empty($profile['pubkey'])) {
47                         return false;
48                 }
49                 $pubkey = $profile['pubkey'];
50
51                 $ohash = self::hash(self::signable_options($data['signature']));
52                 $dhash = self::hash(self::signable_data($data));
53
54                 $x = Crypto::rsaVerify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
55                 logger('LD-verify: ' . intval($x));
56
57                 if (empty($x)) {
58                         return false;
59                 } else {
60                         return $actor;
61                 }
62         }
63
64         public static function sign($data, $owner)
65         {
66                 $options = [
67                         'type' => 'RsaSignature2017',
68                         'nonce' => random_string(64),
69                         'creator' => $owner['url'] . '#main-key',
70                         'created' => DateTimeFormat::utcNow(DateTimeFormat::ATOM)
71                 ];
72
73                 $ohash = self::hash(self::signable_options($options));
74                 $dhash = self::hash(self::signable_data($data));
75                 $options['signatureValue'] = base64_encode(Crypto::rsaSign($ohash . $dhash, $owner['uprvkey']));
76
77                 return array_merge($data, ['signature' => $options]);
78         }
79
80
81         private static function signable_data($data)
82         {
83                 unset($data['signature']);
84                 return $data;
85         }
86
87
88         private static function signable_options($options)
89         {
90                 $newopts = ['@context' => 'https://w3id.org/identity/v1'];
91                 if (!empty($options)) {
92                         foreach ($options as $k => $v) {
93                                 if (!in_array($k, ['type', 'id', 'signatureValue'])) {
94                                         $newopts[$k] = $v;
95                                 }
96                         }
97                 }
98                 return $newopts;
99         }
100
101         private static function hash($obj)
102         {
103                 return hash('sha256', JsonLD::normalize($obj));
104         }
105 }