ccipher_factory 0.1.0
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 +7 -0
- data/.rspec +3 -0
- data/Gemfile +30 -0
- data/Gemfile.lock-java +65 -0
- data/Gemfile.lock-ruby +67 -0
- data/README.md +80 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ccipher_factory.gemspec +46 -0
- data/lib/ccipher_factory/asymkey/asymkey.rb +16 -0
- data/lib/ccipher_factory/asymkey/asymkey_generator.rb +87 -0
- data/lib/ccipher_factory/asymkey/ecc_keypair.rb +56 -0
- data/lib/ccipher_factory/asymkey_cipher/asymkey_cipher.rb +63 -0
- data/lib/ccipher_factory/asymkey_cipher/asymkey_signer.rb +44 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_decrypt.rb +55 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_encrypt.rb +70 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_signer.rb +88 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_verifier.rb +100 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_decrypt.rb +80 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_encrypt.rb +101 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_signer.rb +80 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_verifier.rb +56 -0
- data/lib/ccipher_factory/composite_cipher/composite_cipher.rb +28 -0
- data/lib/ccipher_factory/composite_cipher/decrypt_verifier.rb +116 -0
- data/lib/ccipher_factory/composite_cipher/sign_encryptor.rb +100 -0
- data/lib/ccipher_factory/compression/compression_helper.rb +103 -0
- data/lib/ccipher_factory/compression/compressor.rb +55 -0
- data/lib/ccipher_factory/compression/zlib_compressor.rb +48 -0
- data/lib/ccipher_factory/compression/zlib_decompressor.rb +67 -0
- data/lib/ccipher_factory/digest/digest.rb +180 -0
- data/lib/ccipher_factory/digest/supported_digest.rb +47 -0
- data/lib/ccipher_factory/encoding/asn1.rb +43 -0
- data/lib/ccipher_factory/encoding/bin_struct.rb +207 -0
- data/lib/ccipher_factory/encoding/binenc_constant.rb +149 -0
- data/lib/ccipher_factory/helpers/common.rb +124 -0
- data/lib/ccipher_factory/kcv/kcv.rb +89 -0
- data/lib/ccipher_factory/kdf/hkdf.rb +114 -0
- data/lib/ccipher_factory/kdf/kdf.rb +73 -0
- data/lib/ccipher_factory/kdf/pbkdf2.rb +82 -0
- data/lib/ccipher_factory/kdf/scrypt.rb +105 -0
- data/lib/ccipher_factory/shamir/shamir_sharing.rb +293 -0
- data/lib/ccipher_factory/shamir/shamir_sharing_helper.rb +88 -0
- data/lib/ccipher_factory/symkey/derived_symkey.rb +110 -0
- data/lib/ccipher_factory/symkey/hardware_symkey.rb +0 -0
- data/lib/ccipher_factory/symkey/soft_symkey.rb +63 -0
- data/lib/ccipher_factory/symkey/symkey.rb +122 -0
- data/lib/ccipher_factory/symkey/symkey_generator.rb +70 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_decrypt.rb +64 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_encrypt.rb +65 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_sign.rb +84 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_verify.rb +85 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_cipher.rb +101 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_decrypt.rb +144 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_encrypt.rb +164 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_sign.rb +70 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_signer.rb +59 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_verify.rb +76 -0
- data/lib/ccipher_factory/version.rb +5 -0
- data/lib/ccipher_factory.rb +52 -0
- data/run_test.rb +27 -0
- metadata +172 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
#require_relative 'shamir_sharing'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module ShamirSharingHelper
|
6
|
+
|
7
|
+
class ShamirSharingError < StandardError; end
|
8
|
+
class InvalidShare < StandardError; end
|
9
|
+
class NotEnoughShare < StandardError; end
|
10
|
+
|
11
|
+
def shamir_split(data, totalShare, reqShare)
|
12
|
+
|
13
|
+
rand = Ccrypto::AlgoFactory.engine(Ccrypto::SecureRandomConfig)
|
14
|
+
|
15
|
+
ssc = Ccrypto::SecretSharingConfig.new
|
16
|
+
ssc.split_into = totalShare
|
17
|
+
ssc.required_parts = reqShare
|
18
|
+
ss = Ccrypto::AlgoFactory.engine(ssc)
|
19
|
+
|
20
|
+
serial = rand.random_bytes(8)
|
21
|
+
shares = ss.split(data)
|
22
|
+
shares = shares.map { |s|
|
23
|
+
ts = BinStruct.instance.struct(:shared_secret)
|
24
|
+
ts.req_share = reqShare
|
25
|
+
ts.share_id = s[0]
|
26
|
+
ts.serial = serial
|
27
|
+
ts.shared_value = s[1]
|
28
|
+
ts.encoded
|
29
|
+
}
|
30
|
+
|
31
|
+
#shares = []
|
32
|
+
#(1..totalShare).each do |i|
|
33
|
+
# share = ss.compute_share(i)
|
34
|
+
# ts = Encoding::ASN1Encoder.instance(:shared_secret)
|
35
|
+
# ts.set(:req_share, reqShare)
|
36
|
+
# ts.set(:share_id, share[0])
|
37
|
+
# ts.set(:serial, serial)
|
38
|
+
# sbin = share[1].map { |v| v.chr }.join
|
39
|
+
# ts.set(:shared_value, sbin)
|
40
|
+
# shares << ts.to_asn1
|
41
|
+
#end
|
42
|
+
|
43
|
+
shares
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def shamir_recover(shares)
|
48
|
+
|
49
|
+
shares = [shares] if not shares.is_a?(Array)
|
50
|
+
shares = [] if is_empty?(shares)
|
51
|
+
|
52
|
+
reqShare = nil
|
53
|
+
res = { }
|
54
|
+
foundSerial = nil
|
55
|
+
shares.each do |s|
|
56
|
+
ts = BinStruct.instance.struct_from_bin(s)
|
57
|
+
|
58
|
+
raise ShamirSharingError, "Not a shared secret envelope [#{ts.id}]" if ts.oid != BTag.constant_value(:shared_secret)
|
59
|
+
|
60
|
+
serial = ts.serial
|
61
|
+
raise InvalidShare, "Given share not in same batch. Cannot proceed" if not_empty?(foundSerial) and serial != foundSerial
|
62
|
+
|
63
|
+
rs = ts.req_share
|
64
|
+
raise ShamirSharingError, "Inconsistancy required shares value in given shares" if not_empty?(reqShare) and rs != reqShare
|
65
|
+
reqShare = rs
|
66
|
+
|
67
|
+
sid = ts.share_id
|
68
|
+
if not res.keys.include?(sid)
|
69
|
+
val = ts.shared_value
|
70
|
+
#res[sid.to_i] = val.chars.map(&:ord)
|
71
|
+
res[sid.to_i] = val
|
72
|
+
end
|
73
|
+
|
74
|
+
foundSerial = serial
|
75
|
+
end
|
76
|
+
|
77
|
+
raise NotEnoughShare, "Required #{reqShare} share(s) but only #{res.size} is/are given" if res.size < reqShare or res.size == 0
|
78
|
+
|
79
|
+
#ssc = Ccrypto::SecretSharingConfig.new
|
80
|
+
#ssc.required_parts = reqShare
|
81
|
+
#ss = Ccrypto::AlgoFactory.engine(ssc)
|
82
|
+
ss = Ccrypto::AlgoFactory.engine(Ccrypto::SecretSharingConfig)
|
83
|
+
ss.combine(reqShare, res)
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
|
2
|
+
require_relative '../kdf/kdf'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
class DerivedSymKey
|
6
|
+
include TR::CondUtils
|
7
|
+
include SymKey
|
8
|
+
include Common
|
9
|
+
|
10
|
+
def self.from_encoded(bin, &block)
|
11
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
12
|
+
from_tspec(ts, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_tspec(ts, &block)
|
16
|
+
|
17
|
+
raise SymKeyError, "Block is required" if not block
|
18
|
+
|
19
|
+
pass = block.call(:password)
|
20
|
+
raise SymKeyError, "Password to derive symkey is not available" if is_empty?(pass)
|
21
|
+
|
22
|
+
keytype = BTag.value_constant(ts.keytype)
|
23
|
+
keysize = ts.keysize
|
24
|
+
dsk = DerivedSymKey.new(keytype, keysize)
|
25
|
+
dsk.kdf = KDF.from_encoded(ts.kdf_config)
|
26
|
+
dsk.derive(pass)
|
27
|
+
|
28
|
+
kcvBin = ts.kcv
|
29
|
+
|
30
|
+
# default is NOT to generate the KCV flag to beat the recursive test
|
31
|
+
if block
|
32
|
+
if not_empty?(kcvBin) and block.call(:pre_verify_password) == true
|
33
|
+
kcv = KCV.from_encoded(kcvBin)
|
34
|
+
kcv.key = dsk
|
35
|
+
raise SymKeyError, "Given password is incorrect" if not kcv.is_matched?
|
36
|
+
end
|
37
|
+
#else
|
38
|
+
# raise SymKeyError, "Given password is incorrect" if not kcv.is_matched?
|
39
|
+
end
|
40
|
+
|
41
|
+
dsk
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.logger
|
46
|
+
if @logger.nil?
|
47
|
+
@logger = Tlogger.new
|
48
|
+
@logger.tag = :derived_symkey
|
49
|
+
end
|
50
|
+
@logger
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :kdf
|
54
|
+
def activate_password_verifier
|
55
|
+
@passVer = true
|
56
|
+
end
|
57
|
+
def deactivate_password_verifier
|
58
|
+
@passVer = false
|
59
|
+
end
|
60
|
+
|
61
|
+
def derive(pass, eng = :scrypt, &block)
|
62
|
+
|
63
|
+
if is_empty?(@kdf)
|
64
|
+
@kdf = KDF.instance(eng)
|
65
|
+
if block
|
66
|
+
case eng
|
67
|
+
when :scrypt
|
68
|
+
@kdf.cost = block.call(:kdf_scrypt_cost)
|
69
|
+
@kdf.parallel = block.call(:kdf_scrypt_parallel)
|
70
|
+
@kdf.blocksize = block.call(:kdf_scrypt_blocksize)
|
71
|
+
@kdf.salt = block.call(:kdf_scrypt_salt)
|
72
|
+
@kdf.digestAlgo = block.call(:kdf_scrypt_digestAlgo)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@kdf.derive_init(@keysize)
|
77
|
+
end
|
78
|
+
|
79
|
+
@kdf.derive_update(pass)
|
80
|
+
@kdfAsn1 = @kdf.derive_final
|
81
|
+
|
82
|
+
@key = @kdf.derivedVal
|
83
|
+
|
84
|
+
#logger.debug "Derived : #{@key}"
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def encoded
|
89
|
+
|
90
|
+
ts = BinStruct.instance.struct(:symkey_derived)
|
91
|
+
ts.keytype = BTag.constant_value(@keytype)
|
92
|
+
ts.keysize = @keysize
|
93
|
+
ts.kdf_config = @kdfAsn1
|
94
|
+
if @passVer == true
|
95
|
+
kcv = KCV.new
|
96
|
+
kcv.key = self
|
97
|
+
ts.kcv = kcv.encoded
|
98
|
+
else
|
99
|
+
ts.kcv = ""
|
100
|
+
end
|
101
|
+
ts.encoded
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def logger
|
106
|
+
self.class.logger
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
class SoftSymKey
|
6
|
+
include TR::CondUtils
|
7
|
+
include SymKey
|
8
|
+
include Common
|
9
|
+
|
10
|
+
def self.from_encoded(bin, &block)
|
11
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
12
|
+
from_tspec(ts, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_tspec(ts, &block)
|
16
|
+
|
17
|
+
#raise SymKeyError, "Given envelope not symkey enveloppe [#{ts.id}]" if ts.id != :symkey
|
18
|
+
raise SymKeyError, "Given envelope not symkey enveloppe [#{ts.oid}]" if ts.oid != BTag.constant_value(:symkey)
|
19
|
+
|
20
|
+
#keytype = Tag.constant_key(ts.value(:keytype))
|
21
|
+
#keysize = ts.value(:keysize)
|
22
|
+
#key = ts.value(:key)
|
23
|
+
|
24
|
+
keytype = BTag.value_constant(ts.keytype)
|
25
|
+
keysize = ts.keysize
|
26
|
+
key = ts.key
|
27
|
+
if is_empty?(key)
|
28
|
+
if not block
|
29
|
+
raise SymKeyError, "Key is not in the meta data. Key is required to complete the construction of the object"
|
30
|
+
end
|
31
|
+
key = block.call(:key)
|
32
|
+
end
|
33
|
+
|
34
|
+
SoftSymKey.new(keytype, keysize, key)
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Mixin methods
|
39
|
+
##
|
40
|
+
def initialize(keytype, keysize, key = nil)
|
41
|
+
super(keytype, keysize, key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def encoded
|
45
|
+
ts = BinStruct.instance.struct(:symkey)
|
46
|
+
ts.keytype = BTag.constant_value(@keytype)
|
47
|
+
ts.keysize = @keysize
|
48
|
+
if is_attach_mode?
|
49
|
+
case @key
|
50
|
+
when String
|
51
|
+
ts.key = @key
|
52
|
+
else
|
53
|
+
ts.key = @key.to_bin
|
54
|
+
end
|
55
|
+
else
|
56
|
+
ts.key = ""
|
57
|
+
end
|
58
|
+
ts.encoded
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
|
2
|
+
require_relative '../shamir/shamir_sharing_helper'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
#
|
6
|
+
# Generic category to handle 4 types of symkey:
|
7
|
+
# - software internal generated symkey (key value is generated internally)
|
8
|
+
# - software external generated symkey (key value is being set by caller)
|
9
|
+
# - derived symkey (key value is derived from password)
|
10
|
+
# - hardware symkey (key value is stored in hardware and not going to be available)
|
11
|
+
module SymKey
|
12
|
+
extend TR::CondUtils
|
13
|
+
include ShamirSharingHelper
|
14
|
+
|
15
|
+
class SymKeyError < StandardError; end
|
16
|
+
|
17
|
+
|
18
|
+
#module ClassMethods
|
19
|
+
# include ShamirSharingHelper
|
20
|
+
|
21
|
+
# def from_shares(keytype, keysize, shares)
|
22
|
+
# #self.send(:initialize, *[keytype, keysize, shamir_recover(shares)])
|
23
|
+
# #SymKey.instance_method(:initialize).bind(self).call(keytype, keysize, shamir_recover(shares))
|
24
|
+
|
25
|
+
# end
|
26
|
+
#end
|
27
|
+
#def self.included(klass)
|
28
|
+
# klass.extend(ClassMethods)
|
29
|
+
#end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Mixin methods
|
33
|
+
##
|
34
|
+
|
35
|
+
# Symmetric key type. Supported key type refers
|
36
|
+
# CcipherFactory::SymKeyGenerator#supported_symkey
|
37
|
+
attr_accessor :keytype
|
38
|
+
|
39
|
+
# Key length in bits
|
40
|
+
attr_accessor :keysize
|
41
|
+
|
42
|
+
# Raw key. It could be bytes or key object
|
43
|
+
attr_accessor :key
|
44
|
+
|
45
|
+
def initialize(keytype, keysize, key = nil)
|
46
|
+
@keytype = keytype
|
47
|
+
@keysize = keysize
|
48
|
+
@key = key
|
49
|
+
end
|
50
|
+
|
51
|
+
# split the raw key value into secret shares
|
52
|
+
def split_key(totalShare, reqShare, &block)
|
53
|
+
shamir_split(@key, totalShare, reqShare)
|
54
|
+
end
|
55
|
+
|
56
|
+
# merge the splited share values into raw key value back
|
57
|
+
def merge_key(shares)
|
58
|
+
@key = shamir_recover(shares)
|
59
|
+
end
|
60
|
+
|
61
|
+
def dispose
|
62
|
+
@key = nil
|
63
|
+
GC.start
|
64
|
+
end
|
65
|
+
|
66
|
+
def raw_key
|
67
|
+
if not @key.nil?
|
68
|
+
nativeHelper = Ccrypto::UtilFactory.instance(:native_helper)
|
69
|
+
if @key.is_a?(String) or nativeHelper.is_byte_array?(@key)
|
70
|
+
@key
|
71
|
+
elsif @key.respond_to?(:to_bin)
|
72
|
+
@key.to_bin
|
73
|
+
else
|
74
|
+
raise SymKeyError, "Not sure how to get raw_key for #{@key.inspect}"
|
75
|
+
end
|
76
|
+
#case @key
|
77
|
+
#when String, ::Java::byte[]
|
78
|
+
# @key
|
79
|
+
#else
|
80
|
+
# if @key.respond_to?(:to_bin)
|
81
|
+
# @key.to_bin
|
82
|
+
# else
|
83
|
+
# raise SymKeyError, "Not sure how to get raw_key for #{@key.inspect}"
|
84
|
+
# end
|
85
|
+
#end
|
86
|
+
else
|
87
|
+
raise SymKeyError, "Key instance is nil. Cannot get raw_key from nil instance"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_equals?(key)
|
92
|
+
comp = Ccrypto::UtilFactory.instance(:comparator)
|
93
|
+
comp.is_equal?(@key, key)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.from_encoded(bin, &block)
|
97
|
+
raise SymKeyError, "Input should not be empty" if is_empty?(bin)
|
98
|
+
|
99
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
100
|
+
case ts.oid
|
101
|
+
when BTag.constant_value(:symkey_derived)
|
102
|
+
DerivedSymKey.from_tspec(ts, &block)
|
103
|
+
when BTag.constant_value(:symkey)
|
104
|
+
SoftSymKey.from_tspec(ts, &block)
|
105
|
+
else
|
106
|
+
raise SymKeyError, "Unknown symkey envelope '#{ts.oid}'"
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
#case ts.id
|
111
|
+
#when :symkey_derived
|
112
|
+
# DerivedSymKey.from_tspec(ts, &block)
|
113
|
+
#when :symkey
|
114
|
+
# SoftSymKey.from_tspec(ts, &block)
|
115
|
+
#else
|
116
|
+
# raise SymKeyError, "Unknown symkey envelope '#{ts.id}'"
|
117
|
+
#end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
require 'openssl'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require_relative 'soft_symkey'
|
6
|
+
require_relative 'derived_symkey'
|
7
|
+
|
8
|
+
module CcipherFactory
|
9
|
+
module SymKeyGenerator
|
10
|
+
include TR::CondUtils
|
11
|
+
|
12
|
+
class SymKeyGeneratorError < StandardError; end
|
13
|
+
|
14
|
+
def self.supported_symkey
|
15
|
+
#{
|
16
|
+
# aes: [[128, 256], [:cbc, :cfb, :ctr, :ofb, :gcm]],
|
17
|
+
# chacha20: [[256],[:poly1305]],
|
18
|
+
# blowfish: [[128],[:ecb, :cbc, :cfb, :ofb]],
|
19
|
+
# camellia: [[128,192,256],[:ecb, :cbc, :cfb, :ofb, :ctr]],
|
20
|
+
# aria: [[128,192,256],[:ecb, :cbc, :cfb, :ofb, :ctr, :gcm]]
|
21
|
+
#}
|
22
|
+
{
|
23
|
+
aes: { keysize: [128, 192, 256], mode: [:cbc, :cfb, :ctr, :ofb, :gcm] },
|
24
|
+
chacha20: { keysize: [256], mode: [:poly1305] },
|
25
|
+
blowfish: { keysize: [128], mode: [:ecb, :cbc, :cfb, :ofb] },
|
26
|
+
camellia: { keysize: [128, 192, 256], mode: [:ecb, :cbc, :cfb, :ofb, :ctr] },
|
27
|
+
aria: { keysize: [128, 192, 256], mode: [:ecb, :cbc, :cfb, :ofb, :ctr, :gcm] }
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.generate(keytype, keysize, *args, &block)
|
33
|
+
raise SymKeyGeneratorError, "Unsupported symmetric key algo '#{keytype}'. Supported symmetric keys are: #{supported_symkey.keys.join(", ")}" if not supported_symkey.keys.include?(keytype)
|
34
|
+
|
35
|
+
kc = Ccrypto::KeyConfig.new
|
36
|
+
kc.algo = keytype
|
37
|
+
kc.keysize = keysize
|
38
|
+
ke = Ccrypto::AlgoFactory.engine(Ccrypto::KeyConfig)
|
39
|
+
sk = ke.generate(kc)
|
40
|
+
|
41
|
+
#SoftSymKey.new(keytype, keysize, SecureRandom.random_bytes(keysize/8))
|
42
|
+
SoftSymKey.new(keytype, keysize, sk)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.derive(keytype, keysize, *args, &block)
|
46
|
+
raise SymKeyGeneratorError, "Unsupported symmetric key algo '#{keytype}'. Supported symmetric keys are: #{supported_symkey.keys.join(", ")}" if not supported_symkey.keys.include?(keytype)
|
47
|
+
|
48
|
+
raise SymKeyGeneratorError, "Block is required" if not block
|
49
|
+
|
50
|
+
kdf = block.call(:kdf)
|
51
|
+
kdf = :scrypt if is_empty?(kdf)
|
52
|
+
|
53
|
+
pass = block.call(:password)
|
54
|
+
raise SymKeyGeneratorError, "Password is not given to derive the symkey" if is_empty?(pass)
|
55
|
+
|
56
|
+
dsk = DerivedSymKey.new(keytype, keysize)
|
57
|
+
dsk.derive(pass, kdf, &block)
|
58
|
+
dsk
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.logger
|
62
|
+
if @logger.nil?
|
63
|
+
@logger = Tlogger.new
|
64
|
+
@logger.tag = :symkey_gen
|
65
|
+
end
|
66
|
+
@logger
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module CcipherFactory
|
4
|
+
module SymKeyCipher
|
5
|
+
module SymKeyAttDecrypt
|
6
|
+
include Common
|
7
|
+
|
8
|
+
attr_accessor :key
|
9
|
+
def att_decrypt_init(*args, &block)
|
10
|
+
|
11
|
+
raise SymKeyCipherError, "Output is required for attached decryption" if not is_output_given?
|
12
|
+
|
13
|
+
@initParams = args
|
14
|
+
|
15
|
+
if block
|
16
|
+
instance_eval(&block)
|
17
|
+
att_decrypt_final
|
18
|
+
else
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def att_decrypt_update(val)
|
25
|
+
if @dec.nil?
|
26
|
+
intOutputBuf.write(val)
|
27
|
+
begin
|
28
|
+
Encoding.extract_meta(intOutputBuf) do |meta, bal|
|
29
|
+
|
30
|
+
@dec = SymKeyCipher.decryptor
|
31
|
+
@dec.output(@output)
|
32
|
+
@dec.key = @key
|
33
|
+
@dec.decrypt_init(*@initParams)
|
34
|
+
@dec.decrypt_update_meta(meta)
|
35
|
+
|
36
|
+
logger.tdebug :att_dec, "Balance has data length #{bal.length}"
|
37
|
+
att_decrypt_update(bal) if bal.length > 0
|
38
|
+
|
39
|
+
disposeOutput(intOutputBuf)
|
40
|
+
|
41
|
+
end
|
42
|
+
rescue Encoding::InsufficientData => e
|
43
|
+
end
|
44
|
+
else
|
45
|
+
logger.tdebug :att_dec, "Updating cipher size #{val.length}"
|
46
|
+
@dec.decrypt_update_cipher(val)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def att_decrypt_final
|
51
|
+
@dec.decrypt_final
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def logger
|
56
|
+
if @logger.nil?
|
57
|
+
@logger = Tlogger.new
|
58
|
+
end
|
59
|
+
@logger
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey_cipher'
|
3
|
+
|
4
|
+
require_relative '../compression/compression_helper'
|
5
|
+
|
6
|
+
module CcipherFactory
|
7
|
+
|
8
|
+
module SymKeyCipher
|
9
|
+
module SymKeyAttEncrypt
|
10
|
+
include Common
|
11
|
+
include Compression::CompressionHelper
|
12
|
+
|
13
|
+
attr_accessor :key, :mode
|
14
|
+
def att_encrypt_init(*args, &block)
|
15
|
+
|
16
|
+
raise SymKeyCipherError, "Cipher requires output to be set" if not is_output_given?
|
17
|
+
|
18
|
+
@enc = SymKeyCipher.encryptor
|
19
|
+
@enc.compression_on if is_compression_on?
|
20
|
+
@enc.output(intOutputFile)
|
21
|
+
@enc.key = @key
|
22
|
+
@enc.mode = @mode if not_empty?(@mode)
|
23
|
+
|
24
|
+
@enc.encrypt_init(*args)
|
25
|
+
|
26
|
+
if block
|
27
|
+
instance_eval(&block)
|
28
|
+
att_encrypt_final
|
29
|
+
else
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def att_encrypt_update(val)
|
36
|
+
raise SymKeyCipherError, "Please call att_encrypt_init() before calling update()" if @enc.nil?
|
37
|
+
|
38
|
+
@enc.encrypt_update(val)
|
39
|
+
end
|
40
|
+
|
41
|
+
def att_encrypt_final
|
42
|
+
|
43
|
+
meta = @enc.encrypt_final
|
44
|
+
|
45
|
+
write_to_output(meta)
|
46
|
+
intOutputFile.rewind
|
47
|
+
while not intOutputFile.eof?
|
48
|
+
write_to_output(intOutputFile.read)
|
49
|
+
end
|
50
|
+
|
51
|
+
intOutputFile.close!
|
52
|
+
|
53
|
+
nil
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(mtd, *args, &block)
|
58
|
+
if not_empty?(@enc)
|
59
|
+
@enc.send(mtd, *args, &block)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey_signer'
|
3
|
+
|
4
|
+
require_relative '../compression/compression_helper'
|
5
|
+
|
6
|
+
module CcipherFactory
|
7
|
+
module SymKeySigner
|
8
|
+
|
9
|
+
module SymKeyAttSign
|
10
|
+
|
11
|
+
include Common
|
12
|
+
include Compression::CompressionHelper
|
13
|
+
|
14
|
+
attr_accessor :signing_key
|
15
|
+
|
16
|
+
def att_sign_init(opts = { }, &block)
|
17
|
+
|
18
|
+
@signer = SymKeySigner.signer
|
19
|
+
@signer.signing_key = @signing_key
|
20
|
+
@signer.sign_init(opts)
|
21
|
+
|
22
|
+
@totalPlain = 0
|
23
|
+
@totalCompressed = 0
|
24
|
+
|
25
|
+
if block
|
26
|
+
instance_eval(&block)
|
27
|
+
att_sign_final
|
28
|
+
else
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def att_sign_update(val)
|
35
|
+
raise SymKeySignerError, "Output is required for attached sign" if not is_output_given?
|
36
|
+
|
37
|
+
@totalPlain += val.length
|
38
|
+
@signer.sign_update(val)
|
39
|
+
res = compress_data_if_active(val)
|
40
|
+
intOutputFile.write(res)
|
41
|
+
@totalCompressed += res.length
|
42
|
+
end
|
43
|
+
|
44
|
+
def att_sign_final
|
45
|
+
|
46
|
+
meta = @signer.sign_final
|
47
|
+
|
48
|
+
#ts = Encoding::ASN1Encoder.instance(:symkey_att_sign)
|
49
|
+
ts = BinStruct.instance.struct(:symkey_att_sign)
|
50
|
+
ts.symkey_signature = meta
|
51
|
+
|
52
|
+
if is_compression_on?
|
53
|
+
compRes = compressor.compress_final
|
54
|
+
ts.compression = compRes
|
55
|
+
else
|
56
|
+
ts.compression = encode_null_compressor
|
57
|
+
end
|
58
|
+
|
59
|
+
attMeta = ts.encoded
|
60
|
+
|
61
|
+
write_to_output(attMeta)
|
62
|
+
intOutputFile.rewind
|
63
|
+
while not intOutputFile.eof?
|
64
|
+
write_to_output(intOutputFile.read)
|
65
|
+
end
|
66
|
+
|
67
|
+
logger.tdebug :symkey_att_sign, "Total Plain : #{@totalPlain} / Total Compressed : #{@totalCompressed} = #{(@totalCompressed*1.0)/@totalPlain*100} %" if is_compression_on?
|
68
|
+
|
69
|
+
intOutputFile.close!
|
70
|
+
|
71
|
+
attMeta
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def logger
|
76
|
+
if @logger.nil?
|
77
|
+
@logger = Tlogger.new
|
78
|
+
end
|
79
|
+
@logger
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|