jansupol / jsonbapi

0 stars 0 forks source link

ES6 Compatible Parsing & Serialization #50

Open jansupol opened 7 years ago

jansupol commented 7 years ago

ES6 (EcmaScript version 6) and forward specifies very specific rules for serialization including "predictive property" order. This may appear strange but for a human creating the properties A, B, C and getting them serialized as A, C, B is slightly awkward, although completely compatible with JSON.

In addition, ES6 also specifies strict rules for serializing numbers which are quite different from what native Java does.

Anyway, a huge advantage with ES6 parsing and serialization is that it makes it possible creating very elegant "crypto safe" objects as described here: https://cyberphone.github.io/doc/security/jsonsignatures.html

This is currently supported by an open source library of mine (https://github.com/cyberphone/openkeystore#openkeystore) but it would be even cooler if ES6 compatible parsing and serialization would be a part of JSON-B or at least of your reference implementation. This should be coordinated with your JavaScript engine since the very same scheme must be running there already.

jansupol commented 6 years ago
jansupol commented 6 years ago

@rmannibucau Commented Default is the lexicographic order. However you can use https://github.com/javaee/jsonb-spec/blob/master/api/src/main/java/javax/json/bind/annotation/JsonbPropertyOrder.java to fit your need.

jansupol commented 6 years ago

@cyberphone Commented This issue is actually a bit flawed (dated) because ES6 compatible JSON serialization consists of two entirely different things:

https://tools.ietf.org/id/draft-erdtman-jose-cleartext-jws-00.html depends on both features.

Predictive property ordering a la ES6 requires something like: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html. Is that achievable through the various Java/JSON APIs? Bear with me, I'm unarguable NOT an expert on those.

JSON Number serialization is an awkward chapter, not even JDK's JavaScript engine (Nashorn) follows the ECMAScript standard. MSFT is currently working on getting their counterpart ES6 compatible.

jansupol commented 6 years ago

@rmannibucau Commented Hmm, parsing is not (and must not actually to respect the mapping side of the spec) affected at jsonp or jsonb level since it is a bean matching which is done so we are all good.

Ordering is deterministic and predictable as mentionned in previous mail and should in any case be enforced by the user if needed with the related API (order annotation).

The primitive serialization is handled by json-p accoring to json spec.

jansupol commented 6 years ago

@cyberphone Commented For enveloped clear text signatures based on ES6 rules, parsing and serialization are closely intertwined. In retrospect I've noted that this complicates the implementation in many JSON APIs, which is why I nowadays rather advocate for using traditional canonicalization, like in XML DSig but way simpler: https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html

It would be interesting hearing your opinion on this matter because a draft is just a draft :-)

jansupol commented 6 years ago

@rmannibucau Commented I strongly think we can't change the defaults since they really match today's way of working. However JSON-P (I don't think JSON-B is affected) can get a flag you pass to the generator factory to normalize the data. Would make sense. Then JSON-B would just passtrough the flag.

jansupol commented 6 years ago

@cyberphone Commented

I strongly think we can't change the defaults since they really match today's way of working

For my poor understanding only: Does this mean that the Java APIs in question by default are unable parsing JSON Numbers or JSON Strings produced by Browsers and Node.js?

jansupol commented 6 years ago

@rmannibucau Commented No, it works well. It just means that normalizing everything is not good since current representation - which is stable/deterministic - is already in used and what is used and mainstream.

jansupol commented 6 years ago

@cyberphone Commented That was what I expected. This also means that if the serialization API (JSON-P?) would be enhanced with ES6 compliant serialization of Strings and Numbers (for ints, floats and doubles only NB) as default, nothing would/should change/break with respect to the User Community. Such code is readily available.

The remaining hurdle (property ordering), would in your case already be fixed (-minus some minor spec work) if the IETF signature scheme in the workings, would be revised to rather depend of lexicographic than on predictive ordering.

Well, there is this I-JSON thing as well, but as shown by the following Twitter message

{"id": 10765432100123456789, "id_str": "10765432100123456789", ...}

the industry have already found "solutions" 😂

jansupol commented 6 years ago

@cyberphone Commented Oops! I just found a (for the mentioned application only) breaking issue:

4.2 Customizing Property Order To customize the order of serialized properties only for one specific type, JSON Binding provides javax.json.bind.annotation.JsonbPropertyOrder annotation. Order specified by JsonbPropertyOrder annotation overrides order specified by PropertyOrderStrategy

Here is the "problem": https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html#json.wireformat

jansupol commented 6 years ago

@cyberphone Commented After chatting with @rmannibucau on IRC it became clear that changing default serialization of numbers to match ES6 is unrealistic since there are systems out there relying on JSON-P's specific formatting.

That effectively leaves us (me) with a single option: Add an item CANONICALIZED to the PropertyOrderStrategy set which implies the following: