CBOR.js and the "CBOR" object

Although CBOR is supported by all main-stream browsers (for WebAuthn), there is AFAIK still no public API. Something along these lines seems possible: https://github.com/cyberphone/CBOR.js#cborjs

One of the core ideas behind this particular take on the matter is defining a CBOR profile that could be adopted by other software platforms as well in order to avoid the chaos with JSON where Oracle and Microsoft use different approaches for encoding integers outside of Number.

IMHO this belongs on the Web platform first, maybe with WinterCG's awareness. Then once it gains serious adoption, it could make sense to bring it to the native language.

Importantly, most the speed-ups don't truly need engine support to accomplish:

  • Most engines already provide an optimized string-from-UTF-8 API. Embedders could use that for their string creation
  • Binary values could trivially be memcpy'd
  • Integer types are all accelerated.

There's also the issue of how to decode CBOR maps. WebAuthn decodes them to objects, while the CBOR spec allows keys to be of arbitrary type.

Thanx Claudia, I was not aware of https://wintercg.org/ which seems like a very appropriate forum for a CBOR API for JavaScript. It is now easy to evaluate in Node.js as well:
https://www.npmjs.com/package/cbor-object

Regarding the CBOR used in WebAuthn, the CBOR object handles this as well as anything else in the CBOR spec. by using an object wrapping model. Some people have issues with this concept, but CBOR doesn't map to JavaScript in the same way as JSON.

// Retrieve the COSE public key from a WebAuthn "create" response using the "CBOR" object.

let attestationObject = "o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEgwRgIhAJAtFeK1V\
q7p3Ca831Cj7_VtDkJDfCmegT9ta0MTmhOLAiEA8DH0c3HHmJ-jZzM3yUBOxpCc-rKuhQ2w-M9qL7d\
YVptjeDVjgVkCTjCCAkowggEyoAMCAQICBBJKcv4wDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjW\
XViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAwWhgPMjA1MDA\
5MDQwMDAwMDBaMCwxKjAoBgNVBAMMIVl1YmljbyBVMkYgRUUgU2VyaWFsIDI0OTQxNDk3MjE1ODBZM\
BMGByqGSM49AgEGCCqGSM49AwEHA0IABD2LG70vy_YIbhB0cWAUaEhBU8HG07S2il6FXm5AdX7iK82\
JiL8779fN8hywv116FQ2ESv6YEDxsZgfZ-q4ofAKjOzA5MCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40L\
jEuNDE0ODIuMS4xMBMGCysGAQQBguUcAgEBBAQDAgUgMA0GCSqGSIb3DQEBCwUAA4IBAQChTx7qAHb\
2uEdqEKK-cuYNAnG7Rlst-_x8G9EtNRmJkXAyYx15XQl_owomoyVjToVyG8LQGoYwP2vAdeWZcxnhI\
hSLBJbuyNH0-Uz0EQ3mJsKJRD0fD1u7I5yhPoHR1aqd9a-ONhJkdb_COvBigxVyUnYv9oh5vPDvV41\
V1n-VG08ytjyK6lsPmcZ9fYFKf_Wm9S34PolKOl2ci4Ln-LyNr0yAF1_4ly_aeTM-xGXYBurMlI8bq\
yIEWpVVikjCAibawAPUH7yeBeooprteEKSd4GCgpPaiZ2o01oxKvoxhh0NVuQJ-goyp4GSwAtYujYz\
wdEkhdT0148h8XVd5RT53aGF1dGhEYXRhWMQpKq1f5ajcmlZCmysIZPaRJNEdlha6g3LgxNIVM3vlv\
UEAAAAAAAAAAAAAAAAAAAAAAAAAAABAW0wCAz7PAtQy-TxtfW_IeycCXoC9rhItgvbC24Hpjmigqeb\
3nZ2DaYCVpGQ3Tzs2kTUiam2F2zhMx40FQTYGYaUBAgMmIAEhWCCIx4IAYlx5O68bwCKgnuzQZ8MN5\
PiN4B9ikm7oukKeYyJYIHZR6JW3eKPDxVXDjlZ6Qpnq55jUYqhKoqTrwtZqvvTP";

// FIDO attestations have a weird (entirely non-standard) binary format...
let authData = CBOR.decode(CBOR.fromBase64Url(attestationObject))
	.get(CBOR.String("authData")).getBytes();
let pubKeyOffset = 55 + (authData[53] << 8) + authData[54];
let pubKeyBinary = authData.slice(pubKeyOffset, authData.length);

// Note: the CBOR data is a sequence, requiring the "extended" decoding scheme.
console.log(CBOR.decodeExtended(CBOR.initExtended(pubKeyBinary, true, false)).toString());

This code can be tested in a browser debug console after invoking: https://cyberphone.github.io/CBOR.js/doc/playground.html

It would be nice to get some feedback on this API, and in particular the wrapper concept.

Apparently the WinterCG is not a proper home for the CBOR object:
https://lists.w3.org/Archives/Public/public-wintercg/2023Mar/0000.html

The group is quite active; it's just that in 2023 few people conduct their activity on mailing lists :-)

2 Likes

Read the reply to that - they're very active...in WinterCG ยท GitHub