├── test
├── src
│ └── test
│ │ └── resources
│ │ ├── keyfile32
│ │ ├── kdb.key
│ │ ├── keyfile64
│ │ ├── issue-38
│ │ └── Database
│ │ │ ├── README.md
│ │ │ ├── Database.kdbx
│ │ │ └── Database.keyx
│ │ ├── random_file
│ │ ├── test1.kdbx
│ │ ├── test123.kdb
│ │ ├── test123.kdbx
│ │ ├── kdbwithkey.kdb
│ │ ├── letter J.jpeg
│ │ ├── letter L.jpeg
│ │ ├── Attachment.kdbx
│ │ ├── V4-AES-AES.kdbx
│ │ ├── testDeleted.kdbx
│ │ ├── EmptyPassword.kdbx
│ │ ├── V3-CustomIcon.kdbx
│ │ ├── V4-AES-Argon2.kdbx
│ │ ├── V4-CustomIcon.kdbx
│ │ ├── issue-70
│ │ ├── test1.kdbx
│ │ ├── test2.kdbx
│ │ └── test-hugoo10.kdbx
│ │ ├── kdbx_hash_test.kdbx
│ │ ├── kdbx_keyfile32.kdbx
│ │ ├── kdbx_keyfile64.kdbx
│ │ ├── Database-4.1-123.kdbx
│ │ ├── ExampleDatabase.kdbx
│ │ ├── KeyFileDatabase.kdbx
│ │ ├── NoPasswordWithKey.kdbx
│ │ ├── V4-ChaCha20-AES.kdbx
│ │ ├── test123-AES-AES.kdbx
│ │ ├── test123-AES-Argon2.kdbx
│ │ ├── EmptyPasswordWithKey.kdbx
│ │ ├── kdb_with_random_file.kdbx
│ │ ├── test123-ChaCha20-AES.kdbx
│ │ ├── V4-AES-Argon2-CustomIcon.kdbx
│ │ ├── issue-27
│ │ ├── bogus-timestamp.kdbx
│ │ └── bogus-timestamp2.kdbx
│ │ ├── test123-ChaCha20-Argon2.kdbx
│ │ ├── V4-ChaCha20-Argon2-Attachment.kdbx
│ │ ├── EmptyPasswordWithKey.key
│ │ ├── KeyFileDatabase.key
│ │ ├── NoPasswordWithKey.key
│ │ ├── kdbx_hash_test.keyx
│ │ └── kdbx_hash_test_wrong_hash.keyx
└── pom.xml
├── .travis.yml
├── .gitignore
├── all
├── src
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ ├── IgnoreMe.java
│ │ └── package-info.java
└── pom.xml
├── database
├── src
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ ├── StreamConfiguration.java
│ │ ├── security
│ │ ├── KeyDerivationFunction.java
│ │ ├── CipherAlgorithm.java
│ │ └── ChaCha.java
│ │ ├── Icon.java
│ │ ├── Credentials.java
│ │ ├── protect
│ │ └── ProtectedDatabase.java
│ │ ├── SerializableDatabase.java
│ │ └── StreamFormat.java
└── pom.xml
├── jaxb
├── src
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── jaxb
│ │ │ ├── JaxbRecycleBinTest.java
│ │ │ ├── JaxbV4LoadTest.java
│ │ │ ├── JaxbBasicDatabaseTest.java
│ │ │ ├── JaxbLoaderTest.java
│ │ │ ├── JaxbSerializableDatabaseTest.java
│ │ │ ├── JaxbPropertyValueTest.java
│ │ │ ├── JaxbBinaryPropertyV3Test.java
│ │ │ ├── JaxbTest.java
│ │ │ ├── JaxbBinaryPropertyV4Test.java
│ │ │ └── JaxbSaveAndReloadTest.java
│ ├── main
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── jaxb
│ │ │ ├── base
│ │ │ ├── ValueBinding.java
│ │ │ └── AbstractJaxbParentedBinding.java
│ │ │ ├── util
│ │ │ ├── JaxbUtil.java
│ │ │ └── DateAdapter.java
│ │ │ └── JaxbIcon.java
│ └── generated
│ │ └── java
│ │ ├── org
│ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── jaxb
│ │ │ └── binding
│ │ │ ├── Adapter2.java
│ │ │ ├── Adapter3.java
│ │ │ ├── Adapter1.java
│ │ │ ├── Parented.java
│ │ │ ├── History.java
│ │ │ ├── ValueExtender.java
│ │ │ └── CustomData.java
│ │ └── META-INF
│ │ └── sun-jaxb.episode
├── gradle-source-sets.txt
└── bindings.xml
├── simple
├── src
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── simple
│ │ │ ├── SimpleRecycleBinTest.java
│ │ │ ├── SimpleDatabaseTest.java
│ │ │ ├── SimpleDatabaseLoaderTest.java
│ │ │ ├── SimplePropertyValueTest.java
│ │ │ ├── SimpleBinaryPropertyV4Test.java
│ │ │ └── SimpleBinaryPropertyV3Test.java
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ └── kdbx
│ │ └── simple
│ │ ├── converter
│ │ ├── KeePassBooleanConverter.java
│ │ ├── EmptyStringConverter.java
│ │ ├── TimeConverter.java
│ │ ├── UuidConverter.java
│ │ ├── Base64ByteArrayConverter.java
│ │ └── ValueConverter.java
│ │ └── SimpleIcon.java
└── pom.xml
├── dom
├── src
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── dom
│ │ │ ├── DomRecycleBinTest.java
│ │ │ ├── DomV4Test.java
│ │ │ ├── DomHelperTest.java
│ │ │ ├── DomDatabaseWrapperLoaderTest.java
│ │ │ ├── DomPropertyValueTest.java
│ │ │ ├── DomBinaryPropertyV3Test.java
│ │ │ ├── DomBinaryPropertyV4Test.java
│ │ │ ├── DomDatabaseWrapperTest.java
│ │ │ └── DomSaveAndReloadTest.java
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ └── kdbx
│ │ └── dom
│ │ └── DomIconWrapper.java
└── pom.xml
├── bitbucket-pipelines.yml
├── logback.xml
├── util
├── src
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── test
│ │ ├── util
│ │ ├── TestUtil.java
│ │ └── HexViewer.java
│ │ └── maven
│ │ └── MavenRunListener.java
└── pom.xml
├── kdb
├── src
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdb
│ │ │ ├── KeyFileTest.java
│ │ │ ├── KdbSerializerTest.java
│ │ │ ├── KdbDatabaseLoaderTest.java
│ │ │ └── KdbDatabaseTest.java
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ └── kdb
│ │ ├── KdbIcon.java
│ │ └── KdbCredentials.java
└── pom.xml
├── jackson
├── src
│ ├── main
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ └── jackson
│ │ │ ├── converter
│ │ │ ├── Base64ToByteConverter.java
│ │ │ ├── ByteToBase64Converter.java
│ │ │ ├── StringToBooleanConverter.java
│ │ │ ├── BooleanToStringConverter.java
│ │ │ ├── UUIDToBase64Converter.java
│ │ │ ├── DateToStringConverter.java
│ │ │ ├── Base64ToUUIDConverter.java
│ │ │ ├── StringToDateConverter.java
│ │ │ ├── ValueSerializer.java
│ │ │ └── ValueDeserializer.java
│ │ │ ├── JacksonHistory.java
│ │ │ └── JacksonIcon.java
│ └── test
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ ├── JacksonRecycleBinTest.java
│ │ ├── JacksonDatabaseTest.java
│ │ ├── JacksonDatabaseLoaderTest.java
│ │ ├── JacksonPropertyValueTest.java
│ │ ├── JacksonBinaryPropertyV3Test.java
│ │ ├── JacksonBinaryPropertyV4Test.java
│ │ ├── JacksonDatabaseLoadTest.java
│ │ └── JacksonSaveAndReloadTest.java
└── pom.xml
├── example
├── src
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── linguafranca
│ │ │ └── pwdb
│ │ │ └── kdbx
│ │ │ ├── validation
│ │ │ ├── Issue38Test.java
│ │ │ ├── Issue70Test.java
│ │ │ ├── Issue27Test.java
│ │ │ └── Issue33Test.java
│ │ │ ├── SaxParseTest.java
│ │ │ └── UtilTest.java
│ └── main
│ │ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ ├── example
│ │ └── SecureCharBufferPropertyValue.java
│ │ └── kdbx
│ │ └── ChooseFile.java
└── pom.xml
├── kdbx
├── pom.xml
└── src
│ ├── test
│ └── java
│ │ └── org
│ │ └── linguafranca
│ │ └── pwdb
│ │ ├── kdbx
│ │ ├── HelperTest.java
│ │ └── HelpersTest.java
│ │ └── security
│ │ └── StreamEncryptionTest.java
│ └── main
│ └── java
│ └── org
│ └── linguafranca
│ └── pwdb
│ ├── hashedblock
│ ├── CollectingOutputStream.java
│ └── CollectingInputStream.java
│ └── kdbx
│ └── KdbxCreds.java
└── .circleci
└── config.yml
/test/src/test/resources/keyfile32:
--------------------------------------------------------------------------------
1 | KQQWFvUqScAobSfwq4z5MwnbITIb38vm
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk: openjdk7
3 | script: mvn clean test
4 |
--------------------------------------------------------------------------------
/test/src/test/resources/kdb.key:
--------------------------------------------------------------------------------
1 | a320d61f69f0903d9f4cecb95c81b35f77b1af232a0b8f2d84377f7df57022d4
--------------------------------------------------------------------------------
/test/src/test/resources/keyfile64:
--------------------------------------------------------------------------------
1 | bc63a755436af06b88027816446ba0486e8e15fac0e26dbaee82f662c77546bc
--------------------------------------------------------------------------------
/test/src/test/resources/issue-38/Database/README.md:
--------------------------------------------------------------------------------
1 | This was rasied as Issue 38 - Keyfile is version 2, which was not supported.
--------------------------------------------------------------------------------
/test/src/test/resources/random_file:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/random_file
--------------------------------------------------------------------------------
/test/src/test/resources/test1.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test1.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/test123.kdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123.kdb
--------------------------------------------------------------------------------
/test/src/test/resources/test123.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/kdbwithkey.kdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/kdbwithkey.kdb
--------------------------------------------------------------------------------
/test/src/test/resources/letter J.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/letter J.jpeg
--------------------------------------------------------------------------------
/test/src/test/resources/letter L.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/letter L.jpeg
--------------------------------------------------------------------------------
/test/src/test/resources/Attachment.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/Attachment.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-AES-AES.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-AES-AES.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/testDeleted.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/testDeleted.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/EmptyPassword.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/EmptyPassword.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V3-CustomIcon.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V3-CustomIcon.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-AES-Argon2.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-AES-Argon2.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-CustomIcon.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-CustomIcon.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-70/test1.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-70/test1.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-70/test2.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-70/test2.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/kdbx_hash_test.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/kdbx_hash_test.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/kdbx_keyfile32.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/kdbx_keyfile32.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/kdbx_keyfile64.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/kdbx_keyfile64.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/Database-4.1-123.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/Database-4.1-123.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/ExampleDatabase.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/ExampleDatabase.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/KeyFileDatabase.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/KeyFileDatabase.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/NoPasswordWithKey.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/NoPasswordWithKey.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-ChaCha20-AES.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-ChaCha20-AES.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/test123-AES-AES.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123-AES-AES.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/test123-AES-Argon2.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123-AES-Argon2.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/EmptyPasswordWithKey.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/EmptyPasswordWithKey.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-70/test-hugoo10.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-70/test-hugoo10.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/kdb_with_random_file.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/kdb_with_random_file.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/test123-ChaCha20-AES.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123-ChaCha20-AES.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-AES-Argon2-CustomIcon.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-AES-Argon2-CustomIcon.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-27/bogus-timestamp.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-27/bogus-timestamp.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/test123-ChaCha20-Argon2.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/test123-ChaCha20-Argon2.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-27/bogus-timestamp2.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-27/bogus-timestamp2.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/issue-38/Database/Database.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/issue-38/Database/Database.kdbx
--------------------------------------------------------------------------------
/test/src/test/resources/V4-ChaCha20-Argon2-Attachment.kdbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jorabin/KeePassJava2/HEAD/test/src/test/resources/V4-ChaCha20-Argon2-Attachment.kdbx
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | testOutput
2 | build
3 | .vscode/*
4 | *.versionsBackup
5 | **/target
6 |
7 | #settings.gradle
8 | #gradlew
9 | #gradlew.bat
10 | #.gradle
11 | #gradle
12 | #build.gradle
13 |
14 |
--------------------------------------------------------------------------------
/all/src/main/java/org/linguafranca/pwdb/IgnoreMe.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb;
2 |
3 | /**
4 | * This is here for Javadoc generation purposes only
5 | */
6 | public class IgnoreMe {
7 | }
8 |
--------------------------------------------------------------------------------
/test/src/test/resources/EmptyPasswordWithKey.key:
--------------------------------------------------------------------------------
1 | 1.00 Vevc5pI13VSR11q74seXQkKJrccSkjnNZ6cfFBYhvpk=
2 |
--------------------------------------------------------------------------------
/test/src/test/resources/KeyFileDatabase.key:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1.00
5 |
6 |
7 | uE9L7SGiT0+PrSvZ0oIzaLjtpsiu50ciR/JXc44Pw24=
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/src/test/resources/NoPasswordWithKey.key:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1.00
5 |
6 |
7 | RJS69T/8tKYwO/fXPNGdtHlgLM5VfJmBDQLOlsg1AcE=
8 |
9 |
10 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/StreamConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb;
2 |
3 | /**
4 | * A marker interface for KdbxHeader and similar, if there ever is one
5 | */
6 | public interface StreamConfiguration {
7 | class None implements StreamConfiguration {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/src/test/resources/kdbx_hash_test.keyx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 |
6 |
7 |
8 | 66F110CA E32995B5 EFA8E672 1E70C773
9 | 48F8E260 EEDD8744 93F41803 5BFDC27D
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/src/test/resources/issue-38/Database/Database.keyx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 |
6 |
7 |
8 | A700DD37 8EBAABE2 1936E1F9 9FED8DEE
9 | D0F71664 B25B0DD2 961FFDA6 9E194E75
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/src/test/resources/kdbx_hash_test_wrong_hash.keyx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 |
6 |
7 |
8 | 66F110CA E32995B5 EFA8E672 1E70C773
9 | 48F8E260 EEDD8744 93F41803 5BFDC27D
10 |
11 |
12 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbRecycleBinTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.jaxb;
2 |
3 | import org.linguafranca.pwdb.checks.RecycleBinChecks;
4 |
5 | /**
6 | * @author jo
7 | */
8 | public class JaxbRecycleBinTest extends RecycleBinChecks {
9 | public JaxbRecycleBinTest() {
10 | database = new JaxbDatabase();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/jaxb/gradle-source-sets.txt:
--------------------------------------------------------------------------------
1 | sourceSets {
2 | main {
3 | java {
4 | srcDirs = ['src/main/java', 'src/generated/java']
5 | }
6 | resources {
7 | srcDirs = ['src/main/resources']
8 | }
9 | }
10 | test{
11 | java {
12 | srcDirs = ['src/test/java']
13 | }
14 | resources {
15 | srcDirs = ['src/test/resources']
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimpleRecycleBinTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.simple;
2 |
3 | import org.linguafranca.pwdb.checks.RecycleBinChecks;
4 |
5 | /**
6 | * @author jo
7 | */
8 | public class SimpleRecycleBinTest extends RecycleBinChecks {
9 | public SimpleRecycleBinTest() {
10 | database = new SimpleDatabase();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomRecycleBinTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.dom;
2 |
3 | import org.linguafranca.pwdb.checks.RecycleBinChecks;
4 |
5 | import java.io.IOException;
6 |
7 | /**
8 | * @author jo
9 | */
10 | public class DomRecycleBinTest extends RecycleBinChecks {
11 | public DomRecycleBinTest() throws IOException {
12 | database = new DomDatabaseWrapper();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/all/src/main/java/org/linguafranca/pwdb/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This module provides a simple import of the database implementations of KeePass, "all" in the diagram below.
3 | *
4 | *
5 | *
6 | * @see Module Structure
7 | * in the readme at GitHub for a discussion of the project modules and links to JavaDocs.
8 | */
9 | package org.linguafranca.pwdb;
--------------------------------------------------------------------------------
/bitbucket-pipelines.yml:
--------------------------------------------------------------------------------
1 | # This is a sample build configuration for Java (Maven).
2 | # Check our guides at https://confluence.atlassian.com/x/zd-5Mw for more examples.
3 | # Only use spaces to indent your .yml configuration.
4 | # -----
5 | # You can specify a custom docker image from Docker Hub as your build environment.
6 | image: maven:3.5.2-jdk-7
7 |
8 | pipelines:
9 | #only on this branch
10 | bitbucket-build:
11 | - step:
12 | caches:
13 | - maven
14 | script: # Modify the commands below to build your repository.
15 | - mvn -B verify # -B batch mode makes Maven less verbose
--------------------------------------------------------------------------------
/logback.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
9 |
10 | -%highlight(%-5level) %d{HH:mm:ss.SSS} [%thread] %logger{36} - %cyan(%marker) %msg%n
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 100
20 |
21 |
--------------------------------------------------------------------------------
/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/ValueBinding.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.jaxb.base;
2 |
3 | import javax.xml.bind.annotation.XmlAccessType;
4 | import javax.xml.bind.annotation.XmlAccessorType;
5 | import javax.xml.bind.annotation.XmlTransient;
6 | import javax.xml.bind.annotation.XmlValue;
7 |
8 | /**
9 | * Ancestor class of StringField.Value, providing a way of flagging protection
10 | * separate from @Protected and @ProtectInMemory
11 | */
12 | @XmlAccessorType(XmlAccessType.FIELD)
13 | public abstract class ValueBinding {
14 |
15 | @XmlTransient
16 | public boolean protectOnOutput;
17 |
18 | @XmlValue
19 | public String value;
20 |
21 | public String getValue(){
22 | return value;
23 | }
24 |
25 | public void setValue(String string){
26 | value = string;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/util/src/main/java/org/linguafranca/test/util/TestUtil.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.test.util;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 | import java.io.PrintStream;
6 |
7 | public class TestUtil {
8 | /**
9 | * Do nothing output stream
10 | */
11 | public static class NullOutputStream extends OutputStream {
12 |
13 | @Override
14 | public void write(int b) throws IOException {
15 |
16 | }
17 | }
18 | /**
19 | * set system property to suppress output from tests
20 | * @return if "inhibitConsoleOutput" has been set, e.g. in a profile
21 | */
22 | public static PrintStream getTestPrintStream() {
23 | return Boolean.getBoolean("inhibitConsoleOutput") ?
24 | new PrintStream(new NullOutputStream()) :
25 | new PrintStream(System.out);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/kdb/src/test/java/org/linguafranca/pwdb/kdb/KeyFileTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdb;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | import static org.junit.Assert.assertEquals;
9 |
10 | /**
11 | * @author jo
12 | */
13 | public class KeyFileTest {
14 |
15 | @Test
16 | public void openKdbWithKeyFile() throws IOException {
17 | InputStream key = getClass().getClassLoader().getResourceAsStream("kdb.key");
18 | KdbCredentials creds = new KdbCredentials.KeyFile("123".getBytes(), key);
19 | InputStream is = getClass().getClassLoader().getResourceAsStream("kdbwithkey.kdb");
20 | KdbDatabase db = KdbDatabase.load(creds, is);
21 | assertEquals(1, db.getRootGroup().getGroupsCount());
22 | assertEquals("General", db.getRootGroup().getGroups().get(0).getName());
23 | }
24 | }
--------------------------------------------------------------------------------
/util/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.linguafranca.pwdb
8 | KeePassJava2-parent
9 | 2.2.4
10 |
11 |
12 | PWDB :: Util
13 | Some underlying utilities which are needed for running tests.
14 | util
15 |
16 |
17 | true
18 |
19 |
20 |
21 |
22 | junit
23 | junit
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/Adapter2.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import javax.xml.bind.annotation.adapters.XmlAdapter;
12 |
13 | public class Adapter2
14 | extends XmlAdapter
15 | {
16 |
17 |
18 | public Boolean unmarshal(String value) {
19 | return (org.linguafranca.pwdb.kdbx.Helpers.toBoolean(value));
20 | }
21 |
22 | public String marshal(Boolean value) {
23 | return (org.linguafranca.pwdb.kdbx.Helpers.fromBoolean(value));
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/security/KeyDerivationFunction.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.security;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * Interface defining a Key Derivation Function
7 | */
8 | public interface KeyDerivationFunction {
9 | /**
10 | * The UUID of this key derivation function
11 | */
12 | UUID getKdfUuid();
13 |
14 | /**
15 | * Transform a key using this key derivation function
16 | *
17 | * @param key the key to transform
18 | * @param transformParams the parameters defining the way the transformation is to be carried out
19 | * @return a transformed key
20 | */
21 | byte[] getTransformedKey(byte[] key, VariantDictionary transformParams);
22 |
23 | /**
24 | * Create default KDF parameters
25 | */
26 | VariantDictionary createKdfParameters();
27 |
28 | /**
29 | * Get a name
30 | */
31 | String getName();
32 | }
33 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/Adapter3.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import java.util.UUID;
12 | import javax.xml.bind.annotation.adapters.XmlAdapter;
13 |
14 | public class Adapter3
15 | extends XmlAdapter
16 | {
17 |
18 |
19 | public UUID unmarshal(String value) {
20 | return (org.linguafranca.pwdb.kdbx.Helpers.uuidFromBase64(value));
21 | }
22 |
23 | public String marshal(UUID value) {
24 | return (org.linguafranca.pwdb.kdbx.Helpers.base64FromUuid(value));
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/Adapter1.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import java.util.Date;
12 | import javax.xml.bind.annotation.adapters.XmlAdapter;
13 |
14 | public class Adapter1
15 | extends XmlAdapter
16 | {
17 |
18 |
19 | public Date unmarshal(String value) {
20 | return (org.linguafranca.pwdb.kdbx.jaxb.util.DateAdapter.fromString(value));
21 | }
22 |
23 | public String marshal(Date value) {
24 | return (org.linguafranca.pwdb.kdbx.jaxb.util.DateAdapter.toString(value));
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/util/src/main/java/org/linguafranca/test/util/HexViewer.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.test.util;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.PrintStream;
6 |
7 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
8 |
9 | /**
10 | * Useful for e.g. viewing the raw file contents
11 | */
12 | public class HexViewer {
13 |
14 | static PrintStream printStream = getTestPrintStream();
15 |
16 | public static void list(InputStream is) throws IOException {
17 | for (int i = 0; i < 32; i++) {
18 | byte[] buf = new byte [16];
19 | is.read(buf);
20 | StringBuilder sb = new StringBuilder();
21 | for (byte b: buf) {
22 | sb.append(String.format("%02X ", b));
23 | }
24 | sb.append(" ");
25 | for (byte b : buf) {
26 | sb.append(b < 0x20 || b > 0x7e ? (char) 0x00B7 : (char) b);
27 | }
28 | printStream.println(sb);
29 | }
30 | }
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/Icon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb;
18 |
19 | /**
20 | * Interface for icons.
21 | *
22 | * Intended as a point of flexibility, at some point this
23 | * may get embellished to allow custom icons and retrieval
24 | * of icon assets and so on.
25 | *
26 | * @author Jo
27 | */
28 | public interface Icon {
29 | int getIndex();
30 |
31 | void setIndex(int index);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/Base64ToByteConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jackson.converter;
18 |
19 | import java.util.Base64;
20 |
21 | import com.fasterxml.jackson.databind.util.StdConverter;
22 |
23 | public class Base64ToByteConverter extends StdConverter {
24 |
25 | @Override
26 | public byte[] convert(String value) {
27 | return Base64.getDecoder().decode(value);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ByteToBase64Converter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import java.util.Base64;
19 |
20 | import com.fasterxml.jackson.databind.util.StdConverter;
21 |
22 | public class ByteToBase64Converter extends StdConverter {
23 |
24 | @Override
25 | public String convert(byte[] value) {
26 | return new String(Base64.getEncoder().encode(value));
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/base/AbstractJaxbParentedBinding.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb.base;
18 |
19 | import javax.xml.bind.annotation.XmlTransient;
20 |
21 | /**
22 | * Ancestor class for Entry and Group Jaxb Bindings, allowing insertion of
23 | * a reference to the parent group.
24 | *
25 | * @author jo
26 | */
27 | public abstract class AbstractJaxbParentedBinding {
28 | @XmlTransient
29 | public AbstractJaxbParentedBinding parent;
30 | }
31 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/StringToBooleanConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import org.linguafranca.pwdb.kdbx.Helpers;
19 |
20 | import com.fasterxml.jackson.databind.util.StdConverter;
21 |
22 | public class StringToBooleanConverter extends StdConverter{
23 |
24 | @Override
25 | public Boolean convert(String value) {
26 | return Helpers.toBoolean(value);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/BooleanToStringConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jackson.converter;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 |
21 | import com.fasterxml.jackson.databind.util.StdConverter;
22 |
23 | public class BooleanToStringConverter extends StdConverter {
24 |
25 | @Override
26 | public String convert(Boolean value) {
27 | return Helpers.fromBoolean(value);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/UUIDToBase64Converter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import java.util.UUID;
19 |
20 | import org.linguafranca.pwdb.kdbx.Helpers;
21 |
22 | import com.fasterxml.jackson.databind.util.StdConverter;
23 |
24 | public class UUIDToBase64Converter extends StdConverter {
25 |
26 | @Override
27 | public String convert(UUID value) {
28 | return Helpers.base64FromUuid(value);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/DateToStringConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jackson.converter;
18 |
19 | import java.util.Date;
20 |
21 | import org.linguafranca.pwdb.kdbx.Helpers;
22 |
23 | import com.fasterxml.jackson.databind.util.StdConverter;
24 |
25 | public class DateToStringConverter extends StdConverter {
26 |
27 | @Override
28 | public String convert(Date date) {
29 | return Helpers.fromDate(date);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/dom/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KeePassJava2-parent
5 | org.linguafranca.pwdb
6 | 2.2.4
7 | ../pom.xml
8 |
9 | 4.0.0
10 |
11 | KeePassJava2-dom
12 | KeePassJava2 :: DOM
13 |
14 |
15 |
16 | org.linguafranca.pwdb
17 | KeePassJava2-kdbx
18 | ${project.version}
19 |
20 |
21 | org.linguafranca.pwdb
22 | test
23 | ${project.version}
24 | test-jar
25 | test
26 |
27 |
28 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonRecycleBinTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import org.linguafranca.pwdb.checks.RecycleBinChecks;
19 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
20 |
21 | public class JacksonRecycleBinTest extends RecycleBinChecks {
22 |
23 | public JacksonRecycleBinTest() {
24 | try {
25 | database = new JacksonDatabase();
26 | } catch(Exception e) {
27 | e.printStackTrace();
28 | }
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbV4LoadTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.jaxb;
2 |
3 | import org.junit.Test;
4 | import org.linguafranca.pwdb.Entry;
5 | import org.linguafranca.pwdb.Visitor;
6 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
7 |
8 | import java.io.InputStream;
9 | import java.io.PrintStream;
10 |
11 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
12 |
13 | /**
14 | * @author jo
15 | */
16 | public class JaxbV4LoadTest {
17 |
18 | static PrintStream printStream = getTestPrintStream();
19 |
20 | @Test
21 | public void loadKdbxV4() throws Exception {
22 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-AES-Argon2.kdbx");
23 | JaxbDatabase database = JaxbDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
24 | database.visit(new Visitor.Print(printStream));
25 | // test what happens to dates in V4
26 | database.visit(new Visitor.Default(){
27 | @Override
28 | public void visit(Entry entry) {
29 | printStream.println(entry.getCreationTime());
30 | }
31 | });
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/Parented.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import javax.xml.bind.annotation.XmlAccessType;
12 | import javax.xml.bind.annotation.XmlAccessorType;
13 | import javax.xml.bind.annotation.XmlSeeAlso;
14 | import javax.xml.bind.annotation.XmlType;
15 |
16 |
17 | /**
18 | * This class, while generated, is not used see {@link
19 | * org.linguafranca.pwdb.kdbx.jaxb.org.linguafranca.pwdb.base.AbstractJaxbParentedBinding} which is the
20 | * actual implementation class.
21 | *
22 | *
23 | *
24 | */
25 | @XmlAccessorType(XmlAccessType.FIELD)
26 | @XmlType(name = "Parented")
27 | @XmlSeeAlso({
28 | JaxbGroupBinding.class,
29 | JaxbEntryBinding.class
30 | })
31 | public abstract class Parented {
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbBasicDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
20 | import org.linguafranca.pwdb.Database;
21 |
22 | import java.io.IOException;
23 |
24 | /**
25 | * @author jo
26 | */
27 | public class JaxbBasicDatabaseTest extends BasicDatabaseChecks {
28 |
29 | public JaxbBasicDatabaseTest() throws IOException {
30 | }
31 |
32 | @Override
33 | public Database createDatabase() {
34 | return new JaxbDatabase();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import java.io.IOException;
19 |
20 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
21 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
22 |
23 | public class JacksonDatabaseTest extends BasicDatabaseChecks {
24 |
25 | public JacksonDatabaseTest() throws IOException {
26 |
27 | }
28 |
29 |
30 | @Override
31 | public Database createDatabase() throws IOException {
32 | return new JacksonDatabase();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/kdb/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KeePassJava2-parent
5 | org.linguafranca.pwdb
6 | 2.2.4
7 | ../pom.xml
8 |
9 | 4.0.0
10 |
11 | KeePassJava2-kdb
12 | KeePassJava2 :: KDB
13 | Contains an implementation that can load KDB files.
14 |
15 |
16 |
17 | org.linguafranca.pwdb
18 | database
19 | ${project.version}
20 |
21 |
22 | org.linguafranca.pwdb
23 | test
24 | ${project.version}
25 | test-jar
26 | test
27 |
28 |
29 |
--------------------------------------------------------------------------------
/database/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KeePassJava2-parent
5 | org.linguafranca.pwdb
6 | 2.2.4
7 | ../pom.xml
8 |
9 | 4.0.0
10 |
11 | database
12 | PWDB :: Database
13 | Contains root definitions of PWDB Databases etc.
14 |
15 |
16 |
17 | com.google.guava
18 | guava
19 |
20 |
21 | org.bouncycastle
22 | bcpkix-jdk18on
23 |
24 |
25 | org.linguafranca.pwdb
26 | util
27 | ${project.version}
28 |
29 |
30 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/Base64ToUUIDConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jackson.converter;
18 |
19 | import java.util.UUID;
20 |
21 | import org.linguafranca.pwdb.kdbx.Helpers;
22 |
23 | import com.fasterxml.jackson.databind.util.StdConverter;
24 |
25 | public class Base64ToUUIDConverter extends StdConverter {
26 |
27 | @Override
28 | public UUID convert(String value) {
29 | if(value == null || value.isEmpty()) {
30 | return UUID.randomUUID();
31 | }
32 | return Helpers.uuidFromBase64(value);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomV4Test.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.dom;
2 |
3 | import org.junit.Test;
4 | import org.linguafranca.pwdb.Visitor;
5 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
6 |
7 | import java.io.InputStream;
8 | import java.io.PrintStream;
9 |
10 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
11 |
12 | /**
13 | * @author jo
14 | */
15 | public class DomV4Test {
16 |
17 | static PrintStream printStream = getTestPrintStream();
18 |
19 | @Test
20 | public void loadKdbxV4() throws Exception {
21 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-AES-Argon2.kdbx");
22 | DomDatabaseWrapper database = DomDatabaseWrapper.load(new KdbxCreds("123".getBytes()), inputStream);
23 | database.visit(new Visitor.Print(printStream));
24 | // test what happens to dates in V4
25 | database.visit(new Visitor.Default(){
26 |
27 | @Override
28 | public void visit(DomEntryWrapper entry) {
29 | printStream.println(entry.getCreationTime());
30 | }
31 | });
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/util/JaxbUtil.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.jaxb.util;
2 |
3 | import javax.xml.bind.JAXBContext;
4 | import javax.xml.bind.JAXBElement;
5 | import javax.xml.bind.JAXBException;
6 | import javax.xml.bind.util.JAXBSource;
7 | import javax.xml.namespace.QName;
8 |
9 | public class JaxbUtil {
10 |
11 | // https://stackoverflow.com/questions/879453/how-to-make-a-deep-copy-of-jaxb-object-like-xmlbean-xmlobject-copy
12 | // however it does not copy transients which we need it to, so we don't use it
13 | public static T deepCopyJAXB(T object, Class clazz) {
14 | try {
15 | JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
16 | JAXBElement contentObject = new JAXBElement(new QName(clazz.getSimpleName()), clazz, object);
17 | JAXBSource source = new JAXBSource(jaxbContext, contentObject);
18 | return jaxbContext.createUnmarshaller().unmarshal(source, clazz).getValue();
19 | } catch (JAXBException e) {
20 | throw new RuntimeException(e);
21 | }
22 | }
23 |
24 | public static T deepCopyJAXB(T object) {
25 | if(object==null) throw new RuntimeException("Can't guess at class");
26 | return deepCopyJAXB(object, (Class) object.getClass());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimpleDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple;
18 |
19 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
20 | import org.linguafranca.pwdb.Database;
21 |
22 | import java.io.IOException;
23 |
24 | /**
25 | * @author jo
26 | */
27 | public class SimpleDatabaseTest extends BasicDatabaseChecks {
28 |
29 | public SimpleDatabaseTest() throws IOException {
30 | }
31 |
32 | @Override
33 | public Database createDatabase() {
34 | try {
35 | return new SimpleDatabase();
36 | } catch (Exception e) {
37 | throw new IllegalStateException();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/util/DateAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb.util;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 |
21 | import java.util.Date;
22 |
23 | /**
24 | * Used for loading the database template which contains placeholders.
25 | * @author jo
26 | */
27 | public class DateAdapter {
28 | public static String toString(Date date) {
29 | return Helpers.fromDate(date);
30 | }
31 |
32 | public static Date fromString(String string) {
33 | // this is found in the base template
34 | if (string.equals("${creationDate}")) {
35 | return new Date();
36 | }
37 | return Helpers.toDate(string);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/security/CipherAlgorithm.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.security;
2 |
3 | import java.io.InputStream;
4 | import java.io.OutputStream;
5 | import java.util.UUID;
6 |
7 | /**
8 | * Interface defining an algorithm for encrypting and decrypting database contents
9 | */
10 | public interface CipherAlgorithm {
11 | /**
12 | * Returns the UUID of this algorithm
13 | */
14 | UUID getCipherUuid();
15 |
16 | /**
17 | * Return the name of this algorithm
18 | */
19 | String getName();
20 |
21 | /**
22 | * Create a decrypted stream from the supplied encrypted one
23 | *
24 | * @param encryptedInputStream an encrypted stream
25 | * @param key the decryption key
26 | * @param iv the iv
27 | * @return an unencrypted stream
28 | */
29 | InputStream getDecryptedInputStream(InputStream encryptedInputStream, byte[] key, byte[] iv);
30 |
31 | /**
32 | * Create an encrypted stream from the supplied unencrypted one
33 | *
34 | * @param decryptedOutputStream an unencrypted stream
35 | * @param key a key
36 | * @param iv an iv
37 | * @return an encrypted stream
38 | */
39 | OutputStream getEncryptedOutputStream(OutputStream decryptedOutputStream, byte[] key, byte[] iv);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonDatabaseLoaderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import java.io.InputStream;
19 |
20 | import org.linguafranca.pwdb.checks.DatabaseLoaderChecks;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
23 |
24 | public class JacksonDatabaseLoaderTest extends DatabaseLoaderChecks{
25 |
26 |
27 | public JacksonDatabaseLoaderTest() throws Exception{
28 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
29 | // file has password credentials
30 | Credentials credentials = new KdbxCreds("123".getBytes());
31 | super.database = JacksonDatabase.load(credentials, inputStream);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/KeePassBooleanConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple.converter;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 | import org.simpleframework.xml.convert.Converter;
21 | import org.simpleframework.xml.stream.InputNode;
22 | import org.simpleframework.xml.stream.OutputNode;
23 |
24 | /**
25 | * @author jo
26 | */
27 | public class KeePassBooleanConverter implements Converter{
28 | @Override
29 | public Boolean read(InputNode inputNode) throws Exception {
30 | return Helpers.toBoolean(inputNode.getValue());
31 | }
32 |
33 | @Override
34 | public void write(OutputNode outputNode, Boolean bool) throws Exception {
35 | outputNode.setValue(Helpers.fromBoolean(bool));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/Credentials.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb;
18 |
19 | import org.linguafranca.pwdb.security.Encryption;
20 |
21 | import java.security.MessageDigest;
22 |
23 | /**
24 | * Supports a contract that yields a key for decryption of databases
25 | *
26 | * @author jo
27 | */
28 | public interface Credentials {
29 |
30 | /**
31 | * Implementation of no credentials
32 | */
33 | class None implements Credentials {
34 | @Override
35 | public byte[] getKey() {
36 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
37 | return md.digest(new byte[0]);
38 | }
39 | }
40 |
41 | /**
42 | * Returns a digest of the composition of credentials supplied
43 | */
44 | byte[] getKey();
45 | }
46 |
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimpleDatabaseLoaderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple;
18 |
19 | import org.linguafranca.pwdb.checks.DatabaseLoaderChecks;
20 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
21 | import org.linguafranca.pwdb.Credentials;
22 |
23 | import java.io.InputStream;
24 |
25 | /**
26 | * @author jo
27 | */
28 | public class SimpleDatabaseLoaderTest extends DatabaseLoaderChecks {
29 |
30 | public SimpleDatabaseLoaderTest() throws Exception {
31 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
32 | // file has password credentials
33 | Credentials credentials = new KdbxCreds("123".getBytes());
34 | super.database = SimpleDatabase.load(credentials, inputStream);
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue38Test.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.validation;
2 |
3 | import org.junit.Test;
4 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
5 | import org.linguafranca.pwdb.kdbx.dom.DomDatabaseWrapper;
6 | import org.linguafranca.pwdb.kdbx.dom.DomEntryWrapper;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.PrintStream;
11 | import java.util.List;
12 |
13 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
14 |
15 | /**
16 | * Bug report on GitHub, the Keyfile is Version 2 (Hex)
17 | */
18 | public class Issue38Test {
19 |
20 | static PrintStream printStream = getTestPrintStream();
21 | @Test
22 | public void testV2Keyfile() throws IOException {
23 | InputStream databaseStream = Issue38Test.class.getClassLoader().getResourceAsStream("issue-38/Database/Database.kdbx");
24 | InputStream keyStream = Issue38Test.class.getClassLoader().getResourceAsStream("issue-38/Database/Database.keyx");
25 | assert keyStream != null;
26 | KdbxCreds creds = new KdbxCreds("MyPassword".getBytes(), keyStream);
27 | assert databaseStream != null;
28 | DomDatabaseWrapper database = DomDatabaseWrapper.load(creds, databaseStream);
29 | List extends DomEntryWrapper> entries = database.findEntries("Sample Entry");
30 | DomEntryWrapper entry = entries.get(0);
31 | printStream.println(entry.getTitle());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/StringToDateConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import java.util.Date;
19 | import java.util.Objects;
20 |
21 | import org.linguafranca.pwdb.kdbx.Helpers;
22 |
23 | import com.fasterxml.jackson.databind.util.StdConverter;
24 |
25 | public class StringToDateConverter extends StdConverter {
26 |
27 | @Override
28 | public Date convert(String value) {
29 | // TODO: It would really be better if we could inhibit deserialize date elements that are not present
30 | if (Objects.isNull(value) || value.isEmpty()) {
31 | return null;
32 | }
33 | if(value.equals("${creationDate}")) {
34 | return new Date();
35 | }
36 | return Helpers.toDate(value);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbIcon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdb;
18 |
19 | import org.linguafranca.pwdb.Icon;
20 |
21 | /**
22 | * Contains the index of an icon
23 | *
24 | * @author jo
25 | */
26 | public class KdbIcon implements Icon {
27 | int index = 0;
28 |
29 | KdbIcon(int index) {
30 | this.index = index;
31 | }
32 |
33 | @Override
34 | public int getIndex() {
35 | return index;
36 | }
37 |
38 | @Override
39 | public void setIndex(int index) {
40 | this.index = index;
41 | }
42 |
43 | @Override
44 | public boolean equals(Object o) {
45 | if (this == o) return true;
46 | if (o == null || !(o instanceof Icon)) return false;
47 |
48 | Icon icon = (Icon) o;
49 |
50 | return index == icon.getIndex();
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomHelperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.kdbx.Helpers;
21 |
22 | import java.io.PrintStream;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
26 |
27 | /**
28 | * @author jo
29 | */
30 | public class DomHelperTest {
31 |
32 | static PrintStream printStream = getTestPrintStream();
33 |
34 | @Test
35 | public void testBase64RandomUuid() throws Exception {
36 | // just check that it can do something
37 | String uuid1 = DomHelper.base64RandomUuid();
38 | printStream.println(Helpers.uuidFromBase64(uuid1));
39 | String uuid2 = DomHelper.base64RandomUuid();
40 | printStream.println(Helpers.uuidFromBase64(uuid2));
41 | }
42 | }
--------------------------------------------------------------------------------
/kdb/src/test/java/org/linguafranca/pwdb/kdb/KdbSerializerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdb;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.Database;
21 | import org.linguafranca.pwdb.Visitor;
22 |
23 | import java.io.InputStream;
24 | import java.io.PrintStream;
25 |
26 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
27 |
28 | /**
29 | * @author jo
30 | */
31 | public class KdbSerializerTest {
32 |
33 | static PrintStream printStream = getTestPrintStream();
34 |
35 |
36 | @Test
37 | public void testCreateKdbDatabase() throws Exception {
38 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdb");
39 | Database database = KdbDatabase.load(new KdbCredentials.Password("123".getBytes()), inputStream);
40 | database.visit(new Visitor.Print(printStream));
41 | }
42 | }
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/EmptyStringConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple.converter;
18 |
19 | import org.simpleframework.xml.convert.Converter;
20 | import org.simpleframework.xml.stream.InputNode;
21 | import org.simpleframework.xml.stream.OutputNode;
22 |
23 | /**
24 | * @author jo
25 | */
26 | public class EmptyStringConverter implements Converter {
27 | @Override
28 | public String read(InputNode inputNode) throws Exception {
29 | String value = inputNode.getValue();
30 | return value == null ? "": value;
31 | }
32 |
33 | @Override
34 | public void write(OutputNode outputNode, String s) throws Exception {
35 | if(s==null || s.equals("")) {
36 | outputNode.setValue(null);
37 | } else {
38 | outputNode.setValue(s);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/kdb/src/test/java/org/linguafranca/pwdb/kdb/KdbDatabaseLoaderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdb;
18 |
19 | import org.linguafranca.pwdb.Credentials;
20 | import org.linguafranca.pwdb.checks.DatabaseLoaderChecks;
21 |
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 |
25 | /**
26 | * @author jo
27 | */
28 | public class KdbDatabaseLoaderTest extends DatabaseLoaderChecks {
29 |
30 | public KdbDatabaseLoaderTest() throws IOException {
31 | // get an input stream from KDB file
32 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdb");
33 | // file has password credentials
34 | Credentials credentials = new KdbCredentials.Password("123".getBytes());
35 | // open database.
36 | super.database = KdbDatabase.load(credentials, inputStream);
37 | super.skipDateCheck = true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/kdb/src/test/java/org/linguafranca/pwdb/kdb/KdbDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdb;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
21 | import org.linguafranca.pwdb.Database;
22 |
23 | import java.io.IOException;
24 |
25 | import static org.junit.Assert.assertFalse;
26 |
27 | /**
28 | * @author Jo
29 | */
30 | public class KdbDatabaseTest extends BasicDatabaseChecks {
31 | @Override
32 | public Database createDatabase() throws IOException {
33 | return new KdbDatabase();
34 | }
35 |
36 | public KdbDatabaseTest() throws IOException {
37 | super();
38 | }
39 |
40 | @Test
41 | public void supportedFunctionalityTest(){
42 | assertFalse(database.supportsBinaryProperties());
43 | assertFalse(database.supportsNonStandardPropertyNames());
44 | assertFalse(database.supportsRecycleBin());
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/TimeConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple.converter;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 | import org.simpleframework.xml.convert.Converter;
21 | import org.simpleframework.xml.stream.InputNode;
22 | import org.simpleframework.xml.stream.OutputNode;
23 |
24 | import java.util.Date;
25 |
26 | /**
27 | * @author jo
28 | */
29 | public class TimeConverter implements Converter{
30 | @Override
31 | public Date read(InputNode inputNode) throws Exception {
32 | String value = inputNode.getValue();
33 | if (value.equals("${creationDate}")) {
34 | return new Date();
35 | }
36 | return Helpers.toDate(value);
37 | }
38 |
39 | @Override
40 | public void write(OutputNode outputNode, Date date) throws Exception {
41 | outputNode.setValue(Helpers.fromDate(date));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/UuidConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple.converter;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 | import org.simpleframework.xml.convert.Converter;
21 | import org.simpleframework.xml.stream.InputNode;
22 | import org.simpleframework.xml.stream.OutputNode;
23 |
24 | import java.util.UUID;
25 |
26 | /**
27 | * @author jo
28 | */
29 | public class UuidConverter implements Converter {
30 | @Override
31 | public UUID read(InputNode inputNode) throws Exception {
32 | String value = inputNode.getValue();
33 | if (value == null || value.equals("")) {
34 | return UUID.randomUUID();
35 | }
36 | return Helpers.uuidFromBase64(value);
37 | }
38 |
39 | @Override
40 | public void write(OutputNode outputNode, UUID uuid) throws Exception {
41 | outputNode.setValue(Helpers.base64FromUuid(uuid));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonHistory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
22 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
23 |
24 | public class JacksonHistory {
25 |
26 | @JacksonXmlProperty(localName = "Entry") /* Workaround jackson */
27 | @JacksonXmlElementWrapper(useWrapping = false)
28 | private List entry;
29 |
30 | public JacksonHistory() {
31 | entry = new ArrayList<>();
32 | }
33 |
34 | /**
35 | * @return the entry
36 | */
37 | public List getEntry() {
38 | return entry;
39 | }
40 |
41 | /**
42 | * @param entry the entry to set
43 | */
44 | public void setEntry(List entry) {
45 | this.entry = entry;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbLoaderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.linguafranca.pwdb.checks.DatabaseLoaderChecks;
20 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
21 |
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 |
25 | /**
26 | * @author jo
27 | */
28 | public class JaxbLoaderTest extends DatabaseLoaderChecks {
29 |
30 | public JaxbLoaderTest() throws IOException {
31 | // get an input stream from kdbx file
32 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
33 | // file has password credentials
34 | KdbxCreds credentials = new KdbxCreds("123".getBytes());
35 | // open database. DomDatabaseWrapper is so-called, since it wraps
36 | // a W3C DOM, populated from the KeePass XML, and presents it
37 | // through a org.linguafranca.keepass.Database interface.
38 | super.database = JaxbDatabase.load(credentials, inputStream);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/jaxb/src/main/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbIcon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.linguafranca.pwdb.Icon;
20 |
21 | /**
22 | * @author jo
23 | */
24 | @SuppressWarnings("WeakerAccess")
25 | public class JaxbIcon implements Icon{
26 | private int index;
27 |
28 | public JaxbIcon(int iconID) {
29 | index = iconID;
30 | }
31 |
32 | public JaxbIcon() {
33 | index = 0;
34 | }
35 |
36 | @Override
37 | public int getIndex() {
38 | return index;
39 | }
40 |
41 | @Override
42 | public void setIndex(int index) {
43 | this.index = index;
44 | }
45 |
46 | @Override
47 | public boolean equals(Object o) {
48 | if (this == o) return true;
49 | if (o == null || getClass() != o.getClass()) return false;
50 |
51 | JaxbIcon that = (JaxbIcon) o;
52 |
53 | return index == that.index;
54 |
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 | return index;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/SimpleIcon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple;
18 |
19 | import org.linguafranca.pwdb.Icon;
20 |
21 | /**
22 | * @author jo
23 | */
24 | @SuppressWarnings("WeakerAccess")
25 | public class SimpleIcon implements Icon {
26 | private int index;
27 |
28 | public SimpleIcon() {
29 | }
30 |
31 | public SimpleIcon(int index) {
32 | this.index = index;
33 | }
34 |
35 | @Override
36 | public int getIndex() {
37 | return index;
38 | }
39 |
40 | @Override
41 | public void setIndex(int i) {
42 | index = i;
43 | }
44 |
45 | @Override
46 | public boolean equals(Object o) {
47 | if (this == o) return true;
48 | if (o == null || getClass() != o.getClass()) return false;
49 |
50 | SimpleIcon that = (SimpleIcon) o;
51 |
52 | return index == that.index;
53 |
54 | }
55 |
56 | @Override
57 | public int hashCode() {
58 | return index;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/dom/src/main/java/org/linguafranca/pwdb/kdbx/dom/DomIconWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.Icon;
20 | import org.w3c.dom.Element;
21 |
22 | /**
23 | * Class wraps Icons from a {@link DomSerializableDatabase} as {@link Icon}
24 | *
25 | * @author jo
26 | */
27 | public class DomIconWrapper implements Icon {
28 |
29 | private final Element element;
30 |
31 | public DomIconWrapper(Element element) {
32 | this.element = element;
33 | }
34 |
35 | @Override
36 | public int getIndex() {
37 | return Integer.parseInt(element.getTextContent());
38 | }
39 |
40 | @Override
41 | public void setIndex(int index) {
42 | element.setTextContent(String.valueOf(index));
43 | }
44 |
45 | @Override
46 | public boolean equals(Object o) {
47 | if (this == o) return true;
48 | if (o == null || !(o instanceof Icon)) return false;
49 |
50 | Icon that = (Icon) o;
51 |
52 | return this.getIndex() == that.getIndex();
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/SaxParseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx;
18 |
19 | import org.junit.Test;
20 | import org.xml.sax.SAXException;
21 |
22 | import javax.xml.parsers.ParserConfigurationException;
23 | import java.io.IOException;
24 | import java.io.OutputStream;
25 | import java.io.PrintWriter;
26 |
27 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
28 |
29 | /**
30 | * @author jo
31 | */
32 |
33 | public class SaxParseTest extends SaxParse {
34 |
35 | OutputStream outputStream = getTestPrintStream();
36 | @Test
37 | public void exampleSaxParsingV3 () throws IOException, SAXException, ParserConfigurationException {
38 | super.exampleSaxParsing("test123.kdbx", new KdbxCreds("123".getBytes()), new PrintWriter(outputStream));
39 | }
40 | @Test
41 | public void exampleSaxParsingV4 () throws IOException, SAXException, ParserConfigurationException {
42 | super.exampleSaxParsing("V4-AES-AES.kdbx", new KdbxCreds("123".getBytes()), new PrintWriter(outputStream));
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/JacksonIcon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jackson;
18 |
19 | import org.linguafranca.pwdb.Icon;
20 |
21 | /**
22 | * @author giusvale
23 | */
24 | public class JacksonIcon implements Icon {
25 |
26 | private int index;
27 |
28 | public JacksonIcon(int iconID) {
29 | index = iconID;
30 | }
31 |
32 | public JacksonIcon() {
33 | this.index = 0;
34 | }
35 |
36 | @Override
37 | public int getIndex() {
38 | return this.index;
39 | }
40 |
41 | @Override
42 | public void setIndex(int index) {
43 | this.index = index;
44 | }
45 |
46 | @Override
47 | public boolean equals(Object o) {
48 | if (this == o)
49 | return true;
50 | if (o == null || getClass() != o.getClass())
51 | return false;
52 |
53 | JacksonIcon that = (JacksonIcon) o;
54 |
55 | return index == that.index;
56 |
57 | }
58 |
59 | @Override
60 | public int hashCode() {
61 | return index;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/Base64ByteArrayConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple.converter;
18 |
19 | import org.linguafranca.pwdb.kdbx.Helpers;
20 | import org.linguafranca.pwdb.kdbx.simple.model.KeePassFile;
21 | import org.simpleframework.xml.convert.Converter;
22 | import org.simpleframework.xml.stream.InputNode;
23 | import org.simpleframework.xml.stream.OutputNode;
24 |
25 | /**
26 | * @author jo
27 | */
28 | public class Base64ByteArrayConverter implements Converter{
29 | @Override
30 | public KeePassFile.ByteArray read(InputNode inputNode) throws Exception {
31 | String input = inputNode.getValue();
32 | byte[] value = input == null? new byte[0] : input.getBytes();
33 | return new KeePassFile.ByteArray(Helpers.decodeBase64Content(value, false));
34 | }
35 |
36 | @Override
37 | public void write(OutputNode outputNode, KeePassFile.ByteArray bytes) throws Exception {
38 | outputNode.setValue(Helpers.encodeBase64Content(bytes.getContent(), false));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomDatabaseWrapperLoaderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.checks.DatabaseLoaderChecks;
20 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
21 | import org.linguafranca.pwdb.Credentials;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 |
26 | /**
27 | * @author jo
28 | */
29 | public class DomDatabaseWrapperLoaderTest extends DatabaseLoaderChecks {
30 |
31 | public DomDatabaseWrapperLoaderTest() throws IOException {
32 | // get an input stream from kdbx file
33 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
34 | // file has password credentials
35 | Credentials credentials = new KdbxCreds("123".getBytes());
36 | // open database. DomDatabaseWrapper is so-called, since it wraps
37 | // a W3C DOM, populated from the KeePass XML, and presents it
38 | // through a org.linguafranca.keepass.Database interface.
39 | super.database = DomDatabaseWrapper.load(credentials, inputStream);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/UtilTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import java.io.PrintWriter;
8 |
9 | import static org.linguafranca.pwdb.kdbx.Util.*;
10 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
11 |
12 | public class UtilTest {
13 |
14 | OutputStream outputStream = getTestPrintStream();
15 | @Test public void listDatabaseTest() throws IOException {
16 | listDatabase("V3-CustomIcon.kdbx", new KdbxCreds("123".getBytes()), outputStream);
17 | }
18 |
19 | @Test
20 | public void listXmlTest() throws IOException {
21 | PrintWriter writer = new PrintWriter(outputStream);
22 | listXml("V3-CustomIcon.kdbx", new KdbxCreds("123".getBytes()), writer);
23 | writer.flush();
24 | }
25 |
26 | /**
27 | * List Database Encryption Characteristics
28 | */
29 | @Test
30 | public void listKdbxHeaderParams () throws IOException {
31 | PrintWriter writer = new PrintWriter(outputStream);
32 | listKdbxHeaderProperties("test123.kdbx", writer);
33 | listKdbxHeaderProperties("V4-AES-AES.kdbx", writer);
34 | listKdbxHeaderProperties("V4-AES-Argon2.kdbx", writer);
35 | listKdbxHeaderProperties("V4-ChaCha20-AES.kdbx", writer);
36 | listKdbxHeaderProperties("V4-ChaCha20-Argon2-Attachment.kdbx", writer);
37 | writer.flush();
38 | }
39 |
40 | @Test
41 | public void listHeaderPropertiesAndXml() throws IOException {
42 | PrintWriter writer = new PrintWriter(outputStream);
43 | listKdbxHeaderProperties("V4-AES-Argon2-CustomIcon.kdbx", writer);
44 | listXml("V4-AES-Argon2-CustomIcon.kdbx", new KdbxCreds("123".getBytes()), writer);
45 | writer.flush();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KeePassJava2-parent
5 | org.linguafranca.pwdb
6 | 2.2.4
7 |
8 | 4.0.0
9 |
10 | test
11 | PWDB :: Test
12 | Contains the shared test classes for exercising the functionality of a PWDB database implementation.
13 |
14 |
15 | true
16 |
17 |
18 |
19 |
20 | org.linguafranca.pwdb
21 | database
22 | ${project.version}
23 |
24 |
25 | org.linguafranca.pwdb
26 | util
27 | 2.2.4
28 | test
29 |
30 |
31 |
32 |
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-jar-plugin
37 | 2.2
38 |
39 |
40 |
41 | test-jar
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSerializableDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.StreamFormat;
21 | import org.linguafranca.pwdb.Visitor;
22 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
23 |
24 | import java.io.InputStream;
25 | import java.io.PrintStream;
26 |
27 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
28 |
29 | /**
30 | * @author jo
31 | */
32 | public class JaxbSerializableDatabaseTest {
33 |
34 | static PrintStream printStream = getTestPrintStream();
35 |
36 | @Test
37 | public void createEmptyDatabase() throws Exception {
38 | JaxbDatabase db = JaxbDatabase.createEmptyDatabase();
39 | db.save(new StreamFormat.None(), new KdbxCreds.None(), printStream);
40 | }
41 | @Test
42 | public void loadXml() throws Exception {
43 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
44 | JaxbDatabase database = JaxbDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
45 | database.visit(new Visitor.Print(printStream));
46 | database.save(new StreamFormat.None(), new KdbxCreds.None(), printStream);
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue70Test.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.validation;
2 |
3 | import org.junit.Test;
4 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
5 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | /**
11 | * Review Issue-70 https://github.com/jorabin/KeePassJava2/issues/70
12 | */
13 | public class Issue70Test {
14 |
15 | public static final String TEST_RESOURCE1 = "issue-70/test2.kdbx";
16 | public static final KdbxCreds CREDENTIALS1 = new KdbxCreds("KeePassJava2".getBytes());
17 | public static final String TEST_RESOURCE2 = "Database-4.1-123.kdbx";
18 | public static final KdbxCreds CREDENTIALS2 = new KdbxCreds("123".getBytes());
19 | public static final String TEST_RESOURCE3 = "issue-70/test-hugoo10.kdbx";
20 | public static final KdbxCreds CREDENTIALS3 = new KdbxCreds("test".getBytes());
21 |
22 |
23 | /* custom data missing from meta */
24 | @Test
25 | public void testCustomData() throws IOException {
26 | try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(TEST_RESOURCE1)) {
27 | JacksonDatabase database = JacksonDatabase.load(CREDENTIALS1, inputStream);
28 | }
29 | }
30 |
31 | @Test
32 | public void testFileFormat_4_1() throws IOException {
33 | try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(TEST_RESOURCE2)){
34 | JacksonDatabase database = JacksonDatabase.load(CREDENTIALS2, inputStream);
35 | }
36 | }
37 |
38 | /* custom data missing from entry definition */
39 | @Test
40 | public void testCustomData2() throws IOException {
41 | try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(TEST_RESOURCE3)){
42 | JacksonDatabase database = JacksonDatabase.load(CREDENTIALS3, inputStream);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbPropertyValueTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jaxb;
17 |
18 | import org.linguafranca.pwdb.Credentials;
19 | import org.linguafranca.pwdb.Database;
20 | import org.linguafranca.pwdb.checks.PropertyValueChecks;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.OutputStream;
26 |
27 | public class JaxbPropertyValueTest extends PropertyValueChecks {
28 |
29 | public JaxbPropertyValueTest() throws IOException {
30 | super(false);
31 | }
32 |
33 |
34 | @Override
35 | public Database createDatabase() throws IOException {
36 | return new JaxbDatabase();
37 | }
38 |
39 | @Override
40 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
41 | database.save(credentials, outputStream);
42 | }
43 |
44 | @Override
45 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
46 | try {
47 | return JaxbDatabase.load(credentials, inputStream);
48 | } catch (Exception e) {
49 | throw new IOException(e);
50 | }
51 | }
52 |
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomPropertyValueTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.dom;
17 |
18 | import org.linguafranca.pwdb.Credentials;
19 | import org.linguafranca.pwdb.Database;
20 | import org.linguafranca.pwdb.checks.PropertyValueChecks;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.OutputStream;
26 |
27 | public class DomPropertyValueTest extends PropertyValueChecks {
28 |
29 | public DomPropertyValueTest() throws IOException {
30 | super(false);
31 | }
32 |
33 |
34 | @Override
35 | public Database createDatabase() throws IOException {
36 | return new DomDatabaseWrapper();
37 | }
38 |
39 | @Override
40 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
41 | database.save(credentials, outputStream);
42 | }
43 |
44 | @Override
45 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
46 | try {
47 | return DomDatabaseWrapper.load(credentials, inputStream);
48 | } catch (Exception e) {
49 | throw new IOException(e);
50 | }
51 | }
52 |
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimplePropertyValueTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.simple;
17 |
18 | import org.linguafranca.pwdb.Credentials;
19 | import org.linguafranca.pwdb.Database;
20 | import org.linguafranca.pwdb.checks.PropertyValueChecks;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.OutputStream;
26 |
27 | public class SimplePropertyValueTest extends PropertyValueChecks {
28 |
29 | public SimplePropertyValueTest() throws IOException {
30 | super(false);
31 | }
32 |
33 |
34 | @Override
35 | public Database createDatabase() throws IOException {
36 | return new SimpleDatabase();
37 | }
38 |
39 | @Override
40 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
41 | database.save(credentials, outputStream);
42 | }
43 |
44 | @Override
45 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
46 | try {
47 | return SimpleDatabase.load(credentials, inputStream);
48 | } catch (Exception e) {
49 | throw new IOException(e);
50 | }
51 | }
52 |
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomBinaryPropertyV3Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
20 | import org.linguafranca.pwdb.Database;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 | import org.linguafranca.pwdb.Credentials;
23 |
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.OutputStream;
27 |
28 | /**
29 | * @author jo
30 | */
31 | public class DomBinaryPropertyV3Test extends BinaryPropertyChecks {
32 |
33 | public DomBinaryPropertyV3Test() throws IOException {
34 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Attachment.kdbx");
35 | database = DomDatabaseWrapper.load(new KdbxCreds("123".getBytes()), inputStream);
36 | }
37 |
38 | @Override
39 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
40 | database.save(credentials, outputStream);
41 | }
42 |
43 | @Override
44 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
45 | return DomDatabaseWrapper.load(credentials, inputStream);
46 | }
47 |
48 | @Override
49 | public Database newDatabase() {
50 | return new DomDatabaseWrapper();
51 | }
52 |
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 | }
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbBinaryPropertyV3Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.linguafranca.pwdb.Database;
20 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 | import org.linguafranca.pwdb.Credentials;
23 |
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.OutputStream;
27 |
28 | /**
29 | * @author jo
30 | */
31 | public class JaxbBinaryPropertyV3Test extends BinaryPropertyChecks {
32 |
33 | public JaxbBinaryPropertyV3Test() throws IOException {
34 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Attachment.kdbx");
35 | database = JaxbDatabase.load(new KdbxCreds("123".getBytes()),inputStream);
36 | }
37 |
38 | @Override
39 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
40 | database.save(credentials,outputStream);
41 | }
42 |
43 |
44 | @Override
45 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
46 | return JaxbDatabase.load(credentials, inputStream);
47 | }
48 |
49 | @Override
50 | public Database newDatabase() {
51 | return new JaxbDatabase();
52 | }
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/History.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import javax.xml.bind.annotation.XmlAccessType;
12 | import javax.xml.bind.annotation.XmlAccessorType;
13 | import javax.xml.bind.annotation.XmlElement;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import javax.xml.bind.annotation.XmlType;
16 |
17 |
18 | /**
19 | * Java class for anonymous complex type.
20 | *
21 | *
The following schema fragment specifies the expected content contained within this class.
22 | *
23 | *
24 | * <complexType>
25 | * <complexContent>
26 | * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
27 | * <sequence>
28 | * <element ref="{}Entry"/>
29 | * </sequence>
30 | * </restriction>
31 | * </complexContent>
32 | * </complexType>
33 | *
34 | *
35 | *
36 | */
37 | @XmlAccessorType(XmlAccessType.FIELD)
38 | @XmlType(name = "", propOrder = {
39 | "entry"
40 | })
41 | @XmlRootElement(name = "History")
42 | public class History {
43 |
44 | @XmlElement(name = "Entry", required = true)
45 | protected JaxbEntryBinding entry;
46 |
47 | /**
48 | * Gets the value of the entry property.
49 | *
50 | * @return
51 | * possible object is
52 | * {@link JaxbEntryBinding }
53 | *
54 | */
55 | public JaxbEntryBinding getEntry() {
56 | return entry;
57 | }
58 |
59 | /**
60 | * Sets the value of the entry property.
61 | *
62 | * @param value
63 | * allowed object is
64 | * {@link JaxbEntryBinding }
65 | *
66 | */
67 | public void setEntry(JaxbEntryBinding value) {
68 | this.entry = value;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/security/ChaCha.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.security;
2 |
3 | import org.bouncycastle.crypto.StreamCipher;
4 | import org.bouncycastle.crypto.engines.ChaCha7539Engine;
5 | import org.bouncycastle.crypto.io.CipherInputStream;
6 | import org.bouncycastle.crypto.io.CipherOutputStream;
7 | import org.bouncycastle.crypto.params.KeyParameter;
8 | import org.bouncycastle.crypto.params.ParametersWithIV;
9 |
10 | import java.io.InputStream;
11 | import java.io.OutputStream;
12 | import java.util.UUID;
13 |
14 | /**
15 | * ChaCha20 may be used for the inner stream as well as for the underlying database encryption scheme
16 | *
17 | * A singleton
18 | */
19 | public class ChaCha implements CipherAlgorithm {
20 |
21 | private static final UUID CHA_CHA_20_CIPHER = UUID.fromString("d6038a2b-8b6f-4cb5-a524-339a31dbb59a");
22 |
23 | private static final String name = "CHA_CHA_20";
24 |
25 | // hide constructor to enforce singleton
26 | private ChaCha(){}
27 | private static final ChaCha instance = new ChaCha();
28 |
29 | public static ChaCha getInstance() {
30 | return instance;
31 | }
32 |
33 | @Override
34 | public UUID getCipherUuid() {
35 | return CHA_CHA_20_CIPHER;
36 | }
37 |
38 | @Override
39 | public String getName(){
40 | return name;
41 | }
42 |
43 | @Override
44 | public InputStream getDecryptedInputStream(InputStream encryptedInputStream, byte[] key, byte[] iv) {
45 | final ParametersWithIV keyAndIV = new ParametersWithIV(new KeyParameter(key), iv);
46 | StreamCipher cipher = new ChaCha7539Engine();
47 | cipher.init(false, keyAndIV);
48 | return new CipherInputStream(encryptedInputStream, cipher);
49 | }
50 |
51 | @Override
52 | public OutputStream getEncryptedOutputStream(OutputStream decryptedOutputStream, byte[] key, byte[] iv) {
53 | final ParametersWithIV keyAndIV = new ParametersWithIV(new KeyParameter(key), iv);
54 | StreamCipher cipher = new ChaCha7539Engine();
55 | cipher.init(true, keyAndIV);
56 | return new CipherOutputStream(decryptedOutputStream, cipher);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/example/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | KeePassJava2-parent
21 | org.linguafranca.pwdb
22 | 2.2.4
23 | ../pom.xml
24 |
25 | 4.0.0
26 |
27 | example
28 | PWDB :: Example
29 | Examples of how to use PWDB
30 |
31 |
32 | true
33 |
34 |
35 |
36 |
37 | org.linguafranca.pwdb
38 | KeePassJava2
39 | ${project.version}
40 |
41 |
42 | io.github.novacrypto
43 | SecureString
44 | 2022.01.17
45 |
46 |
47 | org.linguafranca.pwdb
48 | test
49 | ${project.version}
50 | test-jar
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/kdbx/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | KeePassJava2-parent
21 | org.linguafranca.pwdb
22 | 2.2.4
23 | ../pom.xml
24 |
25 | 4.0.0
26 |
27 | KeePassJava2-kdbx
28 | KeePassJava2 :: KDBX
29 | Base classes and resources for other KDBX modules.
30 | KDBX Stream Support.
31 | Security support.
32 |
33 |
34 |
35 |
36 |
37 | org.linguafranca.pwdb
38 | database
39 | ${project.version}
40 |
41 |
42 | commons-codec
43 | commons-codec
44 | 1.17.0
45 |
46 |
47 | org.linguafranca.pwdb
48 | test
49 | ${project.version}
50 | test-jar
51 | test
52 |
53 |
54 |
--------------------------------------------------------------------------------
/kdbx/src/test/java/org/linguafranca/pwdb/kdbx/HelperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx;
18 |
19 | import org.junit.Test;
20 |
21 | import java.io.PrintStream;
22 | import java.util.UUID;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
26 |
27 | /**
28 | * tests the operation of Hex conversion
29 | */
30 | public class HelperTest {
31 | static PrintStream printStream = getTestPrintStream();
32 |
33 | @Test
34 | public void testBase64() throws Exception {
35 | String inputString = "0tU8XFRUX2TCk5tmmrshuQ==";
36 | printStream.println("Input string: " + inputString);
37 | String hexString = "D2D53C5C54545F64C2939B669ABB21B9";
38 | String convertedString = Helpers.hexStringFromBase64("0tU8XFRUX2TCk5tmmrshuQ==");
39 | printStream.println("Converted string: " + convertedString);
40 | assertEquals(hexString, convertedString.toUpperCase());
41 |
42 | UUID uuid = Helpers.uuidFromBase64(inputString);
43 | printStream.println("UUID: " + uuid.toString());
44 | assertEquals("d2d53c5c-5454-5f64-c293-9b669abb21b9", uuid.toString());
45 |
46 | String uuidHex = Helpers.hexStringFromUuid(uuid);
47 | printStream.println("Hex from UUID: " + uuidHex);
48 | assertEquals(hexString, uuidHex.toUpperCase());
49 |
50 | String base64 = Helpers.base64FromUuid(uuid);
51 | printStream.println("Base 64: " + base64);
52 | assertEquals(inputString, base64);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonPropertyValueTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
19 | import org.linguafranca.pwdb.checks.PropertyValueChecks;
20 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
21 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
22 | import org.linguafranca.pwdb.kdbx.jackson.JacksonEntry;
23 | import org.linguafranca.pwdb.kdbx.jackson.JacksonGroup;
24 | import org.linguafranca.pwdb.kdbx.jackson.JacksonIcon;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.OutputStream;
29 |
30 | public class JacksonPropertyValueTest extends PropertyValueChecks {
31 |
32 | public JacksonPropertyValueTest() throws IOException {
33 | super(true);
34 | }
35 |
36 | @Override
37 | public void saveDatabase(JacksonDatabase database, Credentials credentials, OutputStream outputStream) throws IOException {
38 | database.save(credentials, outputStream);
39 | }
40 |
41 | @Override
42 | public JacksonDatabase loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
43 | return JacksonDatabase.load(credentials, inputStream);
44 | }
45 |
46 | @Override
47 | public Credentials getCreds(byte[] creds) {
48 | return new KdbxCreds(creds);
49 | }
50 | @Override
51 | public JacksonDatabase createDatabase() throws IOException {
52 | return new JacksonDatabase();
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/jackson/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | KeePassJava2-parent
20 | org.linguafranca.pwdb
21 | 2.2.4
22 | ../pom.xml
23 |
24 | 4.0.0
25 |
26 | KeePassJava2-jackson
27 | KeePassJava2 :: Jackson
28 | Contains a Jackson XML implementation for KDBX.
29 |
30 |
31 |
32 | org.linguafranca.pwdb
33 | KeePassJava2-kdbx
34 | ${project.version}
35 |
36 |
37 | org.linguafranca.pwdb
38 | test
39 | ${project.version}
40 | test-jar
41 | test
42 |
43 |
44 | com.fasterxml.jackson.dataformat
45 | jackson-dataformat-xml
46 | 2.18.2
47 |
48 |
49 | com.fasterxml.woodstox
50 | woodstox-core
51 | 7.0.0
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/kdbx/src/test/java/org/linguafranca/pwdb/security/StreamEncryptionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.security;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.security.StreamEncryptor.*;
21 |
22 | import java.io.PrintStream;
23 | import java.security.SecureRandom;
24 |
25 | import static org.junit.Assert.assertEquals;
26 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
27 |
28 | /**
29 | * Verify that the inner random encryption works two-way
30 | * @author jo
31 | */
32 | public class StreamEncryptionTest {
33 |
34 | static PrintStream printStream = getTestPrintStream();
35 |
36 | @Test
37 | public void salsa20() {
38 | byte[] key = SecureRandom.getSeed(32);
39 | StreamEncryptor ss = new Salsa20(key);
40 | StreamEncryptor tt = new Salsa20(key);
41 |
42 | verifyTwoWay(ss, tt);
43 | }
44 |
45 | @Test
46 | public void chacha20() {
47 | byte[] key = SecureRandom.getSeed(32);
48 | StreamEncryptor ss = new ChaCha20(key);
49 | StreamEncryptor tt = new ChaCha20(key);
50 |
51 | verifyTwoWay(ss, tt);
52 | }
53 |
54 | private void verifyTwoWay(StreamEncryptor ss, StreamEncryptor tt) {
55 |
56 | byte[] e = ss.encrypt("new secret".getBytes());
57 | byte[] f = ss.encrypt("secret 2".getBytes());
58 |
59 |
60 | String s1 = new String(tt.encrypt(e));
61 | String t1 = new String(tt.encrypt(f));
62 |
63 | assertEquals("new secret", s1);
64 | assertEquals("secret 2", t1);
65 |
66 | printStream.println(s1);
67 | printStream.println(t1);
68 | }
69 |
70 | }
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimpleBinaryPropertyV4Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple;
18 |
19 | import org.junit.Ignore;
20 | import org.linguafranca.pwdb.Credentials;
21 | import org.linguafranca.pwdb.Database;
22 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
23 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
24 |
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.OutputStream;
28 |
29 | /**
30 | * @author jo
31 | */
32 | @Ignore
33 | public class SimpleBinaryPropertyV4Test extends BinaryPropertyChecks {
34 |
35 | public SimpleBinaryPropertyV4Test() throws Exception {
36 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-ChaCha20-Argon2-Attachment.kdbx");
37 | database = SimpleDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
38 | }
39 |
40 | @Override
41 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
42 | database.save(credentials, outputStream);
43 | }
44 |
45 | @Override
46 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
47 | try {
48 | return SimpleDatabase.load(credentials, inputStream);
49 | } catch (Exception e) {
50 | throw new RuntimeException(e);
51 | }
52 | }
53 |
54 | @Override
55 | public Database newDatabase() {
56 | return new SimpleDatabase();
57 | }
58 |
59 | @Override
60 | public Credentials getCreds(byte[] creds) {
61 | return new KdbxCreds(creds);
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/ValueExtender.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import javax.xml.bind.annotation.XmlAccessType;
12 | import javax.xml.bind.annotation.XmlAccessorType;
13 | import javax.xml.bind.annotation.XmlSeeAlso;
14 | import javax.xml.bind.annotation.XmlType;
15 | import javax.xml.bind.annotation.XmlValue;
16 |
17 |
18 | /**
19 | * Abstract parent for StringField/Value so that
20 | * to allow creation of a custom mapping that contains extra
21 | * non-serialised (transient) fields.
22 | *
23 | *
24 | * Java class for ValueExtender complex type.
25 | *
26 | *
The following schema fragment specifies the expected content contained within this class.
27 | *
28 | *
29 | * <complexType name="ValueExtender">
30 | * <simpleContent>
31 | * <extension base="<http://www.w3.org/2001/XMLSchema>string">
32 | * </extension>
33 | * </simpleContent>
34 | * </complexType>
35 | *
36 | *
37 | *
38 | */
39 | @XmlAccessorType(XmlAccessType.FIELD)
40 | @XmlType(name = "ValueExtender", propOrder = {
41 | "value"
42 | })
43 | @XmlSeeAlso({
44 | org.linguafranca.pwdb.kdbx.jaxb.binding.StringField.Value.class
45 | })
46 | public abstract class ValueExtender {
47 |
48 | @XmlValue
49 | protected String value;
50 |
51 | /**
52 | * Gets the value of the value property.
53 | *
54 | * @return
55 | * possible object is
56 | * {@link String }
57 | *
58 | */
59 | public String getValue() {
60 | return value;
61 | }
62 |
63 | /**
64 | * Sets the value of the value property.
65 | *
66 | * @param value
67 | * allowed object is
68 | * {@link String }
69 | *
70 | */
71 | public void setValue(String value) {
72 | this.value = value;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/protect/ProtectedDatabase.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.protect;
2 |
3 | import org.linguafranca.pwdb.*;
4 | import org.linguafranca.pwdb.base.AbstractDatabase;
5 |
6 | import java.util.Collections;
7 | import java.util.List;
8 |
9 | /**
10 | * Base class for Databases which support storage using {@link PropertyValue}s.
11 | *
12 | * By default {@link Entry#STANDARD_PROPERTY_NAME_PASSWORD} is defined as protected and the property value strategy
13 | * establishes {@link org.linguafranca.pwdb.PropertyValue.StringStore} storage for unprotected values and
14 | * {@link org.linguafranca.pwdb.PropertyValue.SealedStore} for protected values.
15 | */
16 | public abstract class ProtectedDatabase, G extends Group, E extends Entry, I extends Icon> extends AbstractDatabase {
17 | private PropertyValue.Strategy valueStrategy = new PropertyValue.Strategy.Default();
18 |
19 | @Override
20 | public boolean shouldProtect(String propertyName){
21 | return valueStrategy.getProtectedProperties().contains(propertyName);
22 | }
23 |
24 | @Override
25 | public void setShouldProtect(String propertyName, boolean protect){
26 | if (protect) {
27 | valueStrategy.getProtectedProperties().add(propertyName);
28 | } else {
29 | valueStrategy.getProtectedProperties().remove(propertyName);
30 | }
31 | }
32 |
33 | @Override
34 | public List listShouldProtect(){
35 | return Collections.unmodifiableList(valueStrategy.getProtectedProperties());
36 | }
37 |
38 | /**
39 | * Get the default means of storage of unprotected and protected property values
40 | */
41 | @Override
42 | public PropertyValue.Strategy getPropertyValueStrategy(){
43 | return this.valueStrategy;
44 | }
45 | /**
46 | * Set the default means of storage of unprotected and protected property values
47 | * @param strategy a property value strategy
48 | */
49 | @Override
50 | public void setPropertyValueStrategy(PropertyValue.Strategy strategy){
51 | this.valueStrategy = strategy;
52 | }
53 |
54 | @Override
55 | public boolean supportsPropertyValueStrategy(){
56 | return true;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/kdbx/src/main/java/org/linguafranca/pwdb/hashedblock/CollectingOutputStream.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.hashedblock;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.io.*;
6 |
7 | /**
8 | * Class allows the forwarding (as a filter) and collection of written bytes as a buffer
9 | * - e.g. to provide for HMAC operations
10 | *
11 | * @author jo
12 | */
13 | public class CollectingOutputStream extends FilterOutputStream {
14 |
15 | private final ByteArrayOutputStream collectedBytes = new ByteArrayOutputStream();
16 | private boolean collecting = true;
17 |
18 | /**
19 | * Create a collecting stream which is set to collect from the get go
20 | *
21 | * @param out the output stream to forward/collect
22 | */
23 | public CollectingOutputStream(OutputStream out) {
24 | this(out, true);
25 | }
26 |
27 | /**
28 | * Create a collecting stream
29 | *
30 | * @param out the output stream to forward/collect
31 | * @param collecting whether the initial state is collecting or not
32 | */
33 | public CollectingOutputStream(OutputStream out, boolean collecting) {
34 | super(out);
35 | this.collecting = collecting;
36 | }
37 |
38 | @Override
39 | public void write(int toWrite) throws IOException {
40 | super.write(toWrite);
41 | if (collecting) {
42 | collectedBytes.write(toWrite);
43 | }
44 | }
45 |
46 | @Override
47 | public void write(byte @NotNull [] b) throws IOException {
48 | write(b, 0, b.length);
49 | }
50 |
51 | @Override
52 | public void write(byte @NotNull [] b, int off, int len) throws IOException {
53 | super.write(b, off, len);
54 | }
55 |
56 | /**
57 | * Get the collected bytes as a byte array
58 | */
59 | public byte[] getCollectedBytes() {
60 | return collectedBytes.toByteArray();
61 | }
62 |
63 | /**
64 | * True if we are currently collecting bytes
65 | */
66 | public boolean isCollecting() {
67 | return collecting;
68 | }
69 |
70 | /**
71 | * Cganeg the state of collecting bytes
72 | * @param collecting true to collect
73 | */
74 | public void setCollecting(boolean collecting) {
75 | this.collecting = collecting;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/SerializableDatabase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb;
18 |
19 | import org.linguafranca.pwdb.security.StreamEncryptor;
20 |
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 | import java.io.OutputStream;
24 |
25 | /**
26 | * This interface allows for serialization and deserialization of databases, which is
27 | * theoretically decoupled from the actual format they use for serialization.
28 | *
29 | * Databases instantiate themselves from a stream and serialize to a stream,
30 | * and need to be able to encrypt and decrypt data (e.g. Protected fields in KDBX format).
31 | *
32 | * KDBX V3 databases contain a header hash (i.e. a hash of the contents of
33 | * some portion of the {@link StreamFormat} they have been loaded from or saved to).
34 | * Which means that databases must support the setting of this value after the header
35 | * has been written on save, and reading the value after load to allow for integrity checking.
36 | *
37 | * KDBX V4 databases have their attachments in the header so databases need to support setting
38 | * and getting of attachments for serialization
39 | */
40 | public interface SerializableDatabase {
41 |
42 | SerializableDatabase load(InputStream inputStream) throws IOException;
43 |
44 | void save(OutputStream outputStream) throws IOException;
45 |
46 | StreamEncryptor getEncryption();
47 |
48 | void setEncryption(StreamEncryptor encryption);
49 |
50 | byte[] getHeaderHash();
51 |
52 | void setHeaderHash(byte[] hash);
53 |
54 | void addBinary(int index, byte[] payload);
55 |
56 | byte[] getBinary(int index);
57 |
58 | int getBinaryCount();
59 | }
60 |
--------------------------------------------------------------------------------
/simple/src/test/java/org/linguafranca/pwdb/kdbx/simple/SimpleBinaryPropertyV3Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.simple;
18 |
19 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
20 | import org.linguafranca.pwdb.Database;
21 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
22 | import org.linguafranca.pwdb.Credentials;
23 |
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.OutputStream;
27 |
28 | /**
29 | * @author jo
30 | */
31 | public class SimpleBinaryPropertyV3Test extends BinaryPropertyChecks {
32 |
33 | public SimpleBinaryPropertyV3Test() {
34 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Attachment.kdbx");
35 | try {
36 | database = SimpleDatabase.load(new KdbxCreds("123".getBytes()),inputStream);
37 | } catch (Exception e) {
38 | throw new IllegalStateException(e);
39 | }
40 | }
41 |
42 | @Override
43 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
44 | database.save(credentials, outputStream);
45 | }
46 |
47 |
48 | @Override
49 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
50 | try {
51 | return SimpleDatabase.load(credentials, inputStream);
52 | } catch (Exception e) {
53 | throw new RuntimeException(e);
54 | }
55 | }
56 |
57 |
58 | @Override
59 | public Database newDatabase() {
60 | return new SimpleDatabase();
61 | }
62 |
63 | @Override
64 | public Credentials getCreds(byte[] creds) {
65 | return new KdbxCreds(creds);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonBinaryPropertyV3Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb;
18 |
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.OutputStream;
22 |
23 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
24 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
25 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
26 |
27 | public class JacksonBinaryPropertyV3Test extends BinaryPropertyChecks {
28 |
29 |
30 | public JacksonBinaryPropertyV3Test() {
31 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Attachment.kdbx");
32 | try {
33 | database = JacksonDatabase.load(new KdbxCreds("123".getBytes()),inputStream);
34 | } catch (Exception e) {
35 | throw new IllegalStateException(e);
36 | }
37 | }
38 |
39 | @Override
40 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
41 | database.save(credentials, outputStream);
42 | }
43 |
44 | @Override
45 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
46 | return JacksonDatabase.load(credentials, inputStream);
47 | }
48 |
49 | @Override
50 | public Database newDatabase() {
51 | Database result = null;
52 | try {
53 | result = new JacksonDatabase();
54 | } catch(Exception e) {
55 | throw new RuntimeException(e);
56 | }
57 | return result;
58 |
59 | }
60 |
61 | @Override
62 | public Credentials getCreds(byte[] creds) {
63 | return new KdbxCreds(creds);
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomBinaryPropertyV4Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.Credentials;
20 | import org.linguafranca.pwdb.Database;
21 | import org.linguafranca.pwdb.StreamFormat;
22 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
23 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
24 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
25 | import org.linguafranca.pwdb.kdbx.KdbxStreamFormat;
26 |
27 | import java.io.IOException;
28 | import java.io.InputStream;
29 | import java.io.OutputStream;
30 |
31 | /**
32 | * @author jo
33 | */
34 | public class DomBinaryPropertyV4Test extends BinaryPropertyChecks {
35 |
36 | public DomBinaryPropertyV4Test() throws IOException {
37 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-ChaCha20-Argon2-Attachment.kdbx");
38 | database = DomDatabaseWrapper.load(new KdbxCreds("123".getBytes()), inputStream);
39 | }
40 |
41 | @Override
42 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
43 | StreamFormat sf = new KdbxStreamFormat(new KdbxHeader(4));
44 | database.save(sf, credentials, outputStream);
45 | }
46 |
47 |
48 | @Override
49 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
50 | return DomDatabaseWrapper.load(credentials, inputStream);
51 | }
52 |
53 | @Override
54 | public Database newDatabase() {
55 | return new DomDatabaseWrapper();
56 | }
57 |
58 | @Override
59 | public Credentials getCreds(byte[] creds) {
60 | return new KdbxCreds(creds);
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.junit.Test;
20 | import org.linguafranca.pwdb.kdbx.jaxb.binding.KeePassFile;
21 | import org.linguafranca.pwdb.kdbx.jaxb.binding.StringField;
22 |
23 | import javax.xml.bind.*;
24 | import java.io.PrintStream;
25 |
26 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
27 |
28 | /**
29 | * @author jo
30 | */
31 | public class JaxbTest {
32 | static PrintStream printStream = getTestPrintStream();
33 |
34 | @Test
35 | public void unmarshal() throws JAXBException {
36 | JAXBContext jc = JAXBContext.newInstance(KeePassFile.class);
37 | Unmarshaller u = jc.createUnmarshaller();
38 | u.setEventHandler(new ValidationEventHandler() {
39 | @Override
40 | public boolean handleEvent(ValidationEvent event) {
41 | printStream.println(event.getLocator().getLineNumber() +": "+ event.getMessage());
42 | return true;
43 | }
44 | });
45 | u.setListener(new Unmarshaller.Listener() {
46 | @Override
47 | public void afterUnmarshal(Object target, Object parent) {
48 | if (target instanceof StringField.Value) {
49 | StringField.Value value = (StringField.Value) target;
50 | printStream.println(value.getValue());
51 | }
52 | super.afterUnmarshal(target, parent);
53 | }
54 | });
55 | KeePassFile kpf = (KeePassFile) u.unmarshal(getClass().getClassLoader().getResourceAsStream("ExampleDatabase.xml"));
56 | printStream.println(kpf.getMeta().getDatabaseDescription());
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbBinaryPropertyV4Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.junit.Ignore;
20 | import org.linguafranca.pwdb.Credentials;
21 | import org.linguafranca.pwdb.Database;
22 | import org.linguafranca.pwdb.StreamFormat;
23 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
24 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
25 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
26 | import org.linguafranca.pwdb.kdbx.KdbxStreamFormat;
27 |
28 | import java.io.IOException;
29 | import java.io.InputStream;
30 | import java.io.OutputStream;
31 |
32 | /**
33 | * @author jo
34 | */
35 | @Ignore
36 | public class JaxbBinaryPropertyV4Test extends BinaryPropertyChecks {
37 |
38 | public JaxbBinaryPropertyV4Test() throws IOException {
39 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-ChaCha20-Argon2-Attachment.kdbx");
40 | database = JaxbDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
41 | }
42 |
43 | @Override
44 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
45 | StreamFormat sf = new KdbxStreamFormat(new KdbxHeader(4));
46 | database.save(sf, credentials, outputStream);
47 | }
48 |
49 | @Override
50 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
51 | return JaxbDatabase.load(credentials, inputStream);
52 | }
53 |
54 | @Override
55 | public Database newDatabase() {
56 | return new JaxbDatabase();
57 | }
58 |
59 | @Override
60 | public Credentials getCreds(byte[] creds) {
61 | return new KdbxCreds(creds);
62 | }
63 | }
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonBinaryPropertyV4Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 | import java.io.OutputStream;
21 |
22 | import org.linguafranca.pwdb.checks.BinaryPropertyChecks;
23 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
24 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
25 |
26 | public class JacksonBinaryPropertyV4Test extends BinaryPropertyChecks{
27 |
28 |
29 | public JacksonBinaryPropertyV4Test() throws Exception{
30 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-ChaCha20-Argon2-Attachment.kdbx");
31 | database = JacksonDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
32 | }
33 |
34 |
35 | @Override
36 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
37 | database.save(credentials, outputStream);
38 | }
39 |
40 | @Override
41 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
42 | try {
43 | return JacksonDatabase.load(credentials, inputStream);
44 | } catch (Exception e) {
45 | throw new RuntimeException(e);
46 | }
47 | }
48 |
49 | @Override
50 | public Database newDatabase() {
51 | Database result = null;
52 | try {
53 | result = new JacksonDatabase();
54 | } catch (Exception e) {
55 | throw new RuntimeException(e);
56 | }
57 | return result;
58 |
59 | }
60 |
61 | @Override
62 | public Credentials getCreds(byte[] creds) {
63 | return new KdbxCreds(creds);
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/kdbx/src/test/java/org/linguafranca/pwdb/kdbx/HelpersTest.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.PrintStream;
6 | import java.text.ParseException;
7 | import java.time.Instant;
8 | import java.time.ZoneId;
9 | import java.time.ZonedDateTime;
10 | import java.util.Date;
11 |
12 | import static org.junit.Assert.*;
13 | import static org.linguafranca.pwdb.kdbx.Helpers.dateTimeFormatter;
14 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
15 |
16 | public class HelpersTest {
17 |
18 | static PrintStream printStream = getTestPrintStream();
19 |
20 | public String testDate = "2023-05-09T16:11:29Z";
21 | public Date testDateAsDate = Date.from(ZonedDateTime.parse(testDate, dateTimeFormatter).toInstant());
22 | public String v4Encoding = "sWfs2w4AAAA=";
23 |
24 | @Test
25 | public void toDate() throws ParseException {
26 | Date date = Helpers.toDate(v4Encoding);
27 | assertEquals(testDateAsDate.getTime(), date.getTime());
28 | }
29 |
30 | @Test
31 | public void toDate2() throws ParseException {
32 | Date date = Helpers.toDate(testDate);
33 | assertEquals(testDateAsDate, date);
34 | }
35 |
36 | @Test
37 | public void toDate3() throws ParseException {
38 | ZonedDateTime zdt = ZonedDateTime.parse(testDate, dateTimeFormatter);
39 | printStream.println(zdt);
40 | Instant instant = zdt.toInstant();
41 | printStream.println(instant);
42 | Date date = Date.from(instant);
43 | printStream.println(date.clone());
44 | assertEquals(instant.toEpochMilli(), date.getTime());
45 | assertEquals(instant.toEpochMilli(), testDateAsDate.getTime());
46 | }
47 |
48 | @Test
49 | public void fromDate() throws ParseException {
50 | Helpers.isV4.set(false);
51 | assertEquals(testDate, Helpers.fromDate(testDateAsDate));
52 | Helpers.isV4.set(true);
53 | assertEquals(v4Encoding, Helpers.fromDate(testDateAsDate));
54 | }
55 |
56 | @Test
57 | public void fromDateV3() throws ParseException {
58 | assertEquals(testDate, Helpers.fromDateV3(testDateAsDate));
59 | }
60 |
61 | @Test
62 | public void fromDateV4() throws ParseException {
63 | String base64 = Helpers.fromDateV4(testDateAsDate);
64 | printStream.println(Helpers.toDate(base64));
65 | assertEquals(v4Encoding, base64);
66 | }
67 | }
--------------------------------------------------------------------------------
/example/src/main/java/org/linguafranca/pwdb/example/SecureCharBufferPropertyValue.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.example;
2 |
3 | import io.github.novacrypto.SecureCharBuffer;
4 | import org.linguafranca.pwdb.PropertyValue;
5 |
6 | import java.nio.ByteBuffer;
7 | import java.nio.CharBuffer;
8 | import java.nio.charset.StandardCharsets;
9 |
10 | /**
11 | * SecureCharBufferPropertyValue uses {@link SecureCharBuffer}
12 | */
13 | public class SecureCharBufferPropertyValue implements PropertyValue {
14 | private final SecureCharBuffer value;
15 |
16 | /**
17 | * Builder for {@link SecureCharBufferPropertyValue}
18 | */
19 | static class Factory implements PropertyValue.Factory {
20 |
21 | @Override
22 | public PropertyValue of(CharSequence aString) {
23 | return new SecureCharBufferPropertyValue(aString);
24 | }
25 |
26 | @Override
27 | public PropertyValue of(char[] value) {
28 | return new SecureCharBufferPropertyValue(value);
29 | }
30 |
31 | @Override
32 | public PropertyValue of(byte[] value) {
33 | return new SecureCharBufferPropertyValue(value);
34 | }
35 | }
36 |
37 | public SecureCharBufferPropertyValue(CharSequence aString) {
38 | this.value = SecureCharBuffer.withCapacity(aString.length());
39 | this.value.append(aString);
40 | }
41 |
42 | public SecureCharBufferPropertyValue(char [] value) {
43 | this.value = SecureCharBuffer.withCapacity(value.length);
44 | this.value.append(CharBuffer.wrap(value));
45 | }
46 |
47 | public SecureCharBufferPropertyValue(byte [] value) {
48 | this.value = SecureCharBuffer.withCapacity(value.length);
49 | this.value.append(StandardCharsets.UTF_8.decode(ByteBuffer.wrap(value)));
50 | }
51 | @Override
52 | public String getValueAsString() {
53 | return this.value.toStringAble().toString();
54 | }
55 |
56 | @Override
57 | public CharSequence getValue() {
58 | return this.value;
59 | }
60 |
61 | @Override
62 | public char [] getValueAsChars() {
63 | return CharBuffer.wrap(value).array();
64 | }
65 |
66 | @Override
67 | public byte [] getValueAsBytes() {
68 | return StandardCharsets.UTF_8.encode(CharBuffer.wrap(value)).array();
69 | }
70 |
71 | @Override
72 | public boolean isProtected() {
73 | return true;
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/jaxb/src/generated/java/META-INF/sun-jaxb.episode:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/util/src/main/java/org/linguafranca/test/maven/MavenRunListener.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.test.maven;
2 |
3 | import org.junit.runner.Description;
4 | import org.junit.runner.notification.Failure;
5 | import org.junit.runner.notification.RunListener;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.slf4j.Marker;
9 | import org.slf4j.MarkerFactory;
10 |
11 | /**
12 | * Helper class to identify the test being run by maven surefire in the log output. This
13 | * is particularly useful if there is a lot of "chatty" testing going on.
14 | *
15 | * See: Using Custom Listeners and Reporters
16 | */
17 | @RunListener.ThreadSafe
18 | public class MavenRunListener extends RunListener {
19 | static Logger logger = LoggerFactory.getLogger("MavenRunListener");
20 | static Marker marker = MarkerFactory.getMarker("Starting Test");
21 | static Marker endMarker = MarkerFactory.getMarker("Finished Test");
22 | static Marker failMarker = MarkerFactory.getMarker("Failed Test");
23 | static Marker assumeFailMarker = MarkerFactory.getMarker("Assumption Failed");
24 | static Marker ignoredMarker = MarkerFactory.getMarker("Ignored Test");
25 |
26 | @Override
27 | public void testStarted(Description description) throws Exception {
28 | super.testStarted(description);
29 | logger.info(marker, "{}", description.getDisplayName());
30 | }
31 |
32 | @Override
33 | public void testFailure(Failure failure) throws Exception {
34 | super.testFailure(failure);
35 | logger.error(failMarker, "{} {}", failure.getMessage(), failure.getDescription().getDisplayName());
36 | }
37 |
38 | @Override
39 | public void testAssumptionFailure(Failure failure) {
40 | super.testAssumptionFailure(failure);
41 | logger.warn(assumeFailMarker, "{} {}", failure.getMessage(), failure.getDescription().getDisplayName());
42 | }
43 |
44 | @Override
45 | public void testIgnored(Description description) throws Exception {
46 | super.testIgnored(description);
47 | logger.info(ignoredMarker, "{}", description.getDisplayName());
48 | }
49 |
50 | @Override
51 | public void testFinished(Description description) throws Exception {
52 | super.testFinished(description);
53 | logger.info(endMarker, "Finished {}", description.getDisplayName());
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/all/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | KeePassJava2-parent
21 | org.linguafranca.pwdb
22 | 2.2.4
23 | ../pom.xml
24 |
25 |
26 | 4.0.0
27 |
28 | KeePassJava2
29 | KeePassJava2 :: All
30 | Supports KDBX Password Database Versions 3.1, 4 and 4.1.
31 |
32 |
33 |
34 | org.linguafranca.pwdb
35 | KeePassJava2-kdb
36 | ${project.version}
37 |
38 |
39 | org.linguafranca.pwdb
40 | KeePassJava2-dom
41 | ${project.version}
42 |
43 |
44 | org.linguafranca.pwdb
45 | KeePassJava2-jaxb
46 | ${project.version}
47 |
48 |
49 | org.linguafranca.pwdb
50 | KeePassJava2-simple
51 | ${project.version}
52 |
53 |
54 | org.linguafranca.pwdb
55 | KeePassJava2-jackson
56 | ${project.version}
57 |
58 |
59 |
--------------------------------------------------------------------------------
/simple/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | KeePassJava2-parent
21 | org.linguafranca.pwdb
22 | 2.2.4
23 | ../pom.xml
24 |
25 | 4.0.0
26 |
27 | KeePassJava2-simple
28 | KeePassJava2 :: Simple
29 | Contains a Simple XML framework implementation of KDBX.
30 |
31 |
32 |
33 | org.linguafranca.pwdb
34 | KeePassJava2-kdbx
35 | ${project.version}
36 |
37 |
38 | org.linguafranca.pwdb
39 | test
40 | ${project.version}
41 | test-jar
42 | test
43 |
44 |
45 | com.carrotsearch.thirdparty
46 | simple-xml-safe
47 | 2.7.1
48 |
49 |
50 | org.apache.httpcomponents
51 | httpcore
52 | 4.4.16
53 |
54 |
55 | com.fasterxml
56 | aalto-xml
57 | 1.3.3
58 |
59 |
60 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomDatabaseWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.checks.BasicDatabaseChecks;
20 | import org.junit.Test;
21 | import org.linguafranca.pwdb.Database;
22 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
23 | import org.linguafranca.pwdb.StreamFormat;
24 | import org.linguafranca.pwdb.Credentials;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.PrintStream;
29 |
30 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
31 |
32 | /**
33 | * @author jo
34 | */
35 | public class DomDatabaseWrapperTest extends BasicDatabaseChecks {
36 |
37 | static PrintStream printStream = getTestPrintStream();
38 |
39 | public DomDatabaseWrapperTest() throws IOException {
40 | }
41 |
42 | @Test
43 | public void inspectPasswordDatabase() throws IOException {
44 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
45 | DomDatabaseWrapper database = new DomDatabaseWrapper(new KdbxCreds("123".getBytes()), inputStream);
46 |
47 | database.save(new StreamFormat.None(), new Credentials.None(), printStream);
48 | }
49 |
50 | @Test
51 | public void inspectKeyfileDatabase() throws IOException {
52 | InputStream keyFileInputStream = getClass().getClassLoader().getResourceAsStream("KeyFileDatabase.key");
53 | Credentials credentials = new KdbxCreds("123".getBytes(), keyFileInputStream);
54 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("KeyFileDatabase.kdbx");
55 | DomDatabaseWrapper database = new DomDatabaseWrapper(credentials, inputStream);
56 |
57 | database.save(new StreamFormat.None(), new Credentials.None(), printStream);
58 | }
59 |
60 | @Override
61 | public Database createDatabase() throws IOException {
62 | return new DomDatabaseWrapper();
63 | }
64 | }
--------------------------------------------------------------------------------
/jaxb/src/generated/java/org/linguafranca/pwdb/kdbx/jaxb/binding/CustomData.java:
--------------------------------------------------------------------------------
1 | //
2 | // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
3 | // See http://java.sun.com/xml/jaxb
4 | // Any modifications to this file will be lost upon recompilation of the source schema.
5 | // Generated on: 2023.05.17 at 11:23:19 AM BST
6 | //
7 |
8 |
9 | package org.linguafranca.pwdb.kdbx.jaxb.binding;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import javax.xml.bind.annotation.XmlAccessType;
14 | import javax.xml.bind.annotation.XmlAccessorType;
15 | import javax.xml.bind.annotation.XmlAnyElement;
16 | import javax.xml.bind.annotation.XmlType;
17 |
18 |
19 | /**
20 | * Third party programs and plugins can put custom data here.
21 | * Unique element names should be used, e.g. "PluginName_ItemName".
22 | *
23 | *
24 | *
Java class for customData complex type.
25 | *
26 | *
The following schema fragment specifies the expected content contained within this class.
27 | *
28 | *
29 | * <complexType name="customData">
30 | * <complexContent>
31 | * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
32 | * <sequence>
33 | * <any maxOccurs="unbounded" minOccurs="0"/>
34 | * </sequence>
35 | * </restriction>
36 | * </complexContent>
37 | * </complexType>
38 | *
39 | *
40 | *
41 | */
42 | @XmlAccessorType(XmlAccessType.FIELD)
43 | @XmlType(name = "customData", propOrder = {
44 | "any"
45 | })
46 | public class CustomData {
47 |
48 | @XmlAnyElement(lax = true)
49 | protected List any;
50 |
51 | /**
52 | * Gets the value of the any property.
53 | *
54 | *
55 | * This accessor method returns a reference to the live list,
56 | * not a snapshot. Therefore any modification you make to the
57 | * returned list will be present inside the JAXB object.
58 | * This is why there is not a set method for the any property.
59 | *
60 | *
61 | * For example, to add a new item, do as follows:
62 | *
63 | * getAny().add(newItem);
64 | *
65 | *
66 | *
67 | *
68 | * Objects of the following type(s) are allowed in the list
69 | * {@link Object }
70 | *
71 | *
72 | */
73 | public List getAny() {
74 | if (any == null) {
75 | any = new ArrayList();
76 | }
77 | return this.any;
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/kdbx/src/main/java/org/linguafranca/pwdb/hashedblock/CollectingInputStream.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.hashedblock;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.io.ByteArrayOutputStream;
6 | import java.io.FilterInputStream;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | /**
11 | * Class allows the forwarding (as a filter) and collection of read bytes as a buffer
12 | * - e.g. to provide for HMAC operations
13 | *
14 | * @author jo
15 | */
16 | public class CollectingInputStream extends FilterInputStream {
17 |
18 | private ByteArrayOutputStream collectedBytes = new ByteArrayOutputStream();
19 | private boolean collecting = true;
20 |
21 | /**
22 | * Create a collecting stream which is set to collect from the get go
23 | *
24 | * @param in the input stream to forward/collect
25 | */
26 | public CollectingInputStream(InputStream in) {
27 | this(in, true);
28 | }
29 |
30 | /**
31 | * Create a collecting stream
32 | *
33 | * @param in the input stream to forward/collect
34 | * @param collecting whether the initial state is collecting or not
35 | */
36 | public CollectingInputStream(InputStream in, boolean collecting) {
37 | super(in);
38 | this.collecting = collecting;
39 | }
40 |
41 | @Override
42 | public int read() throws IOException {
43 | int result = super.read();
44 | if (collecting && result != -1) {
45 | collectedBytes.write(result);
46 | }
47 | return result;
48 | }
49 |
50 | @Override
51 | public int read(@NotNull byte[] b) throws IOException {
52 | return read(b, 0, b.length);
53 | }
54 |
55 | @Override
56 | public int read(@NotNull byte[] b, int off, int len) throws IOException {
57 | int result = super.read(b, off, len);
58 | if (collecting && result != -1) {
59 | collectedBytes.write(b, off, result);
60 | }
61 | return result;
62 | }
63 |
64 | @Override
65 | public long skip(long n) throws IOException {
66 | return super.skip(n);
67 | }
68 |
69 | /**
70 | * Get the collected bytes as a byte array
71 | */
72 | public byte[] getCollectedBytes() {
73 | return collectedBytes.toByteArray();
74 | }
75 |
76 | /**
77 | * True if we are currently collecting bytes
78 | */
79 | public boolean isCollecting() {
80 | return collecting;
81 | }
82 |
83 | /**
84 | * Cganeg the state of collecting bytes
85 | * @param collecting true to collect
86 | */
87 | public void setCollecting(boolean collecting) {
88 | this.collecting = collecting;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/kdbx/src/main/java/org/linguafranca/pwdb/kdbx/KdbxCreds.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx;
18 |
19 | import org.jetbrains.annotations.NotNull;
20 | import org.linguafranca.pwdb.Credentials;
21 | import org.linguafranca.pwdb.security.Encryption;
22 |
23 | import java.io.InputStream;
24 | import java.security.MessageDigest;
25 |
26 | /**
27 | * The class implements {@link Credentials} for KDBX files.
28 | *
29 | * @author jo
30 | */
31 | public class KdbxCreds implements Credentials {
32 |
33 | private final byte[] key;
34 |
35 | /**
36 | * Constructor for password with KDBX Keyfile
37 | * @param password Master Password (new byte[0] if empty, not none)
38 | * @param inputStream inputstream of the keyfile
39 | */
40 | public KdbxCreds(@NotNull byte[] password, @NotNull InputStream inputStream) {
41 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
42 | byte[] pwKey = md.digest(password);
43 | md.update(pwKey);
44 |
45 | byte[] keyFileData = KdbxKeyFile.load(inputStream);
46 | if (keyFileData == null) {
47 | throw new IllegalStateException("Could not read key file");
48 | }
49 | this.key = md.digest(keyFileData);
50 | }
51 |
52 | /**
53 | * Constructor for KDBX Keyfile with no password
54 | * @param inputStream inputstream of the keyfile
55 | */
56 | public KdbxCreds(@NotNull InputStream inputStream) {
57 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
58 | byte[] keyFileData = KdbxKeyFile.load(inputStream);
59 | if (keyFileData == null) {
60 | throw new IllegalStateException("Could not read key file");
61 | }
62 | this.key = md.digest(keyFileData);
63 | }
64 |
65 |
66 | public KdbxCreds(@NotNull byte[] password) {
67 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
68 | byte[] digest = md.digest(password);
69 | key = md.digest(digest);
70 | }
71 |
72 | @Override
73 | public byte[] getKey() {
74 | return key;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import com.fasterxml.jackson.core.JsonGenerator;
19 | import com.fasterxml.jackson.databind.SerializerProvider;
20 | import com.fasterxml.jackson.databind.ser.std.StdSerializer;
21 | import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
22 | import org.apache.commons.codec.binary.Base64;
23 | import org.linguafranca.pwdb.PropertyValue;
24 | import org.linguafranca.pwdb.security.StreamEncryptor;
25 |
26 | import java.io.IOException;
27 |
28 |
29 | public class ValueSerializer extends StdSerializer {
30 |
31 | private final StreamEncryptor encryptor;
32 | private final PropertyValue.Strategy propertyValueStrategy;
33 |
34 | public ValueSerializer(StreamEncryptor encryptor, PropertyValue.Strategy propertyValueStrategy) {
35 | super(ValueSerializer.class, false);
36 | this.encryptor = encryptor;
37 | this.propertyValueStrategy = propertyValueStrategy;
38 | }
39 |
40 | private String encrypt(byte[] bytes) {
41 | //Cipher
42 | byte[] encrypted = encryptor.encrypt(bytes);
43 | //Convert to base64
44 | return new String(Base64.encodeBase64(encrypted));
45 | }
46 |
47 | @Override
48 | public void serialize(PropertyValue value, JsonGenerator gen, SerializerProvider provider) throws IOException {
49 |
50 | final ToXmlGenerator xmlGenerator = (ToXmlGenerator) gen;
51 | xmlGenerator.writeStartObject();
52 |
53 | String stringToWrite = value.isProtected() ?
54 | encrypt(value.getValueAsBytes()) :
55 | value.getValueAsString();
56 |
57 | if (value.isProtected()) {
58 | xmlGenerator.setNextIsAttribute(true);
59 | xmlGenerator.writeStringField("Protected", "True");
60 | }
61 | xmlGenerator.setNextIsAttribute(false);
62 | xmlGenerator.setNextIsUnwrapped(true);
63 | xmlGenerator.writeStringField("text", stringToWrite);
64 | xmlGenerator.writeEndObject();
65 | }
66 | }
--------------------------------------------------------------------------------
/database/src/main/java/org/linguafranca/pwdb/StreamFormat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb;
18 |
19 | import org.linguafranca.pwdb.security.StreamEncryptor;
20 |
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 | import java.io.OutputStream;
24 |
25 | /**
26 | * Interface provides for wrapping a database serialization in a stream format, e.g. KDBX or none.
27 | *
28 | * @author jo
29 | */
30 | public interface StreamFormat {
31 | /**
32 | * Class allows for serializing a database directly to or from a stream with no encryption etc
33 | */
34 | class None implements StreamFormat {
35 |
36 | @Override
37 | public void load(SerializableDatabase serializableDatabase, Credentials credentials, InputStream inputStream) throws IOException {
38 | serializableDatabase.setEncryption(new StreamEncryptor.None());
39 | serializableDatabase.load(inputStream);
40 | inputStream.close();
41 | }
42 |
43 | @Override
44 | public void save(SerializableDatabase serializableDatabase, Credentials credentials, OutputStream outputStream) throws IOException {
45 | serializableDatabase.setEncryption(new StreamEncryptor.None());
46 | serializableDatabase.save(outputStream);
47 | outputStream.flush();
48 | outputStream.close();
49 | }
50 |
51 | @Override
52 | public StreamConfiguration.None getStreamConfiguration() {
53 | return new StreamConfiguration.None();
54 | }
55 |
56 | @Override
57 | public void setStreamConfiguration(StreamConfiguration.None configuration) {
58 |
59 | }
60 | }
61 |
62 | void load(SerializableDatabase serializableDatabase, Credentials credentials, InputStream encryptedInputStream) throws IOException;
63 |
64 | void save(SerializableDatabase serializableDatabase, Credentials credentials, OutputStream encryptedOutputStream) throws IOException;
65 |
66 | C getStreamConfiguration();
67 |
68 | void setStreamConfiguration(C configuration);
69 | }
70 |
--------------------------------------------------------------------------------
/jaxb/src/test/java/org/linguafranca/pwdb/kdbx/jaxb/JaxbSaveAndReloadTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.jaxb;
18 |
19 | import org.linguafranca.pwdb.Credentials;
20 | import org.linguafranca.pwdb.StreamFormat;
21 | import org.linguafranca.pwdb.checks.SaveAndReloadChecks;
22 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
23 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
24 |
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.OutputStream;
28 |
29 | /**
30 | * @author jo
31 | */
32 | public class JaxbSaveAndReloadTest extends SaveAndReloadChecks {
33 | @Override
34 | public JaxbDatabase getDatabase() {
35 | return new JaxbDatabase();
36 | }
37 | @Override
38 | public JaxbDatabase getDatabase(String name, Credentials credentials) throws IOException {
39 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream(name);
40 | return JaxbDatabase.load(credentials, inputStream);
41 | }
42 |
43 | @Override
44 | public void saveDatabase(JaxbDatabase database, Credentials credentials, OutputStream outputStream) throws IOException {
45 | database.save(credentials, outputStream);
46 | }
47 |
48 | @Override
49 | public JaxbDatabase loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
50 | return JaxbDatabase.load(credentials, inputStream);
51 | }
52 |
53 | @Override
54 | public Credentials getCreds(byte[] creds) {
55 | return new KdbxCreds(creds);
56 | }
57 |
58 |
59 | @Override
60 | public boolean verifyStreamFormat(StreamFormat s1, StreamFormat s2) {
61 | KdbxHeader h1 = (KdbxHeader) s1.getStreamConfiguration();
62 | KdbxHeader h2 = (KdbxHeader) s1.getStreamConfiguration();
63 | return (h1.getVersion() == h2.getVersion() &&
64 | h1.getProtectedStreamAlgorithm().equals(h2.getProtectedStreamAlgorithm()) &&
65 | h1.getKeyDerivationFunction().equals(h2.getKeyDerivationFunction()) &&
66 | h1.getCipherAlgorithm().equals(h2.getCipherAlgorithm()));
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/dom/src/test/java/org/linguafranca/pwdb/kdbx/dom/DomSaveAndReloadTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdbx.dom;
18 |
19 | import org.linguafranca.pwdb.StreamFormat;
20 | import org.linguafranca.pwdb.checks.SaveAndReloadChecks;
21 | import org.linguafranca.pwdb.Database;
22 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
23 | import org.linguafranca.pwdb.Credentials;
24 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.OutputStream;
29 |
30 | /**
31 | * @author jo
32 | */
33 | public class DomSaveAndReloadTest extends SaveAndReloadChecks {
34 |
35 | @Override
36 | public Database getDatabase() {
37 | return new DomDatabaseWrapper();
38 | }
39 | @Override
40 | public Database getDatabase(String name, Credentials credentials) throws IOException {
41 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream(name);
42 | return DomDatabaseWrapper.load(credentials, inputStream);
43 | }
44 |
45 | @Override
46 | public void saveDatabase(Database database, Credentials credentials, OutputStream outputStream) throws IOException {
47 | database.save(credentials, outputStream);
48 | }
49 |
50 | @Override
51 | public Database loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
52 | return DomDatabaseWrapper.load(credentials, inputStream);
53 | }
54 |
55 | @Override
56 | public Credentials getCreds(byte[] creds) {
57 | return new KdbxCreds("123".getBytes());
58 | }
59 |
60 | @Override
61 | public boolean verifyStreamFormat(StreamFormat s1, StreamFormat s2) {
62 | KdbxHeader h1 = (KdbxHeader) s1.getStreamConfiguration();
63 | KdbxHeader h2 = (KdbxHeader) s1.getStreamConfiguration();
64 | return (h1.getVersion() == h2.getVersion() &&
65 | h1.getProtectedStreamAlgorithm().equals(h2.getProtectedStreamAlgorithm()) &&
66 | h1.getKeyDerivationFunction().equals(h2.getKeyDerivationFunction()) &&
67 | h1.getCipherAlgorithm().equals(h2.getCipherAlgorithm()));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/kdb/src/main/java/org/linguafranca/pwdb/kdb/KdbCredentials.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Jo Rabin
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.linguafranca.pwdb.kdb;
18 |
19 | import com.google.common.io.ByteStreams;
20 | import org.linguafranca.pwdb.Credentials;
21 | import org.linguafranca.pwdb.security.Encryption;
22 | import org.bouncycastle.util.encoders.Hex;
23 |
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.security.MessageDigest;
27 |
28 | /**
29 | * Has inner classes representing credentials appropriate to KDB files
30 | *
31 | * @author jo
32 | */
33 | public interface KdbCredentials extends Credentials {
34 |
35 | /**
36 | * Password only credentials
37 | */
38 | class Password implements KdbCredentials {
39 |
40 | private final byte [] key;
41 |
42 | public Password(byte[] password) {
43 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
44 | this.key = md.digest(password);
45 | }
46 |
47 | @Override
48 | public byte[] getKey() {
49 | return key;
50 | }
51 | }
52 |
53 | /**
54 | * Key file credentials
55 | */
56 | class KeyFile implements KdbCredentials {
57 |
58 | private final byte[] key;
59 |
60 | public KeyFile(byte[] password, InputStream inputStream) {
61 | MessageDigest md = Encryption.getSha256MessageDigestInstance();
62 | byte[] pwKey = md.digest(password);
63 | md.update(pwKey);
64 |
65 | try {
66 | byte [] keyFileData = ByteStreams.toByteArray(inputStream);
67 | if (keyFileData.length == 64) {
68 | keyFileData = Hex.decode(keyFileData);
69 | key = md.digest(keyFileData);
70 | return;
71 | }
72 | throw new IllegalStateException("Invalid length key file " + keyFileData.length);
73 | } catch (IOException e) {
74 | throw new IllegalStateException("Could not read key file", e);
75 | }
76 | }
77 |
78 | @Override
79 | public byte[] getKey() {
80 | return this.key;
81 | }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Use the latest 2.1 version of CircleCI pipeline process engine.
2 | # See: https://circleci.com/docs/2.0/configuration-reference
3 | version: 2.1
4 |
5 | # Define a job to be invoked later in a workflow.
6 | # See: https://circleci.com/docs/2.0/configuration-reference/#jobs
7 | jobs:
8 | # Below is the definition of your job to build and test your app, you can rename and customize it as you want.
9 | build-and-test-8:
10 | # These next lines define a Docker executor: https://circleci.com/docs/2.0/executor-types/
11 | # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
12 | # Be sure to update the Docker image tag below to openjdk version of your application.
13 | # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/openjdk
14 | docker:
15 | - image: cimg/openjdk:8.0
16 | # Add steps to the job
17 | # See: https://circleci.com/docs/2.0/configuration-reference/#steps
18 | steps:
19 | # Checkout the code as the first step.
20 | - checkout
21 | # Use mvn clean and package as the standard maven build phase
22 | - run:
23 | name: Build
24 | command: mvn -B -DskipTests clean package
25 | # Then run your tests!
26 | - run:
27 | name: Test
28 | command: mvn -P inhibitConsoleOutput test
29 |
30 | build-and-test-11:
31 | # These next lines define a Docker executor: https://circleci.com/docs/2.0/executor-types/
32 | # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
33 | # Be sure to update the Docker image tag below to openjdk version of your application.
34 | # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/openjdk
35 | docker:
36 | - image: cimg/openjdk:11.0
37 | # Add steps to the job
38 | # See: https://circleci.com/docs/2.0/configuration-reference/#steps
39 | steps:
40 | # Checkout the code as the first step.
41 | - checkout
42 | # Use mvn clean and package as the standard maven build phase
43 | - run:
44 | name: Build
45 | command: mvn -B -DskipTests clean package
46 | # Then run your tests!
47 | - run:
48 | name: Test
49 | command: mvn -P inhibitConsoleOutput test
50 |
51 | # Invoke jobs via workflows
52 | # See: https://circleci.com/docs/2.0/configuration-reference/#workflows
53 | workflows:
54 | build-8-11: # This is the name of the workflow, feel free to change it to better match your workflow.
55 | # Inside the workflow, you define the jobs you want to run.
56 | jobs:
57 | - build-and-test-8
58 | - build-and-test-11
59 |
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue27Test.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.validation;
2 |
3 | import com.google.common.io.CharStreams;
4 | import org.junit.Ignore;
5 | import org.junit.Test;
6 | import org.linguafranca.pwdb.kdbx.Helpers;
7 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
8 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
9 | import org.linguafranca.pwdb.kdbx.KdbxSerializer;
10 | import org.linguafranca.pwdb.kdbx.jaxb.JaxbDatabase;
11 | import org.linguafranca.pwdb.kdbx.jaxb.JaxbEntry;
12 |
13 | import java.io.IOException;
14 | import java.io.InputStream;
15 | import java.io.InputStreamReader;
16 | import java.io.PrintStream;
17 | import java.nio.charset.StandardCharsets;
18 | import java.util.List;
19 |
20 | import static org.junit.Assert.assertEquals;
21 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
22 |
23 | public class Issue27Test {
24 | static PrintStream printStream = getTestPrintStream();
25 | /**
26 | * Check load of problem file
27 | */
28 | @Test
29 | public void testIssue27() throws IOException {
30 | InputStream is = this.getClass().getClassLoader().getResourceAsStream("issue-27/bogus-timestamp2.kdbx");
31 | KdbxCreds creds = new KdbxCreds("passwordless".getBytes());
32 | JaxbDatabase db = JaxbDatabase.load(creds, is);
33 | List extends JaxbEntry> entries = db.findEntries("testtitle");
34 |
35 | for (JaxbEntry entry: entries) {
36 | printStream.println(Helpers.fromDateV3(entry.getCreationTime()));
37 | assertEquals("2021-01-11T09:18:56Z", Helpers.fromDateV3(entry.getCreationTime()));
38 | }
39 | }
40 |
41 | /**
42 | * Verify that V4 dates are still processed correctly
43 | */
44 | @Test
45 | public void testV4Date() throws IOException {
46 | InputStream is = this.getClass().getClassLoader().getResourceAsStream("V4-AES-AES.kdbx");
47 | KdbxCreds creds = new KdbxCreds("123".getBytes());
48 | JaxbDatabase db = JaxbDatabase.load(creds, is);
49 | List extends JaxbEntry> entries = db.findEntries("Sample Entry #2 - Copy");
50 |
51 | for (JaxbEntry entry: entries) {
52 | printStream.println(Helpers.fromDate(entry.getCreationTime()));
53 | assertEquals("2018-01-26T13:20:58Z", Helpers.fromDateV3(entry.getCreationTime()));
54 | }
55 | }
56 |
57 | @Test @Ignore
58 | public void testIssue27XML() throws IOException {
59 |
60 | InputStream is = this.getClass().getClassLoader().getResourceAsStream("issue-27/bogus-timestamp2.kdbx");
61 | KdbxCreds creds = new KdbxCreds("passwordless".getBytes());
62 | InputStream plainText = KdbxSerializer.createUnencryptedInputStream(creds,new KdbxHeader(), is);
63 | printStream.println(CharStreams.toString(new InputStreamReader(plainText, StandardCharsets.UTF_8)));
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/simple/src/main/java/org/linguafranca/pwdb/kdbx/simple/converter/ValueConverter.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.simple.converter;
2 |
3 | import org.apache.commons.codec.binary.Base64;
4 | import org.linguafranca.pwdb.kdbx.simple.model.EntryClasses;
5 | import org.linguafranca.pwdb.security.StreamEncryptor;
6 | import org.simpleframework.xml.convert.Converter;
7 | import org.simpleframework.xml.stream.InputNode;
8 | import org.simpleframework.xml.stream.OutputNode;
9 |
10 | import java.nio.charset.StandardCharsets;
11 | import java.util.Objects;
12 |
13 | /**
14 | * Value converter takes care of encryption and decryption of protected fields
15 | */
16 | public class ValueConverter implements Converter {
17 |
18 | private final StreamEncryptor encryption;
19 |
20 | public ValueConverter(StreamEncryptor encryption) {
21 | this.encryption = encryption;
22 | }
23 |
24 | /**
25 | * De-serialise (unmarshal) the input node
26 | * @param node this is the node to deserialize the object from
27 | *
28 | * @return the de-serialised object
29 | */
30 | @Override
31 | public EntryClasses.StringProperty.Value read(InputNode node) throws Exception {
32 | EntryClasses.StringProperty.Value value = new EntryClasses.StringProperty.Value();
33 | if (Objects.nonNull(node.getAttribute("Protected")) && node.getAttribute("Protected").getValue().equals("True")) {
34 | byte[] encrypted = new byte[0];
35 | // you can only read the value once
36 | String text = node.getValue();
37 | if (Objects.nonNull(text)) {
38 | encrypted = Base64.decodeBase64(text.getBytes());
39 | }
40 | String decrypted = new String(encryption.decrypt(encrypted), StandardCharsets.UTF_8);
41 | value.setText(decrypted);
42 | value.setProtected(null);
43 | value.setProtectOnOutput(true);
44 | } else {
45 | value.setProtectOnOutput(false);
46 | value.setText(node.getValue());
47 | }
48 | return value;
49 | }
50 |
51 | /**
52 | * Serialise (marshal) the object
53 | * @param node this is the node to serialized the object to
54 | * @param value this is the value that is to be serialized
55 | */
56 | @Override
57 | public void write(OutputNode node, EntryClasses.StringProperty.Value value) throws Exception {
58 | if (value.getProtectOnOutput()) {
59 | byte [] encrypted = encryption.encrypt(value.getText().getBytes(StandardCharsets.UTF_8));
60 | byte [] base64Encoded = Base64.encodeBase64(encrypted);
61 | node.setValue(new String(base64Encoded));
62 | node.getAttributes().put("Protected", "True");
63 | } else {
64 | node.setValue(value.getText());
65 | }
66 | //node.getAttributes().remove("protectInMemory");
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/jaxb/bindings.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
22 |
23 |
24 |
28 |
29 |
30 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | This class, while generated, is not used see {@link
49 | org.linguafranca.pwdb.kdbx.jaxb.org.linguafranca.pwdb.base.AbstractJaxbParentedBinding} which is the
50 | actual implementation class.
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/example/src/main/java/org/linguafranca/pwdb/kdbx/ChooseFile.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx;
2 |
3 | import com.google.common.base.Strings;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import javax.swing.*;
8 | import javax.swing.filechooser.FileFilter;
9 | import java.io.*;
10 | import java.net.URL;
11 | import java.nio.charset.Charset;
12 | import java.nio.file.Files;
13 | import java.nio.file.Paths;
14 |
15 | import static org.linguafranca.pwdb.kdbx.Util.streamToString;
16 |
17 | /**
18 | * Utility to allow browsing of database files and listing content to console
19 | */
20 | public class ChooseFile {
21 |
22 | public static void main(String[] args) throws IOException {
23 | ChooseFile cf = new ChooseFile();
24 | cf.choose();
25 | }
26 |
27 | Logger logger = LoggerFactory.getLogger(this.getClass());
28 |
29 | public ChooseFile(){
30 |
31 | }
32 | public void choose() throws IOException {
33 | final JFileChooser fc = new JFileChooser();
34 | // get a file in the test resource directory
35 | URL resources = this.getClass().getClassLoader().getResource("kdb.key");
36 | try {
37 | fc.setCurrentDirectory(Paths.get(resources.toURI()).toFile());
38 | } catch (Exception e) {
39 | throw new RuntimeException(e);
40 | }
41 | fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
42 | fc.setFileFilter(new FileFilter() {
43 | @Override
44 | public boolean accept(File f) {
45 | return f.getName().endsWith(".kdbx");
46 | }
47 |
48 | @Override
49 | public String getDescription() {
50 | return "KDBX Database";
51 | }
52 | });
53 |
54 | int returnVal = fc.showOpenDialog(null);
55 | if (returnVal == JFileChooser.APPROVE_OPTION) {
56 | String s = (String)JOptionPane.showInputDialog(
57 | null,
58 | "Enter the password for " + fc.getSelectedFile().getName(),
59 | "Password",
60 | JOptionPane.PLAIN_MESSAGE,
61 | null,
62 | null,
63 | "123");
64 | if (Strings.isNullOrEmpty(s)) {
65 | return;
66 | }
67 | logger.info("Opening {}", fc.getSelectedFile().getPath());
68 | try (InputStream is = Files.newInputStream(Paths.get(fc.getSelectedFile().getPath()))) {
69 | InputStream ss = KdbxSerializer.createUnencryptedInputStream(new KdbxCreds(s.getBytes()), new KdbxHeader(), is);
70 | System.out.println(streamToString(ss));
71 | System.out.println();
72 | System.out.flush();
73 | }
74 | /* try (InputStream is = Files.newInputStream(Paths.get(fc.getSelectedFile().getPath()))) {
75 | HexViewer.list(is);
76 | }*/
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonDatabaseLoadTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import java.io.InputStream;
19 | import java.io.PrintStream;
20 |
21 | import org.junit.Test;
22 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
23 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
24 |
25 | import static org.linguafranca.test.util.TestUtil.getTestPrintStream;
26 |
27 | public class JacksonDatabaseLoadTest {
28 |
29 | static PrintStream printStream = getTestPrintStream();
30 |
31 |
32 | @Test
33 | public void loadXml() throws Exception {
34 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("ExampleDatabase.xml");
35 | JacksonDatabase database = JacksonDatabase.loadXml(inputStream);
36 | database.visit(new Visitor.Print(printStream));
37 | }
38 | @Test
39 | public void loadKdbx() throws Exception {
40 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test123.kdbx");
41 | JacksonDatabase database = JacksonDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
42 | database.visit(new Visitor.Print(printStream));
43 | }
44 |
45 | @Test
46 | public void loadKdbxV4() throws Exception {
47 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("V4-AES-Argon2.kdbx");
48 | JacksonDatabase database = JacksonDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
49 | database.visit(new Visitor.Print(printStream));
50 | // test what happens to dates in V4
51 | database.visit(new Visitor.Default(){
52 | @Override
53 | public void visit(Entry entry) {
54 | printStream.println(entry.getCreationTime());
55 | }
56 | });
57 | }
58 |
59 | @Test
60 | public void emptyDb() throws Exception {
61 | JacksonDatabase database = new JacksonDatabase();
62 | printStream.println(database.getDescription());
63 | }
64 |
65 | @Test
66 | public void dbWithDeleted() throws Exception {
67 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("testDeleted.kdbx");
68 | JacksonDatabase database = JacksonDatabase.load(new KdbxCreds("123".getBytes()), inputStream);
69 | database.visit(new Visitor.Print(printStream));
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/example/src/test/java/org/linguafranca/pwdb/kdbx/validation/Issue33Test.java:
--------------------------------------------------------------------------------
1 | package org.linguafranca.pwdb.kdbx.validation;
2 |
3 |
4 | import org.junit.Before;
5 | import org.junit.BeforeClass;
6 | import org.junit.Test;
7 | import org.linguafranca.pwdb.Credentials;
8 | import org.linguafranca.pwdb.StreamFormat;
9 | import org.linguafranca.pwdb.kdbx.Helpers;
10 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
11 | import org.linguafranca.pwdb.kdbx.Util;
12 | import org.linguafranca.pwdb.kdbx.dom.DomDatabaseWrapper;
13 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
14 | import org.linguafranca.pwdb.kdbx.jaxb.JaxbDatabase;
15 | import org.linguafranca.pwdb.kdbx.simple.SimpleDatabase;
16 |
17 | import java.io.*;
18 | import java.nio.file.Files;
19 | import java.nio.file.Paths;
20 |
21 | /**
22 | * Review Issue-33 https://github.com/jorabin/KeePassJava2/issues/33
23 | */
24 | public class Issue33Test {
25 |
26 | public static final String TEST_RESOURCE = "V4-AES-Argon2-CustomIcon.kdbx";
27 | public static final String TEST_OUTPUT_DIR = "testOutput";
28 | public static final File TEST_XML_FILE = Paths.get(TEST_OUTPUT_DIR,"Issue33Source.xml").toFile();
29 | public static final KdbxCreds CREDENTIALS = new KdbxCreds("123".getBytes());
30 |
31 |
32 | InputStream inputStream;
33 |
34 | @BeforeClass
35 | public static void listXml() throws IOException {
36 | Files.createDirectories(Paths.get(TEST_OUTPUT_DIR));
37 | Util.listXml(TEST_RESOURCE, CREDENTIALS, new PrintWriter(TEST_XML_FILE));
38 | Helpers.isV4.set(true);
39 | }
40 |
41 | @Before
42 | public void refreshInputStream() {
43 | inputStream = this.getClass().getClassLoader().getResourceAsStream(TEST_RESOURCE);
44 | }
45 |
46 | @Test
47 | public void testDomDatabaseWrapper() throws IOException {
48 | DomDatabaseWrapper database = DomDatabaseWrapper.load(CREDENTIALS, inputStream);
49 | database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Dom.xml")));
50 | }
51 |
52 | @Test
53 | public void testJaxbDatabase() throws IOException {
54 | JaxbDatabase database = JaxbDatabase.load(CREDENTIALS, inputStream);
55 | database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Jaxb.xml")));
56 | }
57 |
58 | @Test
59 | public void testSimpleDatabase() throws IOException {
60 | SimpleDatabase database = SimpleDatabase.load(CREDENTIALS, inputStream);
61 | database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Simple.xml")));
62 | }
63 |
64 | @Test
65 | public void testJacksonDatabase() throws IOException {
66 | JacksonDatabase database = JacksonDatabase.load(CREDENTIALS, inputStream);
67 | database.save(new StreamFormat.None(), new Credentials.None(), Files.newOutputStream(Paths.get(TEST_OUTPUT_DIR, "Issue33Jackson.xml")));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/jackson/src/main/java/org/linguafranca/pwdb/kdbx/jackson/converter/ValueDeserializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb.kdbx.jackson.converter;
17 |
18 | import com.fasterxml.jackson.core.JsonParser;
19 | import com.fasterxml.jackson.databind.DeserializationContext;
20 | import com.fasterxml.jackson.databind.JsonNode;
21 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
22 | import org.apache.commons.codec.binary.Base64;
23 | import org.linguafranca.pwdb.Database;
24 | import org.linguafranca.pwdb.PropertyValue;
25 | import org.linguafranca.pwdb.kdbx.Helpers;
26 | import org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses;
27 | import org.linguafranca.pwdb.security.StreamEncryptor;
28 |
29 | import java.io.IOException;
30 | import java.nio.charset.StandardCharsets;
31 |
32 | public class ValueDeserializer extends StdDeserializer {
33 |
34 | private final StreamEncryptor encryptor;
35 | private final PropertyValue.Strategy strategy;
36 |
37 | public ValueDeserializer(StreamEncryptor encryptor, PropertyValue.Strategy strategy) {
38 | super(ValueDeserializer.class);
39 | this.encryptor = encryptor;
40 | this.strategy = strategy;
41 | }
42 |
43 | @Override
44 | public PropertyValue deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
45 |
46 | JsonNode node = p.getCodec().readTree(p);
47 |
48 | if (node.isTextual()) {
49 | return strategy.newUnprotected().of(node.textValue());
50 | }
51 |
52 | if (node.isObject()) {
53 | // TODO not clear what is happening here, looks like it's not exactly correct
54 | //We need to decrypt all Protected values
55 | String cipherText = "";
56 | if (node.has("")) {
57 | cipherText = node.get("").asText();
58 | }
59 |
60 | if (node.has("Protected") && Boolean.TRUE.equals(Helpers.toBoolean(node.get("Protected").asText()))) {
61 | //Decode to byte the Base64 text
62 | byte[] encrypted = Base64.decodeBase64(cipherText.getBytes());
63 | byte[] decrypted = encryptor.decrypt(encrypted);
64 | return strategy.newProtected().of(decrypted);
65 | }
66 | return strategy.newUnprotected().of(cipherText);
67 | }
68 |
69 | throw new IllegalStateException("Error parsing XML node type is " + node.getClass());
70 | }
71 | }
--------------------------------------------------------------------------------
/jackson/src/test/java/org/linguafranca/pwdb/JacksonSaveAndReloadTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Giuseppe Valente
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.linguafranca.pwdb;
17 |
18 | import static org.junit.Assert.assertTrue;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.OutputStream;
23 |
24 | import org.linguafranca.pwdb.checks.SaveAndReloadChecks;
25 | import org.linguafranca.pwdb.kdbx.KdbxCreds;
26 | import org.linguafranca.pwdb.kdbx.KdbxHeader;
27 |
28 | import org.linguafranca.pwdb.kdbx.jackson.JacksonDatabase;
29 | import org.linguafranca.pwdb.kdbx.jackson.JacksonEntry;
30 | import org.linguafranca.pwdb.kdbx.jackson.JacksonGroup;
31 | import org.linguafranca.pwdb.kdbx.jackson.JacksonIcon;
32 |
33 |
34 | public class JacksonSaveAndReloadTest extends SaveAndReloadChecks{
35 |
36 | @Override
37 | public JacksonDatabase getDatabase() {
38 | try {
39 | return new JacksonDatabase();
40 | } catch(Exception e) {
41 | return null;
42 | }
43 |
44 | }
45 |
46 | @Override
47 | public JacksonDatabase getDatabase(String name, Credentials credentials) throws IOException {
48 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream(name);
49 | return JacksonDatabase.load(credentials, inputStream);
50 | }
51 |
52 | @Override
53 | public void saveDatabase(JacksonDatabase database, Credentials credentials, OutputStream outputStream) throws IOException {
54 | database.save(credentials, outputStream);
55 | }
56 |
57 | @Override
58 | public JacksonDatabase loadDatabase(Credentials credentials, InputStream inputStream) throws IOException {
59 | return JacksonDatabase.load(credentials, inputStream);
60 | }
61 |
62 |
63 | @Override
64 | public boolean verifyStreamFormat(StreamFormat s1, StreamFormat s2) {
65 | KdbxHeader h1 = (KdbxHeader) s1.getStreamConfiguration();
66 | KdbxHeader h2 = (KdbxHeader) s1.getStreamConfiguration();
67 | return (h1.getVersion() == h2.getVersion() &&
68 | h1.getProtectedStreamAlgorithm().equals(h2.getProtectedStreamAlgorithm()) &&
69 | h1.getKeyDerivationFunction().equals(h2.getKeyDerivationFunction()) &&
70 | h1.getCipherAlgorithm().equals(h2.getCipherAlgorithm()));
71 | }
72 |
73 |
74 | @Override
75 | public Credentials getCreds(byte[] creds) {
76 | return new KdbxCreds(creds);
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------