diff --git a/pom.xml b/pom.xml
index 30a7fd3..b53a1aa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
1.2.0
1.7.36
- 2.9.0
+ 2.15.2
5.8.2
@@ -69,11 +69,16 @@
slf4j-api
${slf4j.version}
-
- com.google.code.gson
- gson
- ${gson.version}
-
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 1e6e53a..97af1f7 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -10,9 +10,10 @@
module org.cryptomator.integrations.win {
requires org.cryptomator.integrations.api;
requires org.slf4j;
- requires com.google.gson;
+ requires com.fasterxml.jackson.annotation;
+ requires com.fasterxml.jackson.databind;
- opens org.cryptomator.windows.keychain to com.google.gson;
+ opens org.cryptomator.windows.keychain to com.fasterxml.jackson.databind;
provides AutoStartProvider with WindowsAutoStart;
provides KeychainAccessProvider with WindowsProtectedKeychainAccess;
diff --git a/src/main/java/org/cryptomator/windows/keychain/ByteArrayJsonAdapter.java b/src/main/java/org/cryptomator/windows/keychain/ByteArrayJsonAdapter.java
deleted file mode 100644
index 0761e36..0000000
--- a/src/main/java/org/cryptomator/windows/keychain/ByteArrayJsonAdapter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.cryptomator.windows.keychain;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import java.lang.reflect.Type;
-import java.util.Base64;
-
-class ByteArrayJsonAdapter implements JsonSerializer, JsonDeserializer {
-
- @Override
- public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
- return Base64.getDecoder().decode(json.getAsString());
- }
-
- @Override
- public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
- return new JsonPrimitive(Base64.getEncoder().encodeToString(src));
- }
-
-}
diff --git a/src/main/java/org/cryptomator/windows/keychain/KeychainEntry.java b/src/main/java/org/cryptomator/windows/keychain/KeychainEntry.java
index 7a22db5..fd295f1 100644
--- a/src/main/java/org/cryptomator/windows/keychain/KeychainEntry.java
+++ b/src/main/java/org/cryptomator/windows/keychain/KeychainEntry.java
@@ -1,12 +1,7 @@
package org.cryptomator.windows.keychain;
-import com.google.gson.annotations.SerializedName;
-class KeychainEntry {
+import com.fasterxml.jackson.annotation.JsonProperty;
- @SerializedName("ciphertext")
- byte[] ciphertext;
-
- @SerializedName("salt")
- byte[] salt;
+record KeychainEntry(@JsonProperty("ciphertext") byte[] ciphertext, @JsonProperty("salt") byte[] salt) {
}
diff --git a/src/main/java/org/cryptomator/windows/keychain/WindowsProtectedKeychainAccess.java b/src/main/java/org/cryptomator/windows/keychain/WindowsProtectedKeychainAccess.java
index 9e3e591..abb71f1 100644
--- a/src/main/java/org/cryptomator/windows/keychain/WindowsProtectedKeychainAccess.java
+++ b/src/main/java/org/cryptomator/windows/keychain/WindowsProtectedKeychainAccess.java
@@ -1,9 +1,8 @@
package org.cryptomator.windows.keychain;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonParseException;
-import com.google.gson.reflect.TypeToken;
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.cryptomator.integrations.common.OperatingSystem;
import org.cryptomator.integrations.common.Priority;
import org.cryptomator.integrations.keychain.KeychainAccessException;
@@ -19,7 +18,6 @@
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
-import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.file.Files;
@@ -49,11 +47,7 @@ public class WindowsProtectedKeychainAccess implements KeychainAccessProvider {
private static final Logger LOG = LoggerFactory.getLogger(WindowsProtectedKeychainAccess.class);
private static final Path USER_HOME_REL = Path.of("~");
private static final Path USER_HOME = Path.of(System.getProperty("user.home"));
- private static final Gson GSON = new GsonBuilder() //
- .setPrettyPrinting() //
- .registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) //
- .disableHtmlEscaping() //
- .create();
+ private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
private final List keychainPaths;
private final WinDataProtection dataProtection;
@@ -103,12 +97,11 @@ public void storePassphrase(String key, String displayName, CharSequence passphr
ByteBuffer buf = UTF_8.encode(CharBuffer.wrap(passphrase));
byte[] cleartext = new byte[buf.remaining()];
buf.get(cleartext);
- KeychainEntry entry = new KeychainEntry();
- entry.salt = generateSalt();
- entry.ciphertext = dataProtection.protect(cleartext, entry.salt);
+ var salt = generateSalt();
+ var ciphertext = dataProtection.protect(cleartext, salt);
Arrays.fill(buf.array(), (byte) 0x00);
Arrays.fill(cleartext, (byte) 0x00);
- keychainEntries.put(key, entry);
+ keychainEntries.put(key, new KeychainEntry(ciphertext, salt));
saveKeychainEntries();
}
@@ -119,7 +112,7 @@ public char[] loadPassphrase(String key) throws KeychainAccessException {
if (entry == null) {
return null;
}
- byte[] cleartext = dataProtection.unprotect(entry.ciphertext, entry.salt);
+ byte[] cleartext = dataProtection.unprotect(entry.ciphertext(), entry.salt());
if (cleartext == null) {
return null;
}
@@ -184,12 +177,15 @@ private void loadKeychainEntriesIfNeeded() throws KeychainAccessException {
//visible for testing
Optional