Skip to content

Commit

Permalink
Support enc repo v5
Browse files Browse the repository at this point in the history
  • Loading branch information
杨赫然 committed Jul 5, 2023
1 parent 864cef1 commit 7940252
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 32 deletions.
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
10 changes: 5 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
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
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
19 changes: 16 additions & 3 deletions server/repo-mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ seaf_repo_from_commit (SeafRepo *repo, SeafCommit *commit)
memcpy (repo->magic, commit->magic, 64);
memcpy (repo->random_key, commit->random_key, 96);
memcpy (repo->salt, commit->salt, 64);
} else if (repo->enc_version == 5) {
memcpy (repo->magic, commit->magic, 64);
memcpy (repo->random_key, commit->random_key, 96);
memcpy (repo->salt, commit->salt, 64);
repo->key_iter = commit->key_iter;
}
}
repo->no_local_history = commit->no_local_history;
Expand Down Expand Up @@ -179,6 +184,11 @@ seaf_repo_to_commit (SeafRepo *repo, SeafCommit *commit)
commit->magic = g_strdup (repo->magic);
commit->random_key = g_strdup (repo->random_key);
commit->salt = g_strdup (repo->salt);
} else if (commit->enc_version == 5) {
commit->magic = g_strdup (repo->magic);
commit->random_key = g_strdup (repo->random_key);
commit->salt = g_strdup (repo->salt);
commit->key_iter = repo->key_iter;
}
}
commit->no_local_history = repo->no_local_history;
Expand Down Expand Up @@ -3741,7 +3751,7 @@ create_repo_common (SeafRepoManager *mgr,
SeafBranch *master = NULL;
int ret = -1;

if (enc_version != 4 && enc_version != 3 && enc_version != 2 && enc_version != -1) {
if (enc_version != 5 && enc_version != 4 && enc_version != 3 && enc_version != 2 && enc_version != -1) {
seaf_warning ("Unsupported enc version %d.\n", enc_version);
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS,
"Unsupported encryption version");
Expand Down Expand Up @@ -3782,6 +3792,9 @@ create_repo_common (SeafRepoManager *mgr,
}
if (enc_version >= 3)
memcpy (repo->salt, salt, 64);
if (enc_version >= 5) {
repo->key_iter = seaf->key_iter;
}

repo->version = CURRENT_REPO_VERSION;
memcpy (repo->store_id, repo_id, 36);
Expand Down Expand Up @@ -3855,8 +3868,8 @@ seaf_repo_manager_create_new_repo (SeafRepoManager *mgr,
if (seafile_generate_repo_salt (salt) < 0) {
goto bad;
}
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) {
goto bad;
}
}
Expand Down
Loading

0 comments on commit 7940252

Please sign in to comment.