vchain_client 1.0.31 → 1.0.32
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/blockstack_client.rb +164 -44
- data/lib/vchain_client/signatures.rb +3 -3
- data/lib/vchain_client.rb +80 -44
- metadata +3 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e4b2a962bad37488c062c7c29ddab6e411e5507
|
4
|
+
data.tar.gz: 67a335740fcc0a6c2ec7f8916c9fb1db0bb1e376
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c722e9d3ec77bfe1b028efd110256d44cf4a52a9c4c90b30dea97c8dc33a2d0e2a2ea8e34132e95c42592927e63c4a5f1fc1ad96df19714de32eb64cebafee6
|
7
|
+
data.tar.gz: 050f73ac82958a1b5ffc609bb2529f4ee150847162938e1621acda2e9b4a4d5f337211c59a901ddf7b3ee53508e54472bd0b0c6214de40018dc639d402587681
|
@@ -2,14 +2,15 @@ module VChainClient
|
|
2
2
|
|
3
3
|
class BlockstackClient
|
4
4
|
|
5
|
-
|
5
|
+
MASTER_ECC_PUBLIC_KEY = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXGOuvJT5hb/bR5y/JADHxJEEaQzuJUzw
|
6
6
|
Xet0UYuBrILjHB9HcxFc+WwuCflIRWtRDsNfaY6Ra7j/cRYLeiocYA=="
|
7
7
|
|
8
8
|
@config = nil
|
9
9
|
@log = nil
|
10
10
|
|
11
11
|
@@recs_cache = {}
|
12
|
-
@@
|
12
|
+
@@ecc_keys_cache = {}
|
13
|
+
@@rsa_keys_cache = {}
|
13
14
|
|
14
15
|
def initialize(config)
|
15
16
|
@config = config
|
@@ -138,7 +139,7 @@ module VChainClient
|
|
138
139
|
|
139
140
|
if record != nil
|
140
141
|
|
141
|
-
if record.key?("
|
142
|
+
if record.key?("ecc_pubkey")
|
142
143
|
|
143
144
|
if record.key?("vchain_role")
|
144
145
|
|
@@ -203,16 +204,16 @@ module VChainClient
|
|
203
204
|
|
204
205
|
end
|
205
206
|
|
206
|
-
|
207
|
+
validator_ecc_pub_key = nil
|
207
208
|
if record["vchain_role"] != 'validator'
|
208
209
|
|
209
210
|
begin
|
210
211
|
|
211
|
-
|
212
|
+
validator_ecc_pub_key = self.getPublicKeyECC(validator_blockstack_id)
|
212
213
|
|
213
214
|
rescue => e
|
214
215
|
if @log.error?
|
215
|
-
@log.error("[Blockstack.checkBlockstackRecord]
|
216
|
+
@log.error("[Blockstack.checkBlockstackRecord] getPublicKeyECC raised exception:")
|
216
217
|
@log.error("#{e.class}, #{e.message}")
|
217
218
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
218
219
|
@log.error("-> type: #{type}")
|
@@ -223,10 +224,10 @@ module VChainClient
|
|
223
224
|
end
|
224
225
|
|
225
226
|
else
|
226
|
-
|
227
|
+
validator_ecc_pub_key = MASTER_ECC_PUBLIC_KEY;
|
227
228
|
end
|
228
229
|
|
229
|
-
if
|
230
|
+
if validator_ecc_pub_key == nil
|
230
231
|
if @log.error?
|
231
232
|
@log.error("[Blockstack.checkBlockstackRecord] failed to retrieve public key:")
|
232
233
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
@@ -238,18 +239,36 @@ module VChainClient
|
|
238
239
|
end
|
239
240
|
|
240
241
|
# check client's sig
|
241
|
-
client_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["
|
242
|
+
client_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["ecc_pubkey"] + record["sig_version"];
|
243
|
+
|
244
|
+
validator_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["ecc_pubkey"] + record["sig_version"] + record["validator_vchain_id"] + validator_blockstack_id
|
245
|
+
|
246
|
+
if record["sig_version"] != "1"
|
247
|
+
|
248
|
+
# need to retrieve RSA key
|
249
|
+
if !record.key?("rsa_pubkey")
|
250
|
+
if @log.error?
|
251
|
+
@log.error("[Blockstack.checkBlockstackRecord] record doesn't have 'rsa_pubkey' field")
|
252
|
+
@log.error("-> blockstack_id: #{blockstack_id}")
|
253
|
+
@log.error("-> type: #{type}")
|
254
|
+
end
|
255
|
+
|
256
|
+
return false
|
257
|
+
end
|
258
|
+
|
259
|
+
client_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["ecc_pubkey"] + record["rsa_pubkey"] + record["sig_version"];
|
260
|
+
|
261
|
+
validator_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["ecc_pubkey"] + record["rsa_pubkey"] + record["sig_version"] + record["validator_vchain_id"] + validator_blockstack_id
|
262
|
+
end
|
242
263
|
|
243
264
|
begin
|
244
265
|
|
245
|
-
if signaturesHelper.verifySignature(client_sig_to_check, record["client_sig"], record["
|
266
|
+
if signaturesHelper.verifySignature(client_sig_to_check, record["client_sig"], record["ecc_pubkey"])
|
246
267
|
|
247
268
|
# check validator's sig
|
248
|
-
validator_sig_to_check = record["vchain_id"] + record["vchain_role"] + blockstack_id + record["pubkey"] + record["sig_version"] + record["validator_vchain_id"] + validator_blockstack_id
|
249
|
-
|
250
269
|
begin
|
251
270
|
|
252
|
-
if signaturesHelper.verifySignature(validator_sig_to_check, record["validator_sig"],
|
271
|
+
if signaturesHelper.verifySignature(validator_sig_to_check, record["validator_sig"], validator_ecc_pub_key)
|
253
272
|
|
254
273
|
return true;
|
255
274
|
|
@@ -260,7 +279,7 @@ module VChainClient
|
|
260
279
|
@log.error("-> type: #{type}")
|
261
280
|
@log.error("--> validator_sig_to_check: #{validator_sig_to_check}")
|
262
281
|
@log.error("--> validator_sig: "+ Base64.encode64(record["validator_sig"]))
|
263
|
-
@log.error("-->
|
282
|
+
@log.error("--> validator_ecc_pub_key: #{validator_ecc_pub_key}")
|
264
283
|
end
|
265
284
|
|
266
285
|
return false
|
@@ -274,7 +293,7 @@ module VChainClient
|
|
274
293
|
@log.error("-> type: #{type}")
|
275
294
|
@log.error("--> validator_sig_to_check: #{validator_sig_to_check}")
|
276
295
|
@log.error("--> validator_sig: "+ Base64.encode64(record["validator_sig"]))
|
277
|
-
@log.error("-->
|
296
|
+
@log.error("--> validator_ecc_pub_key: #{validator_ecc_pub_key}")
|
278
297
|
end
|
279
298
|
|
280
299
|
raise e
|
@@ -287,7 +306,7 @@ module VChainClient
|
|
287
306
|
@log.error("-> type: #{type}")
|
288
307
|
@log.error("--> client_sig_to_check: #{client_sig_to_check}")
|
289
308
|
@log.error("--> client_sig: "+ Base64.encode64(record["client_sig"]))
|
290
|
-
@log.error("-->
|
309
|
+
@log.error("--> ecc_pubkey: "+ record["ecc_pubkey"])
|
291
310
|
end
|
292
311
|
|
293
312
|
return false
|
@@ -301,7 +320,7 @@ module VChainClient
|
|
301
320
|
@log.error("-> type: #{type}")
|
302
321
|
@log.error("--> client_sig_to_check: #{client_sig_to_check}")
|
303
322
|
@log.error("--> client_sig: "+ Base64.encode64(record["client_sig"]))
|
304
|
-
@log.error("-->
|
323
|
+
@log.error("--> ecc_pubkey: "+ record["ecc_pubkey"])
|
305
324
|
end
|
306
325
|
|
307
326
|
raise e
|
@@ -317,7 +336,7 @@ module VChainClient
|
|
317
336
|
|
318
337
|
else
|
319
338
|
if @log.error?
|
320
|
-
@log.error("[Blockstack.checkBlockstackRecord] record doesn't have '
|
339
|
+
@log.error("[Blockstack.checkBlockstackRecord] record doesn't have 'ecc_pubkey' field")
|
321
340
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
322
341
|
@log.error("-> type: #{type}")
|
323
342
|
end
|
@@ -334,41 +353,107 @@ module VChainClient
|
|
334
353
|
return false
|
335
354
|
end
|
336
355
|
|
337
|
-
def
|
356
|
+
def getPublicKeyECC(blockstack_id, force_refresh=false)
|
338
357
|
|
339
358
|
if @log.debug?
|
340
|
-
@log.debug("[Blockstack.
|
359
|
+
@log.debug("[Blockstack.getPublicKeyECC] input:")
|
341
360
|
@log.debug("-> blockstack_id: #{blockstack_id}")
|
342
361
|
end
|
343
362
|
|
344
|
-
if
|
363
|
+
if !force_refresh
|
364
|
+
if @@ecc_keys_cache.key?(blockstack_id)
|
345
365
|
|
346
|
-
|
347
|
-
|
366
|
+
if @log.debug?
|
367
|
+
@log.debug("[Blockstack.getPublicKeyECC] '#{blockstack_id}' is in a cache")
|
368
|
+
end
|
369
|
+
|
370
|
+
return @@ecc_keys_cache[blockstack_id]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
if @log.debug?
|
375
|
+
@log.debug("[Blockstack.getPublicKeyECC] '#{blockstack_id}' is not in a cache yet")
|
376
|
+
end
|
377
|
+
|
378
|
+
begin
|
379
|
+
|
380
|
+
record = self.getBlockstackRecord(blockstack_id, force_refresh);
|
381
|
+
|
382
|
+
if record != nil
|
383
|
+
|
384
|
+
if record.key?("ecc_pubkey")
|
385
|
+
|
386
|
+
@@ecc_keys_cache[blockstack_id] = record["ecc_pubkey"]
|
387
|
+
|
388
|
+
return record["ecc_pubkey"]
|
389
|
+
|
390
|
+
else
|
391
|
+
if @log.error?
|
392
|
+
@log.error("[Blockstack.getPublicKeyECC] record '#{blockstack_id}' doesn't have 'ecc_pubkey' field")
|
393
|
+
@log.error("-> blockstack_id: #{blockstack_id}")
|
394
|
+
@log.error("--> blockstack_id: #{blockstack_id}")
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
else
|
399
|
+
if @log.error?
|
400
|
+
@log.error("[Blockstack.getPublicKeyECC] failed to retrieve '#{blockstack_id}' record")
|
401
|
+
@log.error("-> blockstack_id: #{blockstack_id}")
|
402
|
+
@log.error("--> blockstack_id: #{blockstack_id}")
|
403
|
+
end
|
348
404
|
end
|
349
405
|
|
350
|
-
|
406
|
+
rescue => e
|
407
|
+
if @log.error?
|
408
|
+
@log.error("[Blockstack.getPublicKeyECC] getBlockstackRecord raised exception:")
|
409
|
+
@log.error("#{e.class}, #{e.message}")
|
410
|
+
@log.error("-> blockstack_id: #{blockstack_id}")
|
411
|
+
@log.error("--> blockstack_id: #{blockstack_id}")
|
412
|
+
end
|
413
|
+
|
414
|
+
raise e
|
415
|
+
end
|
416
|
+
|
417
|
+
return nil
|
418
|
+
end
|
419
|
+
|
420
|
+
def getPublicKeyRSA(blockstack_id, force_refresh=false)
|
421
|
+
|
422
|
+
if @log.debug?
|
423
|
+
@log.debug("[Blockstack.getPublicKeyRSA] input:")
|
424
|
+
@log.debug("-> blockstack_id: #{blockstack_id}")
|
425
|
+
end
|
426
|
+
|
427
|
+
if !force_refresh
|
428
|
+
if @@rsa_keys_cache.key?(blockstack_id)
|
429
|
+
|
430
|
+
if @log.debug?
|
431
|
+
@log.debug("[Blockstack.getPublicKeyRSA] '#{blockstack_id}' is in a cache")
|
432
|
+
end
|
433
|
+
|
434
|
+
return @@rsa_keys_cache[blockstack_id]
|
435
|
+
end
|
351
436
|
end
|
352
437
|
|
353
438
|
if @log.debug?
|
354
|
-
@log.debug("[Blockstack.
|
439
|
+
@log.debug("[Blockstack.getPublicKeyRSA] '#{blockstack_id}' is not in a cache yet")
|
355
440
|
end
|
356
441
|
|
357
442
|
begin
|
358
443
|
|
359
|
-
record = self.getBlockstackRecord(blockstack_id);
|
444
|
+
record = self.getBlockstackRecord(blockstack_id, force_refresh);
|
360
445
|
|
361
446
|
if record != nil
|
362
447
|
|
363
|
-
if record.key?("
|
448
|
+
if record.key?("rsa_pubkey")
|
364
449
|
|
365
|
-
@@
|
450
|
+
@@rsa_keys_cache[blockstack_id] = record["rsa_pubkey"]
|
366
451
|
|
367
|
-
return record["
|
452
|
+
return record["rsa_pubkey"]
|
368
453
|
|
369
454
|
else
|
370
455
|
if @log.error?
|
371
|
-
@log.error("[Blockstack.
|
456
|
+
@log.error("[Blockstack.getPublicKeyRSA] record '#{blockstack_id}' doesn't have 'rsa_pubkey' field")
|
372
457
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
373
458
|
@log.error("--> blockstack_id: #{blockstack_id}")
|
374
459
|
end
|
@@ -376,7 +461,7 @@ module VChainClient
|
|
376
461
|
|
377
462
|
else
|
378
463
|
if @log.error?
|
379
|
-
@log.error("[Blockstack.
|
464
|
+
@log.error("[Blockstack.getPublicKeyRSA] failed to retrieve '#{blockstack_id}' record")
|
380
465
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
381
466
|
@log.error("--> blockstack_id: #{blockstack_id}")
|
382
467
|
end
|
@@ -384,7 +469,7 @@ module VChainClient
|
|
384
469
|
|
385
470
|
rescue => e
|
386
471
|
if @log.error?
|
387
|
-
@log.error("[Blockstack.
|
472
|
+
@log.error("[Blockstack.getPublicKeyRSA] getBlockstackRecord raised exception:")
|
388
473
|
@log.error("#{e.class}, #{e.message}")
|
389
474
|
@log.error("-> blockstack_id: #{blockstack_id}")
|
390
475
|
@log.error("--> blockstack_id: #{blockstack_id}")
|
@@ -396,19 +481,21 @@ module VChainClient
|
|
396
481
|
return nil
|
397
482
|
end
|
398
483
|
|
399
|
-
def getBlockstackRecord(blockstack_id)
|
484
|
+
def getBlockstackRecord(blockstack_id, force_refresh=false)
|
400
485
|
|
401
486
|
if @log.debug?
|
402
487
|
@log.debug("[Blockstack.getBlockstackRecord] input:")
|
403
488
|
@log.debug("-> blockstack_id: #{blockstack_id}")
|
404
489
|
end
|
405
490
|
|
406
|
-
if
|
407
|
-
if
|
408
|
-
|
409
|
-
|
491
|
+
if !force_refresh
|
492
|
+
if @@recs_cache.key?(blockstack_id)
|
493
|
+
if @log.debug?
|
494
|
+
@log.debug("[Blockstack.getBlockstackRecord] '#{blockstack_id}' is in a cache")
|
495
|
+
end
|
410
496
|
|
411
|
-
|
497
|
+
return @@recs_cache[blockstack_id]
|
498
|
+
end
|
412
499
|
end
|
413
500
|
|
414
501
|
blockstack_path = @config["blockstack"]["path"]
|
@@ -469,7 +556,7 @@ module VChainClient
|
|
469
556
|
recs = line.split(" ")
|
470
557
|
|
471
558
|
if recs.size == 3
|
472
|
-
if recs[0] == "A1" || recs[0] == "A2" || recs[0] == "A3" || recs[0] == "A4" || recs[0] == "A5" || recs[0] == "A6" || recs[0] == "A7" || recs[0] == "A8"
|
559
|
+
if recs[0] == "A1" || recs[0] == "A2" || recs[0] == "A3" || recs[0] == "A4" || recs[0] == "A5" || recs[0] == "A6" || recs[0] == "A7" || recs[0] == "A8" || recs[0] == "A9"
|
473
560
|
fz[recs[0]] = recs[2][1..-2]
|
474
561
|
end
|
475
562
|
end
|
@@ -480,13 +567,45 @@ module VChainClient
|
|
480
567
|
@log.debug(fz)
|
481
568
|
end
|
482
569
|
|
483
|
-
if fz.key?("A1") &&
|
570
|
+
if fz.key?("A1") &&
|
571
|
+
fz.key?("A2") &&
|
572
|
+
fz.key?("A3") &&
|
573
|
+
fz.key?("A4") &&
|
574
|
+
fz.key?("A5") &&
|
575
|
+
fz.key?("A6") &&
|
576
|
+
fz.key?("A7") &&
|
577
|
+
fz.key?("A8")
|
578
|
+
|
579
|
+
ecc_pubkey_aligned = fz["A1"]
|
580
|
+
ecc_pubkey = ecc_pubkey_aligned[0..63] + "\n" +
|
581
|
+
ecc_pubkey_aligned[64..ecc_pubkey_aligned.length]
|
484
582
|
|
485
|
-
|
486
|
-
|
583
|
+
rsa_pubkey = nil
|
584
|
+
if fz["A7"] != "1"
|
585
|
+
|
586
|
+
if !fz.key?("A9")
|
587
|
+
if @log.error?
|
588
|
+
@log.error("[Blockstack.getBlockstackRecord] no 'A9' field, sig ver is >1")
|
589
|
+
@log.error("-> blockstack_id: #{blockstack_id}")
|
590
|
+
@log.error("--> blockstack_id: #{blockstack_id}")
|
591
|
+
end
|
592
|
+
|
593
|
+
return nil
|
594
|
+
end
|
595
|
+
|
596
|
+
rsa_pubkey_aligned = fz["A9"]
|
597
|
+
rsa_pubkey = rsa_pubkey_aligned[0..63] + "\n" +
|
598
|
+
rsa_pubkey_aligned[64..127] + "\n" +
|
599
|
+
rsa_pubkey_aligned[128..191] + "\n" +
|
600
|
+
rsa_pubkey_aligned[192..255] + "\n" +
|
601
|
+
rsa_pubkey_aligned[256..319] + "\n" +
|
602
|
+
rsa_pubkey_aligned[320..383] + "\n" +
|
603
|
+
rsa_pubkey_aligned[384..rsa_pubkey_aligned.length]
|
604
|
+
end
|
487
605
|
|
488
606
|
output = {
|
489
|
-
"
|
607
|
+
"ecc_pubkey" => ecc_pubkey,
|
608
|
+
"rsa_pubkey" => rsa_pubkey,
|
490
609
|
"vchain_id" => fz["A2"],
|
491
610
|
"validator_sig" => Base64.decode64(fz["A3"]),
|
492
611
|
"validator_vchain_id" => fz["A4"],
|
@@ -502,7 +621,8 @@ module VChainClient
|
|
502
621
|
end
|
503
622
|
|
504
623
|
@@recs_cache[blockstack_id] = output
|
505
|
-
@@
|
624
|
+
@@ecc_keys_cache[blockstack_id] = ecc_pubkey
|
625
|
+
@@rsa_keys_cache[blockstack_id] = rsa_pubkey
|
506
626
|
|
507
627
|
return output
|
508
628
|
|
@@ -17,7 +17,7 @@ module VChainClient
|
|
17
17
|
def signBatchRequest(batch, timestamp)
|
18
18
|
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
19
19
|
|
20
|
-
priv_key_path = @config["
|
20
|
+
priv_key_path = @config["ecc_private_key_location"]
|
21
21
|
|
22
22
|
if @log.debug?
|
23
23
|
@log.debug("[Signatures.signBatchRequest] input:")
|
@@ -160,7 +160,7 @@ module VChainClient
|
|
160
160
|
|
161
161
|
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
162
162
|
|
163
|
-
priv_key_path = @config["
|
163
|
+
priv_key_path = @config["ecc_private_key_location"]
|
164
164
|
|
165
165
|
if @log.debug?
|
166
166
|
@log.debug("[Signatures.signRequest] input:")
|
@@ -370,7 +370,7 @@ module VChainClient
|
|
370
370
|
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
371
371
|
|
372
372
|
this_client_id = @config["blockstack"]["client_id"]
|
373
|
-
priv_key_path = @config["
|
373
|
+
priv_key_path = @config["ecc_private_key_location"]
|
374
374
|
|
375
375
|
if @log.debug?
|
376
376
|
@log.debug("[Signatures.signDataPoint] input:")
|
data/lib/vchain_client.rb
CHANGED
@@ -5,7 +5,6 @@ module VChainClient
|
|
5
5
|
require 'rest-client'
|
6
6
|
require 'base64'
|
7
7
|
require 'openssl'
|
8
|
-
require 'openssl-pkey-ec-ies'
|
9
8
|
require 'log4r'
|
10
9
|
require 'json'
|
11
10
|
|
@@ -27,7 +26,7 @@ module VChainClient
|
|
27
26
|
|
28
27
|
DATA_POINT_VERSION = "1"
|
29
28
|
|
30
|
-
CLIENT_LIB_VERSION = "1.0.
|
29
|
+
CLIENT_LIB_VERSION = "1.0.32"
|
31
30
|
|
32
31
|
@config = nil
|
33
32
|
@log = nil
|
@@ -430,7 +429,7 @@ module VChainClient
|
|
430
429
|
}
|
431
430
|
|
432
431
|
client_id = @config["client_id"]
|
433
|
-
api_url = @config["api"]["url"] + "v0.
|
432
|
+
api_url = @config["api"]["url"] + "v0.3/batchAddDataPoint/"
|
434
433
|
|
435
434
|
whole_signature = nil
|
436
435
|
|
@@ -534,7 +533,7 @@ module VChainClient
|
|
534
533
|
def add_data_point(point_type, input, weight = 1)
|
535
534
|
|
536
535
|
client_id = @config["client_id"]
|
537
|
-
api_url = @config["api"]["url"] + "v0.
|
536
|
+
api_url = @config["api"]["url"] + "v0.3/addDataPoint/"
|
538
537
|
|
539
538
|
time = Time.now.getutc
|
540
539
|
timestamp = time.to_i
|
@@ -809,7 +808,7 @@ module VChainClient
|
|
809
808
|
|
810
809
|
client_id = @config["client_id"]
|
811
810
|
|
812
|
-
api_url = @config["api"]["url"] + "v0.
|
811
|
+
api_url = @config["api"]["url"] + "v0.3/check/";
|
813
812
|
|
814
813
|
document = input
|
815
814
|
|
@@ -841,37 +840,64 @@ module VChainClient
|
|
841
840
|
|
842
841
|
sent_document = document.clone
|
843
842
|
|
844
|
-
|
843
|
+
vchain_public_key_body = nil
|
845
844
|
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
@log.debug("-> hashed input:")
|
850
|
-
@log.debug(document)
|
851
|
-
end
|
845
|
+
begin
|
846
|
+
|
847
|
+
vchain_public_key_body = blockstackClient.getPublicKeyRSA("vchain_core_01.id")
|
852
848
|
|
853
|
-
|
854
|
-
|
849
|
+
rescue => e
|
850
|
+
if @log.error?
|
851
|
+
@log.error("[check] failed to retrieve vchain public RSA key from Blockstack")
|
852
|
+
@log.error("#{e.class}, #{e.message}")
|
853
|
+
end
|
855
854
|
|
856
|
-
|
855
|
+
raise e
|
856
|
+
end
|
857
|
+
|
858
|
+
if vchain_public_key_body == nil
|
857
859
|
if @log.error?
|
858
|
-
@log.error("[check] failed to
|
860
|
+
@log.error("[check] failed to retrieve vchain public RSA key from Blockstack")
|
859
861
|
end
|
860
862
|
|
861
863
|
return false
|
862
864
|
end
|
863
865
|
|
864
|
-
|
865
|
-
|
866
|
-
|
866
|
+
vchain_public_key_str = "-----BEGIN PUBLIC KEY-----\n"
|
867
|
+
vchain_public_key_str += vchain_public_key_body
|
868
|
+
vchain_public_key_str += "\n-----END PUBLIC KEY-----"
|
867
869
|
|
868
|
-
|
869
|
-
|
870
|
-
encrypted_doc = Base64.encode64(vchain_pubkey.public_encrypt(document.to_json))
|
870
|
+
vchain_public_key = OpenSSL::PKey::RSA.new(vchain_public_key_str)
|
871
871
|
|
872
|
-
|
872
|
+
cif = OpenSSL::Cipher.new('AES-256-CBC')
|
873
873
|
|
874
|
-
|
874
|
+
cif.encrypt
|
875
|
+
|
876
|
+
cif.key = key = cif.random_key
|
877
|
+
cif.iv = iv = cif.random_iv
|
878
|
+
|
879
|
+
encoded_doc = cif.update(document.to_json) +
|
880
|
+
cif.final
|
881
|
+
|
882
|
+
encoded_key = vchain_public_key.public_encrypt(key, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
883
|
+
|
884
|
+
encoded_iv = vchain_public_key.public_encrypt(iv, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
885
|
+
|
886
|
+
doc_to_send = {
|
887
|
+
"key" => Base64.encode64(encoded_key),
|
888
|
+
"iv" => Base64.encode64(encoded_iv),
|
889
|
+
"payload" => Base64.encode64(encoded_doc),
|
890
|
+
"client_id" => client_id
|
891
|
+
}
|
892
|
+
|
893
|
+
if @log.debug?
|
894
|
+
@log.debug("[check] will call "+ api_url +" using vchain_client_id "+ client_id)
|
895
|
+
@log.debug("-> is_already_hashed: #{is_already_hashed}")
|
896
|
+
@log.debug("-> hashed input:")
|
897
|
+
@log.debug(document)
|
898
|
+
@log.debug("-> sending:")
|
899
|
+
@log.debug(doc_to_send)
|
900
|
+
end
|
875
901
|
|
876
902
|
req = nil
|
877
903
|
|
@@ -885,7 +911,7 @@ module VChainClient
|
|
885
911
|
res = RestClient::Resource.new api_url
|
886
912
|
end
|
887
913
|
|
888
|
-
req = res.post
|
914
|
+
req = res.post doc_to_send.to_json, :content_type => 'application/json'
|
889
915
|
|
890
916
|
if req.code != 200
|
891
917
|
|
@@ -1526,46 +1552,54 @@ module VChainClient
|
|
1526
1552
|
return output
|
1527
1553
|
end
|
1528
1554
|
|
1529
|
-
def self.generateBlockstackCommand(config)
|
1555
|
+
def self.generateBlockstackCommand(config, role, validator_sig = nil)
|
1530
1556
|
|
1531
1557
|
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
1532
1558
|
|
1533
1559
|
blockstack_id = config["blockstack"]["client_id"]
|
1534
1560
|
|
1535
|
-
#A1 pubkey
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1561
|
+
#A1 ECC pubkey
|
1562
|
+
ecc_public_key_location = config["ecc_public_key_location"]
|
1563
|
+
ecc_pub_key = File.read(ecc_public_key_location)
|
1564
|
+
ecc_pub_key.slice! "-----BEGIN PUBLIC KEY-----\n"
|
1565
|
+
ecc_pub_key.slice! "\n-----END PUBLIC KEY-----\n"
|
1566
|
+
ecc_pub_key_aligned = ecc_pub_key.gsub(/\n/, "")
|
1541
1567
|
|
1542
1568
|
#A2 vchain_client_id
|
1543
1569
|
vchain_client_id = config["client_id"]
|
1544
1570
|
|
1545
|
-
#A3 validator_sig
|
1546
|
-
validator_sig = nil
|
1547
|
-
if config.key?("validator_sig")
|
1548
|
-
validator_sig = config["validator_sig"]
|
1549
|
-
end
|
1550
|
-
|
1551
1571
|
#A4 validator_vchain_id
|
1552
1572
|
validator_vchain_id = "da93b5f7-2295-4435-a67a-4fc226eca3ac"
|
1573
|
+
#validator_vchain_id = "35645858-630d-4873-9a2d-1ea7ec3b6d10"
|
1553
1574
|
|
1554
1575
|
#A5 validator_blockstack_id
|
1555
1576
|
validator_blockstack_id = "vchain_core_01.id"
|
1577
|
+
#validator_blockstack_id = "master"
|
1556
1578
|
|
1557
1579
|
#A6 vchain_role
|
1558
|
-
vchain_role =
|
1580
|
+
vchain_role = role
|
1559
1581
|
|
1560
1582
|
#A7 sig_version
|
1561
|
-
sig_version = "
|
1583
|
+
sig_version = "2"
|
1562
1584
|
|
1563
1585
|
#A8 client_sig
|
1564
1586
|
client_sig = nil
|
1565
|
-
priv_key_path = config["
|
1587
|
+
priv_key_path = config["ecc_private_key_location"]
|
1566
1588
|
priv_key = File.read(priv_key_path)
|
1567
1589
|
|
1568
|
-
|
1590
|
+
#A9 RSA pubkey
|
1591
|
+
rsa_public_key_location = config["rsa_public_key_location"]
|
1592
|
+
rsa_pub_key = File.read(rsa_public_key_location)
|
1593
|
+
rsa_pub_key.slice! "-----BEGIN PUBLIC KEY-----\n"
|
1594
|
+
rsa_pub_key.slice! "\n-----END PUBLIC KEY-----\n"
|
1595
|
+
rsa_pub_key_aligned = rsa_pub_key.gsub(/\n/, "")
|
1596
|
+
|
1597
|
+
whole_sign = vchain_client_id +
|
1598
|
+
vchain_role +
|
1599
|
+
blockstack_id +
|
1600
|
+
ecc_pub_key +
|
1601
|
+
rsa_pub_key +
|
1602
|
+
sig_version
|
1569
1603
|
|
1570
1604
|
ec = OpenSSL::PKey::EC.new(priv_key)
|
1571
1605
|
digest = OpenSSL::Digest::SHA256.new
|
@@ -1578,7 +1612,8 @@ module VChainClient
|
|
1578
1612
|
|
1579
1613
|
puts "blockstack_id = " + blockstack_id
|
1580
1614
|
puts "vchain_client_id = " + vchain_client_id
|
1581
|
-
puts "
|
1615
|
+
puts "ecc_pub_key = "+ ecc_pub_key_aligned
|
1616
|
+
puts "rsa_pub_key = "+ rsa_pub_key_aligned
|
1582
1617
|
puts "validator_vchain_id = "+ validator_vchain_id
|
1583
1618
|
puts "vchain_role = " + vchain_role
|
1584
1619
|
puts "client_sig = " + client_sig
|
@@ -1586,7 +1621,7 @@ module VChainClient
|
|
1586
1621
|
else
|
1587
1622
|
puts "BLOCKSTACK_DEBUG=1 blockstack update "+ blockstack_id +" '$ORIGIN "+ blockstack_id +"
|
1588
1623
|
$TTL 3600
|
1589
|
-
A1 TXT \""+
|
1624
|
+
A1 TXT \""+ ecc_pub_key_aligned +"\"
|
1590
1625
|
A2 TXT \""+ vchain_client_id +"\"
|
1591
1626
|
A3 TXT \""+ validator_sig +"\"
|
1592
1627
|
A4 TXT \""+ validator_vchain_id +"\"
|
@@ -1594,6 +1629,7 @@ A5 TXT \""+ validator_blockstack_id +"\"
|
|
1594
1629
|
A6 TXT \""+ vchain_role +"\"
|
1595
1630
|
A7 TXT \""+ sig_version +"\"
|
1596
1631
|
A8 TXT \""+ client_sig +"\"
|
1632
|
+
A9 TXT \""+ rsa_pub_key_aligned +"\"
|
1597
1633
|
_tcp._http URI 10 1 \"http://example.com\"
|
1598
1634
|
'"
|
1599
1635
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vchain_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksandr Gorelik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: log4r
|
@@ -70,26 +70,6 @@ dependencies:
|
|
70
70
|
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 2.0.0
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
|
-
name: openssl-pkey-ec-ies
|
75
|
-
requirement: !ruby/object:Gem::Requirement
|
76
|
-
requirements:
|
77
|
-
- - "~>"
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: 0.0.1
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.0.1
|
83
|
-
type: :runtime
|
84
|
-
prerelease: false
|
85
|
-
version_requirements: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 0.0.1
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: 0.0.1
|
93
73
|
description: Fully functional client for VChain Platform written on Ruby. For more
|
94
74
|
info visit https://bitbucket.org/vchain_dev/ruby-client
|
95
75
|
email: alexander@vchain.tech
|
@@ -127,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
107
|
version: '0'
|
128
108
|
requirements: []
|
129
109
|
rubyforge_project:
|
130
|
-
rubygems_version: 2.
|
110
|
+
rubygems_version: 2.6.10
|
131
111
|
signing_key:
|
132
112
|
specification_version: 4
|
133
113
|
summary: VChain Platform client written on Ruby
|