jorabin / KeePassJava2

Java API for KeePass Password Databases - Read/Write 2.x (File versions 3 and 4), Read 1.x
Apache License 2.0
251 stars 70 forks source link

Unparseable date #27

Closed robertvazan closed 1 year ago

robertvazan commented 3 years ago

I am getting this exception when parsing KDBX 3.1 file that was edited (loaded, modified, saved) by pykeepass:

Caused by: java.lang.IllegalStateException: java.text.ParseException: Unparseable date: "2021-01-02T03:31:49.386013+00:00"
    at org.linguafranca.pwdb.kdbx.Helpers.toDate(Helpers.java:83)
    at org.linguafranca.pwdb.kdbx.simple.converter.TimeConverter.read(TimeConverter.java:36)
    at org.linguafranca.pwdb.kdbx.simple.converter.TimeConverter.read(TimeConverter.java:29)
    ...
    at org.linguafranca.pwdb.kdbx.simple.SimpleDatabase.load(SimpleDatabase.java:192)
    ...

KeePassJava2 expects timestamps to match format yyyy-MM-dd'T'HH:mm:ss'Z'.

So which implementation of the format is wrong, pykeepass or KeePassJava2?

KeePassX opens the file without error and displays the timestamps correctly.

jorabin commented 3 years ago

Interesting, not seen before as far as I know, which means:

1) Keepass itself only generates timestamps of the format yyyy-MM-dd'T'HH:mm:ss'Z' 2) If Keepass itself opens such files without error then I guess other implementations should too, since that is the only measure by which one can measure conformance - what KeepassX does is maybe immaterial to that since it is not definitive. 3) as to which is wrong, I would call on the old dictum: "be strict in your production and be generous in your consumption" so pykeepass is wrong, but KeePassJava2 should (maybe) accommodate incorrect implementations, but only if the original KeePass does.

Please attach an example of such a file, without which it won't be possible to make progress on this. Better still, propose a fix.

Jo

robertvazan commented 3 years ago

Here's an example KDBX file that was created in KeePassX and then edited with pykeepass, which added single entry.

timestamp_test.zip

Password is 'passwordless'.

Evidlo commented 3 years ago

This is the date format returned by Python's date.isoformat(). While there is no Keepass spec, there is an unofficial one here, which claims that datetimes should be in one of the ISO8601 formats.

jorabin commented 3 years ago

That's a nice piece of documentation.

For many of the motivations discussed there I also created various pieces of documentation which you may have read in familiarising with this project. In particular I created an XSD (XML Schema, a formal definition of XML in XML).

The format defined in that file says "This is ISO Date time stored as UTC (Z time zone)", which like the other definition is based on observation, rather than scrutiny of the C# code for KeePass, which hitherto has not been necessary.

I'll have a look at the file you attached in an earlier comment later.

jorabin commented 3 years ago

Hi @robertvazan

Your file doesn't demonstrate the problem. Here's its XML: scratch_1.xml.zip

All the timestamps are in the "correct" format, did you attach the wrong file?

robertvazan commented 3 years ago

Sorry. I didn't test the last file. This one definitely causes the exception:

bogus-timestamp.zip

I am using KeePassJava2 2.1.4 from Maven Central and I am getting this exception:

Caused by: java.lang.IllegalStateException: java.text.ParseException: Unparseable date: "2021-01-11T09:18:56.769557+00:00"
    at org.linguafranca.pwdb.kdbx.Helpers.toDate(Helpers.java:83)
    at org.linguafranca.pwdb.kdbx.simple.converter.TimeConverter.read(TimeConverter.java:36)
    at org.linguafranca.pwdb.kdbx.simple.converter.TimeConverter.read(TimeConverter.java:29)
    at org.simpleframework.xml.convert.AnnotationStrategy.read(AnnotationStrategy.java:126)
    ...
    at org.simpleframework.xml.core.Persister.read(Persister.java:444)
    at org.linguafranca.pwdb.kdbx.simple.SimpleDatabase.load(SimpleDatabase.java:192)

Password is "passwordless".

jorabin commented 1 year ago

Format allowed now looser, hope that's useful ...

jorabin commented 1 year ago

Closed in 2.2.1