]> git.mxchange.org Git - friendica.git/blob - include/crypto.php
Issue 2957: The avatar problem with mastodon should now finally be solved
[friendica.git] / include / crypto.php
1 <?php
2
3 require_once 'library/ASNValue.class.php';
4 require_once 'library/asn1.php';
5
6 // supported algorithms are 'sha256', 'sha1'
7
8 function rsa_sign($data, $key, $alg = 'sha256') {
9         openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
10         return $sig;
11 }
12
13 function rsa_verify($data, $sig, $key, $alg = 'sha256') {
14         return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
15 }
16
17 function DerToPem($Der, $Private = false) {
18         //Encode:
19         $Der = base64_encode($Der);
20         //Split lines:
21         $lines = str_split($Der, 65);
22         $body = implode("\n", $lines);
23         //Get title:
24         $title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
25         //Add wrapping:
26         $result = "-----BEGIN {$title}-----\n";
27         $result .= $body . "\n";
28         $result .= "-----END {$title}-----\n";
29
30         return $result;
31 }
32
33 function DerToRsa($Der) {
34         //Encode:
35         $Der = base64_encode($Der);
36         //Split lines:
37         $lines = str_split($Der, 64);
38         $body = implode("\n", $lines);
39         //Get title:
40         $title = 'RSA PUBLIC KEY';
41         //Add wrapping:
42         $result = "-----BEGIN {$title}-----\n";
43         $result .= $body . "\n";
44         $result .= "-----END {$title}-----\n";
45
46         return $result;
47 }
48
49 function pkcs8_encode($Modulus, $PublicExponent) {
50         //Encode key sequence
51         $modulus = new ASNValue(ASNValue::TAG_INTEGER);
52         $modulus->SetIntBuffer($Modulus);
53         $publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
54         $publicExponent->SetIntBuffer($PublicExponent);
55         $keySequenceItems = array($modulus, $publicExponent);
56         $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
57         $keySequence->SetSequence($keySequenceItems);
58         //Encode bit string
59         $bitStringValue = $keySequence->Encode();
60         $bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte
61         $bitString = new ASNValue(ASNValue::TAG_BITSTRING);
62         $bitString->Value = $bitStringValue;
63         //Encode body
64         $bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode();
65         $body = new ASNValue(ASNValue::TAG_SEQUENCE);
66         $body->Value = $bodyValue;
67         //Get DER encoded public key:
68         $PublicDER = $body->Encode();
69         return $PublicDER;
70 }
71
72 function pkcs1_encode($Modulus, $PublicExponent) {
73         //Encode key sequence
74         $modulus = new ASNValue(ASNValue::TAG_INTEGER);
75         $modulus->SetIntBuffer($Modulus);
76         $publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
77         $publicExponent->SetIntBuffer($PublicExponent);
78         $keySequenceItems = array($modulus, $publicExponent);
79         $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
80         $keySequence->SetSequence($keySequenceItems);
81         //Encode bit string
82         $bitStringValue = $keySequence->Encode();
83         return $bitStringValue;
84 }
85
86 function metopem($m, $e) {
87         $der = pkcs8_encode($m, $e);
88         $key = DerToPem($der, false);
89         return $key;
90 }
91
92 function pubrsatome($key,&$m,&$e) {
93         require_once('library/asn1.php');
94         require_once('include/salmon.php');
95
96         $lines = explode("\n", $key);
97         unset($lines[0]);
98         unset($lines[count($lines)]);
99         $x = base64_decode(implode('', $lines));
100
101         $r = ASN_BASE::parseASNString($x);
102
103         $m = base64url_decode($r[0]->asnData[0]->asnData);
104         $e = base64url_decode($r[0]->asnData[1]->asnData);
105 }
106
107
108 function rsatopem($key) {
109         pubrsatome($key, $m, $e);
110         return metopem($m, $e);
111 }
112
113 function pemtorsa($key) {
114         pemtome($key, $m, $e);
115         return metorsa($m, $e);
116 }
117
118 function pemtome($key, &$m, &$e) {
119         require_once('include/salmon.php');
120         $lines = explode("\n", $key);
121         unset($lines[0]);
122         unset($lines[count($lines)]);
123         $x = base64_decode(implode('', $lines));
124
125         $r = ASN_BASE::parseASNString($x);
126
127         $m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData);
128         $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
129 }
130
131 function metorsa($m, $e) {
132         $der = pkcs1_encode($m, $e);
133         $key = DerToRsa($der);
134         return $key;
135 }
136
137 function salmon_key($pubkey) {
138         pemtome($pubkey, $m, $e);
139         return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true) ;
140 }
141
142 function new_keypair($bits) {
143         $openssl_options = array(
144                 'digest_alg'       => 'sha1',
145                 'private_key_bits' => $bits,
146                 'encrypt_key'      => false
147         );
148
149         $conf = get_config('system', 'openssl_conf_file');
150         if ($conf) {
151                 $openssl_options['config'] = $conf;
152         }
153         $result = openssl_pkey_new($openssl_options);
154
155         if (empty($result)) {
156                 logger('new_keypair: failed');
157                 return false;
158         }
159
160         // Get private key
161         $response = array('prvkey' => '', 'pubkey' => '');
162
163         openssl_pkey_export($result, $response['prvkey']);
164
165         // Get public key
166         $pkey = openssl_pkey_get_details($result);
167         $response['pubkey'] = $pkey["key"];
168
169         return $response;
170 }