EncryptionUtil::createInstructionFile()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 21
rs 9.7998
cc 2
nc 2
nop 5
1
<?php
2
class EncryptionUtil{
3
	public static $INSTRUCTION_SUFFIX = ".instruction";
4
	public static function genereateOnceUsedKey($length=32){
5
		$randpwd = "";  
6
		for ($i = 0; $i < $length; $i++)  
7
		{  
8
			$randpwd .= chr(mt_rand(33, 126));  
9
		}  
10
		return $randpwd;   
11
	}
12
	public static function encode_AES_ECB($data,$secret_key){
13
		$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_ECB,'');
14
15
		$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_ECB);
16
		$pad = $blocksize - (strlen($data) % $blocksize);
17
		$data = $data . str_repeat(chr($pad), $pad);
18
19
		$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
20
		mcrypt_generic_init($td,$secret_key,$iv);
21
		$encrypted = mcrypt_generic($td,$data);
22
		mcrypt_generic_deinit($td);
23
		return $encrypted;
24
	}
25
	public static function decode_AES_ECB($data,$secret_key){
26
		$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_ECB,'');
27
		$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
28
		mcrypt_generic_init($td,$secret_key,$iv);
29
		$data = mdecrypt_generic($td,$data);
30
		mcrypt_generic_deinit($td);
31
		mcrypt_module_close($td);
32
33
		$dec_s = strlen($data);
34
		$padding = ord($data[$dec_s-1]);
35
		$data = substr($data, 0, -$padding);
36
37
		return trim($data);
38
	}
39
	public static function getKeyEncryptionAlgm($encryptionMaterials){
40
		if(is_array($encryptionMaterials)){
41
			return "RSA";
42
		}else{
43
			return "AES";
44
		}
45
	}
46
	public static function getAdjustedRange($range,$blocksize){
47
		$a = $range["start"];
48
		$b = $range["end"];
49
		$a = $a - ($a%$blocksize)-$blocksize;
50
		if($a < 0)
51
			$a = 0;
52
53
		$b = $b+$blocksize-$b%$blocksize+$blocksize;
54
55
		return array("start"=>$a,"end"=>$b);
56
	}
57
	public static function encodeCek($encryptionMaterials,$cek){
58
		$encrypKeyAlg = EncryptionUtil::getKeyEncryptionAlgm($encryptionMaterials);
59
		if($encrypKeyAlg === "AES"){
60
			$secretKey = $encryptionMaterials;
61
			$encryptedSek = EncryptionUtil::encode_AES_ECB($cek,$secretKey);
62
			if(empty($encryptedSek))
63
				throw new Ks3ClientException("can not encode cek useing AES");
64
		}else if($encrypKeyAlg === "RSA"){
65
			$encryptedSek = "";
66
			openssl_public_encrypt($cek,$encryptedSek, $encryptionMaterials[0]);
67
			if(empty($encryptedSek))
68
				throw new Ks3ClientException("can not encode cek useing RSA");
69
		}
70
		return $encryptedSek;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $encryptedSek does not seem to be defined for all execution paths leading up to this point.
Loading history...
71
	}
72
	public static function decodeCek($encryptionMaterials,$cekEncrypted){
73
		$encrypKeyAlg = EncryptionUtil::getKeyEncryptionAlgm($encryptionMaterials);
74
		if($encrypKeyAlg === "AES"){
75
			$secretKey = $encryptionMaterials;
76
			$cek = EncryptionUtil::decode_AES_ECB($cekEncrypted,$secretKey);
77
			if(empty($cek))
78
				throw new Ks3ClientException("can not decode cek useing AES,secret key maybe not correct");
79
		}else if($encrypKeyAlg === "RSA"){
80
			$cek = "";
81
			openssl_private_decrypt($cekEncrypted,$cek, $encryptionMaterials[1]);
82
			if(empty($cek))
83
				throw new Ks3ClientException("can not decode cek useing RSA,public/private key pair maybe not correct");
84
		}
85
		return $cek;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cek does not seem to be defined for all execution paths leading up to this point.
Loading history...
86
	}
87
	public static function getPKCS5EncrypedLength($length,$blocksize){
88
		$pad = $blocksize - $length%$blocksize;
89
		return $length+$pad;
90
	}
91
	//pkcs5填充
92
	public static function PKCS5Padding($data,$blocksize){
93
		$pad = $blocksize - strlen($data)%$blocksize;
94
		for($i = 0;$i < $pad;$i++){
95
			$data.= chr($pad);
96
		}
97
		return $data;
98
	}
99
	public static function updateContentMD5Header($req){
100
		if(!is_array($req))
101
			return $req;
102
		if(isset($req["ObjectMeta"])){
103
			$meta = $req["ObjectMeta"];
104
		}else{
105
			return $req;
106
		}
107
		if(is_array($meta) && isset($meta["Content-MD5"])){
108
			$md5 = $meta["Content-MD5"];
109
		}else{
110
			return $req;
111
		}
112
		if(empty($md5)){
113
			return $req;
114
		}else{
115
			$req["ObjectMeta"]["Content-MD5"] = NULL;
116
			$req["UserMeta"]["x-kss-meta-x-kss-unencrypted-content-md5"] = $md5;
117
		}
118
		return $req;
119
	}
120
	public static function metaTextLength($req){
121
		if(!is_array($req))
122
			return -1;
123
		if(isset($req["ObjectMeta"])){
124
			$meta = $req["ObjectMeta"];
125
		}else{
126
			return -1;
127
		}
128
		if(is_array($meta) && isset($meta["Content-Length"])){
129
			$length = $meta["Content-Length"];
130
			return $length;
131
		}else
132
			return -1;
133
	}
134
	public static function plainTextLength($args){
135
		if(isset($args["Content"])){
136
			if(is_array($args["Content"])){
137
				$content = $args["Content"]["content"];
138
				$seek_position = 0;
139
				$resourceLength = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $resourceLength is dead and can be removed.
Loading history...
140
				$length = -1;
141
				$isFile = FALSE;
142
143
				if (!is_resource($content)){
144
					$isFile = TRUE;
145
					//如果之前用户已经转化为GBK则不转换
146
					if(Utils::chk_chinese($content)&&!Utils::check_char($content)){
147
						$content = iconv('utf-8','gbk',$content);
148
					}
149
					if(!file_exists($content))
150
						throw new Ks3ClientException("the specified file does not exist ");
151
					$length = Utils::getFileSize($content);
152
					$content = fopen($content,"r");
153
				}else{
154
					$stats = fstat($content);
155
					if ($stats && $stats["size"] >= 0){
0 ignored issues
show
Bug Best Practice introduced by
The expression $stats of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
156
						$length = $stats["size"];	
157
					}
158
				}
159
				$resourceLength = $length;
160
				//优先取用户设置seek_position,没有的话取ftell
161
				if(isset($args["Content"]["seek_position"])&&$args["Content"]["seek_position"]>0){
162
					$seek_position = $args["Content"]["seek_position"];
163
				}else if(!$isFile){
164
					$seek_position = ftell($content);
165
					if($seek_position<0)
166
						$seek_position = 0;
167
					fseek($content,0);
168
				}
169
170
				$lengthInMeta = -1;
171
				if(isset($args["ObjectMeta"]["Content-Length"])){
172
					$lengthInMeta = $args["ObjectMeta"]["Content-Length"];
173
				}
174
				if($lengthInMeta > 0){
175
					$length = $lengthInMeta;
176
				}else if($resourceLength > 0){
177
					//根据seek_position计算实际长度
178
					$length = $resourceLength - $seek_position;
179
				}
180
				if($length <= 0)
181
					throw new Ks3ClientException("calculate content length failed,unexpected contetn length ".$length);
182
				return $length;
183
			}else{
184
				$content = $args["Content"];
185
				$lengthInMeta = EncryptionUtil::metaTextLength($args);
186
				$length = strlen($content);
187
				if($length<$lengthInMeta||$lengthInMeta <= 0)
188
					return $length;
189
				else
190
					return $lengthInMeta;
191
			}
192
		}
193
		return -1;
194
	}
195
	public static function initMultipartUploadContext($initResult,$iv,$cek,$encryptedCek,$matdesc="{}"){
196
		$cacheDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR;
197
		$encryptionDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR;
198
		if(!is_dir($cacheDir))
199
			mkdir($cacheDir);
200
		if(!is_dir($encryptionDir))
201
			mkdir($encryptionDir);
202
		if(is_array($matdesc)){
203
			$matdesc = json_encode($matdesc);
204
		}
205
		$initResult["firstIv"] = base64_encode($iv);
206
		$initResult["nextIv"] = base64_encode($iv);
207
		$initResult["cek"] = base64_encode($cek);
208
		$initResult["encryptedCek"] = base64_encode($encryptedCek);
209
		$initResult["lastPart"] = FALSE;
210
		$initResult["matdesc"] = $matdesc;
211
		$json = json_encode($initResult);
212
		$file = EncryptionUtil::openfile($encryptionDir.$initResult["UploadId"], "w");
213
		fwrite($file, $json);
214
		fclose($file);
215
	}
216
	public static function updateMultipartUploadContext($UploadId,$iv,$lastPart = FALSE){
217
		$encryptionDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR;
218
		$content = EncryptionUtil::getMultipartUploadContext($UploadId);
219
		$content["nextIv"] = base64_encode($iv);
220
		$content["lastPart"] = $lastPart;
221
		$json = json_encode($content);
222
		$file = EncryptionUtil::openfile($encryptionDir.$UploadId, "w");
223
		fwrite($file, $json);
224
		fclose($file);
225
	}
226
	public static function getMultipartUploadContext($UploadId){
227
		$encryptionDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR;
228
		if(!EncryptionUtil::multipartUploadContextExists($UploadId))
229
			throw new Ks3ClientException("can not found multipart upload context in cache dir");
230
		$jsonString = file_get_contents($encryptionDir.$UploadId);
231
		$arry = json_decode($jsonString,TRUE);
232
		return $arry;
233
	}
234
	public static function deleteMultipartUploadContext($UploadId){
235
		$encryptionDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR;
236
		@unlink($encryptionDir.$UploadId);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

236
		/** @scrutinizer ignore-unhandled */ @unlink($encryptionDir.$UploadId);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
237
	}
238
	public static function multipartUploadContextExists($UploadId){
239
		$encryptionDir = KS3_API_PATH.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR;
240
		return file_exists($encryptionDir.$UploadId);
241
	}
242
	public static function openfile($path,$mode){
243
		$file = fopen($path, $mode);
244
		if($file)
0 ignored issues
show
introduced by
$file is of type resource, thus it always evaluated to false.
Loading history...
245
			return $file;
246
		else
247
			throw new Ks3ClientException("open file ".$path." error");
248
	}
249
	//matdesc为字符串或array数据类型。
250
	public static function createInstructionFile($bucket,$key,$cek,$iv,$matdesc="{}"){
251
		if(is_array($matdesc)){
252
			$matdesc = json_encode($matdesc);
253
		}
254
		$key = $key.EncryptionUtil::$INSTRUCTION_SUFFIX;
255
256
		$instruction = json_encode(array(
257
			"x-kss-key"=>$cek,
258
			"x-kss-iv"=>$iv,
259
			"x-kss-matdesc"=>$matdesc
260
			));
261
262
		$req = array(
263
			"Bucket"=>$bucket,
264
			"Key"=>$key,
265
			"Content"=>$instruction,
266
			"UserMeta"=>array(
267
				"x-kss-meta-x-kss-crypto-instr-file"=>base64_encode($key)
268
				)
269
			);
270
		return $req;
271
	}
272
	public static function isInstructionFile($s3Object){
273
		$meta = $s3Object["Meta"];
274
		if(isset($meta["UserMeta"]["x-kss-meta-x-kss-crypto-instr-file"]))
275
			return TRUE;
276
		return FALSE;
277
	}
278
}
279
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...