aboutsummaryrefslogtreecommitdiffstats
path: root/include/crypto.php
blob: 3c68f4ddda1785f3fe399b0e06ada75acfb4a765 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php /** @file */

function rsa_sign($data,$key,$alg = 'sha256') {
	if(! $key)
		return 'no key';
	$sig = '';
	if(intval(OPENSSL_ALGO_SHA256) && $alg === 'sha256')
		$alg = OPENSSL_ALGO_SHA256;
	openssl_sign($data,$sig,$key,$alg);
	return $sig;
}

function rsa_verify($data,$sig,$key,$alg = 'sha256') {

	if(! $key)
		return false;

	if(intval(OPENSSL_ALGO_SHA256) && $alg === 'sha256')
		$alg = OPENSSL_ALGO_SHA256;
	$verify = openssl_verify($data,$sig,$key,$alg);
	return $verify;
}

function pkcs5_pad ($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

function pkcs5_unpad($text)
{
    $pad = ord($text{strlen($text)-1});
    if ($pad > strlen($text)) return false;
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
    return substr($text, 0, -1 * $pad);
} 

function AES256CBC_encrypt($data,$key,$iv) {
	return mcrypt_encrypt(
		MCRYPT_RIJNDAEL_128, 
		str_pad($key,32,"\0"), 
		pkcs5_pad($data,16), 
		MCRYPT_MODE_CBC, 
		str_pad($iv,16,"\0"));
}

function AES256CBC_decrypt($data,$key,$iv) {
	return pkcs5_unpad(mcrypt_decrypt(
		MCRYPT_RIJNDAEL_128, 
		str_pad($key,32,"\0"), 
		$data, 
		MCRYPT_MODE_CBC, 
		str_pad($iv,16,"\0")));
}

function crypto_encapsulate($data,$pubkey,$alg='aes256cbc') {
	if($alg === 'aes256cbc')
		return aes_encapsulate($data,$pubkey);

}


function aes_encapsulate($data,$pubkey) {
	if(! $pubkey)
		logger('aes_encapsulate: no key. data: ' . $data);
	$key = random_string(32,RANDOM_STRING_TEXT);
	$iv  = random_string(16,RANDOM_STRING_TEXT);
	$result['data'] = base64url_encode(AES256CBC_encrypt($data,$key,$iv),true);
	// log the offending call so we can track it down
	if(! openssl_public_encrypt($key,$k,$pubkey)) {
		$x = debug_backtrace();
		logger('aes_encapsulate: RSA failed. ' . print_r($x[0],true));
	}
	$result['alg'] = 'aes256cbc';
 	$result['key'] = base64url_encode($k,true);
	openssl_public_encrypt($iv,$i,$pubkey);
	$result['iv'] = base64url_encode($i,true);
	return $result;
}

function crypto_unencapsulate($data,$prvkey) {
	if(! $data)
		return;
	$alg = ((array_key_exists('alg',$data)) ? $data['alg'] : 'aes256cbc');
	if($alg === 'aes256cbc')
		return aes_unencapsulate($data,$prvkey);

}


function aes_unencapsulate($data,$prvkey) {
	openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey);
	openssl_private_decrypt(base64url_decode($data['iv']),$i,$prvkey);
	return AES256CBC_decrypt(base64url_decode($data['data']),$k,$i);
}

function new_keypair($bits) {

	$openssl_options = array(
		'digest_alg'       => 'sha1',
		'private_key_bits' => $bits,
		'encrypt_key'      => false 
	);

	$conf = get_config('system','openssl_conf_file');
	if($conf)
		$openssl_options['config'] = $conf;
	
	$result = openssl_pkey_new($openssl_options);

	if(empty($result)) {
		logger('new_keypair: failed');
		return false;
	}

	// Get private key

	$response = array('prvkey' => '', 'pubkey' => '');

	openssl_pkey_export($result, $response['prvkey']);

	// Get public key
	$pkey = openssl_pkey_get_details($result);
	$response['pubkey'] = $pkey["key"];

	return $response;

}

function pkcs1to8($oldkey,$len) {

	if($len == 4096)
		$c = 'g';
	if($len == 2048)
		$c = 'Q';

	if(strstr($oldkey,'BEGIN PUBLIC'))
		return $oldkey;

	$oldkey = str_replace('-----BEGIN RSA PUBLIC KEY-----', '', $oldkey);
	$oldkey = trim(str_replace('-----END RSA PUBLIC KEY-----', '', $oldkey));
	$key = 'MIICIjANBgkqhkiG9w0BAQEFAAOCA' . $c . '8A' . str_replace("\n", '', $oldkey);
	$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
	return $key;
}

function pkcs8to1($oldkey,$len) {

	if(strstr($oldkey,'BEGIN RSA'))
		return $oldkey;

	$oldkey = str_replace('-----BEGIN PUBLIC KEY-----', '', $oldkey);
	$oldkey = trim(str_replace('-----END PUBLIC KEY-----', '', $oldkey));
	$key = str_replace("\n",'',$oldkey);
	$key = substr($key,32);
	$key = "-----BEGIN RSA PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END RSA PUBLIC KEY-----";
	return $key;
}