vchain_client 1.0.9 → 1.0.10
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/lib/vchain_client.rb +125 -103
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d417b56044799fb656fbe43b67a13389694df44a
|
4
|
+
data.tar.gz: a698819a9de360ed400cf895f31fbf8739517374
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11959aaa39c50e677b99084fe7cdd5668bb1148a3539d7a72f382ce5e434672b726983c133471e95496ef0a7ac3e2a894d8c617d70f316f21e6232f13bba932b
|
7
|
+
data.tar.gz: a476a96e888e458508f082bac4b62465e537c80c39ca1c0d9ef7a9764d259aefcd2acb50f2517a25ae2ab9850c41c30ddbeb553435d280e023975d31a4583d56
|
data/lib/vchain_client.rb
CHANGED
@@ -398,25 +398,17 @@ module VChainClient
|
|
398
398
|
|
399
399
|
res = JSON.parse req.body
|
400
400
|
|
401
|
-
|
401
|
+
validated_verifications = {}
|
402
402
|
|
403
|
-
|
404
|
-
"status" => "error",
|
405
|
-
"reason" => res["error_reason_code"]
|
406
|
-
}
|
403
|
+
if res.key?("document")
|
407
404
|
|
408
|
-
|
409
|
-
# success result
|
410
|
-
|
411
|
-
res_document = res["document"]
|
405
|
+
res_document = res["document"]
|
412
406
|
|
413
407
|
if @log.debug?
|
414
408
|
@log.debug("[check] recieved verifications")
|
415
409
|
end
|
416
410
|
|
417
|
-
|
418
|
-
|
419
|
-
credentials_hash = self.get_credentials_hash(document)
|
411
|
+
credentials_hash = self.get_credentials_hash(document)
|
420
412
|
|
421
413
|
if @log.debug?
|
422
414
|
@log.debug("[check] credentials_hash: "+ credentials_hash)
|
@@ -428,21 +420,21 @@ module VChainClient
|
|
428
420
|
|
429
421
|
signaturesHelper = VChainClient::Signatures.new(@config)
|
430
422
|
|
431
|
-
|
432
|
-
|
423
|
+
res_document.each { |field, v|
|
424
|
+
if v.key?("verifications") && v["verifications"].length > 0 && field != "type"
|
433
425
|
|
434
426
|
if @log.debug?
|
435
427
|
@log.debug("[check] check recieved verifications for '"+ field +"', number of recieved verifications: "+ v["verifications"].length.to_s)
|
436
428
|
end
|
437
429
|
|
438
|
-
|
430
|
+
v["verifications"].each { |verification|
|
439
431
|
|
440
432
|
if @log.debug?
|
441
433
|
@log.debug("[check] field '"+ field +"', verification:")
|
442
434
|
@log.debug(verification)
|
443
435
|
end
|
444
436
|
|
445
|
-
|
437
|
+
if !verification.key?("blockchain_reciepts")
|
446
438
|
if @log.error?
|
447
439
|
@log.error("[check] not a valid verification - no blockchain_reciepts key")
|
448
440
|
@log.error(verification)
|
@@ -452,7 +444,7 @@ module VChainClient
|
|
452
444
|
next
|
453
445
|
end
|
454
446
|
|
455
|
-
|
447
|
+
if verification["blockchain_reciepts"].length <= 0
|
456
448
|
if @log.error?
|
457
449
|
@log.error("[check] not a valid verification - blockchain_reciepts is empty")
|
458
450
|
@log.error("field '"+ field +"'")
|
@@ -463,8 +455,8 @@ module VChainClient
|
|
463
455
|
next
|
464
456
|
end
|
465
457
|
|
466
|
-
|
467
|
-
|
458
|
+
# 1a. check credentials_hash
|
459
|
+
if credentials_hash != verification["credentials_hash"]
|
468
460
|
if @log.error?
|
469
461
|
@log.error("[check] not a valid verification - credentials_hash mismatch ("+ credentials_hash +")")
|
470
462
|
@log.error("field '"+ field +"'")
|
@@ -475,9 +467,9 @@ module VChainClient
|
|
475
467
|
next
|
476
468
|
end
|
477
469
|
|
478
|
-
|
479
|
-
|
480
|
-
|
470
|
+
# 1b. check field_hash
|
471
|
+
field_hash = Digest::SHA512.hexdigest(field)
|
472
|
+
if field_hash != verification["field_hash"]
|
481
473
|
if @log.error?
|
482
474
|
@log.error("[check] not a valid verification - field_hash mismatch ("+ field_hash +")")
|
483
475
|
@log.error("field '"+ field +"'")
|
@@ -488,9 +480,18 @@ module VChainClient
|
|
488
480
|
next
|
489
481
|
end
|
490
482
|
|
491
|
-
|
492
|
-
|
493
|
-
|
483
|
+
# 1c. check data_hash
|
484
|
+
data_hash = Digest::SHA512.hexdigest(document[field])
|
485
|
+
if res.key?("document")
|
486
|
+
if res["document"].key?("values")
|
487
|
+
if res["document"]["values"].key?(field)
|
488
|
+
if res["document"]["values"][field] != document[field]
|
489
|
+
data_hash = Digest::SHA512.hexdigest(res["document"]["values"][field])
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
if data_hash != verification["data_hash"]
|
494
495
|
if @log.error?
|
495
496
|
@log.error("[check] not a valid verification - data_hash mismatch ("+ data_hash +")")
|
496
497
|
@log.error("field '"+ field +"'")
|
@@ -501,10 +502,10 @@ module VChainClient
|
|
501
502
|
next
|
502
503
|
end
|
503
504
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
505
|
+
# 1d. check checksum
|
506
|
+
checksum_to_hash = credentials_hash + field_hash + data_hash
|
507
|
+
checksum = Digest::SHA512.hexdigest(checksum_to_hash)
|
508
|
+
if checksum != verification["checksum"]
|
508
509
|
if @log.error?
|
509
510
|
@log.error("[check] not a valid verification - checksum mismatch ("+ checksum +")")
|
510
511
|
@log.error("field '"+ field +"'")
|
@@ -518,22 +519,22 @@ module VChainClient
|
|
518
519
|
next
|
519
520
|
end
|
520
521
|
|
521
|
-
|
522
|
+
verification_hash = verification["verification_hash"]
|
522
523
|
if @log.debug?
|
523
524
|
@log.debug("[check] verification_hash: "+ verification_hash)
|
524
525
|
end
|
525
526
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
527
|
+
# 2. check verification_hash to be in target_proof's
|
528
|
+
# first element
|
529
|
+
reciepts_validated = 0
|
530
|
+
verification["blockchain_reciepts"].each { |reciept|
|
530
531
|
|
531
532
|
if @log.debug?
|
532
533
|
@log.debug("reciept to check:")
|
533
534
|
@log.debug(reciept)
|
534
535
|
end
|
535
536
|
|
536
|
-
|
537
|
+
if !reciept.key?("target_proof")
|
537
538
|
if @log.error?
|
538
539
|
@log.error("[check] not a valid blockchain reciept - no target_proof")
|
539
540
|
@log.error(reciept)
|
@@ -545,7 +546,7 @@ module VChainClient
|
|
545
546
|
break
|
546
547
|
end
|
547
548
|
|
548
|
-
|
549
|
+
if reciept["target_proof"].length <= 0
|
549
550
|
if @log.error?
|
550
551
|
@log.error("[check] not a valid blockchain reciept - target_proof length is <= 0")
|
551
552
|
@log.error(reciept)
|
@@ -557,7 +558,7 @@ module VChainClient
|
|
557
558
|
break
|
558
559
|
end
|
559
560
|
|
560
|
-
|
561
|
+
if reciept["target_proof"][0]["left"] != verification_hash && reciept["target_proof"][0]["right"] != verification_hash
|
561
562
|
if @log.error?
|
562
563
|
@log.error("[check] not a valid blockchain reciept - no target element in target_proof.0")
|
563
564
|
@log.error(reciept)
|
@@ -569,26 +570,26 @@ module VChainClient
|
|
569
570
|
break
|
570
571
|
end
|
571
572
|
|
572
|
-
|
573
|
-
|
574
|
-
|
573
|
+
# verification_hash is in tree
|
574
|
+
# and in right position
|
575
|
+
# now,
|
575
576
|
|
576
|
-
|
577
|
-
|
578
|
-
|
577
|
+
# 3. check tree convergence to root hash
|
578
|
+
# and compare this computed root hash
|
579
|
+
# with merkle_tree_root_hash from response
|
579
580
|
if @log.debug?
|
580
581
|
@log.debug("will now build merkle tree with")
|
581
582
|
@log.debug(reciept["target_proof"])
|
582
583
|
@log.debug(reciept["timestamp"])
|
583
584
|
end
|
584
585
|
|
585
|
-
|
586
|
+
computed_tree_root_hash = self.build_merkle_tree(reciept["target_proof"], reciept["timestamp"])
|
586
587
|
|
587
588
|
if @log.debug?
|
588
589
|
@log.debug("computed tree root hash = "+ computed_tree_root_hash)
|
589
590
|
end
|
590
591
|
|
591
|
-
|
592
|
+
if computed_tree_root_hash == nil
|
592
593
|
if @log.error?
|
593
594
|
@log.error("[check] not a valid blockchain reciept - failed to compute tree root hash")
|
594
595
|
@log.error(reciept)
|
@@ -599,7 +600,7 @@ module VChainClient
|
|
599
600
|
|
600
601
|
break
|
601
602
|
end
|
602
|
-
|
603
|
+
if computed_tree_root_hash != reciept["merkle_tree_root_hash"]
|
603
604
|
if @log.error?
|
604
605
|
@log.error("[check] not a valid blockchain reciept - merkle tree root hash mismatch ("+ computed_tree_root_hash +", "+ reciept["merkle_tree_root_hash"] +")")
|
605
606
|
@log.error(reciept)
|
@@ -611,9 +612,9 @@ module VChainClient
|
|
611
612
|
break
|
612
613
|
end
|
613
614
|
|
614
|
-
|
615
|
-
|
616
|
-
|
615
|
+
last_proof_index = reciept["target_proof"].length - 1
|
616
|
+
reciept_stored_last_parent = reciept["target_proof"][last_proof_index]["parent"]
|
617
|
+
if reciept_stored_last_parent != computed_tree_root_hash
|
617
618
|
if @log.error?
|
618
619
|
@log.error("[check] not a valid blockchain reciept - last stored parent != computed_tree_root_hash ("+ reciept_stored_last_parent +", "+ computed_tree_root_hash +")")
|
619
620
|
@log.error(reciept)
|
@@ -625,11 +626,11 @@ module VChainClient
|
|
625
626
|
break
|
626
627
|
end
|
627
628
|
|
628
|
-
|
629
|
-
|
630
|
-
|
629
|
+
# 4. check OP_RETURN in Bitcoin's tx,
|
630
|
+
# compare it to computed root hash of a tree
|
631
|
+
# retrieve some info from tx to verify signature
|
631
632
|
tx = nil
|
632
|
-
|
633
|
+
|
633
634
|
begin
|
634
635
|
|
635
636
|
tx = blockchainConnection.getTx(reciept["blockchain_txid"])
|
@@ -655,7 +656,7 @@ module VChainClient
|
|
655
656
|
@log.debug(tx)
|
656
657
|
end
|
657
658
|
|
658
|
-
|
659
|
+
if tx == nil
|
659
660
|
if @log.error?
|
660
661
|
@log.error("[check] not a valid blockchain reciept - failed to retrieve TX from Blockchain")
|
661
662
|
@log.error(reciept)
|
@@ -667,7 +668,7 @@ module VChainClient
|
|
667
668
|
break
|
668
669
|
end
|
669
670
|
|
670
|
-
|
671
|
+
if tx["block_hash"] != reciept["blockchain_block_hash"]
|
671
672
|
if @log.error?
|
672
673
|
@log.error("[check] not a valid blockchain reciept - block_hash mismatch")
|
673
674
|
@log.error(tx)
|
@@ -680,7 +681,7 @@ module VChainClient
|
|
680
681
|
break
|
681
682
|
end
|
682
683
|
|
683
|
-
|
684
|
+
if tx["block_timestamp"] != reciept["blockchain_timestamp"]
|
684
685
|
if @log.error?
|
685
686
|
@log.error("[check] not a valid blockchain reciept - timestamp mismatch")
|
686
687
|
@log.error(tx)
|
@@ -693,7 +694,7 @@ module VChainClient
|
|
693
694
|
break
|
694
695
|
end
|
695
696
|
|
696
|
-
|
697
|
+
if tx["op_return"] != computed_tree_root_hash
|
697
698
|
if @log.error?
|
698
699
|
@log.error("[check] not a valid blockchain reciept - op_return mismatch")
|
699
700
|
@log.error(computed_tree_root_hash)
|
@@ -707,9 +708,9 @@ module VChainClient
|
|
707
708
|
break
|
708
709
|
end
|
709
710
|
|
710
|
-
|
711
|
-
|
712
|
-
|
711
|
+
blockchain_txid = reciept["blockchain_txid"];
|
712
|
+
blockchain_block_hash = tx["block_hash"];
|
713
|
+
blockchain_timestamp = tx["block_timestamp"];
|
713
714
|
|
714
715
|
if @log.debug?
|
715
716
|
@log.debug(blockchain_txid)
|
@@ -717,14 +718,14 @@ module VChainClient
|
|
717
718
|
@log.debug(blockchain_timestamp)
|
718
719
|
end
|
719
720
|
|
720
|
-
|
721
|
-
|
722
|
-
|
721
|
+
# 5. check tree signature:
|
722
|
+
# a) federative server record in Blockstack (recursive)
|
723
|
+
# b) tree_signature
|
723
724
|
|
724
|
-
|
725
|
+
# a) federative server record in Blockstack (recursive)
|
725
726
|
begin
|
726
727
|
|
727
|
-
|
728
|
+
if !blockstackClient.checkFederativeServer(reciept["federative_server_id"])
|
728
729
|
if @log.error?
|
729
730
|
@log.error("[check] not a valid blockchain reciept - failed to check federative server")
|
730
731
|
@log.error("-> client_id: #{client_id}")
|
@@ -753,11 +754,11 @@ module VChainClient
|
|
753
754
|
raise e
|
754
755
|
end
|
755
756
|
|
756
|
-
|
757
|
+
# b) check tree signature
|
757
758
|
federative_server_pubkey = nil
|
758
759
|
|
759
760
|
begin
|
760
|
-
|
761
|
+
|
761
762
|
federative_server_pubkey = blockstackClient.getPublicKey(reciept["federative_server_id"])
|
762
763
|
|
763
764
|
rescue => e
|
@@ -796,7 +797,7 @@ module VChainClient
|
|
796
797
|
|
797
798
|
begin
|
798
799
|
|
799
|
-
|
800
|
+
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)
|
800
801
|
if @log.error?
|
801
802
|
@log.error("[check] not a valid blockchain reciept - failed to verify tree signature")
|
802
803
|
@log.error("-> client_id: #{client_id}")
|
@@ -839,10 +840,10 @@ module VChainClient
|
|
839
840
|
raise e
|
840
841
|
end
|
841
842
|
|
842
|
-
|
843
|
-
|
843
|
+
reciepts_validated += 1
|
844
|
+
}
|
844
845
|
|
845
|
-
|
846
|
+
if reciepts_validated != verification["blockchain_reciepts"].length
|
846
847
|
if @log.error?
|
847
848
|
@log.error("[check] not a valid verification - not every reciept were validated")
|
848
849
|
@log.error("field '"+ field +"'")
|
@@ -853,16 +854,16 @@ module VChainClient
|
|
853
854
|
next
|
854
855
|
end
|
855
856
|
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
857
|
+
# 6. check verification signatures:
|
858
|
+
# a) check verificator record in Blockstack (recursive)
|
859
|
+
# b) check validator record in Blockstack (recursive)
|
860
|
+
# c) verificator_sig
|
861
|
+
# d) validtor_sig
|
862
|
+
|
863
|
+
# a) check verificator record in Blockstack (recursive)
|
863
864
|
begin
|
864
865
|
|
865
|
-
|
866
|
+
if !blockstackClient.checkVerificator(verification["verificator_id"])
|
866
867
|
if @log.error?
|
867
868
|
@log.error("[check] not a valid verification - failed to check verificator record")
|
868
869
|
@log.error("-> client_id: #{client_id}")
|
@@ -891,10 +892,10 @@ module VChainClient
|
|
891
892
|
raise e
|
892
893
|
end
|
893
894
|
|
894
|
-
|
895
|
+
# b) check validator record in Blockstack (recursive)
|
895
896
|
begin
|
896
897
|
|
897
|
-
|
898
|
+
if !blockstackClient.checkValidator(verification["validator_id"])
|
898
899
|
if @log.error?
|
899
900
|
@log.error("[check] not a valid verification - failed to check validator record")
|
900
901
|
@log.error("-> client_id: #{client_id}")
|
@@ -923,7 +924,7 @@ module VChainClient
|
|
923
924
|
raise e
|
924
925
|
end
|
925
926
|
|
926
|
-
|
927
|
+
# c) check verificator's signature
|
927
928
|
verificator_pubkey = nil
|
928
929
|
|
929
930
|
begin
|
@@ -966,7 +967,7 @@ module VChainClient
|
|
966
967
|
|
967
968
|
begin
|
968
969
|
|
969
|
-
|
970
|
+
if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["verificator_id"], verificator_pubkey, Base64.decode64(verification["verificator_sig"]))
|
970
971
|
if @log.error?
|
971
972
|
@log.error("[check] not a valid verification - failed to check verificator signature")
|
972
973
|
@log.error("-> client_id: #{client_id}")
|
@@ -1007,12 +1008,12 @@ module VChainClient
|
|
1007
1008
|
raise e
|
1008
1009
|
end
|
1009
1010
|
|
1010
|
-
|
1011
|
+
# d) check validator's signature
|
1011
1012
|
validator_pubkey = nil
|
1012
1013
|
|
1013
1014
|
begin
|
1014
1015
|
|
1015
|
-
|
1016
|
+
validator_pubkey = blockstackClient.getPublicKey(verification["validator_id"])
|
1016
1017
|
|
1017
1018
|
rescue => e
|
1018
1019
|
if @log.error?
|
@@ -1050,7 +1051,7 @@ module VChainClient
|
|
1050
1051
|
|
1051
1052
|
begin
|
1052
1053
|
|
1053
|
-
|
1054
|
+
if !signaturesHelper.checkVerificationSignature(field_hash, data_hash, verification["type"], verification["timestamp"], verification["validator_id"], validator_pubkey, Base64.decode64(verification["validator_sig"]))
|
1054
1055
|
if @log.error?
|
1055
1056
|
@log.error("[check] not a valid verification - failed to check verificator signature")
|
1056
1057
|
@log.error("-> client_id: #{client_id}")
|
@@ -1091,15 +1092,15 @@ module VChainClient
|
|
1091
1092
|
raise e
|
1092
1093
|
end
|
1093
1094
|
|
1094
|
-
|
1095
|
-
|
1095
|
+
# 7. timestamps checking
|
1096
|
+
# TODO
|
1096
1097
|
|
1097
1098
|
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1099
|
+
if !validated_verifications.key?(field)
|
1100
|
+
validated_verifications[field] = 0
|
1101
|
+
end
|
1102
|
+
validated_verifications[field] = validated_verifications[field] + 1
|
1103
|
+
}
|
1103
1104
|
|
1104
1105
|
else
|
1105
1106
|
if @log.debug?
|
@@ -1110,29 +1111,50 @@ module VChainClient
|
|
1110
1111
|
|
1111
1112
|
@log.debug("[check] skip '"+ field +"', number of recieved verifications: "+ vers_count.to_s)
|
1112
1113
|
end
|
1113
|
-
|
1114
|
-
|
1114
|
+
end
|
1115
|
+
}
|
1115
1116
|
|
1116
1117
|
if @log.debug?
|
1117
1118
|
@log.debug("[check] temp validated verifications:")
|
1118
1119
|
@log.debug(validated_verifications)
|
1119
1120
|
end
|
1120
1121
|
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1122
|
+
# check input fields
|
1123
|
+
input.each_with_index { |field,index|
|
1124
|
+
if field[0] != 'type' && field[0] != 'client_id'
|
1125
|
+
if !validated_verifications.key?(field[0])
|
1126
|
+
validated_verifications[field[0]] = 0
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
}
|
1129
1130
|
|
1130
1131
|
if @log.debug?
|
1131
1132
|
@log.debug("[check] resulted validated verifications:")
|
1132
1133
|
@log.debug(validated_verifications)
|
1133
1134
|
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
if res["status"] == "ERROR" || res["status"] == "error"
|
1138
|
+
|
1139
|
+
if res["error_reason_code"] == "DOCUMENT_POSSIBLE_MISTAKES"
|
1140
|
+
if res.key?("possible_mistakes")
|
1141
|
+
res["possible_mistakes"].each_with_index { |field,index|
|
1142
|
+
res["possible_mistakes"][index] = validated_verifications[index]
|
1143
|
+
|
1144
|
+
validated_verifications.delete_at(index)
|
1145
|
+
}
|
1146
|
+
end
|
1147
|
+
end
|
1134
1148
|
|
1149
|
+
return {
|
1150
|
+
"status" => "error",
|
1151
|
+
"reason" => res["error_reason_code"]
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
else
|
1155
|
+
# success result
|
1135
1156
|
return validated_verifications
|
1157
|
+
|
1136
1158
|
end
|
1137
1159
|
end
|
1138
1160
|
|