// Encrypt data
$encData = Crypt::symmetricEncryptFileContent( $data, $plainKey );
- // Check if the keyfile needs to be shared
- if ( $userIds = \OCP\Share::getUsersSharingFile( $filePath, true ) ) {
-
- $publicKeys = Keymanager::getPublicKeys( $rootView, $userIds );
-
- \OC_FileProxy::$enabled = false;
-
- // Encrypt plain keyfile to multiple sharefiles
- $multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys );
-
- // Save sharekeys to user folders
- // TODO: openssl_seal generates new shareKeys (envelope keys) each time data is encrypted, but will data still be decryptable using old shareKeys? If so we don't need to replace the old shareKeys here, we only need to set the new ones
- Keymanager::setShareKeys( $rootView, $filePath, $multiEncrypted['keys'] );
+ // Check if key recovery is enabled
+ $recoveryEnabled = $util->recoveryEnabled();
+
+ // Make sure that a share key is generated for the owner too
+ $userIds = array( $userId );
+
+ if ( \OCP\Share::isEnabled() ) {
+
+ // Find out who, if anyone, is sharing the file
+ $shareUids = \OCP\Share::getUsersSharingFile( $filePath, true );
- // Set encrypted keyfile as common varname
- $encKey = $multiEncrypted['encrypted'];
+ $userIds = array_merge( $userIds, $shareUids );
- } else {
+ }
- $publicKey = Keymanager::getPublicKey( $rootView, $userId );
+ // If recovery is enabled, add the
+ // Admin UID to list of users to share to
+ if ( $recoveryEnabled ) {
- // Encrypt plain data to a single user
- $encKey = Crypt::keyEncrypt( $plainKey, $publicKey );
+ // FIXME: Create a separate admin user purely for recovery, and create method in util for fetching this id from DB?
+ $adminUid = 'recoveryAdmin';
+ $userIds[] = $adminUid;
+
}
+ // Remove duplicate UIDs
+ $uniqueUserIds = array_unique ( $userIds );
+
+ // Fetch public keys for all users who will share the file
+ $publicKeys = Keymanager::getPublicKeys( $rootView, $uniqueUserIds );
+
+ \OC_FileProxy::$enabled = false;
+
+ // Encrypt plain keyfile to multiple sharefiles
+ $multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys );
+
+ // Save sharekeys to user folders
+ // TODO: openssl_seal generates new shareKeys (envelope keys) each time data is encrypted, but will data still be decryptable using old shareKeys? If so we don't need to replace the old shareKeys here, we only need to set the new ones
+ Keymanager::setShareKeys( $rootView, $filePath, $multiEncrypted['keys'] );
+
+ // Set encrypted keyfile as common varname
+ $encKey = $multiEncrypted['data'];
+
// Save the key if its new
if ( ! $keyPreExists ) {
# ----------------
# Re-use existing keyfiles so they don't need version control (part implemented, stream{} and util{} remain)
# Make sure user knows if large files weren't encrypted
-# Trashbin support
+
+
+# Test
+# ----
+# Test that writing files works when recovery is enabled, and sharing API is disabled
+# Test trashbin support
// Old Todo:
}
- public function recoveryEnabled( ) {
+ /**
+ * @brief Check whether pwd recovery is enabled for a given user
+ * @return bool
+ * @note If records are not being returned, check for a hidden space
+ * at the start of the uid in db
+ */
+ public function recoveryEnabled() {
- $sql = 'SELECT * FROM `*PREFIX*myusers` WHERE id = ?';
- $args = array(1);
-
- $query = \OCP\DB::prepare($sql);
- $result = $query->execute($args);
+ $sql = 'SELECT
+ recovery
+ FROM
+ `*PREFIX*encryption`
+ WHERE
+ uid = ?';
+
+ $args = array( $this->userId );
- while($row = $result->fetchRow()) {
- $userName = $row['username'];
- }
+ $query = \OCP\DB::prepare( $sql );
+
+ $result = $query->execute( $args );
+
+ // Set default in case no records found
+ $recoveryEnabled = 0;
+
+ while( $row = $result->fetchRow() ) {
+
+ $recoveryEnabled = $row['recovery'];
+
+ }
+
+ return $recoveryEnabled;
+
+ }
+ /**
+ * @brief Enable / disable pwd recovery for a given user
+ * @param bool $enabled Whether to enable or disable recovery
+ * @return bool
+ */
+ public function setRecovery( $enabled ) {
+
+ $sql = 'UPDATE
+ *PREFIX*encryption
+ SET
+ recovery = ?
+ WHERE
+ uid = ?';
+
+ // Ensure value is an integer
+ $enabled = intval( $enabled );
+
+ $args = array( $enabled, $this->userId );
+
+ $query = \OCP\DB::prepare( $sql );
+
+ if ( $query->execute( $args ) ) {
+
+ return true;
+
+ } else {
+
+ return false;
+
+ }
+
}
/**
# then false will be returned. Use strict ordering?
}
+
+ function testRecoveryEnabled() {
+
+ $util = new Encryption\Util( $this->view, $this->userId );
+
+ // Record the value so we can return it to it's original state later
+ $enabled = $util->recoveryEnabled();
+
+ $this->assertTrue( $util->setRecovery( 1 ) );
+
+ $this->assertEquals( 1, $util->recoveryEnabled() );
+
+ $this->assertTrue( $util->setRecovery( 0 ) );
+
+ $this->assertEquals( 0, $util->recoveryEnabled() );
+
+ // Return the setting to it's previous state
+ $this->assertTrue( $util->setRecovery( $enabled ) );
+
+ }
// /**
// * @brief test decryption using legacy blowfish method