Module: Clickwrap::CanonicalJson
- Defined in:
- lib/clickwrap/canonical_json.rb
Overview
Canonical JSON serialization, implementing the JSON Canonicalization Scheme (RFC 8785, https://www.rfc-editor.org/rfc/rfc8785).
Receipts are digested and verified by code that may be years newer than the code that wrote them, and by verifiers written in other languages. So the bytes have to be reproducible from the data alone: no Ruby object serialization, no YAML, no hash insertion order, no database column order, no locale-dependent number formatting.
The Clickwrap profile adds a few rules on top of RFC 8785, applied by the callers in ReceiptSchema rather than here:
* timestamps are UTC strings with exactly six fractional digits;
* digests are "<algorithm>:<lowercase hex>" strings;
* identifiers are strings, never numbers;
* a value that was never collected is an explicit state object, never
`null` and never a missing key that could mean either; and
* host extensions use keys prefixed `x_`.
Defined Under Namespace
Classes: SerializationError
Constant Summary collapse
- MAX_EXACT_INTEGER =
Integers above this magnitude cannot survive a round trip through the IEEE 754 double that RFC 8785 assumes, so serializing one would produce bytes another verifier could not reproduce.
(2**53) - 1
- ESCAPES =
{ "\b" => "\\b", "\t" => "\\t", "\n" => "\\n", "\f" => "\\f", "\r" => "\\r", '"' => '\\"', "\\" => "\\\\" }.freeze
Class Method Summary collapse
-
.canonical?(json_text) ⇒ Boolean
True when
json_textis already in canonical form. -
.canonicalize(json_text) ⇒ Object
Parses JSON text and returns the canonical bytes for it.
-
.generate(value) ⇒ Object
(also: dump)
Returns the canonical UTF-8 JSON bytes for
value.
Class Method Details
.canonical?(json_text) ⇒ Boolean
True when json_text is already in canonical form.
60 61 62 63 64 |
# File 'lib/clickwrap/canonical_json.rb', line 60 def canonical?(json_text) canonicalize(json_text) == json_text rescue JSON::ParserError, SerializationError false end |
.canonicalize(json_text) ⇒ Object
Parses JSON text and returns the canonical bytes for it. Useful for verifying a receipt that arrived as arbitrarily formatted JSON.
55 56 57 |
# File 'lib/clickwrap/canonical_json.rb', line 55 def canonicalize(json_text) generate(JSON.parse(json_text)) end |
.generate(value) ⇒ Object Also known as: dump
Returns the canonical UTF-8 JSON bytes for value.
45 46 47 48 49 |
# File 'lib/clickwrap/canonical_json.rb', line 45 def generate(value) buffer = +"" write(value, buffer) buffer.force_encoding(Encoding::UTF_8) end |