oydid 0.6.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/oydid/basic.rb +29 -1
- data/lib/oydid/log.rb +27 -7
- data/lib/oydid.rb +319 -92
- data/spec/fixtures/multi_hash_legacy.json +1766 -0
- data/spec/oydid_spec.rb +130 -0
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e119ee021cb7e09dd4c7ee6273a4ee778bae850e31b6360a31044c11e674df4c
|
|
4
|
+
data.tar.gz: 9be71c4690f1e6476c6a339a49172575eac79c11406c6a1ac8a49e66c804ee6e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa57e8c74580e2afa7e6adae48528fd8d43fd306176eb9039a1531c9db46c0090702eef2d036ddaee3aef09e568ef8ad2714c990e6745b2dff4ed080d5e18874
|
|
7
|
+
data.tar.gz: 4608b92f08da163850832144c89a9495c182a065155727a8d10bacb83ee00fd47951b442420e9ee24582a5804938349e55649b57fe0e699082aa3311fbc57729
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.8.0
|
data/lib/oydid/basic.rb
CHANGED
|
@@ -35,6 +35,9 @@ class Oydid
|
|
|
35
35
|
|
|
36
36
|
def self.multi_hash(message, options)
|
|
37
37
|
method = options[:digest] || DEFAULT_DIGEST
|
|
38
|
+
# only set within the case statement for digests that are not looked up
|
|
39
|
+
# in the multicodec registry (see BLAKE2B_EXTRA_CODES)
|
|
40
|
+
code = nil
|
|
38
41
|
case method.to_s
|
|
39
42
|
when "sha2-256"
|
|
40
43
|
digest = RbNaCl::Hash.sha256(message)
|
|
@@ -44,6 +47,11 @@ class Oydid
|
|
|
44
47
|
digest = OpenSSL::Digest.digest(method, message)
|
|
45
48
|
when "blake2b-16"
|
|
46
49
|
digest = RbNaCl::Hash.blake2b(message, {digest_size: 16})
|
|
50
|
+
when "blake2b-17", "blake2b-18", "blake2b-19", "blake2b-20",
|
|
51
|
+
"blake2b-21", "blake2b-22", "blake2b-23"
|
|
52
|
+
digest_size = method.to_s.split("-").last.to_i
|
|
53
|
+
digest = RbNaCl::Hash.blake2b(message, {digest_size: digest_size})
|
|
54
|
+
code = BLAKE2B_EXTRA_CODES[digest_size]
|
|
47
55
|
when "blake2b-32"
|
|
48
56
|
digest = RbNaCl::Hash.blake2b(message, {digest_size: 32})
|
|
49
57
|
when "blake2b-64"
|
|
@@ -51,7 +59,7 @@ class Oydid
|
|
|
51
59
|
else
|
|
52
60
|
return [nil, "unsupported digest: '" + method.to_s + "'"]
|
|
53
61
|
end
|
|
54
|
-
code = Multicodecs[method].code
|
|
62
|
+
code = Multicodecs[method].code if code.nil?
|
|
55
63
|
length = digest.bytesize
|
|
56
64
|
encoded = multi_encode([code, length, digest].pack("CCa#{length}"), options)
|
|
57
65
|
# encoded = multi_encode(Multihashes.encode(digest, method.to_s), options)
|
|
@@ -80,6 +88,13 @@ class Oydid
|
|
|
80
88
|
return ["blake2b-64", ""]
|
|
81
89
|
else
|
|
82
90
|
code, length, digest = decoded_message.unpack('CCa*')
|
|
91
|
+
# intermediate BLAKE2b sizes carry a code outside the multicodec
|
|
92
|
+
# registry; require the length byte to match so a stray code
|
|
93
|
+
# cannot be mistaken for one of them
|
|
94
|
+
blake2b_size = BLAKE2B_EXTRA_CODES.key(code)
|
|
95
|
+
if !blake2b_size.nil? && length == blake2b_size
|
|
96
|
+
return ["blake2b-" + blake2b_size.to_s, ""]
|
|
97
|
+
end
|
|
83
98
|
retVal = Multicodecs[code].name rescue nil
|
|
84
99
|
if !retVal.nil?
|
|
85
100
|
return [retVal, ""]
|
|
@@ -1264,6 +1279,19 @@ class Oydid
|
|
|
1264
1279
|
doc_hash = doc_hash.split(LOCATION_PREFIX).first.split(CGI.escape LOCATION_PREFIX).first rescue doc_hash
|
|
1265
1280
|
doc_hash = doc_hash.delete_prefix("did:oyd:")
|
|
1266
1281
|
|
|
1282
|
+
# in-process callers (e.g. a repository holding DIDs in its own database)
|
|
1283
|
+
# can supply a store object responding to #get(doc_hash) that returns
|
|
1284
|
+
# {"doc" => <did document>, "log" => [<log entries>]} or nil. Unlike
|
|
1285
|
+
# options[:local_doc] this resolves *per hash*: dag_update walks several
|
|
1286
|
+
# different documents along an update chain, so a single document must
|
|
1287
|
+
# not be handed back for every hash it asks for.
|
|
1288
|
+
if options[:local_store]
|
|
1289
|
+
local_obj = options[:local_store].get(doc_hash)
|
|
1290
|
+
if !local_obj.nil?
|
|
1291
|
+
return [local_obj, ""]
|
|
1292
|
+
end
|
|
1293
|
+
end
|
|
1294
|
+
|
|
1267
1295
|
if doc_location == ""
|
|
1268
1296
|
doc_location = DEFAULT_LOCATION
|
|
1269
1297
|
end
|
data/lib/oydid/log.rb
CHANGED
|
@@ -297,7 +297,10 @@ class Oydid
|
|
|
297
297
|
did_hash = did_hash.split(LOCATION_PREFIX).first.split(CGI.escape LOCATION_PREFIX).first
|
|
298
298
|
did10 = did_hash[0,10]
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
# pass options through: without them options[:local_store] is lost
|
|
301
|
+
# and the lookup falls back to HTTP against DEFAULT_LOCATION, which
|
|
302
|
+
# breaks every in-process caller that keeps its DIDs locally
|
|
303
|
+
doc = retrieve_document_raw(doc_did, did10 + ".doc", doc_location, options)
|
|
301
304
|
if doc.first.nil?
|
|
302
305
|
currentDID["error"] = 2
|
|
303
306
|
msg = doc.last.to_s
|
|
@@ -309,13 +312,27 @@ class Oydid
|
|
|
309
312
|
end
|
|
310
313
|
doc = doc.first["doc"]
|
|
311
314
|
if el["op"] == 2 # CREATE
|
|
312
|
-
# signature
|
|
313
|
-
|
|
314
|
-
|
|
315
|
+
# The CREATE signature used to be unobtainable in the
|
|
316
|
+
# Client-Managed-Secret-Mode: its payload l1_doc is the hash
|
|
317
|
+
# of a DID document that already contains the TERMINATE
|
|
318
|
+
# signature, so it can only be collected in a phase of its
|
|
319
|
+
# own. CMSM has that phase now and new DIDs always carry the
|
|
320
|
+
# signature - but DIDs created before it do not, and
|
|
321
|
+
# rejecting them would make them unresolvable.
|
|
322
|
+
#
|
|
323
|
+
# The check is therefore tolerant by default and strict on
|
|
324
|
+
# request: a relying party that only accepts DIDs created
|
|
325
|
+
# with a signed CREATE entry sets options[:strict_create_sig].
|
|
326
|
+
if el["sig"].nil?
|
|
327
|
+
if options[:strict_create_sig]
|
|
315
328
|
currentDID["error"] = 1
|
|
316
|
-
currentDID["message"] = "
|
|
329
|
+
currentDID["message"] = "missing signature in CREATE log entry"
|
|
317
330
|
return currentDID
|
|
318
331
|
end
|
|
332
|
+
elsif !match_log_did?(el, doc)
|
|
333
|
+
currentDID["error"] = 1
|
|
334
|
+
currentDID["message"] = "Signatures in log don't match"
|
|
335
|
+
return currentDID
|
|
319
336
|
end
|
|
320
337
|
end
|
|
321
338
|
currentDID["did"] = doc_did
|
|
@@ -353,7 +370,10 @@ class Oydid
|
|
|
353
370
|
did_hash = doc_did.delete_prefix("did:oyd:")
|
|
354
371
|
did_hash = did_hash.split(LOCATION_PREFIX).first.split(CGI.escape LOCATION_PREFIX).first
|
|
355
372
|
did10 = did_hash[0,10]
|
|
356
|
-
|
|
373
|
+
# pass options through: without them options[:local_store] is lost
|
|
374
|
+
# and the lookup falls back to HTTP against DEFAULT_LOCATION, which
|
|
375
|
+
# breaks every in-process caller that keeps its DIDs locally
|
|
376
|
+
doc = retrieve_document_raw(doc_did, did10 + ".doc", doc_location, options)
|
|
357
377
|
doc = doc.first["doc"]
|
|
358
378
|
|
|
359
379
|
if !Oydid.match_log_did?(el, doc)
|
|
@@ -479,7 +499,7 @@ class Oydid
|
|
|
479
499
|
next_did_hash = next_doc_did.delete_prefix("did:oyd:")
|
|
480
500
|
next_did_hash = next_did_hash.split(LOCATION_PREFIX).first.split(CGI.escape LOCATION_PREFIX).first
|
|
481
501
|
next_did10 = next_did_hash[0,10]
|
|
482
|
-
next_doc = retrieve_document_raw(next_doc_did, next_did10 + ".doc", next_doc_location,
|
|
502
|
+
next_doc = retrieve_document_raw(next_doc_did, next_did10 + ".doc", next_doc_location, options)
|
|
483
503
|
if next_doc.first.nil?
|
|
484
504
|
currentDID["error"] = 2
|
|
485
505
|
currentDID["message"] = next_doc.last
|