vchain_client 1.0.9 → 1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|