3 use Friendica\Core\Config;
5 require_once 'library/ASNValue.class.php';
6 require_once 'library/asn1.php';
8 // supported algorithms are 'sha256', 'sha1'
10 function rsa_sign($data, $key, $alg = 'sha256') {
11 openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
15 function rsa_verify($data, $sig, $key, $alg = 'sha256') {
16 return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
19 function DerToPem($Der, $Private = false) {
21 $Der = base64_encode($Der);
23 $lines = str_split($Der, 65);
24 $body = implode("\n", $lines);
26 $title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
28 $result = "-----BEGIN {$title}-----\n";
29 $result .= $body . "\n";
30 $result .= "-----END {$title}-----\n";
35 function DerToRsa($Der) {
37 $Der = base64_encode($Der);
39 $lines = str_split($Der, 64);
40 $body = implode("\n", $lines);
42 $title = 'RSA PUBLIC KEY';
44 $result = "-----BEGIN {$title}-----\n";
45 $result .= $body . "\n";
46 $result .= "-----END {$title}-----\n";
51 function pkcs8_encode($Modulus, $PublicExponent) {
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);
61 $bitStringValue = $keySequence->Encode();
62 $bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte
63 $bitString = new ASNValue(ASNValue::TAG_BITSTRING);
64 $bitString->Value = $bitStringValue;
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();
74 function pkcs1_encode($Modulus, $PublicExponent) {
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);
84 $bitStringValue = $keySequence->Encode();
85 return $bitStringValue;
88 function metopem($m, $e) {
89 $der = pkcs8_encode($m, $e);
90 $key = DerToPem($der, false);
94 function pubrsatome($key,&$m,&$e) {
95 require_once('library/asn1.php');
96 require_once('include/salmon.php');
98 $lines = explode("\n", $key);
100 unset($lines[count($lines)]);
101 $x = base64_decode(implode('', $lines));
103 $r = ASN_BASE::parseASNString($x);
105 $m = base64url_decode($r[0]->asnData[0]->asnData);
106 $e = base64url_decode($r[0]->asnData[1]->asnData);
110 function rsatopem($key) {
111 pubrsatome($key, $m, $e);
112 return metopem($m, $e);
115 function pemtorsa($key) {
116 pemtome($key, $m, $e);
117 return metorsa($m, $e);
120 function pemtome($key, &$m, &$e) {
121 require_once('include/salmon.php');
122 $lines = explode("\n", $key);
124 unset($lines[count($lines)]);
125 $x = base64_decode(implode('', $lines));
127 $r = ASN_BASE::parseASNString($x);
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);
133 function metorsa($m, $e) {
134 $der = pkcs1_encode($m, $e);
135 $key = DerToRsa($der);
139 function salmon_key($pubkey) {
140 pemtome($pubkey, $m, $e);
141 return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true) ;
144 function new_keypair($bits) {
145 $openssl_options = array(
146 'digest_alg' => 'sha1',
147 'private_key_bits' => $bits,
148 'encrypt_key' => false
151 $conf = Config::get('system', 'openssl_conf_file');
153 $openssl_options['config'] = $conf;
155 $result = openssl_pkey_new($openssl_options);
157 if (empty($result)) {
158 logger('new_keypair: failed');
163 $response = array('prvkey' => '', 'pubkey' => '');
165 openssl_pkey_export($result, $response['prvkey']);
168 $pkey = openssl_pkey_get_details($result);
169 $response['pubkey'] = $pkey["key"];