]> git.mxchange.org Git - friendica.git/blob - src/Protocol/Salmon/Format/Magic.php
Merge pull request #12819 from HankG/add-tables-to-optimize
[friendica.git] / src / Protocol / Salmon / Format / Magic.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Protocol\Salmon\Format;
23
24 use Friendica\Util\Strings;
25 use phpseclib3\Math\BigInteger;
26
27 /**
28  * This custom public RSA key format class is meant to be used with the \phpseclib3\Crypto\RSA::addFileFormat method.
29  *
30  * It handles Salmon's specific magic key string starting with "RSA." and which MIME type is application/magic-key or
31  * application/magic-public-key
32  *
33  * @see https://web.archive.org/web/20160506073138/http://salmon-protocol.googlecode.com:80/svn/trunk/draft-panzer-magicsig-01.html#anchor13
34  */
35 class Magic
36 {
37         public static function load($key, $password = ''): array
38         {
39                 if (!is_string($key)) {
40                         throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
41                 }
42
43                 $key_info = explode('.', $key);
44
45                 if (count($key_info) !== 3) {
46                         throw new \UnexpectedValueException('Key should have three components separated by periods');
47                 }
48
49                 if ($key_info[0] !== 'RSA') {
50                         throw new \UnexpectedValueException('Key first component should be "RSA"');
51                 }
52
53                 if (preg_match('#[+/]#', $key_info[1])
54                         || preg_match('#[+/]#', $key_info[1])
55                 ) {
56                         throw new \UnexpectedValueException('Wrong encoding, expecting Base64URLencoding');
57                 }
58
59                 $m = Strings::base64UrlDecode($key_info[1]);
60                 $e = Strings::base64UrlDecode($key_info[2]);
61
62                 if (!$m || !$e) {
63                         throw new \UnexpectedValueException('Base64 decoding produced an error');
64                 }
65
66                 return [
67                         'modulus'        => new BigInteger($m, 256),
68                         'publicExponent' => new BigInteger($e, 256),
69                         'isPublicKey'    => true,
70                 ];
71         }
72
73         public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []): string
74         {
75                 return 'RSA.' . Strings::base64UrlEncode($n->toBytes(), true) . '.' . Strings::base64UrlEncode($e->toBytes(), true);
76         }
77 }