nextcloud / richdocuments

📑 Collabora Online for Nextcloud
https://nextcloud.com/collaboraonline
356 stars 116 forks source link

Writing documents with enabled per-user encryption keys fails (Private Key missing for user) #1379

Closed mario-van-zadel closed 3 years ago

mario-van-zadel commented 3 years ago

Describe the bug When saving a document with enabled per-user encryption keys, an exception Private Key missing for user: please try to log-out and log-in again is thrown. I debugged it and got the following insights:

I replaced the explicit setting of the user by enabling the incognito mode and tested it in my nextcloud setup: https://github.com/mpk-software/richdocuments/commit/a0fed2b940b735eb896559a8fd6cd70232d16cd5

This causes to use the public share key for writing the document instead of trying to determine the current user's encryption key (which seems not to be present in the session established by the collabora server). My above workaround is working and I'm able to save documents with enabled per-user-encryption.

What do you think is the best option for solving the problem with per-user encryption keys? Would it be okay to loose the information about who did the changes on the document (the goal of https://github.com/nextcloud/richdocuments/commit/ada925e4c5031213bf28f6792dd6a84548d05a1c)? Should we only use the incognito mode if per-user encryption is enabled?

To Reproduce Steps to reproduce the behavior:

  1. Enable per-user encryption.
  2. Open a document by using collabora.
  3. Click the "save" icon
  4. Check the logs in Nextcloud's admin section (or nextcloud.log file).

Expected behavior The document should be saved even if per-user-encryptions keys are enabled.

Client details:

Server details

Database: MariaDB 10.2

PHP version: 7.4.14

Nextcloud version: 20.0.7.1

Version of the richdocuments app 3.7.14

Version of Collabora Online 6.4.6.2 (via Docker container)

Logs #### Nextcloud log (data/nextcloud.log) ``` {"reqId":"YDYBW5PA18OcZ0ntcYYM-wAAAAc","level":3,"time":"2021-02-24T07:33:47+00:00","remoteAddr":"202.61.241.10","user":"[user]","app":"richdocuments","method":"POST","url":"/index.php/apps/richdocuments/wopi/files/1151791_oc62dc9c2064/contents?access_token=FquRM0xQcPkz5q5[...]&access_token_ttl=0","message":{"Exception":"OCA\\Encryption\\Exceptions\\PrivateKeyMissingException","Message":"Private Key missing for user: please try to log-out and log-in again","Code":0,"Trace":[{"file":"/www/htdocs/[...]/apps/encryption/lib/KeyManager.php","line":476,"function":"getPrivateKey","class":"OCA\\Encryption\\Session","type":"->","args":[]},{"file":"/www/htdocs/[...]/apps/encryption/lib/Crypto/Encryption.php","line":202,"function":"getFileKey","class":"OCA\\Encryption\\KeyManager","type":"->","args":["/[user]/files/[...].odt","[user]"]},{"file":"/www/htdocs/[...]/lib/private/Files/Stream/Encryption.php","line":268,"function":"begin","class":"OCA\\Encryption\\Crypto\\Encryption","type":"->","args":["/[user]/files/[...].odt","[user]","w",{"oc_encryption_module":"OC_DEFAULT_MODULE","cipher":"AES-256-CTR","signed":"true"},{"users":{"0":"[user]","2":"raspberrypi-backups","3":"windows-vm","4":"joshua","5":"julia"},"public":false}]},{"function":"stream_open","class":"OC\\Files\\Stream\\Encryption","type":"->","args":["ocencryption://","w",0,null]},{"file":"/www/htdocs/[...]/lib/private/Files/Stream/Encryption.php","line":207,"function":"fopen","args":["ocencryption://","w",false,null]},{"file":"/www/htdocs/[...]/lib/private/Files/Stream/Encryption.php","line":187,"function":"wrapSource","class":"OC\\Files\\Stream\\Encryption","type":"::","args":[null,null,"ocencryption","OC\\Files\\Stream\\Encryption","w"]},{"file":"/www/htdocs/[...]/lib/private/Files/Storage/Wrapper/Encryption.php","line":473,"function":"wrap","class":"OC\\Files\\Stream\\Encryption","type":"::","args":[null,"files/[...].odt","/[user]/files/[...].odt",{"oc_encryption_module":"OC_DEFAULT_MODULE","cipher":"AES-256-CTR","signed":"true"},"[user]",{"__class__":"OCA\\Encryption\\Crypto\\Encryption"},{"cache":null,"scanner":null,"watcher":null,"propagator":null,"updater":null,"__class__":"OC\\Files\\Storage\\Wrapper\\Quota"},{"cache":null,"scanner":{"__class__":"OC\\Files\\Cache\\Scanner"},"watcher":null,"propagator":null,"updater":null,"__class__":"OC\\Files\\Storage\\Wrapper\\Encryption"},{"__class__":"OC\\Encryption\\Util"},{"__class__":"OC\\Encryption\\File"},"w",82112,54718,8192,true]},{"file":"/www/htdocs/[...]/lib/private/Files/View.php","line":678,"function":"fopen","class":"OC\\Files\\Storage\\Wrapper\\Encryption","type":"->","args":["files/[...].odt","w"]},{"file":"/www/htdocs/[...]/lib/private/Files/Node/File.php","line":72,"function":"file_put_contents","class":"OC\\Files\\View","type":"->","args":["/[user]/files/[...].odt",null]},{"file":"/www/htdocs/[...]/apps/richdocuments/lib/Controller/WopiController.php","line":466,"function":"putContent","class":"OC\\Files\\Node\\File","type":"->","args":[null]},{"file":"/www/htdocs/[...]/apps/richdocuments/lib/Controller/WopiController.php","line":639,"function":"OCA\\Richdocuments\\Controller\\{closure}","class":"OCA\\Richdocuments\\Controller\\WopiController","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/[...]/apps/richdocuments/lib/Controller/WopiController.php","line":467,"function":"retryOperation","class":"OCA\\Richdocuments\\Controller\\WopiController","type":"->","args":[{"__class__":"Closure"}]},{"file":"/www/htdocs/[...]/lib/private/AppFramework/Http/Dispatcher.php","line":169,"function":"putFile","class":"OCA\\Richdocuments\\Controller\\WopiController","type":"->","args":["1151791","FquRM0xQcPkz5q5[...]"]},{"file":"/www/htdocs/[...]/lib/private/AppFramework/Http/Dispatcher.php","line":100,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Richdocuments\\Controller\\WopiController"},"putFile"]},{"file":"/www/htdocs/[...]/lib/private/AppFramework/App.php","line":152,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Richdocuments\\Controller\\WopiController"},"putFile"]},{"file":"/www/htdocs/[...]/lib/private/Route/Router.php","line":309,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OCA\\Richdocuments\\Controller\\WopiController","putFile",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"fileId":"1151791_oc62dc9c2064","_route":"richdocuments.wopi.putFile"}]},{"file":"/www/htdocs/[...]/lib/base.php","line":1008,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/apps/richdocuments/wopi/files/1151791_oc62dc9c2064/contents"]},{"file":"/www/htdocs/[...]/index.php","line":37,"function":"handleRequest","class":"OC","type":"::","args":[]}],"File":"/www/htdocs/[...]/apps/encryption/lib/Session.php","Line":91,"Hint":"Private Key missing for user: please try to log-out and log-in again","CustomMessage":"getFile failed"},"userAgent":"LOOLWSD WOPI Agent 6.4.6","version":"20.0.7.1"} ``` Some parts of the log entry are replaces by `[...]`.
juliusknorr commented 3 years ago

Thanks a lot for the detailed writeup and investigation.

What do you think is the best option for solving the problem with per-user encryption keys? Would it be okay to loose the information about who did the changes on the document (the goal of ada925e)? Should we only use the incognito mode if per-user encryption is enabled?

In general we should keep the author information when possible of course, but I'd say having those not available would be an acceptable trade-off if it just applies for user-key encryption, however we should probably document that then of course.

So the user scope could be only applied then if either encryption is disabled or if there is a master key enabled

mario-van-zadel commented 3 years ago

... however we should probably document that then of course.

@juliushaertl Do you have an idea for a good place in the documentation to mention the discussed special case?