diff --git a/CHANGELOG.md b/CHANGELOG.md
index c87262d1..931750dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,13 +2,27 @@
Trying to follow the suggestions at [Keep a Change Log](http://keepachangelog.com) and [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
-##[2.2.2]
+## [2.2.3-SNAPSHOT]
+
+### Changed
+
+- Deprecated method Entry.getPassword(): This means that the method getPassword() in the Entry class has been marked as deprecated. Deprecated methods are no longer recommended for use and might be removed in future versions of the code.
+
+### Added
+
+- byte[] getPasswordAsBytes() to AbstractEntry class: This means that a new method getPasswordAsBytes() has been added to the AbstractEntry class. This method likely returns the password in the form of a byte array instead of a plain string.
+
+- byte[] getPropertyAsBytes(String name) to the Entry interface: This indicates that a new method getPropertyAsBytes(String name) has been added to the Entry interface. This method likely returns a specific property as a byte array.
+
+- Added test cases to ensure the byte password is used correctly: This means that new test cases have been added to the codebase to ensure that the handling of byte passwords is functioning correctly. These tests will help verify that the newly introduced methods are working as expected.
+
+## [2.2.2-SNAPSHOT]
### Added
- implementation of database using Jackson
-##[2.2.1]
+## [2.2.1] 2023-08-21
### Added
diff --git a/all/pom.xml b/all/pom.xml
index 892f7056..a0748435 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -19,7 +19,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml
diff --git a/all/src/main/java/org/linguafranca/pwdb/package-info.java b/all/src/main/java/org/linguafranca/pwdb/package-info.java
new file mode 100644
index 00000000..a544df96
--- /dev/null
+++ b/all/src/main/java/org/linguafranca/pwdb/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * This module provides a simple import of the database implementations of KeePass, "all" in the diagram below.
+ *
+ *
+ *
+ * @see Module Structure
+ * in the readme at GitHub for a discussion of the project modules and links to JavaDocs.
+ */
+package org.linguafranca.pwdb;
\ No newline at end of file
diff --git a/database/pom.xml b/database/pom.xml
index 67b6015d..002d10a0 100644
--- a/database/pom.xml
+++ b/database/pom.xml
@@ -3,7 +3,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/database/src/main/java/org/linguafranca/pwdb/Entry.java b/database/src/main/java/org/linguafranca/pwdb/Entry.java
index 4780a0ff..fc7d0cf7 100644
--- a/database/src/main/java/org/linguafranca/pwdb/Entry.java
+++ b/database/src/main/java/org/linguafranca/pwdb/Entry.java
@@ -118,6 +118,17 @@ interface Matcher {
*/
void setProperty(String name, String value);
+ /**
+ * Gets the value of a property.
+ *
+ *
All implementations of Entry are required to support reading and writing of
+ * {@link #STANDARD_PROPERTY_NAMES}.
+ * @param name the name of the property to get
+ * @return a value or null if the property is not known, or if setting of arbitrary properties is not supported
+ * @see Database#supportsNonStandardPropertyNames()
+ */
+
+ byte[] getPropertyAsBytes(String name);
/**
* Removes this non-standard property, if it exists.
*
@@ -219,11 +230,23 @@ interface Matcher {
* Gets the (unencrypted) password field for this entry.
*
*
Implementations should Touch LastAccessedTime when this method is called.
- *
+ *
+ * @deprecated because the string is immutable, and cannot be wiped from memory
+ *
* @return a password
*/
+ @Deprecated
String getPassword();
+ /**
+ * Gets the (unencrypted) password field for this entry.
+ *
+ *
Implementations should Touch LastAccessedTime when this method is called.
+ *
+ * @return a password
+ */
+ public byte[] getPasswordAsBytes();
+
/**
* Sets the plaintext password for this Entry.
*
diff --git a/database/src/main/java/org/linguafranca/pwdb/base/AbstractEntry.java b/database/src/main/java/org/linguafranca/pwdb/base/AbstractEntry.java
index af5614fc..26d69ff3 100644
--- a/database/src/main/java/org/linguafranca/pwdb/base/AbstractEntry.java
+++ b/database/src/main/java/org/linguafranca/pwdb/base/AbstractEntry.java
@@ -84,10 +84,16 @@ public void setUsername(String username) {
}
@Override
+ @Deprecated
public String getPassword() {
return getProperty(STANDARD_PROPERTY_NAME_PASSWORD);
}
+ @Override
+ public byte[] getPasswordAsBytes() {
+ return getPropertyAsBytes(STANDARD_PROPERTY_NAME_PASSWORD);
+ }
+
@Override
public void setPassword(String pass) {
setProperty(STANDARD_PROPERTY_NAME_PASSWORD, pass);
diff --git a/dom/pom.xml b/dom/pom.xml
index f3ccfe79..674166f4 100644
--- a/dom/pom.xml
+++ b/dom/pom.xml
@@ -3,7 +3,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/dom/src/main/java/org/linguafranca/pwdb/kdbx/dom/DomEntryWrapper.java b/dom/src/main/java/org/linguafranca/pwdb/kdbx/dom/DomEntryWrapper.java
index 39575301..a97f61f8 100644
--- a/dom/src/main/java/org/linguafranca/pwdb/kdbx/dom/DomEntryWrapper.java
+++ b/dom/src/main/java/org/linguafranca/pwdb/kdbx/dom/DomEntryWrapper.java
@@ -79,6 +79,11 @@ public void setProperty(String name, String value) {
database.setDirty(true);
}
+ @Override
+ public byte[] getPropertyAsBytes(String name) {
+ return getProperty(name).getBytes();
+ }
+
@Override
public boolean removeProperty(String name) throws IllegalArgumentException {
if (STANDARD_PROPERTY_NAMES.contains(name)) throw new IllegalArgumentException("may not remove property: " + name);
diff --git a/example/pom.xml b/example/pom.xml
index bc807577..cbf75d8b 100644
--- a/example/pom.xml
+++ b/example/pom.xml
@@ -19,7 +19,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue33Test.java b/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue33Test.java
index 09486d82..322ee10a 100644
--- a/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue33Test.java
+++ b/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue33Test.java
@@ -10,6 +10,7 @@
import org.linguafranca.pwdb.kdbx.KdbxCreds;
import org.linguafranca.pwdb.kdbx.Util;
import org.linguafranca.pwdb.kdbx.dom.DomDatabaseWrapper;
+import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
import org.linguafranca.pwdb.kdbx.jaxb.JaxbDatabase;
import org.linguafranca.pwdb.kdbx.simple.SimpleDatabase;
@@ -59,4 +60,10 @@ public void testSimpleDatabase() throws IOException {
SimpleDatabase database = SimpleDatabase.load(CREDENTIALS, inputStream);
database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Simple.xml")));
}
+
+ @Test
+ public void testJacksonDatabase() throws IOException {
+ JacksonDatabase database = JacksonDatabase.load(CREDENTIALS, inputStream);
+ database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Jackson.xml")));
+ }
}
diff --git a/jackson/pom.xml b/jackson/pom.xml
index f6c2027b..63415651 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -18,7 +18,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
@@ -33,41 +33,21 @@
KeePassJava2-kdbx${project.version}
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ 2.15.0
+
+
+ com.fasterxml.woodstox
+ woodstox-core
+ 6.5.0
+ org.linguafranca.pwdbtest${project.version}test
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-xml
- 2.15.0
-
-
- com.fasterxml.woodstox
- woodstox-core
- 6.5.0
-
-
- junit
- junit
- test
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- ${java.version}
- ${java.version}
- src/generated/java
-
-
-
-
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonEntry.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonEntry.java
index c3110e0e..64c845ef 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonEntry.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonEntry.java
@@ -94,18 +94,18 @@ public class JacksonEntry extends AbstractEntry string;
- @JacksonXmlProperty(localName = "Binary") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "Binary") /* Workaround jackson */
@JacksonXmlElementWrapper(useWrapping = false)
protected List binary;
@JacksonXmlProperty(localName = "AutoType")
protected AutoType autoType;
- @JacksonXmlProperty(localName = "History") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "History") /* Workaround jackson */
protected JacksonHistory history;
@JsonIgnore
@@ -316,4 +316,9 @@ protected void touch() {
this.times.setLastModificationTime(new Date());
this.database.setDirty(true);
}
+
+ @Override
+ public byte[] getPropertyAsBytes(String name) {
+ return getByteContent(getStringProperty(name, string));
+ }
}
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonGroup.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonGroup.java
index c7a9dc43..436d66d5 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonGroup.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonGroup.java
@@ -21,7 +21,9 @@
import java.util.List;
import java.util.UUID;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.jetbrains.annotations.NotNull;
+import org.linguafranca.pwdb.base.AbstractGroup;
import org.linguafranca.pwdb.kdbx.jackson.converter.StringToBooleanConverter;
import org.linguafranca.pwdb.kdbx.jackson.converter.UUIDToBase64Converter;
import org.linguafranca.pwdb.kdbx.jackson.converter.Base64ToUUIDConverter;
@@ -51,9 +53,8 @@
"entry",
"group",
})
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class JacksonGroup
- extends org.linguafranca.pwdb.base.AbstractGroup {
+@JsonIgnoreProperties(ignoreUnknown=true)
+public class JacksonGroup extends AbstractGroup {
@JacksonXmlProperty(localName = "UUID")
@JsonDeserialize(converter = Base64ToUUIDConverter.class)
@@ -100,12 +101,12 @@ public class JacksonGroup
@JsonSerialize(converter = UUIDToBase64Converter.class)
protected UUID lastTopVisibleEntry;
- @JacksonXmlProperty(localName = "Entry") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "Entry") /* Workaround jackson */
@JacksonXmlElementWrapper(useWrapping = false)
protected List entries;
- @JacksonXmlProperty(localName = "Group") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "Group") /* Workaround jackson */
@JacksonXmlElementWrapper(useWrapping = false)
protected List groups;
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonHistory.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonHistory.java
index 05ba3537..c9ea238c 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonHistory.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonHistory.java
@@ -23,12 +23,12 @@
public class JacksonHistory {
- @JacksonXmlProperty(localName = "Entry") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "Entry") /* Workaround jackson */
@JacksonXmlElementWrapper(useWrapping = false)
private List entry;
public JacksonHistory() {
- entry = new ArrayList();
+ entry = new ArrayList<>();
}
/**
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonSerializableDatabase.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonSerializableDatabase.java
index d9dd388a..2ecf4f58 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonSerializableDatabase.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonSerializableDatabase.java
@@ -19,14 +19,19 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
+import com.fasterxml.jackson.databind.MapperFeature;
+import org.jetbrains.annotations.NotNull;
+import org.linguafranca.pwdb.Entry;
import org.linguafranca.pwdb.SerializableDatabase;
import org.linguafranca.pwdb.kdbx.Helpers;
-import org.linguafranca.pwdb.kdbx.jackson.converter.ValueDeserialized;
+import org.linguafranca.pwdb.kdbx.jackson.converter.ValueDeserializer;
import org.linguafranca.pwdb.kdbx.jackson.converter.ValueSerializer;
import org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses;
import org.linguafranca.pwdb.kdbx.jackson.model.KeePassFile;
@@ -41,6 +46,8 @@
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
+import static org.linguafranca.pwdb.Entry.STANDARD_PROPERTY_NAME_TITLE;
+
public class JacksonSerializableDatabase implements SerializableDatabase {
public KeePassFile keePassFile;
@@ -67,7 +74,7 @@ public JacksonSerializableDatabase(KeePassFile keePassFile) {
public JacksonSerializableDatabase load(InputStream inputStream) throws IOException {
XmlMapper mapper = new XmlMapper();
SimpleModule module = new SimpleModule();
- module.addDeserializer(EntryClasses.StringProperty.Value.class, new ValueDeserialized(encryptor));
+ module.addDeserializer(EntryClasses.StringProperty.Value.class, new ValueDeserializer(encryptor));
mapper.registerModule(module);
keePassFile = mapper.readValue(inputStream, KeePassFile.class);
return this;
@@ -76,35 +83,88 @@ public JacksonSerializableDatabase load(InputStream inputStream) throws IOExcept
@Override
public void save(OutputStream outputStream) throws IOException {
-
+ prepareForSave(keePassFile.root.group);
try {
-
- XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
- XmlMapper mapper = new XmlMapper();
+
SimpleModule module = new SimpleModule();
module.addSerializer(EntryClasses.StringProperty.Value.class, new ValueSerializer(encryptor));
+ // disable auto-detection, only use annotated values
+ XmlMapper mapper = XmlMapper.builder()
+ .disable(MapperFeature.AUTO_DETECT_CREATORS,
+ MapperFeature.AUTO_DETECT_FIELDS,
+ MapperFeature.AUTO_DETECT_GETTERS,
+ MapperFeature.AUTO_DETECT_SETTERS,
+ MapperFeature.AUTO_DETECT_IS_GETTERS)
+ .build();
mapper.registerModule(module);
mapper.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+
+ // set the serializer to Woodstox
+ System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
+ XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
xmlOutputFactory.setProperty(WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
xmlOutputFactory.setProperty(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE, true);
OutputStreamWriter osw = new OutputStreamWriter(outputStream);
XMLStreamWriter sw = xmlOutputFactory.createXMLStreamWriter(osw);
- sw.setPrefix("xml", "http://www.w3.org/XML/1998/namespace");
+ try {
+ sw.setPrefix("xml", "http://www.w3.org/XML/1998/namespace");
- mapper.writeValue(sw, keePassFile);
-
- sw.writeEndDocument();
- sw.close();
+ mapper.writeValue(sw, keePassFile);
+
+ sw.writeEndDocument();
+ } finally {
+ sw.close();
+ osw.close();
+ }
} catch(Exception e) {
throw new IllegalStateException(e);
}
}
-
+ /**
+ * Create a list of names of properties that should be encrypted by default
+ */
+ @NotNull
+ private List getToEncrypt() {
+ final List toEncrypt = new ArrayList<>();
+ for (String propertyName: Entry.STANDARD_PROPERTY_NAMES) {
+ if (keePassFile.meta.memoryProtection.shouldProtect(propertyName)) {
+ toEncrypt.add(propertyName);
+ }
+ }
+ return toEncrypt;
+ }
+
+ /**
+ * Utility to mark fields that need to be encrypted and vice versa
+ *
+ * @param parent the group to start from
+ */
+ private static void prepareForSave(JacksonGroup parent){
+ for (JacksonGroup group: parent.groups) {
+ prepareForSave(group);
+ }
+ for (JacksonEntry entry: parent.entries) {
+ for (EntryClasses.StringProperty property : entry.string) {
+ boolean shouldProtect = parent.database.shouldProtect(property.getKey());
+ property.getValue().setProtectOnOutput(shouldProtect || property.getValue().getProtectOnOutput());
+ }
+ if (Objects.nonNull(entry.history)) {
+ for (JacksonEntry entry2 : entry.history.getEntry()) {
+ for (EntryClasses.StringProperty property : entry2.string) {
+ boolean shouldProtect = parent.database.shouldProtect(property.getKey());
+ property.getValue().setProtectOnOutput(shouldProtect || property.getValue().getProtectOnOutput());
+ }
+ }
+ }
+ }
+ }
+
@Override
public byte[] getHeaderHash() {
return keePassFile.meta.headerHash;
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserialized.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserializer.java
similarity index 91%
rename from jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserialized.java
rename to jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserializer.java
index e448589e..8f7fda9b 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserialized.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserializer.java
@@ -29,20 +29,20 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-public class ValueDeserialized extends StdDeserializer {
+public class ValueDeserializer extends StdDeserializer {
private StreamEncryptor encryptor;
- public ValueDeserialized() {
- super(ValueDeserialized.class);
+ public ValueDeserializer() {
+ super(ValueDeserializer.class);
}
- public ValueDeserialized(Class v) {
+ public ValueDeserializer(Class v) {
super(v);
}
- public ValueDeserialized(StreamEncryptor encryptor) {
- super(ValueDeserialized.class);
+ public ValueDeserializer(StreamEncryptor encryptor) {
+ super(ValueDeserializer.class);
this.encryptor = encryptor;
}
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueSerializer.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueSerializer.java
index 640f5db8..4d0207d2 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueSerializer.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueSerializer.java
@@ -30,15 +30,7 @@
public class ValueSerializer extends StdSerializer{
- private StreamEncryptor encryptor;
-
- public ValueSerializer() {
- super(ValueSerializer.class, false);
- }
-
- public ValueSerializer(Class v) {
- super(v);
- }
+ private final StreamEncryptor encryptor;
public ValueSerializer(StreamEncryptor encryptor) {
super(ValueSerializer.class, false);
@@ -52,8 +44,9 @@ public void serialize(Value value, JsonGenerator gen, SerializerProvider provide
final ToXmlGenerator xmlGenerator = (ToXmlGenerator) gen;
xmlGenerator.writeStartObject();
+ String stringToWrite = value.getText();
//We need to encrypt and convert to base64 every protected element
- if(value.getProtectOnOutput()) {
+ if (value.getProtectOnOutput()) {
xmlGenerator.setNextIsAttribute(true);
gen.writeStringField("Protected", "True");
String plain = value.getText();
@@ -63,17 +56,12 @@ public void serialize(Value value, JsonGenerator gen, SerializerProvider provide
//Cipher
byte[] encrypted = encryptor.encrypt(plain.getBytes());
//Convert to base64
- String base64 = new String(Base64.encodeBase64(encrypted));
-
- //Destroy from memory the plain value
- plain = null;
- value.setText(base64);
-
+ stringToWrite = new String(Base64.encodeBase64(encrypted));
}
xmlGenerator.setNextIsAttribute(false);
xmlGenerator.setNextIsUnwrapped(true);
- xmlGenerator.writeStringField("text",value.getText());
+ xmlGenerator.writeStringField("text", stringToWrite);
gen.writeEndObject();
diff --git a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/model/EntryClasses.java b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/model/EntryClasses.java
index 553203de..b1963dd3 100644
--- a/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/model/EntryClasses.java
+++ b/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/model/EntryClasses.java
@@ -44,6 +44,10 @@ public static String getStringContent(StringProperty property) {
return property == null || property.value == null ? null : property.value.text;
}
+ public static byte[] getByteContent(StringProperty property) {
+ return property == null || property.value == null ? null : property.value.text.getBytes();
+ }
+
public static BinaryProperty getBinaryProp(String name, List binary) {
for (BinaryProperty property : binary) {
if (property.key.equals(name)) {
@@ -212,7 +216,7 @@ public void setRef(String ref) {
public static class History {
- @JacksonXmlProperty(localName = "Entry") /** Workaround jackson **/
+ @JacksonXmlProperty(localName = "Entry") /* Workaround jackson */
@JacksonXmlElementWrapper(useWrapping = false)
private List list;
diff --git a/jaxb/pom.xml b/jaxb/pom.xml
index fbe8e56a..1493f87d 100644
--- a/jaxb/pom.xml
+++ b/jaxb/pom.xml
@@ -19,7 +19,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbEntry.java b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbEntry.java
index 1eafe10d..d9601c44 100644
--- a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbEntry.java
+++ b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbEntry.java
@@ -280,4 +280,14 @@ protected void touch() {
database.setDirty(true);
delegate.getTimes().setLastModificationTime(new Date());
}
+
+ @Override
+ public byte[] getPropertyAsBytes(String name) {
+ for (StringField field: delegate.getString()){
+ if (field.getKey().equals(name)){
+ return field.getValue().getValueAsByte();
+ }
+ }
+ return null;
+ }
}
diff --git a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSerializableDatabase.java b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSerializableDatabase.java
index b9a0f034..188af88b 100644
--- a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSerializableDatabase.java
+++ b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSerializableDatabase.java
@@ -186,7 +186,7 @@ public void afterMarshal(Object source) {
}
/**
- * Create a list of names of peroperties that should be encrypted by default
+ * Create a list of names of properties that should be encrypted by default
*/
@NotNull
private List getToEncrypt() {
diff --git a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/ValueBinding.java b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/ValueBinding.java
index a89fc2a2..b9d75705 100644
--- a/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/ValueBinding.java
+++ b/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/ValueBinding.java
@@ -22,6 +22,10 @@ public String getValue(){
return value;
}
+ public byte[] getValueAsByte() {
+ return value.getBytes();
+ }
+
public void setValue(String string){
value = string;
}
diff --git a/kdb/pom.xml b/kdb/pom.xml
index 611a3231..9db0908e 100644
--- a/kdb/pom.xml
+++ b/kdb/pom.xml
@@ -3,7 +3,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbEntry.java b/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbEntry.java
index ac9927b7..16642466 100644
--- a/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbEntry.java
+++ b/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbEntry.java
@@ -250,4 +250,16 @@ public boolean getExpires() {
protected void touch() {
lastModificationTime = new Date();
}
+
+ @Override
+ public byte[] getPropertyAsBytes(String name) {
+ switch (name) {
+ case STANDARD_PROPERTY_NAME_USER_NAME: return getUsername().getBytes();
+ case STANDARD_PROPERTY_NAME_PASSWORD: return getPassword().getBytes();
+ case STANDARD_PROPERTY_NAME_URL: return getUrl().getBytes();
+ case STANDARD_PROPERTY_NAME_TITLE: return getTitle().getBytes();
+ case STANDARD_PROPERTY_NAME_NOTES: return getNotes().getBytes();
+ default: return null;
+ }
+ }
}
diff --git a/kdbx/pom.xml b/kdbx/pom.xml
index c642ea8d..f1972337 100644
--- a/kdbx/pom.xml
+++ b/kdbx/pom.xml
@@ -19,7 +19,7 @@
KeePassJava2-parentorg.linguafranca.pwdb
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOT../pom.xml4.0.0
diff --git a/pom.xml b/pom.xml
index f01f78b5..ebfb082b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
org.linguafranca.pwdbKeePassJava2-parent
- 2.2.2-SNAPSHOT
+ 2.2.3-SNAPSHOTdatabasetest
@@ -146,7 +146,7 @@
org.apache.maven.pluginsmaven-dependency-plugin
- 3.0.2
+ 3.6.0
@@ -182,7 +182,7 @@
org.bouncycastlebcpkix-jdk18on
- 1.74
+ 1.76org.slf4j
diff --git a/readme.md b/readme.md
index d7a208b0..ab96cb98 100644
--- a/readme.md
+++ b/readme.md
@@ -270,7 +270,7 @@ bindings might be useful for building other interfaces.
A DOM based implementation of KDBX. Being DOM based it is rather slow, but
messes less with existing content than the other two implementations. Known to work on Android.