diff --git a/media/js/client_crypto.js b/media/js/client_crypto.js new file mode 100644 index 0000000000..5a35f7d8d6 --- /dev/null +++ b/media/js/client_crypto.js @@ -0,0 +1,62 @@ +var salt = sjcl.codec.bytes.toBits([0xda, 0x90, 0x45, 0xc3, 0x06, 0xc7, 0xcc, 0x26]); + +// gen magic_str +function gen_magic_str(repo_id, passwd) { + var magic_array = sjcl.misc.pbkdf2(repo_id + passwd, salt, 1000, 32*8, null); + var magic_str = sjcl.codec.hex.fromBits(magic_array); //convert to hex + return magic_str; +} + +function FileKey(passwd) { + this.passwd = passwd; +} +FileKey.prototype.pre = function() { + var passwd = this.passwd; + + var key_array = sjcl.misc.pbkdf2(passwd, salt, 1000, 32*8, null); + var iv_array = sjcl.misc.pbkdf2(key_array, salt, 10, 32*8, null); + var key = sjcl.codec.hex.fromBits(key_array); + var iv = sjcl.codec.hex.fromBits(iv_array); + + return {key: key, iv:iv}; +}; +// generate an encrypted file key +FileKey.prototype.gen_enc = function() { + var file_key_array; + if (window.crypto && window.crypto.getRandomValues) { + file_key_array = new Uint32Array(8); + window.crypto.getRandomValues(file_key_array); + } else { + file_key_array = []; + for (var i = 0; i < 8; i++) { + file_key_array.push(parseInt(Math.random() * Math.pow(2,32))); + } + } + + var pre = this.pre(); + var key = pre.key, iv = pre.iv; + + var encrypted_file_key_obj = CryptoJS.AES.encrypt(CryptoJS.lib.WordArray.create(file_key_array), CryptoJS.enc.Hex.parse(key), {iv: CryptoJS.enc.Hex.parse(iv)}); + var encrypted_file_key = encrypted_file_key_obj.ciphertext.toString(CryptoJS.enc.Hex); // convert to hex + + return encrypted_file_key; +}; +FileKey.prototype.decrypt = function(encrypted_file_key) { + var pre = this.pre(); + var key = pre.key, iv = pre.iv; + + var file_key_array = CryptoJS.AES.decrypt(CryptoJS.enc.Hex.parse(encrypted_file_key).toString(CryptoJS.enc.Base64), CryptoJS.enc.Hex.parse(key), {iv: CryptoJS.enc.Hex.parse(iv)}); + var file_key = file_key_array.toString(CryptoJS.enc.Hex); + + return file_key; +}; + +// gen key, iv: used in file encrypt/decrypt +function gen_enc_key_iv(file_key) { + var enc_key_array = sjcl.misc.pbkdf2(sjcl.codec.hex.toBits(file_key), salt, 1000, 32*8, null); + var enc_iv_array = sjcl.misc.pbkdf2(enc_key_array, salt, 10, 32*8, null); + var enc_key = sjcl.codec.hex.fromBits(enc_key_array); + var enc_iv = sjcl.codec.hex.fromBits(enc_iv_array); + + return {key: enc_key, iv:enc_iv}; +} diff --git a/media/js/codecBytes.js b/media/js/codecBytes.js deleted file mode 100644 index cde2af3aec..0000000000 --- a/media/js/codecBytes.js +++ /dev/null @@ -1,37 +0,0 @@ -/** @fileOverview Bit array codec implementations. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/** @namespace Arrays of bytes */ -sjcl.codec.bytes = { - /** Convert from a bitArray to an array of bytes. */ - fromBits: function (arr) { - var out = [], bl = sjcl.bitArray.bitLength(arr), i, tmp; - for (i=0; i>> 24); - tmp <<= 8; - } - return out; - }, - /** Convert from an array of bytes to a bitArray. */ - toBits: function (bytes) { - var out = [], i, tmp=0; - for (i=0; i>> 24); + tmp <<= 8; + } + return out; + }, + /** Convert from an array of bytes to a bitArray. */ + toBits: function (bytes) { + var out = [], i, tmp=0; + for (i=0; i - - - -{% endif %} +{% include 'snippets/repo_create_js_files.html' %} - - - -{% endif %} +{% include 'snippets/repo_create_js_files.html' %} - - - -{% endif %} +{% include 'snippets/repo_create_js_files.html' %} - +{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %} + + + + + +{% endif %} diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index 7fcced473a..ab6d9ee3f4 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -89,7 +89,7 @@ if HAS_OFFICE_CONVERTER: import seahub.settings as settings from seahub.settings import FILE_PREVIEW_MAX_SIZE, INIT_PASSWD, USE_PDFJS, FILE_ENCODING_LIST, \ FILE_ENCODING_TRY_LIST, SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD, \ - ENABLE_SUB_LIBRARY, KEEP_ENC_REPO_PASSWD + ENABLE_SUB_LIBRARY, SERVER_CRYPTO # Get an instance of a logger logger = logging.getLogger(__name__) @@ -610,7 +610,7 @@ def repo_history(request, repo_id): password_set = False if repo.props.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)): + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)): try: ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username) if ret == 1: @@ -667,7 +667,7 @@ def repo_view_snapshot(request, repo_id): password_set = False if repo.props.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)): + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)): try: ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username) if ret == 1: @@ -721,7 +721,7 @@ def repo_history_revert(request, repo_id): password_set = False if repo.props.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)): + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)): try: ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username) if ret == 1: @@ -801,7 +801,7 @@ def repo_history_changes(request, repo_id): return HttpResponse(json.dumps(changes), content_type=content_type) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not is_passwd_set(repo_id, request.user.username): return HttpResponse(json.dumps(changes), content_type=content_type) @@ -1114,17 +1114,17 @@ def public_repo_create(request): passwd = form.cleaned_data['passwd'] uuid = form.cleaned_data['uuid'] magic_str = form.cleaned_data['magic_str'] - random_key = form.cleaned_data['random_key'] + encrypted_file_key = form.cleaned_data['encrypted_file_key'] user = request.user.username try: if not encryption: repo_id = seafile_api.create_repo(repo_name, repo_desc, user, None) else: - if KEEP_ENC_REPO_PASSWD: + if SERVER_CRYPTO: repo_id = seafile_api.create_repo(repo_name, repo_desc, user, passwd) else: - repo_id = seafile_api.create_enc_repo(uuid, repo_name, repo_desc, user, magic_str, random_key, enc_version=2) + repo_id = seafile_api.create_enc_repo(uuid, repo_name, repo_desc, user, magic_str, encrypted_file_key, enc_version=2) # set this repo as inner pub seafile_api.add_inner_pub_repo(repo_id, permission) @@ -1391,16 +1391,16 @@ def repo_create(request): passwd = form.cleaned_data['passwd'] uuid = form.cleaned_data['uuid'] magic_str = form.cleaned_data['magic_str'] - random_key = form.cleaned_data['random_key'] + encrypted_file_key = form.cleaned_data['encrypted_file_key'] user = request.user.username try: if not encryption: repo_id = seafile_api.create_repo(repo_name, repo_desc, user, None) else: - if KEEP_ENC_REPO_PASSWD: + if SERVER_CRYPTO: repo_id = seafile_api.create_repo(repo_name, repo_desc, user, passwd) else: - repo_id = seafile_api.create_enc_repo(uuid, repo_name, repo_desc, user, magic_str, random_key, enc_version=2) + repo_id = seafile_api.create_enc_repo(uuid, repo_name, repo_desc, user, magic_str, encrypted_file_key, enc_version=2) except SearpcError, e: repo_id = None diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py index 30a125c1e6..5d799b9179 100644 --- a/seahub/views/ajax.py +++ b/seahub/views/ajax.py @@ -25,7 +25,7 @@ from seahub.signals import repo_created from seahub.utils import check_filename_with_rename from seahub.utils import check_filename_with_rename, EMPTY_SHA1, gen_block_get_url from seahub.utils.star import star_file, unstar_file -from seahub.settings import KEEP_ENC_REPO_PASSWD +from seahub.settings import SERVER_CRYPTO # Get an instance of a logger logger = logging.getLogger(__name__) @@ -184,7 +184,7 @@ def list_dir(request, repo_id): status=403, content_type=content_type) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), @@ -250,7 +250,7 @@ def list_dir_more(request, repo_id): status=403, content_type=content_type) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), @@ -865,7 +865,7 @@ def get_current_commit(request, repo_id): status=403, content_type=content_type) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), diff --git a/seahub/views/repo.py b/seahub/views/repo.py index 600535cb2d..4ad926617a 100644 --- a/seahub/views/repo.py +++ b/seahub/views/repo.py @@ -20,7 +20,7 @@ from seahub.views import gen_path_link, get_user_permission, get_repo_dirents, \ from seahub.utils import get_ccnetapplet_root, gen_file_upload_url, \ get_httpserver_root, gen_dir_share_link -from seahub.settings import ENABLE_SUB_LIBRARY, KEEP_ENC_REPO_PASSWD +from seahub.settings import ENABLE_SUB_LIBRARY, SERVER_CRYPTO # Get an instance of a logger logger = logging.getLogger(__name__) @@ -189,7 +189,7 @@ def render_repo(request, repo): }, context_instance=RequestContext(request)) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, @@ -230,7 +230,7 @@ def render_repo(request, repo): repo_group_str = '' upload_url = get_upload_url(request, repo.id) - if repo.encrypted and repo.enc_version == 2 and not KEEP_ENC_REPO_PASSWD: + if repo.encrypted and repo.enc_version == 2 and not SERVER_CRYPTO: ajax_upload_url = get_blks_upload_url(request, repo.id) ajax_update_url = get_blks_update_url(request, repo.id) else: @@ -316,7 +316,7 @@ def repo_history_view(request, repo_id): }, context_instance=RequestContext(request)) if repo.encrypted and \ - (repo.enc_version == 1 or (repo.enc_version == 2 and KEEP_ENC_REPO_PASSWD)) \ + (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo,