3 require_once('library/asn1.php');
5 function salmon_key($pubkey) {
6 $lines = explode("\n",$pubkey);
8 unset($lines[count($lines)]);
9 $x = base64_decode(implode('',$lines));
11 $r = ASN_BASE::parseASNString($x);
13 $m = $r[0]->asnData[1]->asnData[0]->asnData[0]->asnData;
14 $e = $r[0]->asnData[1]->asnData[0]->asnData[1]->asnData;
17 return 'RSA' . '.' . $m . '.' . $e ;
21 function base64url_encode($s) {
22 return strtr(base64_encode($s),'+/','-_');
25 function base64url_decode($s) {
26 return base64_decode(strtr($s,'-_','+/'));
29 function get_salmon_key($uri,$keyhash) {
32 $debugging = get_config('system','debugging');
34 file_put_contents('salmon.out', "\n" . 'Fetch key' . "\n", FILE_APPEND);
36 if(strstr($uri,'@')) {
37 $arr = webfinger($uri);
39 file_put_contents('salmon.out', "\n" . 'Fetch key from webfinger' . "\n", FILE_APPEND);
42 $html = fetch_url($uri);
44 $h = $a->get_curl_headers();
46 file_put_contents('salmon.out', "\n" . 'Fetch key via HTTP header: ' . $h . "\n", FILE_APPEND);
48 $l = explode("\n",$h);
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)) {
55 file_put_contents('salmon.out', "\n" . 'Fetch key via HTML Link: ' . $link . "\n", FILE_APPEND);
63 // parse the page of the supplied URL looking for rel links
65 require_once('library/HTML5/Parser.php');
66 $dom = HTML5_Parser::parse($html);
71 $items = $dom->getElementsByTagName('link');
73 foreach($items as $item) {
74 $x = $item->getAttribute('rel');
76 $link = $item->getAttribute('href');
78 file_put_contents('salmon.out', "\n" . 'Fetch key via HTML body' . $link . "\n", FILE_APPEND);
87 $arr = fetch_xrd_links($link);
92 if($a['@attributes']['rel'] === 'magic-public-key') {
93 $ret[] = $a['@attributes']['href'];
101 // We have found at least one key URL
102 // If it's inline, parse it - otherwise get the key
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);
110 $ret[$x] = substr($ret[$x],5);
113 $ret[$x] = fetch_url($ret[$x]);
118 file_put_contents('salmon.out', "\n" . 'Key located: ' . print_r($ret,true) . "\n", FILE_APPEND);
120 if(count($ret) == 1) {
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.
131 foreach($ret as $a) {
132 $hash = base64url_encode(hash('sha256',$a));
133 if($hash == $keyhash)