Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support enc repo v5 #624

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions common/commit-mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,9 @@ commit_to_json_object (SeafCommit *commit)
json_object_set_string_member (object, "key", commit->random_key);
if (commit->enc_version >= 3)
json_object_set_string_member (object, "salt", commit->salt);
if (commit->enc_version >= 5) {
json_object_set_int_member (object, "key_iter", commit->key_iter);
}
}
if (commit->no_local_history)
json_object_set_int_member (object, "no_local_history", 1);
Expand Down Expand Up @@ -675,6 +678,7 @@ commit_from_json_object (const char *commit_id, json_t *object)
const char *magic = NULL;
const char *random_key = NULL;
const char *salt = NULL;
int key_iter;
int no_local_history = 0;
int version = 0;
int conflict = 0, new_merge = 0;
Expand Down Expand Up @@ -715,6 +719,8 @@ commit_from_json_object (const char *commit_id, json_t *object)
random_key = json_object_get_string_member (object, "key");
if (enc_version >= 3)
salt = json_object_get_string_member (object, "salt");
if (enc_version >= 5)
key_iter = json_object_get_int_member (object, "key_iter");

if (json_object_has_member (object, "no_local_history"))
no_local_history = json_object_get_int_member (object, "no_local_history");
Expand Down Expand Up @@ -768,6 +774,17 @@ commit_from_json_object (const char *commit_id, json_t *object)
if (!salt || strlen(salt) != 64)
return NULL;
break;
case 5:
if (!magic || strlen(magic) != 64)
return NULL;
if (!random_key || strlen(random_key) != 96)
return NULL;
if (!salt || strlen(salt) != 64)
return NULL;
if (key_iter <= 0) {
return NULL;
}
break;
default:
seaf_warning ("Unknown encryption version %d.\n", enc_version);
return NULL;
Expand Down Expand Up @@ -800,6 +817,8 @@ commit_from_json_object (const char *commit_id, json_t *object)
commit->random_key = g_strdup (random_key);
if (enc_version >= 3)
commit->salt = g_strdup(salt);
if (enc_version >= 5)
commit->key_iter = key_iter;
}
if (no_local_history)
commit->no_local_history = TRUE;
Expand Down
1 change: 1 addition & 0 deletions common/commit-mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct _SeafCommit {
char *magic;
char *random_key;
char *salt;
int key_iter;
gboolean no_local_history;

int version;
Expand Down
12 changes: 7 additions & 5 deletions common/rpc-service.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,8 @@ seafile_generate_magic_and_random_key(int enc_version,
return NULL;
}

seafile_generate_magic (enc_version, repo_id, passwd, salt, magic);
if (seafile_generate_random_key (passwd, enc_version, salt, random_key) < 0) {
seafile_generate_magic (enc_version, repo_id, passwd, salt, magic, seaf->key_iter);
if (seafile_generate_random_key (passwd, enc_version, salt, random_key, seaf->key_iter) < 0) {
return NULL;
}

Expand Down Expand Up @@ -1041,7 +1041,7 @@ seafile_change_repo_passwd (const char *repo_id,
}

if (seafile_verify_repo_passwd (repo_id, old_passwd, repo->magic,
repo->enc_version, repo->salt) < 0) {
repo->enc_version, repo->salt, repo->key_iter) < 0) {
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Incorrect password");
return -1;
}
Expand All @@ -1058,10 +1058,10 @@ seafile_change_repo_passwd (const char *repo_id,

char new_magic[65], new_random_key[97];

seafile_generate_magic (repo->enc_version, repo_id, new_passwd, repo->salt, new_magic);
seafile_generate_magic (repo->enc_version, repo_id, new_passwd, repo->salt, new_magic, repo->key_iter);
if (seafile_update_random_key (old_passwd, repo->random_key,
new_passwd, new_random_key,
repo->enc_version, repo->salt) < 0) {
repo->enc_version, repo->salt, repo->key_iter) < 0) {
ret = -1;
goto out;
}
Expand Down Expand Up @@ -3056,6 +3056,7 @@ seafile_create_enc_repo (const char *repo_id,
const char *random_key,
const char *salt,
int enc_version,
int key_iter,
GError **error)
{
if (!repo_id || !repo_name || !repo_desc || !owner_email) {
Expand All @@ -3069,6 +3070,7 @@ seafile_create_enc_repo (const char *repo_id,
repo_id, repo_name, repo_desc,
owner_email,
magic, random_key, salt, enc_version,
key_iter,
error);
return ret;
}
Expand Down
34 changes: 22 additions & 12 deletions common/seafile-crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,20 @@ seafile_crypt_new (int version, unsigned char *key, unsigned char *iv)
int
seafile_derive_key (const char *data_in, int in_len, int version,
const char *repo_salt,
int iter,
unsigned char *key, unsigned char *iv)
{
if (version >= 3) {
unsigned char repo_salt_bin[32];
hex_to_rawdata (repo_salt, repo_salt_bin, 32);
int key_iter = KEYGEN_ITERATION2;
if (version >= 5) {
key_iter = iter;
}

PKCS5_PBKDF2_HMAC (data_in, in_len,
repo_salt_bin, sizeof(repo_salt_bin),
KEYGEN_ITERATION2,
key_iter,
EVP_sha256(),
32, key);
PKCS5_PBKDF2_HMAC ((char *)key, 32,
Expand Down Expand Up @@ -107,7 +112,8 @@ int
seafile_generate_random_key (const char *passwd,
int version,
const char *repo_salt,
char *random_key)
char *random_key,
int iter)
{
SeafileCrypt *crypt;
unsigned char secret_key[32], *rand_key;
Expand All @@ -120,7 +126,7 @@ seafile_generate_random_key (const char *passwd,
return -1;
}

seafile_derive_key (passwd, strlen(passwd), version, repo_salt, key, iv);
seafile_derive_key (passwd, strlen(passwd), version, repo_salt, iter, key, iv);

crypt = seafile_crypt_new (version, key, iv);

Expand All @@ -139,7 +145,8 @@ void
seafile_generate_magic (int version, const char *repo_id,
const char *passwd,
const char *repo_salt,
char *magic)
char *magic,
int iter)
{
GString *buf = g_string_new (NULL);
unsigned char key[32], iv[16];
Expand All @@ -150,7 +157,7 @@ seafile_generate_magic (int version, const char *repo_id,
*/
g_string_append_printf (buf, "%s%s", repo_id, passwd);

seafile_derive_key (buf->str, buf->len, version, repo_salt, key, iv);
seafile_derive_key (buf->str, buf->len, version, repo_salt, iter, key, iv);

g_string_free (buf, TRUE);
rawdata_to_hex (key, magic, 32);
Expand All @@ -161,21 +168,22 @@ seafile_verify_repo_passwd (const char *repo_id,
const char *passwd,
const char *magic,
int version,
const char *repo_salt)
const char *repo_salt,
int iter)
{
GString *buf = g_string_new (NULL);
unsigned char key[32], iv[16];
char hex[65];

if (version != 1 && version != 2 && version != 3 && version != 4) {
if (version != 1 && version != 2 && version != 3 && version != 4 && version != 5) {
seaf_warning ("Unsupported enc_version %d.\n", version);
return -1;
}

/* Recompute the magic and compare it with the one comes with the repo. */
g_string_append_printf (buf, "%s%s", repo_id, passwd);

seafile_derive_key (buf->str, buf->len, version, repo_salt, key, iv);
seafile_derive_key (buf->str, buf->len, version, repo_salt, iter, key, iv);

g_string_free (buf, TRUE);
if (version >= 2)
Expand All @@ -193,11 +201,12 @@ int
seafile_decrypt_repo_enc_key (int enc_version,
const char *passwd, const char *random_key,
const char *repo_salt,
int iter,
unsigned char *key_out, unsigned char *iv_out)
{
unsigned char key[32], iv[16];

seafile_derive_key (passwd, strlen(passwd), enc_version, repo_salt, key, iv);
seafile_derive_key (passwd, strlen(passwd), enc_version, repo_salt, iter, key, iv);

if (enc_version == 1) {
memcpy (key_out, key, 16);
Expand Down Expand Up @@ -227,6 +236,7 @@ seafile_decrypt_repo_enc_key (int enc_version,

seafile_derive_key ((char *)dec_random_key, 32, enc_version,
repo_salt,
iter,
key, iv);
memcpy (key_out, key, 32);
memcpy (iv_out, iv, 16);
Expand All @@ -241,7 +251,7 @@ seafile_decrypt_repo_enc_key (int enc_version,
int
seafile_update_random_key (const char *old_passwd, const char *old_random_key,
const char *new_passwd, char *new_random_key,
int enc_version, const char *repo_salt)
int enc_version, const char *repo_salt, int iter)
{
unsigned char key[32], iv[16];
unsigned char random_key_raw[48], *secret_key, *new_random_key_raw;
Expand All @@ -250,7 +260,7 @@ seafile_update_random_key (const char *old_passwd, const char *old_random_key,

/* First, use old_passwd to decrypt secret key from old_random_key. */
seafile_derive_key (old_passwd, strlen(old_passwd), enc_version,
repo_salt, key, iv);
repo_salt, iter, key, iv);

hex_to_rawdata (old_random_key, random_key_raw, 48);

Expand All @@ -266,7 +276,7 @@ seafile_update_random_key (const char *old_passwd, const char *old_random_key,

/* Second, use new_passwd to encrypt secret key. */
seafile_derive_key (new_passwd, strlen(new_passwd), enc_version,
repo_salt, key, iv);
repo_salt, iter, key, iv);

crypt = seafile_crypt_new (enc_version, key, iv);

Expand Down
13 changes: 9 additions & 4 deletions common/seafile-crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ seafile_crypt_new (int version, unsigned char *key, unsigned char *iv);
int
seafile_derive_key (const char *data_in, int in_len, int version,
const char *repo_salt,
int iter,
unsigned char *key, unsigned char *iv);

/* @salt must be an char array of size 65 bytes. */
Expand All @@ -69,31 +70,35 @@ int
seafile_generate_random_key (const char *passwd,
int version,
const char *repo_salt,
char *random_key);
char *random_key,
int iter);

void
seafile_generate_magic (int version, const char *repo_id,
const char *passwd,
const char *repo_salt,
char *magic);
char *magic,
int iter);

int
seafile_verify_repo_passwd (const char *repo_id,
const char *passwd,
const char *magic,
int version,
const char *repo_salt);
const char *repo_salt,
int iter);

int
seafile_decrypt_repo_enc_key (int enc_version,
const char *passwd, const char *random_key,
const char *repo_salt,
int iter,
unsigned char *key_out, unsigned char *iv_out);

int
seafile_update_random_key (const char *old_passwd, const char *old_random_key,
const char *new_passwd, char *new_random_key,
int enc_version, const char *repo_salt);
int enc_version, const char *repo_salt, int iter);

int
seafile_encrypt (char **data_out,
Expand Down
1 change: 1 addition & 0 deletions fileserver/commitmgr/commitmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Commit struct {
Magic string `json:"magic,omitempty"`
RandomKey string `json:"key,omitempty"`
Salt string `json:"salt,omitempty"`
KeyIter int `json:"key_iter,omitempty"`
Version int `json:"version,omitempty"`
Conflict int `json:"conflict,omitempty"`
NewMerge int `json:"new_merge,omitempty"`
Expand Down
11 changes: 11 additions & 0 deletions fileserver/repomgr/repomgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Repo struct {
Magic string
RandomKey string
Salt string
KeyIter int
Version int
}

Expand Down Expand Up @@ -145,6 +146,11 @@ func Get(id string) *Repo {
repo.Magic = commit.Magic
repo.RandomKey = commit.RandomKey
repo.Salt = commit.Salt
} else if repo.EncVersion == 5 {
repo.Magic = commit.Magic
repo.RandomKey = commit.RandomKey
repo.Salt = commit.Salt
repo.KeyIter = commit.KeyIter
}
}

Expand All @@ -171,6 +177,11 @@ func RepoToCommit(repo *Repo, commit *commitmgr.Commit) {
commit.Magic = repo.Magic
commit.RandomKey = repo.RandomKey
commit.Salt = repo.Salt
} else if repo.EncVersion == 5 {
commit.Magic = repo.Magic
commit.RandomKey = repo.RandomKey
commit.Salt = repo.Salt
commit.KeyIter = repo.KeyIter
}
} else {
commit.Encrypted = "false"
Expand Down
1 change: 1 addition & 0 deletions include/seafile-rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ seafile_create_enc_repo (const char *repo_id,
const char *random_key,
const char *salt,
int enc_version,
int key_iter,
GError **error);

char *
Expand Down
1 change: 1 addition & 0 deletions lib/rpc_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
[ "string", ["string", "string", "string", "string", "string", "string", "int64", "int"] ],
[ "string", ["string", "string", "string", "string", "string", "string", "string"] ],
[ "string", ["string", "string", "string", "string", "string", "string", "string", "int"] ],
[ "string", ["string", "string", "string", "string", "string", "string", "string", "int", "int"] ],
[ "string", ["string", "string", "string", "string", "string", "string", "string", "int64"] ],
[ "string", ["string", "string", "string", "string", "string", "string", "string", "string", "string"] ],
[ "string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"] ],
Expand Down
4 changes: 2 additions & 2 deletions python/seafile/rpcclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ def seafile_create_repo(name, desc, owner_email, passwd, enc_version):
pass
create_repo = seafile_create_repo

@searpc_func("string", ["string", "string", "string", "string", "string", "string", "string", "int"])
def seafile_create_enc_repo(repo_id, name, desc, owner_email, magic, random_key, salt, enc_version):
@searpc_func("string", ["string", "string", "string", "string", "string", "string", "string", "int", "int"])
def seafile_create_enc_repo(repo_id, name, desc, owner_email, magic, random_key, salt, enc_version, key_iter):
pass
create_enc_repo = seafile_create_enc_repo

Expand Down
4 changes: 2 additions & 2 deletions python/seaserv/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def generate_magic_and_random_key(self, enc_version, repo_id, password):
def create_repo(self, name, desc, username, passwd=None, enc_version=2, storage_id=None):
return seafserv_threaded_rpc.create_repo(name, desc, username, passwd, enc_version)

def create_enc_repo(self, repo_id, name, desc, username, magic, random_key, salt, enc_version):
return seafserv_threaded_rpc.create_enc_repo(repo_id, name, desc, username, magic, random_key, salt, enc_version)
def create_enc_repo(self, repo_id, name, desc, username, magic, random_key, salt, enc_version, key_iter=1000):
return seafserv_threaded_rpc.create_enc_repo(repo_id, name, desc, username, magic, random_key, salt, enc_version, key_iter)

def get_repos_by_id_prefix(self, id_prefix, start=-1, limit=-1):
"""
Expand Down
5 changes: 3 additions & 2 deletions server/passwd-mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,15 @@ seaf_passwd_manager_set_passwd (SeafPasswdManager *mgr,
return -1;
}

if (repo->enc_version != 1 && repo->enc_version != 2 && repo->enc_version != 3 && repo->enc_version != 4) {
if (repo->enc_version != 1 && repo->enc_version != 2 && repo->enc_version != 3 && repo->enc_version != 4 && repo->enc_version != 5) {
seaf_repo_unref (repo);
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS,
"Unsupported encryption version");
return -1;
}

if (seafile_verify_repo_passwd (repo->id, passwd,
repo->magic, repo->enc_version, repo->salt) < 0) {
repo->magic, repo->enc_version, repo->salt, repo->key_iter) < 0) {
seaf_repo_unref (repo);
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL,
"Incorrect password");
Expand All @@ -143,6 +143,7 @@ seaf_passwd_manager_set_passwd (SeafPasswdManager *mgr,
}

if (seafile_decrypt_repo_enc_key (repo->enc_version, passwd, repo->random_key, repo->salt,
repo->key_iter,
crypt_key->key, crypt_key->iv) < 0) {
seaf_repo_unref (repo);
g_free (crypt_key);
Expand Down
Loading