Changing user login pwd now correctly changes encryption key passphrase

All crypt unit tests are now passing
This commit is contained in:
Sam Tuke 2012-12-11 17:12:46 +00:00
parent 31cbb5a09f
commit 453fd66c70
5 changed files with 128 additions and 111 deletions

View File

@ -342,15 +342,10 @@ class Crypt {
// Remove padding
$noPadding = self::removePadding( $keyfileContent );
// Fetch IV from end of file
$iv = substr( $noPadding, -16 );
// Split into enc data and catfile
$catfile = self::splitIv( $noPadding );
// Remove IV and IV identifier text to expose encrypted content
$encryptedContent = substr( $noPadding, 0, -22 );
//trigger_error( "\n\n\$noPadding = ".var_export($noPadding)."\n\n\$iv = ".var_export($iv )."\n\n\$encryptedContent = ".var_export($encryptedContent) );
if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) {
if ( $plainContent = self::decrypt( $catfile['encrypted'], $catfile['iv'], $passphrase ) ) {
return $plainContent;
@ -493,12 +488,12 @@ class Crypt {
public static function keyDecryptKeyfile( $catfile, $keyfile, $privateKey ) {
// Decrypt the keyfile with the user's private key
$decryptedKey = self::keyDecrypt( $keyfile, $privateKey );
$decryptedKeyfile = self::keyDecrypt( $keyfile, $privateKey );
// trigger_error( "\$keyfile = ".var_export($keyfile, 1));
// Decrypt the catfile symmetrically using the decrypted keyfile
$decryptedData = self::symmetricDecryptFileContent( $catfile, $decryptedKey );
$decryptedData = self::symmetricDecryptFileContent( $catfile, $decryptedKeyfile );
return $decryptedData;
@ -704,12 +699,10 @@ class Crypt {
* This function decrypts an content
*/
public static function legacyDecrypt( $content, $passphrase = '' ) {
$passphrase = '';
//trigger_error("OC2 dec \$content = $content \$key = ".strlen($passphrase) );
$bf = self::getBlowfish( "67362885833455692562" );
$bf = self::getBlowfish( $passphrase );
// trigger_error(var_export($bf, 1) );

View File

@ -157,11 +157,11 @@ class Proxy extends \OC_FileProxy {
//$cached = \OC_FileCache_Cached::get( $path, '' );
$keyFile = Keymanager::getFileKey( $filePath );
$encryptedKeyfile = Keymanager::getFileKey( $filePath );
$session = new Session();
$decrypted = Crypt::keyDecryptKeyfile( $data, $keyFile, $session->getPrivateKey( $split[1] ) );
$decrypted = Crypt::keyDecryptKeyfile( $data, $encryptedKeyfile, $session->getPrivateKey( $split[1] ) );
} elseif (
Crypt::mode() == 'server'

View File

@ -302,10 +302,6 @@ class Stream {
*/
public function stream_write( $data ) {
// file_put_contents('/home/samtuke/newtmp.txt', 'stream_write('.$data.')' );
// Disable the file proxies so that encryption is not automatically attempted when the file is written to disk - we are handling that separately here and we don't want to get into an infinite loop
\OC_FileProxy::$enabled = false;

View File

@ -71,12 +71,20 @@ class Util {
# Admin UI:
## DONE: changing user password also changes encryption passphrase
## TODO: add support for optional recovery in case of lost passphrase / keys
## TODO: add admin optional required long passphrase for users
## TODO: add UI buttons for encrypt / decrypt everything
## TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc.
# Sharing:
## TODO: add support for encrypting to multiple public keys
## TODO: add support for decrypting to multiple private keys
# Integration testing:
## TODO: test new encryption with webdav

View File

@ -45,7 +45,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
$this->userId = 'admin';
$this->pass = 'admin';
}
function tearDown(){}
@ -64,8 +64,6 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
$iv = Encryption\Crypt::generateIv();
echo $iv;
$this->assertEquals( 16, strlen( $iv ) );
return $iv;
@ -223,84 +221,106 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
// Get file contents without using any wrapper to get it's actual contents on disk
$retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
//echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile";
// Check that the file was encrypted before being written to disk
$this->assertNotEquals( $this->dataShort, $retreivedCryptedFile );
// Get private key
$encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->userId, $this->view );
$key = Encryption\Keymanager::getFileKey( $filename );
$decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
$manualDecrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key );
// Get keyfile
$encryptedKeyfile = Encryption\Keymanager::getFileKey( $filename );
$decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
// Manually decrypt
$manualDecrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $decryptedKeyfile );
// Check that decrypted data matches
$this->assertEquals( $this->dataShort, $manualDecrypt );
}
// /**
// * @brief Test that data that is written by the crypto stream wrapper
// * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
// */
// function testSymmetricStreamEncryptLongFileContent() {
//
// // Generate a a random filename
// $filename = 'tmp-'.time();
//
// echo "\n\n\$filename = $filename\n\n";
//
// // Save long data as encrypted file using stream wrapper
// $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
//
// // Test that data was successfully written
// $this->assertTrue( is_int( $cryptedFile ) );
//
// // Get file contents without using any wrapper to get it's actual contents on disk
// $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
//
// // echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
//
// // Check that the file was encrypted before being written to disk
// $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
//
// // Manuallly split saved file into separate IVs and encrypted chunks
// $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
//
// //print_r($r);
//
// // Join IVs and their respective data chunks
// $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11] );//.$r[11], $r[12].$r[13], $r[14] );
//
// //print_r($e);
//
// // Manually fetch keyfile
// $keyfile = Encryption\Keymanager::getFileKey( $filename );
//
// // Set var for reassembling decrypted content
// $decrypt = '';
//
// // Manually decrypt chunk
// foreach ($e as $e) {
//
// // echo "\n\$encryptMe = $f";
//
// $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $keyfile );
//
// // Assemble decrypted chunks
// $decrypt .= $chunkDecrypt;
//
// //echo "\n\$chunkDecrypt = $chunkDecrypt";
//
// }
//
// $this->assertEquals( $this->dataLong.$this->dataLong, $decrypt );
//
// // Teardown
//
// $this->view->unlink( $filename );
//
// Encryption\Keymanager::deleteFileKey( $filename );
//
// }
/**
* @brief Test that data that is written by the crypto stream wrapper
* @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
* @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
* reassembly of its data
*/
function testSymmetricStreamEncryptLongFileContent() {
// Generate a a random filename
$filename = 'tmp-'.time();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
// Test that data was successfully written
$this->assertTrue( is_int( $cryptedFile ) );
// Get file contents without using any wrapper to get it's actual contents on disk
$retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
// echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
// Check that the file was encrypted before being written to disk
$this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
// Manuallly split saved file into separate IVs and encrypted chunks
$r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
//print_r($r);
// Join IVs and their respective data chunks
$e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11], $r[12].$r[13] );//.$r[11], $r[12].$r[13], $r[14] );
//print_r($e);
// Get private key
$encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->userId, $this->view );
$decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
// Get keyfile
$encryptedKeyfile = Encryption\Keymanager::getFileKey( $filename );
$decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
// Set var for reassembling decrypted content
$decrypt = '';
// Manually decrypt chunk
foreach ($e as $e) {
// echo "\n\$e = $e";
$chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $decryptedKeyfile );
// Assemble decrypted chunks
$decrypt .= $chunkDecrypt;
// echo "\n\$chunkDecrypt = $chunkDecrypt";
}
// echo "\n\$decrypt = $decrypt";
$this->assertEquals( $this->dataLong.$this->dataLong, $decrypt );
// Teardown
$this->view->unlink( $filename );
Encryption\Keymanager::deleteFileKey( $filename );
}
/**
* @brief Test that data that is read by the crypto stream wrapper
@ -493,17 +513,17 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
}
// /**
// * @brief test decryption using legacy blowfish method
// * @depends testLegacyEncryptShort
// */
// function testLegacyDecryptShort( $crypted ) {
//
// $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
//
// $this->assertEquals( $this->dataShort, $decrypted );
//
// }
/**
* @brief test decryption using legacy blowfish method
* @depends testLegacyEncryptShort
*/
function testLegacyDecryptShort( $crypted ) {
$decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
$this->assertEquals( $this->dataShort, $decrypted );
}
/**
* @brief test encryption using legacy blowfish method
@ -521,17 +541,17 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
}
// /**
// * @brief test decryption using legacy blowfish method
// * @depends testLegacyEncryptLong
// */
// function testLegacyDecryptLong( $crypted ) {
//
// $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
//
// $this->assertEquals( $this->dataLong, $decrypted );
//
// }
/**
* @brief test decryption using legacy blowfish method
* @depends testLegacyEncryptLong
*/
function testLegacyDecryptLong( $crypted ) {
$decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
$this->assertEquals( $this->dataLong, $decrypted );
}
/**
* @brief test generation of legacy encryption key