2011-08-07 19:32:48 +04:00
< ? php
/**
* ownCloud
*
* @ author Frank Karlitschek
2012-05-26 21:14:24 +04:00
* @ copyright 2012 Frank Karlitschek frank @ owncloud . org
2011-08-07 19:32:48 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation ; either
* version 3 of the License , or any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details .
*
* You should have received a copy of the GNU Affero General Public
* License along with this library . If not , see < http :// www . gnu . org / licenses />.
*
*/
2011-08-10 19:24:38 +04:00
// Todo:
2011-08-20 13:53:14 +04:00
// - Crypt/decrypt button in the userinterface
// - Setting if crypto should be on by default
// - Add a setting "Don´ t encrypt files larger than xx because of performance reasons"
2012-03-21 14:57:15 +04:00
// - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension)
2011-08-20 13:53:14 +04:00
// - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster
// - IMPORTANT! Check if the block lenght of the encrypted data stays the same
2011-08-10 19:24:38 +04:00
2012-09-06 01:28:59 +04:00
require_once 'Crypt_Blowfish/Blowfish.php' ;
2011-08-07 19:32:48 +04:00
/**
* This class is for crypting and decrypting
*/
class OC_Crypt {
2011-11-24 04:44:54 +04:00
static private $bf = null ;
2011-08-07 19:32:48 +04:00
2012-09-07 17:22:01 +04:00
public static function loginListener ( $params ) {
2012-10-29 02:58:08 +04:00
self :: init ( $params [ 'uid' ], $params [ 'password' ]);
2011-11-24 04:44:54 +04:00
}
2011-08-10 19:24:38 +04:00
2012-11-02 22:53:02 +04:00
public static function init ( $login , $password ) {
2012-06-21 20:35:12 +04:00
$view = new OC_FilesystemView ( '/' );
2012-09-07 17:22:01 +04:00
if ( ! $view -> file_exists ( '/' . $login )) {
2012-06-21 20:35:12 +04:00
$view -> mkdir ( '/' . $login );
2012-06-16 01:48:39 +04:00
}
OC_FileProxy :: $enabled = false ;
2012-09-07 17:22:01 +04:00
if ( ! $view -> file_exists ( '/' . $login . '/encryption.key' )) { // does key exist?
2012-10-29 02:58:08 +04:00
OC_Crypt :: createkey ( $login , $password );
2012-06-16 01:48:39 +04:00
}
2012-06-21 20:35:12 +04:00
$key = $view -> file_get_contents ( '/' . $login . '/encryption.key' );
2012-06-16 01:48:39 +04:00
OC_FileProxy :: $enabled = true ;
$_SESSION [ 'enckey' ] = OC_Crypt :: decrypt ( $key , $password );
}
2012-05-31 15:25:07 +04:00
2011-08-11 19:49:36 +04:00
2011-11-24 04:44:54 +04:00
/**
* get the blowfish encryption handeler for a key
* @ param string $key ( optional )
2012-02-06 00:49:22 +04:00
* @ return Crypt_Blowfish
2011-11-24 04:44:54 +04:00
*
* if the key is left out , the default handeler will be used
*/
2012-09-07 17:22:01 +04:00
public static function getBlowfish ( $key = '' ) {
if ( $key ) {
2011-11-24 04:44:54 +04:00
return new Crypt_Blowfish ( $key );
} else {
2012-09-07 17:22:01 +04:00
if ( ! isset ( $_SESSION [ 'enckey' ])) {
2011-11-24 04:44:54 +04:00
return false ;
}
2012-09-07 17:22:01 +04:00
if ( ! self :: $bf ) {
2011-11-24 04:44:54 +04:00
self :: $bf = new Crypt_Blowfish ( $_SESSION [ 'enckey' ]);
}
return self :: $bf ;
}
}
2011-08-10 19:24:38 +04:00
2012-02-06 00:49:22 +04:00
public static function createkey ( $username , $passcode ) {
// generate a random key
2012-10-29 02:58:08 +04:00
$key = mt_rand ( 10000 , 99999 ) . mt_rand ( 10000 , 99999 ) . mt_rand ( 10000 , 99999 ) . mt_rand ( 10000 , 99999 );
2011-08-10 19:24:38 +04:00
2012-02-06 00:49:22 +04:00
// encrypt the key with the passcode of the user
2012-10-29 02:58:08 +04:00
$enckey = OC_Crypt :: encrypt ( $key , $passcode );
2011-08-11 19:49:36 +04:00
2012-02-06 00:49:22 +04:00
// Write the file
$proxyEnabled = OC_FileProxy :: $enabled ;
OC_FileProxy :: $enabled = false ;
$view = new OC_FilesystemView ( '/' . $username );
2012-10-29 02:58:08 +04:00
$view -> file_put_contents ( '/encryption.key' , $enckey );
2012-02-06 00:49:22 +04:00
OC_FileProxy :: $enabled = $proxyEnabled ;
2011-08-11 19:49:36 +04:00
}
2011-11-24 04:44:54 +04:00
public static function changekeypasscode ( $oldPassword , $newPassword ) {
2012-09-07 17:22:01 +04:00
if ( OCP\User :: isLoggedIn ()) {
2012-05-01 20:50:31 +04:00
$username = OCP\USER :: getUser ();
2011-11-24 04:44:54 +04:00
$view = new OC_FilesystemView ( '/' . $username );
2011-08-11 19:49:36 +04:00
// read old key
2011-11-24 04:44:54 +04:00
$key = $view -> file_get_contents ( '/encryption.key' );
2011-08-11 19:49:36 +04:00
// decrypt key with old passcode
2011-11-24 04:44:54 +04:00
$key = OC_Crypt :: decrypt ( $key , $oldPassword );
2011-08-11 19:49:36 +04:00
// encrypt again with new passcode
2011-11-24 04:44:54 +04:00
$key = OC_Crypt :: encrypt ( $key , $newPassword );
2011-08-11 19:49:36 +04:00
// store the new key
2011-11-24 04:44:54 +04:00
$view -> file_put_contents ( '/encryption.key' , $key );
2011-08-11 19:49:36 +04:00
}
2011-08-10 19:24:38 +04:00
}
2011-08-07 19:32:48 +04:00
/**
* @ brief encrypts an content
* @ param $content the cleartext message you want to encrypt
2011-11-24 04:44:54 +04:00
* @ param $key the encryption key ( optional )
2011-08-07 19:32:48 +04:00
* @ returns encrypted content
*
* This function encrypts an content
*/
2011-11-24 04:44:54 +04:00
public static function encrypt ( $content , $key = '' ) {
$bf = self :: getBlowfish ( $key );
2012-04-17 22:56:53 +04:00
return $bf -> encrypt ( $content );
2011-08-07 19:32:48 +04:00
}
2011-11-24 04:44:54 +04:00
/**
* @ brief decryption of an content
* @ param $content the cleartext message you want to decrypt
* @ param $key the encryption key ( optional )
* @ returns cleartext content
*
* This function decrypts an content
*/
public static function decrypt ( $content , $key = '' ) {
$bf = self :: getBlowfish ( $key );
2012-04-17 22:56:53 +04:00
$data = $bf -> decrypt ( $content );
2012-06-16 01:48:39 +04:00
return $data ;
2011-11-24 04:44:54 +04:00
}
2011-08-07 19:32:48 +04:00
2011-10-21 19:02:11 +04:00
/**
* @ brief encryption of a file
2012-04-17 22:56:53 +04:00
* @ param string $source
* @ param string $target
* @ param string $key the decryption key
2011-10-21 19:02:11 +04:00
*
* This function encrypts a file
*/
2012-04-17 22:56:53 +04:00
public static function encryptFile ( $source , $target , $key = '' ) {
$handleread = fopen ( $source , " rb " );
2012-10-23 10:01:09 +04:00
if ( $handleread != false ) {
2012-04-17 22:56:53 +04:00
$handlewrite = fopen ( $target , " wb " );
2011-08-10 19:24:38 +04:00
while ( ! feof ( $handleread )) {
$content = fread ( $handleread , 8192 );
$enccontent = OC_CRYPT :: encrypt ( $content , $key );
fwrite ( $handlewrite , $enccontent );
}
fclose ( $handlewrite );
2012-04-17 22:56:53 +04:00
fclose ( $handleread );
2011-08-10 19:24:38 +04:00
}
}
2012-04-17 22:56:53 +04:00
/**
* @ brief decryption of a file
* @ param string $source
* @ param string $target
* @ param string $key the decryption key
*
* This function decrypts a file
*/
public static function decryptFile ( $source , $target , $key = '' ) {
$handleread = fopen ( $source , " rb " );
2012-10-23 10:01:09 +04:00
if ( $handleread != false ) {
2012-04-17 22:56:53 +04:00
$handlewrite = fopen ( $target , " wb " );
2011-08-10 19:24:38 +04:00
while ( ! feof ( $handleread )) {
$content = fread ( $handleread , 8192 );
$enccontent = OC_CRYPT :: decrypt ( $content , $key );
2012-09-07 17:22:01 +04:00
if ( feof ( $handleread )) {
2012-06-16 01:48:39 +04:00
$enccontent = rtrim ( $enccontent , " \0 " );
}
2011-08-10 19:24:38 +04:00
fwrite ( $handlewrite , $enccontent );
}
fclose ( $handlewrite );
2012-04-17 22:56:53 +04:00
fclose ( $handleread );
2011-08-10 19:24:38 +04:00
}
}
2012-08-29 10:42:49 +04:00
2011-10-21 19:02:11 +04:00
/**
* encrypt data in 8192 b sized blocks
*/
2012-09-07 17:22:01 +04:00
public static function blockEncrypt ( $data , $key = '' ) {
2011-10-21 19:02:11 +04:00
$result = '' ;
2012-09-07 17:22:01 +04:00
while ( strlen ( $data )) {
2012-11-02 22:53:02 +04:00
$result .= self :: encrypt ( substr ( $data , 0 , 8192 ), $key );
2012-10-29 02:58:08 +04:00
$data = substr ( $data , 8192 );
2011-10-21 19:02:11 +04:00
}
return $result ;
}
2012-08-29 10:42:49 +04:00
2011-10-21 19:02:11 +04:00
/**
* decrypt data in 8192 b sized blocks
*/
2012-11-02 22:53:02 +04:00
public static function blockDecrypt ( $data , $key = '' , $maxLength = 0 ) {
2011-10-21 19:02:11 +04:00
$result = '' ;
2012-09-07 17:22:01 +04:00
while ( strlen ( $data )) {
2012-11-02 22:53:02 +04:00
$result .= self :: decrypt ( substr ( $data , 0 , 8192 ), $key );
2012-10-29 02:58:08 +04:00
$data = substr ( $data , 8192 );
2011-10-21 19:02:11 +04:00
}
2012-09-07 17:22:01 +04:00
if ( $maxLength > 0 ) {
2012-10-29 02:58:08 +04:00
return substr ( $result , 0 , $maxLength );
2012-06-21 19:37:53 +04:00
} else {
return rtrim ( $result , " \0 " );
}
2011-10-21 19:02:11 +04:00
}
2011-08-07 19:32:48 +04:00
}