Skip to content

Figuring out why encryption on S3 object storage as primary storage is not working + trying to fix it #14027

@lkreher

Description

@lkreher

Steps to reproduce

  1. Install NC
  2. Setup S3 Object Storage as primary storage
  3. enable Encryption
  4. upload files > 10kb
  5. try to retrieve files

Expected behaviour

Files should be retrieved

Actual behaviour

Nextcloud throws an error and files can't be retrieved

Server configuration

Operating system: Ubuntu 16.04.3 LTS

Web server: nginx

Database: MySQL 5.7

PHP version: 7.2 FPM

Nextcloud version: 15.0.2

Updated from an older Nextcloud/ownCloud or fresh install: fresh install

Where did you install Nextcloud from: Nextcloud web installer

Signing status:

Signing status
No errors have been found.

List of activated apps:

App list
Enabled:
  - accessibility: 1.1.0
  - activity: 2.8.2
  - cloud_federation_api: 0.1.0
  - comments: 1.5.0
  - dav: 1.8.1
  - encryption: 2.3.0
  - federatedfilesharing: 1.5.0
  - federation: 1.5.0
  - files: 1.10.0
  - files_pdfviewer: 1.4.0
  - files_sharing: 1.7.0
  - files_texteditor: 2.7.0
  - files_trashbin: 1.5.0
  - files_versions: 1.8.0
  - files_videoplayer: 1.4.0
  - firstrunwizard: 2.4.0
  - gallery: 18.2.0
  - logreader: 2.0.0
  - lookup_server_connector: 1.3.0
  - nextcloud_announcements: 1.4.0
  - notifications: 2.3.0
  - oauth2: 1.3.0
  - password_policy: 1.5.0
  - provisioning_api: 1.5.0
  - serverinfo: 1.5.0
  - sharebymail: 1.5.0
  - support: 1.0.0
  - survey_client: 1.3.0
  - systemtags: 1.5.0
  - theming: 1.6.0
  - twofactor_backupcodes: 1.4.1
  - updatenotification: 1.5.0
  - workflowengine: 1.5.0
Disabled:
  - admin_audit
  - files_external
  - user_ldap

Nextcloud configuration:

Config report
{
    "system": {
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "objectstore": {
            "class": "OC\\Files\\ObjectStore\\S3",
            "arguments": {
                "bucket": "bucket",
                "autocreate": true,
                "key": "key",
                "secret": "secret",
                "region": "eu-central-1",
                "use_ssl": true
            }
        },
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "xxx"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "check_data_directory_permissions": false,
        "dbtype": "mysql",
        "version": "15.0.2.0",
        "overwrite.cli.url": "xxx",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "memcache.local": "\\OC\\Memcache\\Redis",
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "maintenance": false
    }
}

Are you using external storage, if yes which one: S3 object storage

Are you using encryption: yes

Are you using an external user-backend, if yes which one: no

Client configuration

Browser: Chrome

Operating system: Windows

Logs

Nextcloud log (data/nextcloud.log)

Nextcloud log
{"reqId":"zjolUv0wdkO8YqTg4DKt","level":4,"time":"2019-02-04T11:05:56+00:00","remoteAddr":"192.168.10.1","user":"me","app":"webdav","method":"GET","url":"\/remote.php\/webdav\/Nextcloud%20Manual.pdf","message":{"Exception":"OC\\Encryption\\Exceptions\\DecryptionFailedException","Message":"Encryption library: Decryption (symmetric) of content failed: ","Code":0,"Trace":[{"file":"\/home\/vagrant\/Sites\/nextcloud\/apps\/encryption\/lib\/Crypto\/Crypt.php","line":473,"function":"decrypt","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/apps\/encryption\/lib\/Crypto\/Encryption.php","line":379,"function":"symmetricDecryptFileContent","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***","*** sensitive parameter replaced ***",1,"*** sensitive parameter replaced ***"]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/lib\/private\/Files\/Stream\/Encryption.php","line":479,"function":"decrypt","class":"OCA\\Encryption\\Crypto\\Encryption","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/lib\/private\/Files\/Stream\/Encryption.php","line":299,"function":"readCache","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[]},{"function":"stream_read","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[8192]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/3rdparty\/icewind\/streams\/src\/Wrapper.php","line":91,"function":"fread","args":[null,8192]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/3rdparty\/icewind\/streams\/src\/CallbackWrapper.php","line":91,"function":"stream_read","class":"Icewind\\Streams\\Wrapper","type":"->","args":[8192]},{"function":"stream_read","class":"Icewind\\Streams\\CallbackWrapper","type":"->","args":[8192]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/3rdparty\/sabre\/http\/lib\/Sapi.php","line":80,"function":"stream_copy_to_stream","args":[null,null,"6276760"]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/3rdparty\/sabre\/dav\/lib\/DAV\/Server.php","line":498,"function":"sendResponse","class":"Sabre\\HTTP\\Sapi","type":"::","args":[{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/3rdparty\/sabre\/dav\/lib\/DAV\/Server.php","line":254,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[{"absoluteUrl":"http:\/\/nextcloud.lars\/remote.php\/webdav\/Nextcloud%20Manual.pdf","__class__":"Sabre\\HTTP\\Request"},{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/apps\/dav\/appinfo\/v1\/webdav.php","line":80,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"\/home\/vagrant\/Sites\/nextcloud\/remote.php","line":163,"args":["\/home\/vagrant\/Sites\/nextcloud\/apps\/dav\/appinfo\/v1\/webdav.php"],"function":"require_once"}],"File":"\/home\/vagrant\/Sites\/nextcloud\/apps\/encryption\/lib\/Crypto\/Crypt.php","Line":590,"Hint":"Encryption library: Decryption (symmetric) of content failed: ","CustomMessage":"--"},"userAgent":"Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/71.0.3578.98 Safari\/537.36","version":"15.0.2.0"}

Report

This was previously discussed for NC14 in #11826 and others. I've been trying to fix this issue, and noticed multiple problems:

  1. The IV generated to encrypt one block uses random_bytes(16) at Crypt.php#634
    When written to file, read back and evaluated, this block gets interpreted as different character encoding, so 16 characters turn into more or less than 16 bytes.
    Changing Crypt.php#634 to return substr(base64_encode(random_bytes(16)), 0, 16); makes the IV safe from character encoding issues. This way I can successfully decrypt the first and the last block of each file, which means small files can be retrieved.

  2. Blocks don't get read properly. In Encryption.php#473 less than 8192 bytes of data are returned after the first block, even when there are more than 8192 bytes remaining. Retrieving a partial block is guaranteed to result in decryption errors.
    I don't have a solution for this problem. The stream resource is being handled by a 3rdparty library which does not behave as expected.

Looking for someone with an idea how to tackle problem 2. I've been stepping through the process with xdebug for a while and can't figure out how to retrieve a full 8192 bytes at once.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions