vchain_client 1.0.1 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vchain_client.rb CHANGED
@@ -4,8 +4,8 @@ module VChainClient
4
4
 
5
5
  require 'rest-client'
6
6
  require 'base64'
7
- gem "openssl"
8
7
  require 'openssl'
8
+ require 'log4r'
9
9
 
10
10
  require 'vchain_client/blockchain_adapter'
11
11
  require 'vchain_client/bitcoind_blockchain_adapter'
@@ -18,9 +18,12 @@ module VChainClient
18
18
  FIELD_TYPE_HASHED = "fbb6889f44061c2a91e17a411cf168f9457981257a5e0a31fb706cd5cd1e64c263780a42a1fd858ee69429869ab2e2c53b9d94c4a26946f2b0c12f8ce2812d6b"
19
19
 
20
20
  @config = nil
21
+ @log = nil
21
22
 
22
23
  def initialize(config)
23
24
  @config = config
25
+
26
+ @log = Log4r::Logger["vchain_client"]
24
27
  end
25
28
 
26
29
  def hash(arr)
@@ -36,6 +39,10 @@ module VChainClient
36
39
  return Digest::SHA512.hexdigest(what_to_hash)
37
40
  end
38
41
 
42
+ if @log.error?
43
+ @log.error("[get_credentials_hash] unknown document type: '"+ document["type"] +"'")
44
+ end
45
+
39
46
  return nil
40
47
  end
41
48
 
@@ -45,6 +52,11 @@ module VChainClient
45
52
  tree.each { |tree_level|
46
53
  if previous_parent != nil
47
54
  if previous_parent != tree_level["left"] && previous_parent != tree_level["right"]
55
+
56
+ if @log.error?
57
+ @log.error("[build_merkle_tree] wrong tree consequence - no parent in next level")
58
+ end
59
+
48
60
  return nil
49
61
  end
50
62
  end
@@ -60,6 +72,11 @@ module VChainClient
60
72
  level_hash = Digest::SHA256.hexdigest(what_to_hash);
61
73
 
62
74
  if level_hash != tree_level["parent"]
75
+
76
+ if @log.error?
77
+ @log.error("[build_merkle_tree] level hash not equal to its parent")
78
+ end
79
+
63
80
  return nil
64
81
  end
65
82
 
@@ -77,24 +94,63 @@ module VChainClient
77
94
  document = input
78
95
  document = self.hash(document)
79
96
 
97
+ if @log.debug?
98
+ @log.debug("[use] will call "+ api_url +" using vchain_client_id "+ client_id)
99
+ @log.debug("[use] hashed input:")
100
+ @log.debug(document)
101
+ end
102
+
80
103
  document["client_id"] = client_id
81
104
  document["ignore_possible_matches"] = ignore_possible_matches
82
105
 
83
- req = RestClient.post(api_url,
84
- document.to_json,
85
- {'Content-Type' => 'application/json'})
106
+ if @log.debug?
107
+ @log.debug("[use] send_data:")
108
+ @log.debug(document)
109
+ end
86
110
 
87
- if req.code != 200
88
- return false
111
+ begin
112
+
113
+ req = RestClient.post(api_url,
114
+ document.to_json,
115
+ {'Content-Type' => 'application/json'})
116
+
117
+ if req.code != 200
118
+
119
+ if @log.error?
120
+ @log.error("[use] response with code "+ req.code.to_s)
121
+ @log.error("-> ignore_possible_matches: #{ignore_possible_matches}")
122
+ @log.error("-> client_id: #{client_id}")
123
+ @log.error("-> api_url: #{api_url}")
124
+ @log.error("-> document:")
125
+ @log.error(document)
126
+ end
127
+
128
+ return false
129
+
130
+ end
131
+
132
+ return true
133
+
134
+ rescue => e
135
+ if @log.error?
136
+ @log.error("[use] RestClient.post raised exception")
137
+ @log.error("#{e.class}, #{e.message}")
138
+ @log.error("-> ignore_possible_matches: #{ignore_possible_matches}")
139
+ @log.error("-> client_id: #{client_id}")
140
+ @log.error("-> api_url: #{api_url}")
141
+ @log.error("-> document:")
142
+ @log.error(document)
143
+ end
144
+
145
+ raise e
89
146
  end
90
147
 
91
- return true
92
148
  end
93
149
 
94
150
  def do_verify(verification_type, input)
95
151
 
96
152
  client_id = @config["client_id"]
97
- api_url = @config["api"]["url"] + "v0.1/verify/";
153
+ api_url = @config["api"]["url"] + "v0.1/verify/"
98
154
 
99
155
  time = Time.now.getutc
100
156
  timestamp = time.to_i
@@ -102,13 +158,107 @@ module VChainClient
102
158
  document = input
103
159
  document = self.hash(document)
104
160
 
161
+ if @log.debug?
162
+ @log.debug("[verify] will call "+ api_url +" using vchain_client_id "+ client_id)
163
+ @log.debug("-> verification_type: "+ verification_type)
164
+ @log.debug("-> timestamp: "+ timestamp.to_s)
165
+ @log.debug("-> hashed input:")
166
+ @log.debug(document)
167
+ end
168
+
105
169
  signaturesHelper = VChainClient::Signatures.new(@config)
106
170
 
107
- verifications_data = signaturesHelper.signVerification(verification_type, document, timestamp)
171
+ verifications_data = nil
172
+
173
+ begin
174
+
175
+ verifications_data = signaturesHelper.signVerification(verification_type, document, timestamp)
176
+
177
+ rescue => e
178
+ if @log.error?
179
+ @log.error("[verify] Signatures.signVerification raised exception")
180
+ @log.error("#{e.class}, #{e.message}")
181
+ @log.error("-> verification_type: "+ verification_type)
182
+ @log.error("-> timestamp: "+ timestamp.to_s)
183
+ @log.error("-> client_id: #{client_id}")
184
+ @log.error("-> api_url: #{api_url}")
185
+ @log.error("-> document:")
186
+ @log.error(document)
187
+ end
188
+
189
+ raise e
190
+ end
191
+
192
+ if verifications_data == nil
193
+ if @log.error?
194
+ @log.error("[verify] failed to Signatures.signVerification")
195
+ @log.error("-> verification_type: "+ verification_type)
196
+ @log.error("-> timestamp: "+ timestamp.to_s)
197
+ @log.error("-> client_id: #{client_id}")
198
+ @log.error("-> api_url: #{api_url}")
199
+ @log.error("-> document:")
200
+ @log.error(document)
201
+ end
202
+
203
+ return false
204
+ end
205
+
206
+ if @log.debug?
207
+ @log.debug("[verify] verifications_data:")
208
+ @log.debug(document)
209
+ end
108
210
 
109
211
  document = Hash[document.sort]
110
212
 
111
- whole_signature = signaturesHelper.signRequest(document, timestamp)
213
+ if @log.debug?
214
+ @log.debug("[verify] hashed input after sort:")
215
+ @log.debug(document)
216
+ end
217
+
218
+ whole_signature = nil
219
+
220
+ begin
221
+
222
+ whole_signature = signaturesHelper.signRequest(document, timestamp)
223
+
224
+ rescue => e
225
+
226
+ if @log.error?
227
+ @log.error("[verify] Signatures.signRequest raised exception:")
228
+ @log.error("#{e.class}: #{e.message}")
229
+ @log.error("-> verification_type: #{verification_type}")
230
+ @log.error("-> timestamp: "+ timestamp.to_s)
231
+ @log.error("-> client_id: #{client_id}")
232
+ @log.error("-> api_url: #{api_url}")
233
+ @log.error("-> document:")
234
+ @log.error(document)
235
+ end
236
+
237
+ raise e
238
+
239
+ else
240
+
241
+ if whole_signature == nil
242
+
243
+ if @log.error?
244
+ @log.error("[verify] failed to sign request")
245
+ @log.error("-> verification_type: #{verification_type}")
246
+ @log.error("-> timestamp: "+ timestamp.to_s)
247
+ @log.error("-> client_id: #{client_id}")
248
+ @log.error("-> api_url: #{api_url}")
249
+ @log.error("-> document:")
250
+ @log.error(document)
251
+ end
252
+
253
+ return false
254
+ end
255
+
256
+ if @log.debug?
257
+ @log.debug("[verify] signaturesHelper.signRequest went well, whole_signature:")
258
+ @log.debug(whole_signature)
259
+ end
260
+
261
+ end
112
262
 
113
263
  send_data = {}
114
264
  send_data["client_id"] = client_id
@@ -118,15 +268,52 @@ module VChainClient
118
268
  send_data["verifications_signatures"] = verifications_data
119
269
  send_data["signature"] = whole_signature
120
270
 
121
- req = RestClient.post(api_url,
122
- send_data.to_json,
123
- {'Content-Type' => 'application/json'})
124
-
125
- if req.code != 200
126
- return false
127
- end
271
+ if @log.debug?
272
+ @log.debug("[verify] send_data:")
273
+ @log.debug(send_data)
274
+ end
128
275
 
129
- return true
276
+ begin
277
+ req = RestClient.post(api_url,
278
+ send_data.to_json,
279
+ {'Content-Type' => 'application/json'})
280
+
281
+ if req.code != 200
282
+
283
+ if @log.error?
284
+ @log.error("[verify] response with code "+ req.code.to_s)
285
+ @log.error("-> client_id: #{client_id}")
286
+ @log.error("-> api_url: #{api_url}")
287
+ @log.error("-> verification_type: #{verification_type}")
288
+ @log.error("-> timestamp: "+ timestamp.to_s)
289
+ @log.error("-> send_data:")
290
+ @log.error(send_data)
291
+ end
292
+
293
+ return false
294
+ end
295
+
296
+ if @log.debug?
297
+ @log.debug("[verify] response code is 200:")
298
+ @log.debug(req.body)
299
+ end
300
+
301
+ return true
302
+
303
+ rescue => e
304
+ if @log.error?
305
+ @log.error("[verify] RestClient.post raised exception")
306
+ @log.error("#{e.class}, #{e.message}")
307
+ @log.error("-> client_id: #{client_id}")
308
+ @log.error("-> api_url: #{api_url}")
309
+ @log.error("-> verification_type: #{verification_type}")
310
+ @log.error("-> timestamp: "+ timestamp.to_s)
311
+ @log.error("-> send_data:")
312
+ @log.error(send_data)
313
+ end
314
+
315
+ raise e
316
+ end
130
317
  end
131
318
 
132
319
  def do_check(input, is_already_hashed=false)
@@ -142,27 +329,81 @@ module VChainClient
142
329
 
143
330
  document["client_id"] = client_id
144
331
 
145
- req = RestClient.post(api_url,
146
- document.to_json,
147
- {'Content-Type' => 'application/json'})
332
+ if @log.debug?
333
+ @log.debug("[check] will call "+ api_url +" using vchain_client_id "+ client_id)
334
+ @log.debug("-> is_already_hashed: #{is_already_hashed}")
335
+ @log.debug("-> hashed input:")
336
+ @log.debug(document)
337
+ end
148
338
 
149
- if req.code != 200
150
- return false
339
+ req = nil
340
+
341
+ begin
342
+
343
+ req = RestClient.post(api_url,
344
+ document.to_json,
345
+ {'Content-Type' => 'application/json'})
346
+
347
+ if req.code != 200
348
+
349
+ if @log.error?
350
+ @log.error("[check] response with code "+ req.code.to_s)
351
+ @log.error("-> client_id: #{client_id}")
352
+ @log.error("-> api_url: #{api_url}")
353
+ @log.debug("-> is_already_hashed: #{is_already_hashed}")
354
+ @log.error("-> sent data:")
355
+ @log.error(document)
356
+ end
357
+
358
+ return false
359
+
360
+ end
361
+
362
+ rescue => e
363
+ if @log.error?
364
+ @log.error("[check] RestClient.post raised exception:")
365
+ @log.error("#{e.class}, #{e.message}")
366
+ @log.error("-> client_id: #{client_id}")
367
+ @log.error("-> api_url: #{api_url}")
368
+ @log.debug("-> is_already_hashed: #{is_already_hashed}")
369
+ @log.error("-> sent data:")
370
+ @log.error(document)
371
+ end
372
+
373
+ raise e
374
+ end
375
+
376
+ if @log.debug?
377
+ @log.debug("[check] response code is 200:")
378
+ @log.debug(req.body)
151
379
  end
152
380
 
153
381
  res = JSON.parse req.body
154
382
 
155
383
  if res["status"] == "ERROR" || res["status"] == "error"
156
384
 
157
- raise res["error_reason_code"]
385
+ return {
386
+ "status" => "error",
387
+ "reason" => res["error_reason_code"]
388
+ }
158
389
 
159
390
  else
391
+ # success result
392
+
160
393
  res_document = res["document"]
161
394
 
395
+ if @log.debug?
396
+ @log.debug("[check] recieved verifications")
397
+ end
398
+
162
399
  validated_verifications = {}
163
400
 
164
401
  credentials_hash = self.get_credentials_hash(document)
165
402
 
403
+ if @log.debug?
404
+ @log.debug("[check] credentials_hash: "+ credentials_hash)
405
+ end
406
+
166
407
  blockchainConnection = VChainClient::BlockchainConnection.new(@config)
167
408
 
168
409
  blockstackClient = VChainClient::BlockstackClient.new(@config)
@@ -171,40 +412,144 @@ module VChainClient
171
412
 
172
413
  res_document.each { |field, v|
173
414
  if v["verifications"].length > 0 && field != "type"
415
+
416
+ if @log.debug?
417
+ @log.debug("[check] check recieved verifications for '"+ field +"', number of recieved verifications: "+ v["verifications"].length.to_s)
418
+ end
419
+
174
420
  v["verifications"].each { |verification|
175
421
 
176
- next if !verification.key?("blockchain_reciepts")
422
+ if @log.debug?
423
+ @log.debug("[check] field '"+ field +"', verification:")
424
+ @log.debug(verification)
425
+ end
426
+
427
+ if !verification.key?("blockchain_reciepts")
428
+ if @log.error?
429
+ @log.error("[check] not a valid verification - no blockchain_reciepts key")
430
+ @log.error(verification)
431
+ @log.error(document)
432
+ end
433
+
434
+ next
435
+ end
436
+
437
+ if verification["blockchain_reciepts"].length <= 0
438
+ if @log.error?
439
+ @log.error("[check] not a valid verification - blockchain_reciepts is empty")
440
+ @log.error("field '"+ field +"'")
441
+ @log.error(verification)
442
+ @log.error(document)
443
+ end
177
444
 
178
- next if verification["blockchain_reciepts"].length <= 0
445
+ next
446
+ end
179
447
 
180
448
  # 1a. check credentials_hash
181
- next if credentials_hash != verification["credentials_hash"]
449
+ if credentials_hash != verification["credentials_hash"]
450
+ if @log.error?
451
+ @log.error("[check] not a valid verification - credentials_hash mismatch ("+ credentials_hash +")")
452
+ @log.error("field '"+ field +"'")
453
+ @log.error(verification)
454
+ @log.error(document)
455
+ end
456
+
457
+ next
458
+ end
182
459
 
183
460
  # 1b. check field_hash
184
461
  field_hash = Digest::SHA512.hexdigest(field)
185
- next if field_hash != verification["field_hash"]
462
+ if field_hash != verification["field_hash"]
463
+ if @log.error?
464
+ @log.error("[check] not a valid verification - field_hash mismatch ("+ field_hash +")")
465
+ @log.error("field '"+ field +"'")
466
+ @log.error(verification)
467
+ @log.error(document)
468
+ end
469
+
470
+ next
471
+ end
186
472
 
187
473
  # 1c. check data_hash
188
474
  data_hash = Digest::SHA512.hexdigest(document[field])
189
- next if data_hash != verification["data_hash"]
475
+ if data_hash != verification["data_hash"]
476
+ if @log.error?
477
+ @log.error("[check] not a valid verification - data_hash mismatch ("+ data_hash +")")
478
+ @log.error("field '"+ field +"'")
479
+ @log.error(verification)
480
+ @log.error(document)
481
+ end
482
+
483
+ next
484
+ end
190
485
 
191
486
  # 1d. check checksum
192
487
  checksum_to_hash = credentials_hash + field_hash + data_hash
193
488
  checksum = Digest::SHA512.hexdigest(checksum_to_hash)
194
- next if checksum != verification["checksum"]
489
+ if checksum != verification["checksum"]
490
+ if @log.error?
491
+ @log.error("[check] not a valid verification - checksum mismatch ("+ checksum +")")
492
+ @log.error("field '"+ field +"'")
493
+ @log.error(verification)
494
+ @log.error(document)
495
+ @log.error(credentials_hash)
496
+ @log.error(field_hash)
497
+ @log.error(data_hash)
498
+ end
499
+
500
+ next
501
+ end
195
502
 
196
503
  verification_hash = verification["verification_hash"]
504
+ if @log.debug?
505
+ @log.debug("[check] verification_hash: "+ verification_hash)
506
+ end
197
507
 
198
508
  # 2. check verification_hash to be in target_proof's
199
509
  # first element
200
510
  reciepts_validated = 0
201
511
  verification["blockchain_reciepts"].each { |reciept|
202
512
 
203
- break if !reciept.key?("target_proof")
204
-
205
- break if reciept["target_proof"].length <= 0
206
-
207
- break if reciept["target_proof"][0]["left"] != verification_hash && reciept["target_proof"][0]["right"] != verification_hash
513
+ if @log.debug?
514
+ @log.debug("reciept to check:")
515
+ @log.debug(reciept)
516
+ end
517
+
518
+ if !reciept.key?("target_proof")
519
+ if @log.error?
520
+ @log.error("[check] not a valid blockchain reciept - no target_proof")
521
+ @log.error(reciept)
522
+ @log.error("field '"+ field +"'")
523
+ @log.error(verification)
524
+ @log.error(document)
525
+ end
526
+
527
+ break
528
+ end
529
+
530
+ if reciept["target_proof"].length <= 0
531
+ if @log.error?
532
+ @log.error("[check] not a valid blockchain reciept - target_proof length is <= 0")
533
+ @log.error(reciept)
534
+ @log.error("field '"+ field +"'")
535
+ @log.error(verification)
536
+ @log.error(document)
537
+ end
538
+
539
+ break
540
+ end
541
+
542
+ if reciept["target_proof"][0]["left"] != verification_hash && reciept["target_proof"][0]["right"] != verification_hash
543
+ if @log.error?
544
+ @log.error("[check] not a valid blockchain reciept - no target element in target_proof.0")
545
+ @log.error(reciept)
546
+ @log.error("field '"+ field +"'")
547
+ @log.error(verification)
548
+ @log.error(document)
549
+ end
550
+
551
+ break
552
+ end
208
553
 
209
554
  # verification_hash is in tree
210
555
  # and in right position
@@ -213,44 +558,282 @@ module VChainClient
213
558
  # 3. check tree convergence to root hash
214
559
  # and compare this computed root hash
215
560
  # with merkle_tree_root_hash from response
216
- computed_tree_root_hash = self.build_merkle_tree(reciept["target_proof"], reciept["timestamp"])
561
+ if @log.debug?
562
+ @log.debug("will now build merkle tree with")
563
+ @log.debug(reciept["target_proof"])
564
+ @log.debug(reciept["timestamp"])
565
+ end
217
566
 
218
- break if computed_tree_root_hash == nil
219
- break if computed_tree_root_hash != reciept["merkle_tree_root_hash"]
567
+ computed_tree_root_hash = self.build_merkle_tree(reciept["target_proof"], reciept["timestamp"])
568
+
569
+ if @log.debug?
570
+ @log.debug("computed tree root hash = "+ computed_tree_root_hash)
571
+ end
572
+
573
+ if computed_tree_root_hash == nil
574
+ if @log.error?
575
+ @log.error("[check] not a valid blockchain reciept - failed to compute tree root hash")
576
+ @log.error(reciept)
577
+ @log.error("field '"+ field +"'")
578
+ @log.error(verification)
579
+ @log.error(document)
580
+ end
581
+
582
+ break
583
+ end
584
+ if computed_tree_root_hash != reciept["merkle_tree_root_hash"]
585
+ if @log.error?
586
+ @log.error("[check] not a valid blockchain reciept - merkle tree root hash mismatch ("+ computed_tree_root_hash +", "+ reciept["merkle_tree_root_hash"] +")")
587
+ @log.error(reciept)
588
+ @log.error("field '"+ field +"'")
589
+ @log.error(verification)
590
+ @log.error(document)
591
+ end
592
+
593
+ break
594
+ end
220
595
 
221
596
  last_proof_index = reciept["target_proof"].length - 1
222
597
  reciept_stored_last_parent = reciept["target_proof"][last_proof_index]["parent"]
223
- break if reciept_stored_last_parent != computed_tree_root_hash
598
+ if reciept_stored_last_parent != computed_tree_root_hash
599
+ if @log.error?
600
+ @log.error("[check] not a valid blockchain reciept - last stored parent != computed_tree_root_hash ("+ reciept_stored_last_parent +", "+ computed_tree_root_hash +")")
601
+ @log.error(reciept)
602
+ @log.error("field '"+ field +"'")
603
+ @log.error(verification)
604
+ @log.error(document)
605
+ end
606
+
607
+ break
608
+ end
224
609
 
225
610
  # 4. check OP_RETURN in Bitcoin's tx,
226
611
  # compare it to computed root hash of a tree
227
612
  # retrieve some info from tx to verify signature
228
- tx = blockchainConnection.getTx(reciept["blockchain_txid"])
229
-
230
- break if tx == nil
231
- break if tx["block_hash"] != reciept["blockchain_block_hash"]
232
- break if tx["block_timestamp"] != reciept["blockchain_timestamp"]
233
- break if tx["op_return"] != computed_tree_root_hash
613
+ tx = nil
614
+
615
+ begin
616
+
617
+ tx = blockchainConnection.getTx(reciept["blockchain_txid"])
618
+
619
+ rescue => e
620
+ if @log.error?
621
+ @log.error("[check] BlockchainConnection.getTx raised exception:")
622
+ @log.error("#{e.class}, #{e.message}")
623
+ @log.error("-> client_id: #{client_id}")
624
+ @log.error("-> api_url: #{api_url}")
625
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
626
+ @log.error("-> sent data:")
627
+ @log.error(document)
628
+ @log.error("--> blockchain_txid: "+ reciept["blockchain_txid"])
629
+ end
630
+
631
+ raise e
632
+ end
633
+
634
+
635
+ if @log.debug?
636
+ @log.debug("[check] tx ["+ reciept["blockchain_txid"] +"]:")
637
+ @log.debug(tx)
638
+ end
639
+
640
+ if tx == nil
641
+ if @log.error?
642
+ @log.error("[check] not a valid blockchain reciept - failed to retrieve TX from Blockchain")
643
+ @log.error(reciept)
644
+ @log.error("field '"+ field +"'")
645
+ @log.error(verification)
646
+ @log.error(document)
647
+ end
648
+
649
+ break
650
+ end
651
+
652
+ if tx["block_hash"] != reciept["blockchain_block_hash"]
653
+ if @log.error?
654
+ @log.error("[check] not a valid blockchain reciept - block_hash mismatch")
655
+ @log.error(tx)
656
+ @log.error(reciept)
657
+ @log.error("field '"+ field +"'")
658
+ @log.error(verification)
659
+ @log.error(document)
660
+ end
661
+
662
+ break
663
+ end
664
+
665
+ if tx["block_timestamp"] != reciept["blockchain_timestamp"]
666
+ if @log.error?
667
+ @log.error("[check] not a valid blockchain reciept - timestamp mismatch")
668
+ @log.error(tx)
669
+ @log.error(reciept)
670
+ @log.error("field '"+ field +"'")
671
+ @log.error(verification)
672
+ @log.error(document)
673
+ end
674
+
675
+ break
676
+ end
677
+
678
+ if tx["op_return"] != computed_tree_root_hash
679
+ if @log.error?
680
+ @log.error("[check] not a valid blockchain reciept - op_return mismatch")
681
+ @log.error(computed_tree_root_hash)
682
+ @log.error(tx)
683
+ @log.error(reciept)
684
+ @log.error("field '"+ field +"'")
685
+ @log.error(verification)
686
+ @log.error(document)
687
+ end
688
+
689
+ break
690
+ end
234
691
 
235
692
  blockchain_txid = reciept["blockchain_txid"];
236
693
  blockchain_block_hash = tx["block_hash"];
237
694
  blockchain_timestamp = tx["block_timestamp"];
695
+
696
+ if @log.debug?
697
+ @log.debug(blockchain_txid)
698
+ @log.debug(blockchain_block_hash)
699
+ @log.debug(blockchain_timestamp)
700
+ end
238
701
 
239
702
  # 5. check tree signature:
240
703
  # a) federative server record in Blockstack (recursive)
241
704
  # b) tree_signature
242
705
 
243
706
  # a) federative server record in Blockstack (recursive)
244
- break if !blockstackClient.checkFederativeServer(reciept["federative_server_id"])
707
+ begin
708
+
709
+ if !blockstackClient.checkFederativeServer(reciept["federative_server_id"])
710
+ if @log.error?
711
+ @log.error("[check] not a valid blockchain reciept - failed to check federative server")
712
+ @log.error("-> client_id: #{client_id}")
713
+ @log.error("-> api_url: #{api_url}")
714
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
715
+ @log.error("-> sent data:")
716
+ @log.error(document)
717
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
718
+ end
719
+
720
+ break
721
+ end
722
+
723
+ rescue => e
724
+ if @log.error?
725
+ @log.error("[check] Blockstack.checkFederativeServer raised exception:")
726
+ @log.error("#{e.class}, #{e.message}")
727
+ @log.error("-> client_id: #{client_id}")
728
+ @log.error("-> api_url: #{api_url}")
729
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
730
+ @log.error("-> sent data:")
731
+ @log.error(document)
732
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
733
+ end
734
+
735
+ raise e
736
+ end
245
737
 
246
738
  # b) check tree signature
247
- federative_server_pubkey = blockstackClient.getPublicKey(reciept["federative_server_id"])
248
-
249
- break if !signaturesHelper.checkTreeSignature(computed_tree_root_hash, blockchain_txid, blockchain_block_hash, blockchain_timestamp, reciept["federative_server_id"], reciept["federative_server_version"], Base64.decode64(reciept["tree_signature"]), federative_server_pubkey)
739
+ federative_server_pubkey = nil
740
+
741
+ begin
742
+
743
+ federative_server_pubkey = blockstackClient.getPublicKey(reciept["federative_server_id"])
744
+
745
+ rescue => e
746
+ if @log.error?
747
+ @log.error("[check] Blockstack.getPublicKey raised exception:")
748
+ @log.error("#{e.class}, #{e.message}")
749
+ @log.error("-> client_id: #{client_id}")
750
+ @log.error("-> api_url: #{api_url}")
751
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
752
+ @log.error("-> sent data:")
753
+ @log.error(document)
754
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
755
+ end
756
+
757
+ raise e
758
+ end
759
+
760
+ if federative_server_pubkey == nil
761
+ if @log.error?
762
+ @log.error("[check] not a valid blockchain reciept - failed to retrieve public key for federative server '"+ reciept["federative_server_id"] +"'")
763
+ @log.error("-> client_id: #{client_id}")
764
+ @log.error("-> api_url: #{api_url}")
765
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
766
+ @log.error("-> sent data:")
767
+ @log.error(document)
768
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
769
+ end
770
+
771
+ break
772
+ end
773
+
774
+ if @log.debug?
775
+ @log.debug("federative server pubkey:")
776
+ @log.debug(federative_server_pubkey)
777
+ end
778
+
779
+ begin
780
+
781
+ if !signaturesHelper.checkTreeSignature(computed_tree_root_hash, blockchain_txid, blockchain_block_hash, blockchain_timestamp, reciept["federative_server_id"], reciept["federative_server_version"], Base64.decode64(reciept["tree_signature"]), federative_server_pubkey)
782
+ if @log.error?
783
+ @log.error("[check] not a valid blockchain reciept - failed to verify tree signature")
784
+ @log.error("-> client_id: #{client_id}")
785
+ @log.error("-> api_url: #{api_url}")
786
+ @log.debug("-> is_already_hashed: #{is_already_hashed}")
787
+ @log.error("-> sent data:")
788
+ @log.error(document)
789
+ @log.error("--> computed_tree_root_hash: #{computed_tree_root_hash}")
790
+ @log.error("--> blockchain_txid: #{blockchain_txid}")
791
+ @log.error("--> blockchain_block_hash: #{blockchain_block_hash}")
792
+ @log.error("--> blockchain_timestamp: #{blockchain_timestamp}")
793
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
794
+ @log.error("--> federative_server_version: "+ reciept["federative_server_version"])
795
+ @log.error("--> tree_signature: "+ Base64.decode64(reciept["tree_signature"]))
796
+ @log.error("--> federative_server_pubkey: #{federative_server_pubkey}")
797
+ end
798
+
799
+ break
800
+ end
801
+
802
+ rescue => e
803
+ if @log.error?
804
+ @log.error("[check] Blockstack.checkTreeSignature raised exception:")
805
+ @log.error("#{e.class}, #{e.message}")
806
+ @log.error("-> client_id: #{client_id}")
807
+ @log.error("-> api_url: #{api_url}")
808
+ @log.debug("-> is_already_hashed: #{is_already_hashed}")
809
+ @log.error("-> sent data:")
810
+ @log.error(document)
811
+ @log.error("--> computed_tree_root_hash: #{computed_tree_root_hash}")
812
+ @log.error("--> blockchain_txid: #{blockchain_txid}")
813
+ @log.error("--> blockchain_block_hash: #{blockchain_block_hash}")
814
+ @log.error("--> blockchain_timestamp: #{blockchain_timestamp}")
815
+ @log.error("--> federative_server_id: "+ reciept["federative_server_id"])
816
+ @log.error("--> federative_server_version: "+ reciept["federative_server_version"])
817
+ @log.error("--> tree_signature: "+ Base64.decode64(reciept["tree_signature"]))
818
+ @log.error("--> federative_server_pubkey: #{federative_server_pubkey}")
819
+ end
820
+
821
+ raise e
822
+ end
250
823
 
251
824
  reciepts_validated += 1
252
825
  }
253
- next if reciepts_validated != verification["blockchain_reciepts"].length
826
+
827
+ if reciepts_validated != verification["blockchain_reciepts"].length
828
+ if @log.error?
829
+ @log.error("[check] not a valid verification - not every reciept were validated")
830
+ @log.error("field '"+ field +"'")
831
+ @log.error(verification)
832
+ @log.error(document)
833
+ end
834
+
835
+ next
836
+ end
254
837
 
255
838
  # 6. check verification signatures:
256
839
  # a) check verificator record in Blockstack (recursive)
@@ -259,31 +842,259 @@ module VChainClient
259
842
  # d) validtor_sig
260
843
 
261
844
  # a) check verificator record in Blockstack (recursive)
262
- next if !blockstackClient.checkVerificator(verification["verificator_id"])
845
+ begin
846
+
847
+ if !blockstackClient.checkVerificator(verification["verificator_id"])
848
+ if @log.error?
849
+ @log.error("[check] not a valid verification - failed to check verificator record")
850
+ @log.error("-> client_id: #{client_id}")
851
+ @log.error("-> api_url: #{api_url}")
852
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
853
+ @log.error("-> sent data:")
854
+ @log.error(document)
855
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
856
+ end
857
+
858
+ next
859
+ end
860
+
861
+ rescue => e
862
+ if @log.error?
863
+ @log.error("[check] Blockstack.checkVerificator raised exception:")
864
+ @log.error("#{e.class}, #{e.message}")
865
+ @log.error("-> client_id: #{client_id}")
866
+ @log.error("-> api_url: #{api_url}")
867
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
868
+ @log.error("-> sent data:")
869
+ @log.error(document)
870
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
871
+ end
872
+
873
+ raise e
874
+ end
263
875
 
264
876
  # b) check validator record in Blockstack (recursive)
265
- next if !blockstackClient.checkValidator(verification["validator_id"])
877
+ begin
878
+
879
+ if !blockstackClient.checkValidator(verification["validator_id"])
880
+ if @log.error?
881
+ @log.error("[check] not a valid verification - failed to check validator record")
882
+ @log.error("-> client_id: #{client_id}")
883
+ @log.error("-> api_url: #{api_url}")
884
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
885
+ @log.error("-> sent data:")
886
+ @log.error(document)
887
+ @log.error("--> validator_id: "+ verification["validator_id"])
888
+ end
889
+
890
+ next
891
+ end
892
+
893
+ rescue => e
894
+ if @log.error?
895
+ @log.error("[check] Blockstack.checkValidator raised exception:")
896
+ @log.error("#{e.class}, #{e.message}")
897
+ @log.error("-> client_id: #{client_id}")
898
+ @log.error("-> api_url: #{api_url}")
899
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
900
+ @log.error("-> sent data:")
901
+ @log.error(document)
902
+ @log.error("--> validator_id: "+ verification["validator_id"])
903
+ end
904
+
905
+ raise e
906
+ end
266
907
 
267
908
  # c) check verificator's signature
268
- verificator_pubkey = blockstackClient.getPublicKey(verification["verificator_id"])
269
-
270
- next if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["verificator_id"], verificator_pubkey, Base64.decode64(verification["verificator_sig"]))
909
+ verificator_pubkey = nil
910
+
911
+ begin
912
+
913
+ verificator_pubkey = blockstackClient.getPublicKey(verification["verificator_id"])
914
+
915
+ rescue => e
916
+ if @log.error?
917
+ @log.error("[check] Blockstack.getPublicKey raised exception:")
918
+ @log.error("#{e.class}, #{e.message}")
919
+ @log.error("-> client_id: #{client_id}")
920
+ @log.error("-> api_url: #{api_url}")
921
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
922
+ @log.error("-> sent data:")
923
+ @log.error(document)
924
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
925
+ end
926
+
927
+ raise e
928
+ end
929
+
930
+ if verificator_pubkey == nil
931
+ if @log.error?
932
+ @log.error("[check] failed to retrieve public key for verificator")
933
+ @log.error("-> client_id: #{client_id}")
934
+ @log.error("-> api_url: #{api_url}")
935
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
936
+ @log.error("-> sent data:")
937
+ @log.error(document)
938
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
939
+ end
940
+
941
+ next
942
+ end
943
+
944
+ if @log.debug?
945
+ @log.debug("verificator pubkey:")
946
+ @log.debug(verificator_pubkey)
947
+ end
948
+
949
+ begin
950
+
951
+ if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["verificator_id"], verificator_pubkey, Base64.decode64(verification["verificator_sig"]))
952
+ if @log.error?
953
+ @log.error("[check] not a valid verification - failed to check verificator signature")
954
+ @log.error("-> client_id: #{client_id}")
955
+ @log.error("-> api_url: #{api_url}")
956
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
957
+ @log.error("-> sent data:")
958
+ @log.error(document)
959
+ @log.error("--> field_hash: #{field_hash}")
960
+ @log.error("--> data_hash")
961
+ @log.error("--> verification_type: "+ verification["type"])
962
+ @log.error("--> verification_timestamp: "+ verification["timestamp"].to_s)
963
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
964
+ @log.error("--> verificator_pubkey: "+ verificator_pubkey)
965
+ @log.error("--> verificator_sig: "+ Base64.decode64(verification["verificator_sig"]))
966
+ end
967
+
968
+ next
969
+ end
970
+
971
+ rescue => e
972
+ if @log.error?
973
+ @log.error("[check] Signatures.checkVerificationSignature raised exception:")
974
+ @log.error("#{e.class}, #{e.message}")
975
+ @log.error("-> client_id: #{client_id}")
976
+ @log.error("-> api_url: #{api_url}")
977
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
978
+ @log.error("-> sent data:")
979
+ @log.error(document)
980
+ @log.error("--> field_hash: #{field_hash}")
981
+ @log.error("--> data_hash")
982
+ @log.error("--> verification_type: "+ verification["type"])
983
+ @log.error("--> verification_timestamp: "+ verification["timestamp"].to_s)
984
+ @log.error("--> verificator_id: "+ verification["verificator_id"])
985
+ @log.error("--> verificator_pubkey: "+ verificator_pubkey)
986
+ @log.error("--> verificator_sig: "+ Base64.decode64(verification["verificator_sig"]))
987
+ end
988
+
989
+ raise e
990
+ end
271
991
 
272
992
  # d) check validator's signature
273
- validator_pubkey = blockstackClient.getPublicKey(verification["validator_id"])
274
-
275
- next if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["validator_id"], validator_pubkey, Base64.decode64(verification["validator_sig"]))
993
+ validator_pubkey = nil
994
+
995
+ begin
996
+
997
+ validator_pubkey = blockstackClient.getPublicKey(verification["validator_id"])
998
+
999
+ rescue => e
1000
+ if @log.error?
1001
+ @log.error("[check] Blockstack.getPublicKey raised exception:")
1002
+ @log.error("#{e.class}, #{e.message}")
1003
+ @log.error("-> client_id: #{client_id}")
1004
+ @log.error("-> api_url: #{api_url}")
1005
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
1006
+ @log.error("-> sent data:")
1007
+ @log.error(document)
1008
+ @log.error("--> validator_id: "+ verification["validator_id"])
1009
+ end
1010
+
1011
+ raise e
1012
+ end
1013
+
1014
+ if validator_pubkey == nil
1015
+ if @log.error?
1016
+ @log.error("[check] failed to retrieve pubic key for validator")
1017
+ @log.error("-> client_id: #{client_id}")
1018
+ @log.error("-> api_url: #{api_url}")
1019
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
1020
+ @log.error("-> sent data:")
1021
+ @log.error(document)
1022
+ @log.error("--> validator_id: "+ verification["validator_id"])
1023
+ end
1024
+
1025
+ next
1026
+ end
1027
+
1028
+ if @log.debug?
1029
+ @log.debug("validator pubkey:")
1030
+ @log.debug(validator_pubkey)
1031
+ end
1032
+
1033
+ begin
1034
+
1035
+ if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["validator_id"], validator_pubkey, Base64.decode64(verification["validator_sig"]))
1036
+ if @log.error?
1037
+ @log.error("[check] not a valid verification - failed to check verificator signature")
1038
+ @log.error("-> client_id: #{client_id}")
1039
+ @log.error("-> api_url: #{api_url}")
1040
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
1041
+ @log.error("-> sent data:")
1042
+ @log.error(document)
1043
+ @log.error("--> field_hash: #{field_hash}")
1044
+ @log.error("--> data_hash")
1045
+ @log.error("--> verification_type: "+ verification["type"])
1046
+ @log.error("--> verification_timestamp: "+ verification["timestamp"].to_s)
1047
+ @log.error("--> validator_id: "+ verification["validator_id"])
1048
+ @log.error("--> validator_pubkey: "+ validator_pubkey)
1049
+ @log.error("--> validator_sig: "+ Base64.decode64(verification["validator_sig"]))
1050
+ end
1051
+
1052
+ next
1053
+ end
1054
+
1055
+ rescue => e
1056
+ if @log.error?
1057
+ @log.error("[check] Signatures.checkVerificationSignature raised exception:")
1058
+ @log.error("#{e.class}, #{e.message}")
1059
+ @log.error("-> client_id: #{client_id}")
1060
+ @log.error("-> api_url: #{api_url}")
1061
+ @log.error("-> is_already_hashed: #{is_already_hashed}")
1062
+ @log.error("-> sent data:")
1063
+ @log.error(document)
1064
+ @log.error("--> field_hash: #{field_hash}")
1065
+ @log.error("--> data_hash")
1066
+ @log.error("--> verification_type: "+ verification["type"])
1067
+ @log.error("--> verification_timestamp: "+ verification["timestamp"].to_s)
1068
+ @log.error("--> validator_id: "+ verification["validator_id"])
1069
+ @log.error("--> validator_pubkey: "+ validator_pubkey)
1070
+ @log.error("--> validator_sig: "+ Base64.decode64(verification["validator_sig"]))
1071
+ end
1072
+
1073
+ raise e
1074
+ end
276
1075
 
277
1076
  # 7. timestamps checking
278
1077
  # TODO
1078
+
1079
+
279
1080
  if !validated_verifications.key?(field)
280
1081
  validated_verifications[field] = 0
281
1082
  end
282
1083
  validated_verifications[field] = validated_verifications[field] + 1
283
1084
  }
1085
+
1086
+ else
1087
+ if @log.debug?
1088
+ @log.debug("[check] skip '"+ field +"', number of recieved verifications: "+ v["verifications"].length.to_s)
1089
+ end
284
1090
  end
285
1091
  }
286
1092
 
1093
+ if @log.debug?
1094
+ @log.debug("[check] temp validated verifications:")
1095
+ @log.debug(validated_verifications)
1096
+ end
1097
+
287
1098
  # check input fields
288
1099
  input.each_with_index { |field,index|
289
1100
  if field[0] != 'type' && field[0] != 'client_id'
@@ -293,6 +1104,11 @@ module VChainClient
293
1104
  end
294
1105
  }
295
1106
 
1107
+ if @log.debug?
1108
+ @log.debug("[check] resulted validated verifications:")
1109
+ @log.debug(validated_verifications)
1110
+ end
1111
+
296
1112
  return validated_verifications
297
1113
  end
298
1114
  end