feat: cache password
This commit is contained in:
@@ -2,6 +2,7 @@ package me.hatter.integrations.card;
|
||||
|
||||
public class CardHmacDecryptResult {
|
||||
private String plaintext;
|
||||
private String password;
|
||||
|
||||
public String getPlaintext() {
|
||||
return plaintext;
|
||||
@@ -10,4 +11,12 @@ public class CardHmacDecryptResult {
|
||||
public void setPlaintext(String plaintext) {
|
||||
this.plaintext = plaintext;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -25,6 +27,8 @@ public class Utils {
|
||||
private static final File CARD_CONFIG_FILE2 = new File(USER_HOME, ".config/cryptomator/card_config.json");
|
||||
private static final File DEFAULT_ENCRYPTION_KEY_BASE_PATH = new File(USER_HOME, ".config/cryptomator/card_keys/");
|
||||
|
||||
private static final ConcurrentMap<String, String> PASSWORD_CACHE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
public static boolean isCheckPassphraseStored() {
|
||||
final StackTraceElement stack = getCallerStackTrace();
|
||||
if (stack != null) {
|
||||
@@ -97,12 +101,12 @@ public class Utils {
|
||||
throw new KeychainAccessException("Password key file: " + keyFile + " not found");
|
||||
}
|
||||
final String encryptedKey = readFile(keyFile);
|
||||
final byte[] password = decrypt(cardConfig, encryptedKey);
|
||||
final byte[] password = decrypt(cardConfig, vault, encryptedKey);
|
||||
return new String(password, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static void storePassword(CardConfig cardConfig, String vault, String name, CharSequence password) throws KeychainAccessException {
|
||||
final String encryptedPassword = encrypt(cardConfig, password.toString().getBytes(StandardCharsets.UTF_8), name);
|
||||
final String encryptedPassword = encrypt(cardConfig, vault, password.toString().getBytes(StandardCharsets.UTF_8), name);
|
||||
final File keyFile = getKeyFile(cardConfig, vault);
|
||||
writeFile(keyFile, encryptedPassword);
|
||||
}
|
||||
@@ -149,32 +153,58 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] decrypt(CardConfig cardConfig, String input) throws KeychainAccessException {
|
||||
private static byte[] decrypt(CardConfig cardConfig, String vault, String input) throws KeychainAccessException {
|
||||
final List<String> params = new ArrayList<>();
|
||||
params.add("hmac-decrypt");
|
||||
params.add("--ciphertext");
|
||||
params.add(input);
|
||||
params.add("--auto-pbe");
|
||||
params.add("--json");
|
||||
|
||||
final String password = PASSWORD_CACHE_MAP.get(vault);
|
||||
if (password != null) {
|
||||
params.add("--password");
|
||||
params.add(password);
|
||||
} else {
|
||||
params.add("--outputs-password");
|
||||
}
|
||||
|
||||
final UtilsCommandResult decryptResult = runCardCli(
|
||||
cardConfig,
|
||||
null,
|
||||
"hmac-decrypt",
|
||||
"--ciphertext", input,
|
||||
"--auto-pbe",
|
||||
"--json"
|
||||
params.toArray(new String[0])
|
||||
);
|
||||
if (decryptResult.getExitValue() != 0) {
|
||||
throw new KeychainAccessException("card-cli decrypt failed: " + decryptResult);
|
||||
}
|
||||
final String resultString = new String(decryptResult.getStdout(), StandardCharsets.UTF_8);
|
||||
final CardHmacDecryptResult result = new Gson().fromJson(resultString, CardHmacDecryptResult.class);
|
||||
if (result.getPassword() != null) {
|
||||
PASSWORD_CACHE_MAP.put(vault, result.getPassword());
|
||||
}
|
||||
return Base64.getDecoder().decode(result.getPlaintext());
|
||||
}
|
||||
|
||||
private static String encrypt(CardConfig cardConfig, byte[] input, String name) throws KeychainAccessException {
|
||||
private static String encrypt(CardConfig cardConfig, String vault, byte[] input, String name) throws KeychainAccessException {
|
||||
final List<String> params = new ArrayList<>();
|
||||
params.add("hmac-encrypt");
|
||||
params.add("--plaintext");
|
||||
params.add(Base64.getEncoder().encodeToString(input));
|
||||
params.add("--with-pbe-encrypt");
|
||||
params.add("--pbe-iteration");
|
||||
params.add("1000000");
|
||||
params.add("--json");
|
||||
|
||||
final String password = PASSWORD_CACHE_MAP.get(vault);
|
||||
if (password != null) {
|
||||
params.add("--password");
|
||||
params.add(password);
|
||||
}
|
||||
|
||||
final UtilsCommandResult encryptResult = runCardCli(
|
||||
cardConfig,
|
||||
null,
|
||||
"hmac-encrypt",
|
||||
"--plaintext", Base64.getEncoder().encodeToString(input),
|
||||
"--with-pbe-encrypt",
|
||||
"--pbe-iteration", "1000000",
|
||||
"--json"
|
||||
params.toArray(new String[0])
|
||||
);
|
||||
if (encryptResult.getExitValue() != 0) {
|
||||
throw new KeychainAccessException("card-cli encrypt failed: " + encryptResult);
|
||||
|
||||
Reference in New Issue
Block a user