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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8b1fc642be72b8b9a92b137f995360b5d4e68742b5a9744b59b3e88649976bb
4
- data.tar.gz: 291e766737dec1b5756de3408097f5f243b02d3119ab3be2a29444957e82e9af
3
+ metadata.gz: e119ee021cb7e09dd4c7ee6273a4ee778bae850e31b6360a31044c11e674df4c
4
+ data.tar.gz: 9be71c4690f1e6476c6a339a49172575eac79c11406c6a1ac8a49e66c804ee6e
5
5
  SHA512:
6
- metadata.gz: 04bf2f70fcfe5200ed15417dbcd57734b3fe33603bb36eb4dc5007821d6c27af135a3b37552fd75c42a9a1feb02453411a47106340b9abb836496df679ec7b99
7
- data.tar.gz: fd8d594757ecf3119c409b0d6169e607a823b1a575fcb1b5599625c2f305f580e51dee886a3112217272695b69e1da9ca65d1b3b1599a5908f916bce12aaacc1
6
+ metadata.gz: fa57e8c74580e2afa7e6adae48528fd8d43fd306176eb9039a1531c9db46c0090702eef2d036ddaee3aef09e568ef8ad2714c990e6745b2dff4ed080d5e18874
7
+ data.tar.gz: 4608b92f08da163850832144c89a9495c182a065155727a8d10bacb83ee00fd47951b442420e9ee24582a5804938349e55649b57fe0e699082aa3311fbc57729
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.7
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
- doc = retrieve_document_raw(doc_did, did10 + ".doc", doc_location, {})
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 for CREATE is optional (due to CMSM)
313
- if !el["sig"].nil?
314
- if !match_log_did?(el, doc)
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"] = "Signatures in log don't match"
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
- doc = retrieve_document_raw(doc_did, did10 + ".doc", doc_location, {})
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