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