Changing user login pwd now correctly changes encryption key passphrase
All crypt unit tests are now passing
This commit is contained in:
parent
31cbb5a09f
commit
453fd66c70
|
@ -342,15 +342,10 @@ class Crypt {
|
||||||
// Remove padding
|
// Remove padding
|
||||||
$noPadding = self::removePadding( $keyfileContent );
|
$noPadding = self::removePadding( $keyfileContent );
|
||||||
|
|
||||||
// Fetch IV from end of file
|
// Split into enc data and catfile
|
||||||
$iv = substr( $noPadding, -16 );
|
$catfile = self::splitIv( $noPadding );
|
||||||
|
|
||||||
// Remove IV and IV identifier text to expose encrypted content
|
if ( $plainContent = self::decrypt( $catfile['encrypted'], $catfile['iv'], $passphrase ) ) {
|
||||||
$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 ) ) {
|
|
||||||
|
|
||||||
return $plainContent;
|
return $plainContent;
|
||||||
|
|
||||||
|
@ -493,12 +488,12 @@ class Crypt {
|
||||||
public static function keyDecryptKeyfile( $catfile, $keyfile, $privateKey ) {
|
public static function keyDecryptKeyfile( $catfile, $keyfile, $privateKey ) {
|
||||||
|
|
||||||
// Decrypt the keyfile with the user's private key
|
// 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));
|
// trigger_error( "\$keyfile = ".var_export($keyfile, 1));
|
||||||
|
|
||||||
// Decrypt the catfile symmetrically using the decrypted keyfile
|
// Decrypt the catfile symmetrically using the decrypted keyfile
|
||||||
$decryptedData = self::symmetricDecryptFileContent( $catfile, $decryptedKey );
|
$decryptedData = self::symmetricDecryptFileContent( $catfile, $decryptedKeyfile );
|
||||||
|
|
||||||
return $decryptedData;
|
return $decryptedData;
|
||||||
|
|
||||||
|
@ -705,11 +700,9 @@ class Crypt {
|
||||||
*/
|
*/
|
||||||
public static function legacyDecrypt( $content, $passphrase = '' ) {
|
public static function legacyDecrypt( $content, $passphrase = '' ) {
|
||||||
|
|
||||||
$passphrase = '';
|
|
||||||
|
|
||||||
//trigger_error("OC2 dec \$content = $content \$key = ".strlen($passphrase) );
|
//trigger_error("OC2 dec \$content = $content \$key = ".strlen($passphrase) );
|
||||||
|
|
||||||
$bf = self::getBlowfish( "67362885833455692562" );
|
$bf = self::getBlowfish( $passphrase );
|
||||||
|
|
||||||
// trigger_error(var_export($bf, 1) );
|
// trigger_error(var_export($bf, 1) );
|
||||||
|
|
||||||
|
|
|
@ -157,11 +157,11 @@ class Proxy extends \OC_FileProxy {
|
||||||
|
|
||||||
//$cached = \OC_FileCache_Cached::get( $path, '' );
|
//$cached = \OC_FileCache_Cached::get( $path, '' );
|
||||||
|
|
||||||
$keyFile = Keymanager::getFileKey( $filePath );
|
$encryptedKeyfile = Keymanager::getFileKey( $filePath );
|
||||||
|
|
||||||
$session = new Session();
|
$session = new Session();
|
||||||
|
|
||||||
$decrypted = Crypt::keyDecryptKeyfile( $data, $keyFile, $session->getPrivateKey( $split[1] ) );
|
$decrypted = Crypt::keyDecryptKeyfile( $data, $encryptedKeyfile, $session->getPrivateKey( $split[1] ) );
|
||||||
|
|
||||||
} elseif (
|
} elseif (
|
||||||
Crypt::mode() == 'server'
|
Crypt::mode() == 'server'
|
||||||
|
|
|
@ -302,10 +302,6 @@ class Stream {
|
||||||
*/
|
*/
|
||||||
public function stream_write( $data ) {
|
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
|
// 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;
|
\OC_FileProxy::$enabled = false;
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,20 @@ class Util {
|
||||||
|
|
||||||
# Admin UI:
|
# Admin UI:
|
||||||
|
|
||||||
|
## DONE: changing user password also changes encryption passphrase
|
||||||
|
|
||||||
## TODO: add support for optional recovery in case of lost passphrase / keys
|
## TODO: add support for optional recovery in case of lost passphrase / keys
|
||||||
## TODO: add admin optional required long passphrase for users
|
## TODO: add admin optional required long passphrase for users
|
||||||
## TODO: add UI buttons for encrypt / decrypt everything
|
## TODO: add UI buttons for encrypt / decrypt everything
|
||||||
## TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc.
|
## 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:
|
# Integration testing:
|
||||||
|
|
||||||
## TODO: test new encryption with webdav
|
## TODO: test new encryption with webdav
|
||||||
|
|
|
@ -64,8 +64,6 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
$iv = Encryption\Crypt::generateIv();
|
$iv = Encryption\Crypt::generateIv();
|
||||||
|
|
||||||
echo $iv;
|
|
||||||
|
|
||||||
$this->assertEquals( 16, strlen( $iv ) );
|
$this->assertEquals( 16, strlen( $iv ) );
|
||||||
|
|
||||||
return $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
|
// 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 );
|
$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
|
// Check that the file was encrypted before being written to disk
|
||||||
$this->assertNotEquals( $this->dataShort, $retreivedCryptedFile );
|
$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 );
|
$this->assertEquals( $this->dataShort, $manualDecrypt );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * @brief Test that data that is written by the crypto stream wrapper
|
* @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 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
|
||||||
// function testSymmetricStreamEncryptLongFileContent() {
|
* reassembly of its data
|
||||||
//
|
*/
|
||||||
// // Generate a a random filename
|
function testSymmetricStreamEncryptLongFileContent() {
|
||||||
// $filename = 'tmp-'.time();
|
|
||||||
//
|
// Generate a a random filename
|
||||||
// echo "\n\n\$filename = $filename\n\n";
|
$filename = 'tmp-'.time();
|
||||||
//
|
|
||||||
// // Save long data as encrypted file using stream wrapper
|
// Save long data as encrypted file using stream wrapper
|
||||||
// $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
|
$cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
|
||||||
//
|
|
||||||
// // Test that data was successfully written
|
// Test that data was successfully written
|
||||||
// $this->assertTrue( is_int( $cryptedFile ) );
|
$this->assertTrue( is_int( $cryptedFile ) );
|
||||||
//
|
|
||||||
// // Get file contents without using any wrapper to get it's actual contents on disk
|
// 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 );
|
$retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
|
||||||
//
|
|
||||||
// // echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
|
// echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
|
||||||
//
|
|
||||||
// // Check that the file was encrypted before being written to disk
|
// Check that the file was encrypted before being written to disk
|
||||||
// $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
|
$this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
|
||||||
//
|
|
||||||
// // Manuallly split saved file into separate IVs and encrypted chunks
|
// Manuallly split saved file into separate IVs and encrypted chunks
|
||||||
// $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
|
$r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
|
||||||
//
|
|
||||||
// //print_r($r);
|
//print_r($r);
|
||||||
//
|
|
||||||
// // Join IVs and their respective data chunks
|
// 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] );
|
$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);
|
//print_r($e);
|
||||||
//
|
|
||||||
// // Manually fetch keyfile
|
|
||||||
// $keyfile = Encryption\Keymanager::getFileKey( $filename );
|
// Get private key
|
||||||
//
|
$encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->userId, $this->view );
|
||||||
// // Set var for reassembling decrypted content
|
|
||||||
// $decrypt = '';
|
$decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
|
||||||
//
|
|
||||||
// // Manually decrypt chunk
|
|
||||||
// foreach ($e as $e) {
|
// Get keyfile
|
||||||
//
|
$encryptedKeyfile = Encryption\Keymanager::getFileKey( $filename );
|
||||||
// // echo "\n\$encryptMe = $f";
|
|
||||||
//
|
$decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
|
||||||
// $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $keyfile );
|
|
||||||
//
|
|
||||||
// // Assemble decrypted chunks
|
// Set var for reassembling decrypted content
|
||||||
// $decrypt .= $chunkDecrypt;
|
$decrypt = '';
|
||||||
//
|
|
||||||
// //echo "\n\$chunkDecrypt = $chunkDecrypt";
|
// Manually decrypt chunk
|
||||||
//
|
foreach ($e as $e) {
|
||||||
// }
|
|
||||||
//
|
// echo "\n\$e = $e";
|
||||||
// $this->assertEquals( $this->dataLong.$this->dataLong, $decrypt );
|
|
||||||
//
|
$chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $decryptedKeyfile );
|
||||||
// // Teardown
|
|
||||||
//
|
// Assemble decrypted chunks
|
||||||
// $this->view->unlink( $filename );
|
$decrypt .= $chunkDecrypt;
|
||||||
//
|
|
||||||
// Encryption\Keymanager::deleteFileKey( $filename );
|
// 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
|
* @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
|
* @brief test decryption using legacy blowfish method
|
||||||
// * @depends testLegacyEncryptShort
|
* @depends testLegacyEncryptShort
|
||||||
// */
|
*/
|
||||||
// function testLegacyDecryptShort( $crypted ) {
|
function testLegacyDecryptShort( $crypted ) {
|
||||||
//
|
|
||||||
// $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
|
$decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
|
||||||
//
|
|
||||||
// $this->assertEquals( $this->dataShort, $decrypted );
|
$this->assertEquals( $this->dataShort, $decrypted );
|
||||||
//
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief test encryption using legacy blowfish method
|
* @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
|
* @brief test decryption using legacy blowfish method
|
||||||
// * @depends testLegacyEncryptLong
|
* @depends testLegacyEncryptLong
|
||||||
// */
|
*/
|
||||||
// function testLegacyDecryptLong( $crypted ) {
|
function testLegacyDecryptLong( $crypted ) {
|
||||||
//
|
|
||||||
// $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
|
$decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
|
||||||
//
|
|
||||||
// $this->assertEquals( $this->dataLong, $decrypted );
|
$this->assertEquals( $this->dataLong, $decrypted );
|
||||||
//
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief test generation of legacy encryption key
|
* @brief test generation of legacy encryption key
|
||||||
|
|
Loading…
Reference in New Issue