security_client 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 055b4ebf4046542527af7b8df744c592ff0921a8e5d08af6f470e2e72c96c8c2
4
- data.tar.gz: 694fa499f049beaae0480892cb2b2bc0100f1e22fed3eb94ab80c250b026d1a0
3
+ metadata.gz: 7640165682c873870551c45afd84185c197cfeb8a00ca31b8f52ceabe500168e
4
+ data.tar.gz: c413c6901b56ff802ea984cec4b36616113254add9c06e96cb1c6235e6ee7787
5
5
  SHA512:
6
- metadata.gz: 0cb89ec2fca2a529d4a75c39505efcaefd6fd2b1716ec435cc206e56d7b7d03bd8f67b1437295c936147425d062afd6c0422ae5ba2854aefa4da31f01ff476e9
7
- data.tar.gz: 1e6dc6e527eb4d63796d96f000f37245d5b83cf19a7eb9d72c26c955a797099889138d7f1178492a012ba4a5a9915188b58ccfdfda8db09ccb1ea810a94ff7c1
6
+ metadata.gz: a3586c80fb88719b618ed1ff4bebb50c3c3fbfb5f87d5b3e7144e8b6ceda8046a4452c339251ed849551480d02a8de1b599f1cb12b673b0b94b89220bee00c33
7
+ data.tar.gz: 7e5bdd1ef3c9bf4d1e76b1d1503f1a32122891ebfee8250b4db2ce9bda381bd99ec5c84e59b42a98b1dd9c81afaaab685ae04d189a288bce98787ade279a9862
@@ -350,194 +350,194 @@ class SecurityClient::Decryption
350
350
  @decryption_ready = true
351
351
  @decryption_started = false
352
352
 
353
- end
353
+ end
354
354
 
355
- def endpoint_base
356
- @host + '/api/v0'
357
- end
355
+ def endpoint_base
356
+ @host + '/api/v0'
357
+ end
358
358
 
359
- def endpoint
360
- '/api/v0/decryption/key'
361
- end
359
+ def endpoint
360
+ '/api/v0/decryption/key'
361
+ end
362
362
 
363
- def begin
364
- # Begin the decryption process
363
+ def begin
364
+ # Begin the decryption process
365
365
 
366
- # This interface does not take any cipher text in its arguments
367
- # in an attempt to maintain an API that corresponds to the
368
- # encryption object. In doing so, the work that can take place
369
- # in this function is limited. without any data, there is no
370
- # way to determine which key is in use or decrypt any data.
371
- #
372
- # this function simply throws an error if starting an decryption
373
- # while one is already in progress, and initializes the internal
374
- # buffer
366
+ # This interface does not take any cipher text in its arguments
367
+ # in an attempt to maintain an API that corresponds to the
368
+ # encryption object. In doing so, the work that can take place
369
+ # in this function is limited. without any data, there is no
370
+ # way to determine which key is in use or decrypt any data.
371
+ #
372
+ # this function simply throws an error if starting an decryption
373
+ # while one is already in progress, and initializes the internal
374
+ # buffer
375
375
 
376
- raise RuntimeError, 'Decryption is not ready' if !@decryption_ready
376
+ raise RuntimeError, 'Decryption is not ready' if !@decryption_ready
377
377
 
378
- raise RuntimeError, 'Decryption Already Started' if @decryption_started
378
+ raise RuntimeError, 'Decryption Already Started' if @decryption_started
379
379
 
380
- raise RuntimeError, 'Decryption already in progress' if @key.present? and @key.key?("dec")
381
- @decryption_started = true
382
- @data = ''
383
- end
380
+ raise RuntimeError, 'Decryption already in progress' if @key.present? and @key.key?("dec")
381
+ @decryption_started = true
382
+ @data = ''
383
+ end
384
384
 
385
- def update(data)
386
- # Decryption of cipher text is performed here
387
- # Cipher text must be passed to this function in the order in which it was output from the encryption.update function.
388
-
389
- # Each encryption has a header on it that identifies the algorithm
390
- # used and an encryption of the data key that was used to encrypt
391
- # the original plain text. there is no guarantee how much of that
392
- # data will be passed to this function or how many times this
393
- # function will be called to process all of the data. to that end,
394
- # this function buffers data internally, when it is unable to
395
- # process it.
396
- #
397
- # The function buffers data internally until the entire header is
398
- # received. once the header has been received, the encrypted data
399
- # key is sent to the server for decryption. after the header has
400
- # been successfully handled, this function always decrypts all of
401
- # the data in its internal buffer *except* for however many bytes
402
- # are specified by the algorithm's tag size. see the end() function
403
- # for details.
404
-
405
- raise RuntimeError, 'Decryption is not Started' if !@decryption_started
406
-
407
- # Append the incoming data in the internal data buffer
408
- @data = @data + data
409
-
410
- # if there is no key or 'dec' member of key, then the code is still trying to build a complete header
411
- if !@key.present? or !@key.key?("dec")
412
- struct_length = [1,1,1,1,1].pack('CCCCn').length
413
- packed_struct = @data[0...struct_length]
414
-
415
- # Does the buffer contain enough of the header to
416
- # determine the lengths of the initialization vector
417
- # and the key?
418
- if @data.length > struct_length
419
- # Unpack the values packed in encryption
420
- version, flag_for_later, algorithm_id, iv_length, key_length = packed_struct.unpack('CCCCn')
421
-
422
- # verify flag and version are 0
423
- raise RuntimeError, 'invalid encryption header' if version != 0 or flag_for_later != 0
424
-
425
- # Does the buffer contain the entire header?
426
- if @data.length > struct_length + iv_length + key_length
427
- # Extract the initialization vector
428
- iv = @data[struct_length...iv_length + struct_length]
429
- # Extract the encryped key
430
- encrypted_key = @data[struct_length + iv_length...key_length + struct_length + iv_length]
431
- # Remove the header from the buffer
432
- @data = @data[struct_length + iv_length + key_length..-1]
433
-
434
- # generate a local identifier for the key
435
- hash_sha512 = OpenSSL::Digest::SHA512.new
436
- hash_sha512 << encrypted_key
437
- client_id = hash_sha512.digest
438
-
439
- if @key.present?
440
- if @key['client_id'] != client_id
441
- close()
385
+ def update(data)
386
+ # Decryption of cipher text is performed here
387
+ # Cipher text must be passed to this function in the order in which it was output from the encryption.update function.
388
+
389
+ # Each encryption has a header on it that identifies the algorithm
390
+ # used and an encryption of the data key that was used to encrypt
391
+ # the original plain text. there is no guarantee how much of that
392
+ # data will be passed to this function or how many times this
393
+ # function will be called to process all of the data. to that end,
394
+ # this function buffers data internally, when it is unable to
395
+ # process it.
396
+ #
397
+ # The function buffers data internally until the entire header is
398
+ # received. once the header has been received, the encrypted data
399
+ # key is sent to the server for decryption. after the header has
400
+ # been successfully handled, this function always decrypts all of
401
+ # the data in its internal buffer *except* for however many bytes
402
+ # are specified by the algorithm's tag size. see the end() function
403
+ # for details.
404
+
405
+ raise RuntimeError, 'Decryption is not Started' if !@decryption_started
406
+
407
+ # Append the incoming data in the internal data buffer
408
+ @data = @data + data
409
+
410
+ # if there is no key or 'dec' member of key, then the code is still trying to build a complete header
411
+ if !@key.present? or !@key.key?("dec")
412
+ struct_length = [1,1,1,1,1].pack('CCCCn').length
413
+ packed_struct = @data[0...struct_length]
414
+
415
+ # Does the buffer contain enough of the header to
416
+ # determine the lengths of the initialization vector
417
+ # and the key?
418
+ if @data.length > struct_length
419
+ # Unpack the values packed in encryption
420
+ version, flag_for_later, algorithm_id, iv_length, key_length = packed_struct.unpack('CCCCn')
421
+
422
+ # verify flag and version are 0
423
+ raise RuntimeError, 'invalid encryption header' if version != 0 or flag_for_later != 0
424
+
425
+ # Does the buffer contain the entire header?
426
+ if @data.length > struct_length + iv_length + key_length
427
+ # Extract the initialization vector
428
+ iv = @data[struct_length...iv_length + struct_length]
429
+ # Extract the encryped key
430
+ encrypted_key = @data[struct_length + iv_length...key_length + struct_length + iv_length]
431
+ # Remove the header from the buffer
432
+ @data = @data[struct_length + iv_length + key_length..-1]
433
+
434
+ # generate a local identifier for the key
435
+ hash_sha512 = OpenSSL::Digest::SHA512.new
436
+ hash_sha512 << encrypted_key
437
+ client_id = hash_sha512.digest
438
+
439
+ if @key.present?
440
+ if @key['client_id'] != client_id
441
+ close()
442
+ end
442
443
  end
443
- end
444
444
 
445
- # IF key object not exists, request a new one from the server
446
- if !@key.present?
447
- url = endpoint_base + "/decryption/key"
448
- query = {encrypted_data_key: Base64.strict_encode64(encrypted_key)}
449
- headers = Auth.build_headers(@papi, @sapi, endpoint, query, @host, 'post')
450
-
451
- response = HTTParty.post(
452
- url,
453
- body: query.to_json,
454
- headers: headers
455
- )
456
-
457
- # Response status is 200 OK
458
- if response.code == WEBrick::HTTPStatus::RC_OK
459
- @key = {}
460
- @key['finger_print'] = response['key_fingerprint']
461
- @key['client_id'] = client_id
462
- @key['session'] = response['encryption_session']
463
-
464
- @key['algorithm'] = 'aes-256-gcm'
465
-
466
- encrypted_private_key = response['encrypted_private_key']
467
- # Decrypt the encryped private key using SRSA
468
- private_key = OpenSSL::PKey::RSA.new(encrypted_private_key,@srsa)
469
-
470
- wrapped_data_key = response['wrapped_data_key']
471
- # Decode WDK from base64 format
472
- wdk = Base64.strict_decode64(wrapped_data_key)
473
- # Use private key to decrypt the wrapped data key
474
- dk = private_key.private_decrypt(wdk,OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
475
-
476
- @key['raw'] = dk
477
- @key['uses'] = 0
478
- else
479
- # Raise the error if response is not 200
480
- raise RuntimeError, "HTTPError Response: Expected 201, got #{response.code}"
445
+ # IF key object not exists, request a new one from the server
446
+ if !@key.present?
447
+ url = endpoint_base + "/decryption/key"
448
+ query = {encrypted_data_key: Base64.strict_encode64(encrypted_key)}
449
+ headers = Auth.build_headers(@papi, @sapi, endpoint, query, @host, 'post')
450
+
451
+ response = HTTParty.post(
452
+ url,
453
+ body: query.to_json,
454
+ headers: headers
455
+ )
456
+
457
+ # Response status is 200 OK
458
+ if response.code == WEBrick::HTTPStatus::RC_OK
459
+ @key = {}
460
+ @key['finger_print'] = response['key_fingerprint']
461
+ @key['client_id'] = client_id
462
+ @key['session'] = response['encryption_session']
463
+
464
+ @key['algorithm'] = 'aes-256-gcm'
465
+
466
+ encrypted_private_key = response['encrypted_private_key']
467
+ # Decrypt the encryped private key using SRSA
468
+ private_key = OpenSSL::PKey::RSA.new(encrypted_private_key,@srsa)
469
+
470
+ wrapped_data_key = response['wrapped_data_key']
471
+ # Decode WDK from base64 format
472
+ wdk = Base64.strict_decode64(wrapped_data_key)
473
+ # Use private key to decrypt the wrapped data key
474
+ dk = private_key.private_decrypt(wdk,OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
475
+
476
+ @key['raw'] = dk
477
+ @key['uses'] = 0
478
+ else
479
+ # Raise the error if response is not 200
480
+ raise RuntimeError, "HTTPError Response: Expected 201, got #{response.code}"
481
+ end
481
482
  end
482
- end
483
483
 
484
- # If the key object exists, create a new decryptor
485
- # with the initialization vector from the header and
486
- # the decrypted key (which is either new from the
487
- # server or cached from the previous decryption). in
488
- # either case, increment the key usage
484
+ # If the key object exists, create a new decryptor
485
+ # with the initialization vector from the header and
486
+ # the decrypted key (which is either new from the
487
+ # server or cached from the previous decryption). in
488
+ # either case, increment the key usage
489
489
 
490
- if @key.present?
491
- @algo = Algo.new.get_algo(@key['algorithm'])
492
- @key['dec'] = Algo.new.decryptor(@algo, @key['raw'], iv)
493
- @key['uses'] += 1
490
+ if @key.present?
491
+ @algo = Algo.new.get_algo(@key['algorithm'])
492
+ @key['dec'] = Algo.new.decryptor(@algo, @key['raw'], iv)
493
+ @key['uses'] += 1
494
+ end
494
495
  end
495
496
  end
496
497
  end
497
- end
498
498
 
499
- # if the object has a key and a decryptor, then decrypt whatever
500
- # data is in the buffer, less any data that needs to be saved to
501
- # serve as the tag.
502
- plain_text = ''
503
- if @key.present? and @key.key?("dec")
504
- size = @data.length - @algo[:tag_length]
505
- if size > 0
506
- puts @data[0..size-1]
507
-
508
- plain_text = @key['dec'].update(@data[0..size-1])
509
- @data = @data[size..-1]
499
+ # if the object has a key and a decryptor, then decrypt whatever
500
+ # data is in the buffer, less any data that needs to be saved to
501
+ # serve as the tag.
502
+ plain_text = ''
503
+ if @key.present? and @key.key?("dec")
504
+ size = @data.length - @algo[:tag_length]
505
+ if size > 0
506
+ puts @data[0..size-1]
507
+
508
+ plain_text = @key['dec'].update(@data[0..size-1])
509
+ @data = @data[size..-1]
510
+ end
511
+ return plain_text
510
512
  end
511
- return plain_text
512
- end
513
513
 
514
- end
514
+ end
515
515
 
516
- def end
517
- raise RuntimeError, 'Decryption is not Started' if !@decryption_started
518
- # The update function always maintains tag-size bytes in
519
- # the buffer because this function provides no data parameter.
520
- # by the time the caller calls this function, all data must
521
- # have already been input to the decryption object.
516
+ def end
517
+ raise RuntimeError, 'Decryption is not Started' if !@decryption_started
518
+ # The update function always maintains tag-size bytes in
519
+ # the buffer because this function provides no data parameter.
520
+ # by the time the caller calls this function, all data must
521
+ # have already been input to the decryption object.
522
522
 
523
- sz = @data.length - @algo[:tag_length]
523
+ sz = @data.length - @algo[:tag_length]
524
524
 
525
- raise RuntimeError, 'Invalid Tag!' if sz < 0
526
- if sz == 0
527
- @key['dec'].auth_tag = @data
528
- begin
529
- pt = @key['dec'].final
530
- # Delete the decryptor context
531
- @key.delete('dec')
532
- # Return the decrypted plain data
533
- @decryption_started = false
534
- return pt
535
- rescue Exception => e
536
- print 'Invalid cipher data or tag!'
537
- return ''
525
+ raise RuntimeError, 'Invalid Tag!' if sz < 0
526
+ if sz == 0
527
+ @key['dec'].auth_tag = @data
528
+ begin
529
+ pt = @key['dec'].final
530
+ # Delete the decryptor context
531
+ @key.delete('dec')
532
+ # Return the decrypted plain data
533
+ @decryption_started = false
534
+ return pt
535
+ rescue Exception => e
536
+ print 'Invalid cipher data or tag!'
537
+ return ''
538
+ end
538
539
  end
539
540
  end
540
- end
541
541
 
542
542
  def close
543
543
  raise RuntimeError, 'Decryption currently running' if @decryption_started
@@ -1,3 +1,3 @@
1
1
  module SecurityClient
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: security_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - vinaymehta