]> git.mxchange.org Git - friendica.git/blob - include/salmon.php
pull out follow, unfollow and as:actor for handling
[friendica.git] / include / salmon.php
1 <?php
2
3 require_once('library/asn1.php');
4
5 function salmon_key($pubkey) {
6         $lines = explode("\n",$pubkey);
7         unset($lines[0]);
8         unset($lines[count($lines)]);
9         $x = base64_decode(implode('',$lines));
10
11         $r = ASN_BASE::parseASNString($x);
12
13         $m = $r[0]->asnData[1]->asnData[0]->asnData[0]->asnData;
14         $e = $r[0]->asnData[1]->asnData[0]->asnData[1]->asnData;
15
16
17         return 'RSA' . '.' . $m . '.' . $e ;
18 }
19
20
21 function base64url_encode($s) {
22         return strtr(base64_encode($s),'+/','-_');
23 }
24
25 function base64url_decode($s) {
26         return base64_decode(strtr($s,'-_','+/'));
27 }
28
29 function get_salmon_key($uri,$keyhash) {
30         $ret = array();
31
32         $debugging = get_config('system','debugging');
33         if($debugging)          
34                 file_put_contents('salmon.out', "\n" . 'Fetch key' . "\n", FILE_APPEND);
35
36         if(strstr($uri,'@')) {  
37                 $arr = webfinger($uri);
38                 if($debugging)
39                         file_put_contents('salmon.out', "\n" . 'Fetch key from webfinger' . "\n", FILE_APPEND);
40         }
41         else {
42                 $html = fetch_url($uri);
43                 $a = get_app();
44                 $h = $a->get_curl_headers();
45                 if($debugging)
46                         file_put_contents('salmon.out', "\n" . 'Fetch key via HTTP header: ' . $h . "\n", FILE_APPEND);
47
48                 $l = explode("\n",$h);
49                 if(count($l)) {
50                         foreach($l as $line) {                          
51                                 // TODO alter the following regex to support multiple relations (space separated)
52                                 if((stristr($line,'link:')) && preg_match('/<([^>].*)>.*rel\=[\'\"]lrdd[\'\"]/',$line,$matches)) {
53                                         $link = $matches[1];
54                                         if($debugging)
55                                                 file_put_contents('salmon.out', "\n" . 'Fetch key via HTML Link: ' . $link . "\n", FILE_APPEND);
56                                         break;
57                                 }
58                         }
59                 }
60
61                 if(! isset($link)) {
62
63                         // parse the page of the supplied URL looking for rel links
64
65                         require_once('library/HTML5/Parser.php');
66                         $dom = HTML5_Parser::parse($html);
67
68                         if(! $dom)
69                                 return '';
70
71                         $items = $dom->getElementsByTagName('link');
72
73                         foreach($items as $item) {
74                                 $x = $item->getAttribute('rel');
75                                 if($x == "lrdd") {
76                                         $link = $item->getAttribute('href');
77                                         if($debugging)
78                                                 file_put_contents('salmon.out', "\n" . 'Fetch key via HTML body' . $link . "\n", FILE_APPEND);
79                                         break;
80                                 }
81                         }
82                 }
83
84                 if(! isset($link))
85                         return '';
86
87                 $arr = fetch_xrd_links($link);
88         }
89
90         if($arr) {
91                 foreach($arr as $a) {
92                         if($a['@attributes']['rel'] === 'magic-public-key') {
93                                 $ret[] = $a['@attributes']['href'];
94                         }
95                 }
96         }
97         else {
98                 return '';
99         }
100
101         // We have found at least one key URL
102         // If it's inline, parse it - otherwise get the key
103
104         if(count($ret)) {
105                 for($x = 0; $x < count($ret); $x ++) {
106                         if(substr($ret[$x],0,5) === 'data:') {
107                                 if(strstr($ret[$x],','))
108                                         $ret[$x] = substr($ret[$x],strpos($ret[$x],',')+1);
109                                 else
110                                         $ret[$x] = substr($ret[$x],5);
111                         }
112                         else
113                                 $ret[$x] = fetch_url($ret[$x]);
114                 }
115         }
116
117         if($debugging)
118                 file_put_contents('salmon.out', "\n" . 'Key located: ' . print_r($ret,true) . "\n", FILE_APPEND);
119
120         if(count($ret) == 1) {
121
122                 // We only found one one key so we don't care if the hash matches.
123                 // If it's the wrong key we'll find out soon enough because 
124                 // message verification will fail. This also covers some older 
125                 // software which don't supply a keyhash. As long as they only
126                 // have one key we'll be right. 
127
128                 return $ret[0];
129         }
130         else {
131                 foreach($ret as $a) {
132                         $hash = base64url_encode(hash('sha256',$a));
133                         if($hash == $keyhash)
134                                 return $a;
135                 }
136         }
137
138         return '';
139 }
140
141         
142                 
143