Support GNUTLS (#2848)

* Support GNUTLS

* Use switch to check crypt version

---------

Co-authored-by: yangheran <heran.yang@seafile.com>
This commit is contained in:
feiniks 2024-11-08 21:49:26 +08:00 committed by GitHub
parent a5ae65086a
commit 29e247d73d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 60 additions and 13 deletions

View File

@ -1,13 +1,21 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include "common.h"
#include <string.h>
#include <glib.h>
#include <argon2.h>
#include "password-hash.h"
#include "seafile-crypt.h"
#include <openssl/rand.h>
#ifdef USE_GPL_CRYPTO
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <nettle/pbkdf2.h>
#else
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#endif
#include "utils.h"
#include "log.h"
@ -48,11 +56,16 @@ pbkdf2_sha256_derive_key (const char *data_in, int in_len,
unsigned char salt_bin[32] = {0};
hex_to_rawdata (salt, salt_bin, 32);
#ifdef USE_GPL_CRYPTO
pbkdf2_hmac_sha256 (in_len, (const guchar *)data_in, iteration,
sizeof(salt_bin), salt_bin, 32, key);
#else
PKCS5_PBKDF2_HMAC (data_in, in_len,
salt_bin, sizeof(salt_bin),
iteration,
EVP_sha256(),
32, key);
#endif
return 0;
}

View File

@ -53,15 +53,31 @@ seafile_derive_key (const char *data_in, int in_len, int version,
unsigned char *key, unsigned char *iv)
{
#ifdef USE_GPL_CRYPTO
if (version != 2) {
unsigned char repo_salt_bin[32];
if (version == 4)
hex_to_rawdata (repo_salt, repo_salt_bin, 32);
switch (version) {
case 1:
seaf_warning ("Encrypted library version %d is not supported.\n", version);
return -1;
case 2:
pbkdf2_hmac_sha256 (in_len, (const guchar *)data_in, KEYGEN_ITERATION2,
sizeof(salt), salt, 32, key);
pbkdf2_hmac_sha256 (32, (const guchar *)key, 10, sizeof(salt), salt, 16, iv);
case 3:
seaf_warning ("Encrypted library version %d is not supported.\n", version);
return -1;
case 4:
pbkdf2_hmac_sha256 (in_len, (const guchar *)data_in, KEYGEN_ITERATION2,
sizeof(repo_salt_bin), repo_salt_bin, 32, key);
pbkdf2_hmac_sha256 (32, (const guchar *)key, 10, sizeof(repo_salt_bin), repo_salt_bin, 16, iv);
default:
seaf_warning ("Encrypted library version %d is not supported.\n", version);
return -1;
}
pbkdf2_hmac_sha256 (in_len, (const guchar *)data_in, KEYGEN_ITERATION2,
sizeof(salt), salt, 32, key);
pbkdf2_hmac_sha256 (32, (const guchar *)key, 10, sizeof(salt), salt, 16, iv);
return 0;
#else
if (version >= 3) {
@ -123,13 +139,17 @@ seafile_generate_repo_salt (char *repo_salt)
#ifdef USE_GPL_CRYPTO
int rc = gnutls_rnd (GNUTLS_RND_RANDOM, repo_salt_bin, sizeof(repo_salt_bin));
if (rc != 0) {
seaf_warning ("Failed to generate salt for repo encryption.\n");
return -1;
}
#else
int rc = RAND_bytes (repo_salt_bin, sizeof(repo_salt_bin));
#endif
if (rc != 1) {
seaf_warning ("Failed to generate salt for repo encryption.\n");
return -1;
}
#endif
rawdata_to_hex (repo_salt_bin, repo_salt, 32);
@ -413,11 +433,18 @@ seafile_encrypt (char **data_out,
key.size = sizeof(crypt->key);
iv.data = crypt->iv;
iv.size = sizeof(crypt->iv);
rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv);
if (rc < 0) {
seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc));
if (crypt->version == 1 || crypt->version == 3) {
seaf_warning ("Encrypted library version % is not supported.\n", crypt->version);
ret = -1;
goto out;
} else {
rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv);
if (rc < 0) {
seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc));
ret = -1;
goto out;
}
}
enc_buf = g_new (char, buf_size);
@ -467,11 +494,18 @@ seafile_decrypt (char **data_out,
key.size = sizeof(crypt->key);
iv.data = crypt->iv;
iv.size = sizeof(crypt->iv);
rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv);
if (rc < 0) {
seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc));
if (crypt->version == 1 || crypt->version == 3) {
seaf_warning ("Encrypted library version %d is not supported.\n", crypt->version);
ret = -1;
goto out;
} else {
rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv);
if (rc < 0) {
seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc));
ret = -1;
goto out;
}
}
dec_buf = g_new (char, in_len);