wipe private key and salt data before freeing

This commit is contained in:
Levi Neely 2025-03-11 14:57:57 +01:00
parent cac8846eea
commit 1376909eb6
1 changed files with 19 additions and 0 deletions

View File

@ -271,6 +271,7 @@ static int download_keys(unsigned char **rsapriv, size_t *rsaprivlen, unsigned c
break; break;
default: default:
def1: def1:
putil_wipe(rsaprivstruct, rsaprivstructlen);
psync_free(rsaprivstruct); psync_free(rsaprivstruct);
psync_free(rsapubstruct); psync_free(rsapubstruct);
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
@ -292,10 +293,12 @@ static int download_keys(unsigned char **rsapriv, size_t *rsaprivlen, unsigned c
default: default:
def2: def2:
psync_free(*rsapub); psync_free(*rsapub);
putil_wipe(rsaprivstruct, rsaprivstructlen);
psync_free(rsaprivstruct); psync_free(rsaprivstruct);
psync_free(rsapubstruct); psync_free(rsapubstruct);
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
} }
putil_wipe(rsaprivstruct, rsaprivstructlen);
psync_free(rsaprivstruct); psync_free(rsaprivstruct);
psync_free(rsapubstruct); psync_free(rsapubstruct);
return PSYNC_CRYPTO_START_SUCCESS; return PSYNC_CRYPTO_START_SUCCESS;
@ -591,6 +594,7 @@ int pcryptofolder_unlock(const char *password) {
if (unlikely(rowcnt != 0)) { if (unlikely(rowcnt != 0)) {
debug(D_BUG, debug(D_BUG,
"only some of records found in the database, should not happen"); "only some of records found in the database, should not happen");
putil_wipe(rsapriv, rsaprivlen);
psync_free(rsapriv); psync_free(rsapriv);
psync_free(rsapub); psync_free(rsapub);
psync_free(salt); psync_free(salt);
@ -614,8 +618,10 @@ int pcryptofolder_unlock(const char *password) {
if (crypto_pubkey == PSYNC_INVALID_RSA) { if (crypto_pubkey == PSYNC_INVALID_RSA) {
pthread_rwlock_unlock(&crypto_lock); pthread_rwlock_unlock(&crypto_lock);
debug(D_WARNING, "could not load public key"); debug(D_WARNING, "could not load public key");
putil_wipe(rsapriv, rsaprivlen);
psync_free(rsapriv); psync_free(rsapriv);
psync_free(rsapub); psync_free(rsapub);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
} }
@ -641,8 +647,10 @@ int pcryptofolder_unlock(const char *password) {
prsa_free_public(crypto_pubkey); prsa_free_public(crypto_pubkey);
crypto_pubkey = PSYNC_INVALID_RSA; crypto_pubkey = PSYNC_INVALID_RSA;
pthread_rwlock_unlock(&crypto_lock); pthread_rwlock_unlock(&crypto_lock);
putil_wipe(rsapriv, rsaprivlen);
psync_free(rsapriv); psync_free(rsapriv);
psync_free(rsapub); psync_free(rsapub);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_BAD_PASSWORD); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_BAD_PASSWORD);
} }
@ -656,8 +664,10 @@ int pcryptofolder_unlock(const char *password) {
crypto_privkey = PSYNC_INVALID_RSA; crypto_privkey = PSYNC_INVALID_RSA;
pthread_rwlock_unlock(&crypto_lock); pthread_rwlock_unlock(&crypto_lock);
debug(D_ERROR, "keys don't match"); debug(D_ERROR, "keys don't match");
putil_wipe(rsapriv, rsaprivlen);
psync_free(rsapriv); psync_free(rsapriv);
psync_free(rsapub); psync_free(rsapub);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_KEYS_DONT_MATCH); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_KEYS_DONT_MATCH);
} }
@ -672,8 +682,10 @@ int pcryptofolder_unlock(const char *password) {
salt, saltlen, iterations, 0, salt, saltlen, iterations, 0,
publicsha1, privatesha1, flags); publicsha1, privatesha1, flags);
} }
putil_wipe(rsapriv, rsaprivlen);
psync_free(rsapriv); psync_free(rsapriv);
psync_free(rsapub); psync_free(rsapub);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
debug(D_NOTICE, "crypto successfully started"); debug(D_NOTICE, "crypto successfully started");
return PSYNC_CRYPTO_START_SUCCESS; return PSYNC_CRYPTO_START_SUCCESS;
@ -1954,6 +1966,7 @@ int psync_pcloud_crypto_encode_key(const char *newpassphrase, uint32_t flags,
psync_sha256(newpriv, rsaprivlen, newprivsha); psync_sha256(newpriv, rsaprivlen, newprivsha);
rsasign = prsa_sign_sha256_hash(crypto_privkey, newprivsha); rsasign = prsa_sign_sha256_hash(crypto_privkey, newprivsha);
if (is_err(rsasign)) { if (is_err(rsasign)) {
putil_wipe(newpriv, rsaprivlen);
psync_free(newpriv); psync_free(newpriv);
prsa_free_binary(rsapriv); prsa_free_binary(rsapriv);
return to_err(rsasign); return to_err(rsasign);
@ -1961,6 +1974,7 @@ int psync_pcloud_crypto_encode_key(const char *newpassphrase, uint32_t flags,
*privenc = (char *)psync_base64_encode(newpriv, rsaprivlen, &dummy); *privenc = (char *)psync_base64_encode(newpriv, rsaprivlen, &dummy);
*sign = (char *)psync_base64_encode(rsasign->data, rsasign->datalen, &dummy); *sign = (char *)psync_base64_encode(rsasign->data, rsasign->datalen, &dummy);
psync_free(rsasign); psync_free(rsasign);
putil_wipe(newpriv, rsaprivlen);
psync_free(newpriv); psync_free(newpriv);
prsa_free_binary(rsapriv); prsa_free_binary(rsapriv);
@ -2017,6 +2031,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
memset(privatekey_struct, 0, offsetof(priv_key_ver1, key) + privkeylen); memset(privatekey_struct, 0, offsetof(priv_key_ver1, key) + privkeylen);
memcpy(privatekey_struct->key, privkey, privkeylen); memcpy(privatekey_struct->key, privkey, privkeylen);
privatekey_struct->type = PSYNC_CRYPTO_TYPE_RSA4096_64BYTESALT_20000IT; privatekey_struct->type = PSYNC_CRYPTO_TYPE_RSA4096_64BYTESALT_20000IT;
putil_wipe(privkey, privkeylen);
psync_free(privkey); psync_free(privkey);
} else if (!strcmp(id, "crypto_public_key")) { } else if (!strcmp(id, "crypto_public_key")) {
load_str_to(&row[1], &pubkey, &pubkeylen); load_str_to(&row[1], &pubkey, &pubkeylen);
@ -2034,6 +2049,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
continue; continue;
} }
memcpy(privatekey_struct->salt, salt, saltlen); memcpy(privatekey_struct->salt, salt, saltlen);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
} }
} }
@ -2081,7 +2097,9 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
pubkey, pubkeylen, privkey, privkeylen, oldpassphrase, newpassphrase, pubkey, pubkeylen, privkey, privkeylen, oldpassphrase, newpassphrase,
flags, privenc, sign); flags, privenc, sign);
psync_free(pubkey); psync_free(pubkey);
putil_wipe(privkey, privkeylen);
psync_free(privkey); psync_free(privkey);
putil_wipe(salt, saltlen);
psync_free(salt); psync_free(salt);
if (cres) if (cres)
goto ex; goto ex;
@ -2092,6 +2110,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
(unsigned char *)privatekey_struct, (unsigned char *)privatekey_struct,
privkeylen + offsetof(priv_key_ver1, key), oldpassphrase, newpassphrase, privkeylen + offsetof(priv_key_ver1, key), oldpassphrase, newpassphrase,
flags, privenc, sign); flags, privenc, sign);
putil_wipe(privatekey_struct, privkeylen + offsetof(priv_key_ver1, key));
psync_free(privatekey_struct); psync_free(privatekey_struct);
psync_free(pubkey_struct); psync_free(pubkey_struct);
if (cres) if (cres)