From a10ae2816eac4ab9b891972567d20e15dd2cb202 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 5 Nov 2014 14:42:36 +0100 Subject: [PATCH] clean up encryption exceptions --- apps/files_encryption/appinfo/app.php | 6 +- .../exception/encryptionException.php | 50 +++++++++++++++ .../exception/multiKeyDecryptException.php | 34 ++++++++++ .../exception/multiKeyEncryptException.php | 34 ++++++++++ apps/files_encryption/lib/crypt.php | 37 ++++++----- apps/files_encryption/lib/exceptions.php | 63 ------------------- apps/files_encryption/lib/stream.php | 22 ++++--- apps/files_encryption/lib/util.php | 2 +- lib/private/connector/sabre/file.php | 4 +- 9 files changed, 157 insertions(+), 95 deletions(-) create mode 100644 apps/files_encryption/exception/encryptionException.php create mode 100644 apps/files_encryption/exception/multiKeyDecryptException.php create mode 100644 apps/files_encryption/exception/multiKeyEncryptException.php delete mode 100644 apps/files_encryption/lib/exceptions.php diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 4f301f48b3..8bf422a612 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -11,9 +11,9 @@ OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabiliti OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php'; // Exceptions -OC::$CLASSPATH['OCA\Encryption\Exceptions\MultiKeyEncryptException'] = 'files_encryption/lib/exceptions.php'; -OC::$CLASSPATH['OCA\Encryption\Exceptions\MultiKeyDecryptException'] = 'files_encryption/lib/exceptions.php'; -OC::$CLASSPATH['OCA\Encryption\Exceptions\EncryptionException'] = 'files_encryption/lib/exceptions.php'; +OC::$CLASSPATH['OCA\Encryption\Exception\MultiKeyEncryptException'] = 'files_encryption/exception/multiKeyEncryptException.php'; +OC::$CLASSPATH['OCA\Encryption\Exception\MultiKeyDecryptException'] = 'files_encryption/exception/multiKeyDecryptException.php'; +OC::$CLASSPATH['OCA\Encryption\Exception\EncryptionException'] = 'files_encryption/exception/encryptionException.php'; \OCP\Util::addTranslations('files_encryption'); \OCP\Util::addscript('files_encryption', 'encryption'); diff --git a/apps/files_encryption/exception/encryptionException.php b/apps/files_encryption/exception/encryptionException.php new file mode 100644 index 0000000000..c51a3b3439 --- /dev/null +++ b/apps/files_encryption/exception/encryptionException.php @@ -0,0 +1,50 @@ + + * + * 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 . + * + */ + +namespace OCA\Encryption\Exception; + +/** + * Base class for all encryption exception + * + * Possible Error Codes: + * 10 - unknown error + * 20 - unexpected end of encryption header + * 30 - unexpected blog size + * 40 - encryption header to large + * 50 - unknown cipher + * 60 - encryption failed + * 70 - decryption failed + * 80 - empty data + * 90 - private key missing + */ +class EncryptionException extends \Exception { + const UNKNOWN = 10; + const UNEXPECTED_END_OF_ENCRYPTION_HEADER = 20; + const UNEXPECTED_BLOG_SIZE = 30; + const ENCRYPTION_HEADER_TO_LARGE = 40; + const UNKNOWN_CIPHER = 50; + const ENCRYPTION_FAILED = 60; + const DECRYPTION_FAILED = 70; + const EMPTY_DATA = 80; + const PRIVATE_KEY_MISSING = 90; +} diff --git a/apps/files_encryption/exception/multiKeyDecryptException.php b/apps/files_encryption/exception/multiKeyDecryptException.php new file mode 100644 index 0000000000..c1e40e045e --- /dev/null +++ b/apps/files_encryption/exception/multiKeyDecryptException.php @@ -0,0 +1,34 @@ + + * + * 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 . + * + */ + +namespace OCA\Encryption\Exception; + +/** + * Throw this encryption if multi key decryption failed + * + * Possible error codes: + * 110 - openssl_open failed + */ +class MultiKeyDecryptException extends EncryptionException { + const OPENSSL_OPEN_FAILED = 110; +} diff --git a/apps/files_encryption/exception/multiKeyEncryptException.php b/apps/files_encryption/exception/multiKeyEncryptException.php new file mode 100644 index 0000000000..e3aa7de591 --- /dev/null +++ b/apps/files_encryption/exception/multiKeyEncryptException.php @@ -0,0 +1,34 @@ + + * + * 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 . + * + */ + +namespace OCA\Encryption\Exception; + +/** + * Throw this exception if multi key encrytion fails + * + * Possible error codes: + * 110 - openssl_seal failed + */ +class MultiKeyEncryptException extends EncryptionException { + const OPENSSL_SEAL_FAILED = 110; +} diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 59b191097a..cf915ae27b 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -3,10 +3,12 @@ /** * ownCloud * - * @author Sam Tuke, Frank Karlitschek, Robin Appelman - * @copyright 2012 Sam Tuke samtuke@owncloud.com, - * Robin Appelman icewind@owncloud.com, Frank Karlitschek - * frank@owncloud.org + * @copyright (C) 2014 ownCloud, Inc. + * + * @author Bjoern Schiessle + * @author Sam Tuke + * @author Frank Karlitschek + * @author Robin Appelman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -24,7 +26,6 @@ */ namespace OCA\Encryption; -use OCA\Encryption\Exceptions\EncryptionException; /** * Class for common cryptography functionality @@ -189,7 +190,7 @@ class Crypt { * @param string $passphrase * @param string $cypher used for encryption, currently we support AES-128-CFB and AES-256-CFB * @return string encrypted file content - * @throws \OCA\Encryption\Exceptions\EncryptionException + * @throws \OCA\Encryption\Exception\EncryptionException */ private static function encrypt($plainContent, $iv, $passphrase = '', $cipher = Crypt::DEFAULT_CIPHER) { @@ -198,7 +199,7 @@ class Crypt { if (!$encryptedContent) { $error = "Encryption (symmetric) of content failed: " . openssl_error_string(); \OCP\Util::writeLog('Encryption library', $error, \OCP\Util::ERROR); - throw new Exceptions\EncryptionException($error, 50); + throw new Exception\EncryptionException($error, Exception\EncryptionException::ENCRYPTION_FAILED); } return $encryptedContent; @@ -290,7 +291,7 @@ class Crypt { $padded = self::addPadding($catfile); return $padded; - } catch (EncryptionException $e) { + } catch (Exception\EncryptionException $e) { $message = 'Could not encrypt file content (code: ' . $e->getCode() . '): '; \OCP\Util::writeLog('files_encryption', $message . $e->getMessage(), \OCP\Util::ERROR); return false; @@ -378,7 +379,7 @@ class Crypt { * @param string $plainContent content to be encrypted * @param array $publicKeys array keys must be the userId of corresponding user * @return array keys: keys (array, key = userId), data - * @throws \OCA\Encryption\Exceptions\\MultiKeyEncryptException if encryption failed + * @throws \OCA\Encryption\Exception\MultiKeyEncryptException if encryption failed * @note symmetricDecryptFileContent() can decrypt files created using this method */ public static function multiKeyEncrypt($plainContent, array $publicKeys) { @@ -386,7 +387,7 @@ class Crypt { // openssl_seal returns false without errors if $plainContent // is empty, so trigger our own error if (empty($plainContent)) { - throw new Exceptions\MultiKeyEncryptException('Cannot multiKeyEncrypt empty plain content', 10); + throw new Exception\MultiKeyEncryptException('Cannot multiKeyEncrypt empty plain content', Exception\MultiKeyEncryptException::EMPTY_DATA); } // Set empty vars to be set by openssl by reference @@ -413,7 +414,8 @@ class Crypt { ); } else { - throw new Exceptions\MultiKeyEncryptException('multi key encryption failed: ' . openssl_error_string(), 20); + throw new Exception\MultiKeyEncryptException('multi key encryption failed: ' . openssl_error_string(), + Exception\MultiKeyEncryptException::OPENSSL_SEAL_FAILED); } } @@ -423,7 +425,7 @@ class Crypt { * @param string $encryptedContent * @param string $shareKey * @param mixed $privateKey - * @throws \OCA\Encryption\Exceptions\\MultiKeyDecryptException if decryption failed + * @throws \OCA\Encryption\Exception\MultiKeyDecryptException if decryption failed * @internal param string $plainContent contains decrypted content * @return string $plainContent decrypted string * @note symmetricDecryptFileContent() can be used to decrypt files created using this method @@ -433,7 +435,8 @@ class Crypt { public static function multiKeyDecrypt($encryptedContent, $shareKey, $privateKey) { if (!$encryptedContent) { - throw new Exceptions\MultiKeyDecryptException('Cannot mutliKeyDecrypt empty plain content', 10); + throw new Exception\MultiKeyDecryptException('Cannot mutliKeyDecrypt empty plain content', + Exception\MultiKeyDecryptException::EMPTY_DATA); } if (openssl_open($encryptedContent, $plainContent, $shareKey, $privateKey)) { @@ -441,7 +444,8 @@ class Crypt { return $plainContent; } else { - throw new Exceptions\MultiKeyDecryptException('multiKeyDecrypt with share-key' . $shareKey . 'failed: ' . openssl_error_string(), 20); + throw new Exception\MultiKeyDecryptException('multiKeyDecrypt with share-key' . $shareKey . 'failed: ' . openssl_error_string(), + Exception\MultiKeyDecryptException::OPENSSL_OPEN_FAILED); } } @@ -550,14 +554,15 @@ class Crypt { * get chiper from header * * @param array $header - * @throws \OCA\Encryption\Exceptions\EncryptionException + * @throws \OCA\Encryption\Exception\EncryptionException */ public static function getCipher($header) { $cipher = isset($header['cipher']) ? $header['cipher'] : 'AES-128-CFB'; if ($cipher !== 'AES-256-CFB' && $cipher !== 'AES-128-CFB') { - throw new \OCA\Encryption\Exceptions\EncryptionException('file header broken, no supported cipher defined', 40); + throw new Exception\EncryptionException('file header broken, no supported cipher defined', + Exception\EncryptionException::UNKNOWN_CIPHER); } return $cipher; diff --git a/apps/files_encryption/lib/exceptions.php b/apps/files_encryption/lib/exceptions.php deleted file mode 100644 index 5b92f4afe7..0000000000 --- a/apps/files_encryption/lib/exceptions.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * 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 . - * - */ - -namespace OCA\Encryption\Exceptions; - -/** - * General encryption exception - * Possible Error Codes: - * 10 - unexpected end of encryption header - * 20 - unexpected blog size - * 30 - encryption header to large - * 40 - unknown cipher - * 50 - encryption failed - * 60 - no private key available - */ -class EncryptionException extends \Exception { - const UNEXPECTED_END_OF_ENCRTYPTION_HEADER = 10; - const UNEXPECTED_BLOG_SIZE = 20; - const ENCRYPTION_HEADER_TO_LARGE = 30; - const UNKNOWN_CIPHER = 40; - const ENCRYPTION_FAILED = 50; - const NO_PRIVATE_KEY_AVAILABLE = 60; - -} - -/** - * Throw this exception if multi key encrytion fails - * - * Possible error codes: - * 10 - empty plain content was given - * 20 - openssl_seal failed - */ -class MultiKeyEncryptException extends EncryptionException { -} - -/** - * Throw this encryption if multi key decryption failed - * - * Possible error codes: - * 10 - empty encrypted content was given - * 20 - openssl_open failed - */ -class MultiKeyDecryptException extends EncryptionException { -} diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 046c38152b..647ac6a88c 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -2,10 +2,11 @@ /** * ownCloud * - * @author Bjoern Schiessle, Robin Appelman - * @copyright 2014 Bjoern Schiessle - * 2012 Sam Tuke , - * 2011 Robin Appelman + * @copyright (C) 2014 ownCloud, Inc. + * + * @author Bjoern Schiessle + * @author Robin Appelman + * @author Sam Tuke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -30,7 +31,7 @@ */ namespace OCA\Encryption; -use OCA\Encryption\Exceptions\EncryptionException; +use OCA\Encryption\Exception\EncryptionException; /** * Provides 'crypt://' stream wrapper protocol. @@ -91,6 +92,7 @@ class Stream { * @param int $options * @param string $opened_path * @return bool + * @throw \OCA\Encryption\Exception\EncryptionException */ public function stream_open($path, $mode, $options, &$opened_path) { @@ -109,7 +111,7 @@ class Stream { $this->privateKey = $this->session->getPrivateKey(); if ($this->privateKey === false) { throw new EncryptionException('Session does not contain a private key, maybe your login password changed?', - EncryptionException::NO_PRIVATE_KEY_AVAILABLE); + EncryptionException::PRIVATE_KEY_MISSING); } $normalizedPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path)); @@ -249,7 +251,7 @@ class Stream { /** * @param int $count * @return bool|string - * @throws \OCA\Encryption\Exceptions\EncryptionException + * @throws \OCA\Encryption\Exception\EncryptionException */ public function stream_read($count) { @@ -257,7 +259,7 @@ class Stream { if ($count !== Crypt::BLOCKSIZE) { \OCP\Util::writeLog('Encryption library', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL); - throw new \OCA\Encryption\Exceptions\EncryptionException('expected a blog size of 8192 byte', 20); + throw new EncryptionException('expected a blog size of 8192 byte', EncryptionException::UNEXPECTED_BLOG_SIZE); } // Get the data from the file handle @@ -365,14 +367,14 @@ class Stream { /** * write header at beginning of encrypted file * - * @throws Exceptions\EncryptionException + * @throws Exception\EncryptionException */ private function writeHeader() { $header = Crypt::generateHeader(); if (strlen($header) > Crypt::BLOCKSIZE) { - throw new Exceptions\EncryptionException('max header size exceeded', 30); + throw new EncryptionException('max header size exceeded', EncryptionException::ENCRYPTION_HEADER_TO_LARGE); } $paddedHeader = str_pad($header, Crypt::BLOCKSIZE, self::PADDING_CHAR, STR_PAD_RIGHT); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ce5e8c8b54..c8697ae7c8 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -960,7 +960,7 @@ class Util { $plainKeyfile = $this->decryptKeyfile($filePath, $privateKey); // Re-enc keyfile to (additional) sharekeys $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys); - } catch (Exceptions\EncryptionException $e) { + } catch (Exception\EncryptionException $e) { $msg = 'set shareFileKeyFailed (code: ' . $e->getCode() . '): ' . $e->getMessage(); \OCP\Util::writeLog('files_encryption', $msg, \OCP\Util::FATAL); return false; diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index dc036c1adc..db8ce14212 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -100,7 +100,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\ } catch (\OCP\Files\LockNotAcquiredException $e) { // the file is currently being written to by another process throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e); - } catch (\OCA\Encryption\Exceptions\EncryptionException $e) { + } catch (\OCA\Encryption\Exception\EncryptionException $e) { throw new \Sabre\DAV\Exception\Forbidden($e->getMessage()); } @@ -156,7 +156,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\ } else { try { return $this->fileView->fopen(ltrim($this->path, '/'), 'rb'); - } catch (\OCA\Encryption\Exceptions\EncryptionException $e) { + } catch (\OCA\Encryption\Exception\EncryptionException $e) { throw new \Sabre\DAV\Exception\Forbidden($e->getMessage()); } }