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,116 @@
|
|
1
|
+
|
2
|
+
require_relative '../asymkey_cipher/asymkey_cipher'
|
3
|
+
require_relative '../symkey_cipher/symkey_cipher'
|
4
|
+
|
5
|
+
module CcipherFactory
|
6
|
+
module CompositeCipher
|
7
|
+
|
8
|
+
module DecryptVerifier
|
9
|
+
include TR::CondUtils
|
10
|
+
include Common
|
11
|
+
|
12
|
+
include TeLogger::TeLogHelper
|
13
|
+
teLogger_tag :decVer
|
14
|
+
|
15
|
+
attr_accessor :decryption_key, :verification_key
|
16
|
+
def decrypt_verify_init(opts = { }, &block)
|
17
|
+
|
18
|
+
#@dKey = opts[:decryption_key]
|
19
|
+
#@vKey = opts[:verification_key] # optional as asymkey the key is included
|
20
|
+
|
21
|
+
raise CompositeCipherError, "Decryption key is required" if is_empty?(@decryption_key)
|
22
|
+
raise CompositeCipherError, "Output is required" if not is_output_given?
|
23
|
+
|
24
|
+
if block
|
25
|
+
instance_eval(&block)
|
26
|
+
decrypt_verify_final
|
27
|
+
else
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def decrypt_verify_update_meta(meta)
|
34
|
+
|
35
|
+
intOutputBuf.write(meta)
|
36
|
+
|
37
|
+
begin
|
38
|
+
|
39
|
+
Encoding.extract_meta(intOutputBuf) do |meta, bal|
|
40
|
+
|
41
|
+
ts = BinStruct.instance.struct_from_bin(meta)
|
42
|
+
ccBin = ts.cipher_config
|
43
|
+
cc = BinStruct.instance.struct_from_bin(ccBin)
|
44
|
+
scBin = ts.signer_config
|
45
|
+
sc = BinStruct.instance.struct_from_bin(scBin)
|
46
|
+
|
47
|
+
case BTag.value_constant(cc.oid)
|
48
|
+
when :symkey_cipher
|
49
|
+
@cipher = CcipherFactory::SymKeyCipher.decryptor
|
50
|
+
@cipher.output(intOutputFile)
|
51
|
+
@cipher.key = @decryption_key
|
52
|
+
@cipher.decrypt_init
|
53
|
+
@cipher.decrypt_update_meta(ccBin)
|
54
|
+
when :ecc_cipher
|
55
|
+
@cipher = CcipherFactory::AsymKeyCipher.decryptor
|
56
|
+
@cipher.output(intOutputFile)
|
57
|
+
@cipher.decryption_key = @decryption_key
|
58
|
+
@cipher.decrypt_init
|
59
|
+
@cipher.decrypt_update_meta(ccBin)
|
60
|
+
else
|
61
|
+
raise CompositeCipherError, "Unknown envelope type '#{cc.id}'"
|
62
|
+
end
|
63
|
+
|
64
|
+
case BTag.value_constant(sc.oid)
|
65
|
+
when :ecc_att_sign
|
66
|
+
@verifier = AsymKeySigner.att_verifier
|
67
|
+
@verifier.output(@output)
|
68
|
+
when :symkey_att_sign
|
69
|
+
@verifier = SymKeySigner.att_verifier
|
70
|
+
@verifier.output(@output)
|
71
|
+
@verifier.verification_key = @verification_key
|
72
|
+
@verifier.att_verify_init
|
73
|
+
else
|
74
|
+
raise CompositeCipherError, "Unknown signer type '#{sc.id}'"
|
75
|
+
end
|
76
|
+
|
77
|
+
decrypt_verify_update_cipher(bal) if bal.length > 0
|
78
|
+
|
79
|
+
disposeOutput(intOutputBuf)
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
rescue Encoding::InsufficientData
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def decrypt_verify_update_cipher(cipher)
|
91
|
+
raise CompositeCipherError, "Please call update_meta() before calling update_cipher()" if is_empty?(@cipher)
|
92
|
+
|
93
|
+
@cipher.decrypt_update_cipher(cipher)
|
94
|
+
end
|
95
|
+
|
96
|
+
def decrypt_verify_final
|
97
|
+
|
98
|
+
@cipher.decrypt_final
|
99
|
+
|
100
|
+
intOutputFile.rewind
|
101
|
+
while not intOutputFile.eof?
|
102
|
+
@verifier.att_verify_update(intOutputFile.read)
|
103
|
+
end
|
104
|
+
|
105
|
+
@verifier.att_verify_final
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def embedded_signer
|
110
|
+
@verifier.embedded_signer if not_empty?(@verifier) and @verifier.respond_to?(:embedded_signer)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require_relative '../asymkey_cipher/asymkey_cipher'
|
4
|
+
require_relative '../symkey_cipher/symkey_cipher'
|
5
|
+
|
6
|
+
module CcipherFactory
|
7
|
+
module CompositeCipher
|
8
|
+
|
9
|
+
module SignEncryptor
|
10
|
+
include TR::CondUtils
|
11
|
+
include Common
|
12
|
+
include Compression::CompressionHelper
|
13
|
+
|
14
|
+
attr_accessor :signing_key, :encryption_key, :sender_keypair
|
15
|
+
|
16
|
+
def sign_encrypt_init(opts = { }, &block)
|
17
|
+
|
18
|
+
sKey = @signing_key
|
19
|
+
eKey = @encryption_key
|
20
|
+
sender = @sender_keypair
|
21
|
+
|
22
|
+
compress = opts[:compress] || false
|
23
|
+
|
24
|
+
raise CompositeCipherError, "Signing key is required" if is_empty?(sKey)
|
25
|
+
raise CompositeCipherError, "Encryption key is required" if is_empty?(eKey)
|
26
|
+
raise CompositeCipherError, "Output is required" if not is_output_given?
|
27
|
+
|
28
|
+
@signingBuf = Tempfile.new
|
29
|
+
@signingBuf.binmode
|
30
|
+
|
31
|
+
case sKey
|
32
|
+
when SymKey
|
33
|
+
@signer = SymKeySigner.att_signer
|
34
|
+
@signer.output(@signingBuf)
|
35
|
+
@signer.compression_on if is_compression_on?
|
36
|
+
@signer.signing_key = sKey
|
37
|
+
@signer.att_sign_init
|
38
|
+
when AsymKey
|
39
|
+
@signer = AsymKeySigner.att_signer
|
40
|
+
@signer.output(@signingBuf)
|
41
|
+
@signer.compression_on if is_compression_on?
|
42
|
+
@signer.signing_key = sKey
|
43
|
+
@signer.att_sign_init
|
44
|
+
else
|
45
|
+
raise CompositeCipherError, "Unknown signing key type '#{sKey.class}'"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Encryption Key
|
49
|
+
case eKey
|
50
|
+
when SymKey
|
51
|
+
@enc = SymKeyCipher.encryptor
|
52
|
+
@enc.output(@output)
|
53
|
+
@enc.key = eKey
|
54
|
+
@enc.encrypt_init
|
55
|
+
when AsymKey, Ccrypto::PublicKey #, OpenSSL::PKey::EC::Point
|
56
|
+
@enc = AsymKeyCipher.encryptor
|
57
|
+
@enc.output(@output)
|
58
|
+
@enc.recipient_key = eKey
|
59
|
+
@enc.sender_keypair = sender if not_empty?(sender)
|
60
|
+
@enc.encrypt_init
|
61
|
+
else
|
62
|
+
raise CompositeCipherError, "Unknown encryption key type '#{eKey.class}'"
|
63
|
+
end
|
64
|
+
|
65
|
+
if block
|
66
|
+
instance_eval(&block)
|
67
|
+
sign_encrypt_final
|
68
|
+
else
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def sign_encrypt_update(data)
|
75
|
+
@signer.att_sign_update(data)
|
76
|
+
end
|
77
|
+
|
78
|
+
def sign_encrypt_final
|
79
|
+
|
80
|
+
smeta = @signer.att_sign_final
|
81
|
+
|
82
|
+
@signingBuf.rewind
|
83
|
+
while not @signingBuf.eof?
|
84
|
+
@enc.encrypt_update(@signingBuf.read)
|
85
|
+
end
|
86
|
+
|
87
|
+
meta = @enc.encrypt_final
|
88
|
+
|
89
|
+
ts = BinStruct.instance.struct(:sign_encrypt_cipher)
|
90
|
+
ts.signer_config = smeta
|
91
|
+
ts.cipher_config = meta
|
92
|
+
ts.encoded
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
require_relative 'compressor'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module Compression
|
6
|
+
|
7
|
+
module CompressionHelper
|
8
|
+
|
9
|
+
def decompressor_from_encoded(bin)
|
10
|
+
|
11
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
12
|
+
case BTag.value_constant(ts.oid)
|
13
|
+
when :compression_zlib
|
14
|
+
compression_on
|
15
|
+
when :compression_none
|
16
|
+
compression_off
|
17
|
+
else
|
18
|
+
compression_off
|
19
|
+
end
|
20
|
+
|
21
|
+
decompressor.decompress_update_meta(bin)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def compression_on
|
26
|
+
@compress = true
|
27
|
+
end
|
28
|
+
|
29
|
+
def compression_off
|
30
|
+
@compress = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def is_compression_on?
|
34
|
+
if @compress.nil?
|
35
|
+
false
|
36
|
+
else
|
37
|
+
@compress
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def compressor
|
42
|
+
if @compressor.nil?
|
43
|
+
if is_compression_on?
|
44
|
+
@compressor = Compressor.instance.compress
|
45
|
+
@compressor.compress_init
|
46
|
+
else
|
47
|
+
@compressor = Compressor.instance.null_engine
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
@compressor
|
52
|
+
end
|
53
|
+
|
54
|
+
def compress_data_if_active(val)
|
55
|
+
if is_compression_on?
|
56
|
+
logger.tdebug :compress_if_active, "Compression is on"
|
57
|
+
compressor.compress_update(val)
|
58
|
+
else
|
59
|
+
logger.tdebug :compress_if_active, "Compression is OFF"
|
60
|
+
val
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def decompress_data_if_active(val)
|
65
|
+
if is_compression_on?
|
66
|
+
logger.tdebug :decompress_if_active, "Decompression is on"
|
67
|
+
decompressor.decompress_update(val)
|
68
|
+
else
|
69
|
+
logger.tdebug :decompress_if_active, "decompression is OFF"
|
70
|
+
val
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def decompressor
|
75
|
+
if @decompressor.nil?
|
76
|
+
if is_compression_on?
|
77
|
+
@decompressor = Compressor.instance.decompress
|
78
|
+
@decompressor.decompress_init
|
79
|
+
else
|
80
|
+
@decompressor = Compressor.instance.null_engine
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
@decompressor
|
85
|
+
end
|
86
|
+
|
87
|
+
def encode_null_compressor
|
88
|
+
BinStruct.instance.struct(:compression_none).encoded
|
89
|
+
end
|
90
|
+
|
91
|
+
def logger
|
92
|
+
if @logger.nil?
|
93
|
+
@logger = Tlogger.new
|
94
|
+
@logger.tag = :comp_helper
|
95
|
+
end
|
96
|
+
@logger
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
require_relative 'zlib_compressor'
|
3
|
+
require_relative 'zlib_decompressor'
|
4
|
+
|
5
|
+
module CcipherFactory
|
6
|
+
class CompressionError < StandardError; end
|
7
|
+
class DecompressionError < StandardError; end
|
8
|
+
end
|
9
|
+
|
10
|
+
module CcipherFactory
|
11
|
+
module Compression
|
12
|
+
#class CompressionError < StandardError; end
|
13
|
+
#class DecompressionError < StandardError; end
|
14
|
+
|
15
|
+
module NullCompressor
|
16
|
+
def method_missing(mtd, *args, &block)
|
17
|
+
# sink hole
|
18
|
+
#args
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Compressor
|
23
|
+
|
24
|
+
def self.instance(eng = :zlib)
|
25
|
+
Compressor.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def compress
|
29
|
+
self.extend(ZlibCompressor)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def decompress
|
34
|
+
self.extend(ZlibDecompressor)
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def null_engine
|
39
|
+
self.extend(NullCompressor)
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.supported_envelope
|
44
|
+
[:compression_none, :compression_zlib]
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.rebuild(ts, &block)
|
48
|
+
Compressor.new
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require 'zlib'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module Compression
|
6
|
+
module ZlibCompressor
|
7
|
+
include CcipherFactory::Common
|
8
|
+
|
9
|
+
def compress_init(*args, &block)
|
10
|
+
|
11
|
+
@compressor = Ccrypto::UtilFactory.instance(:compression, Ccrypto::CompressionConfig.new)
|
12
|
+
#@compressor = Zlib::Deflate.new
|
13
|
+
|
14
|
+
if block
|
15
|
+
instance_eval(&block)
|
16
|
+
compress_final
|
17
|
+
else
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def compress_update(val)
|
24
|
+
res = @compressor.update(val)
|
25
|
+
#res = @compressor.deflate(val, Zlib::SYNC_FLUSH)
|
26
|
+
write_to_output(res)
|
27
|
+
res
|
28
|
+
end
|
29
|
+
|
30
|
+
def compress_final
|
31
|
+
@compressor.final
|
32
|
+
|
33
|
+
ts = BinStruct.instance.struct(:compression_zlib)
|
34
|
+
ts.encoded
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def logger
|
39
|
+
if @logger.nil?
|
40
|
+
@logger = Tlogger.new
|
41
|
+
@logger.tag = :zlibComp
|
42
|
+
end
|
43
|
+
@logger
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require 'zlib'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module Compression
|
6
|
+
module ZlibDecompressor
|
7
|
+
include CcipherFactory::Common
|
8
|
+
|
9
|
+
def decompress_init(*args, &block)
|
10
|
+
|
11
|
+
if block
|
12
|
+
instance_eval(&block)
|
13
|
+
decompress_final
|
14
|
+
else
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def decompress_update_meta(val)
|
21
|
+
if @decompressor.nil?
|
22
|
+
begin
|
23
|
+
intOutputBuf.write(val)
|
24
|
+
Encoding.extract_meta(intOutputBuf) do |meta, bal|
|
25
|
+
ts = BinStruct.instance.struct_from_bin(meta)
|
26
|
+
|
27
|
+
case ts.oid
|
28
|
+
when BTag.constant_value(:compression_zlib)
|
29
|
+
@decompressor = Ccrypto::UtilFactory.instance(:decompression)
|
30
|
+
else
|
31
|
+
raise DecompressionError, "Unknown compression type '#{ts.id}'"
|
32
|
+
end
|
33
|
+
|
34
|
+
decompress_update(bal)
|
35
|
+
end
|
36
|
+
rescue Encoding::InsufficientData => e
|
37
|
+
end
|
38
|
+
else
|
39
|
+
decompress_update(val)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def decompress_update(val)
|
44
|
+
if val.length > 0
|
45
|
+
check_state
|
46
|
+
begin
|
47
|
+
res = @decompressor.update(val)
|
48
|
+
write_to_output(res)
|
49
|
+
res
|
50
|
+
rescue Exception => ex
|
51
|
+
raise DecompressionError, ex
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def decompress_final
|
57
|
+
@decompressor.final
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def check_state
|
62
|
+
raise DecompressionError, "Please call decompress_update_meta() to setup the state first." if @decompressor.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
|
2
|
+
require_relative 'supported_digest'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module Digest
|
6
|
+
include TR::CondUtils
|
7
|
+
include CcipherFactory::Common
|
8
|
+
|
9
|
+
class DigestError < StandardError; end
|
10
|
+
|
11
|
+
class DigestEngine; end
|
12
|
+
|
13
|
+
def self.instance #(eng = SupportedDigest.instance.default_digest, *args)
|
14
|
+
#raise DigestEror, "Digest '#{eng}' is not supported" if not SupportedDigest.instance.is_supported?(eng)
|
15
|
+
dig = DigestEngine.new
|
16
|
+
dig.extend(Digest)
|
17
|
+
dig
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_encoded(bin, &block)
|
21
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
22
|
+
from_tspec(ts, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_tspec(ts, &block)
|
26
|
+
|
27
|
+
if ts.oid == BTag.constant_value(:digest_attached)
|
28
|
+
dig = from_encoded(ts.digest_config)
|
29
|
+
dig.digestVal = ts.digest_value
|
30
|
+
dig
|
31
|
+
else
|
32
|
+
|
33
|
+
algo = BTag.value_constant(ts.digest_algo)
|
34
|
+
logger.debug "from_encoded algo : #{algo}"
|
35
|
+
dig = instance
|
36
|
+
dig.salt = ts.salt
|
37
|
+
dig.digest_init(algo, dig.salt, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.parse(bin, &block)
|
42
|
+
|
43
|
+
res = { }
|
44
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
45
|
+
res[:type] = BTag.value_constant(ts.oid)
|
46
|
+
|
47
|
+
if res[:type] == :digest_attached
|
48
|
+
#conf = Encoding::ASN1Decoder.from_encoded(ts.value(:digest_config))
|
49
|
+
conf = BinStruct.instance.struct_from_bin(ts.digest_config)
|
50
|
+
res[:algo] = BTag.value_constant(conf.digest_algo)
|
51
|
+
res[:salt] = conf.salt
|
52
|
+
#res[:algo] = Tag.constant_key(conf.value(:digest_algo))
|
53
|
+
#res[:salt] = conf.value(:salt)
|
54
|
+
end
|
55
|
+
|
56
|
+
res[:digest] = ts.digest_value
|
57
|
+
|
58
|
+
res
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.logger
|
63
|
+
if @logger.nil?
|
64
|
+
@logger = Tlogger.new
|
65
|
+
@logger.tag = :ccfact_digest
|
66
|
+
end
|
67
|
+
@logger
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Mixin methods
|
72
|
+
##
|
73
|
+
attr_accessor :algo, :salt, :digestVal
|
74
|
+
def digest_init(*args, &block)
|
75
|
+
|
76
|
+
logger.debug "args : #{args}"
|
77
|
+
|
78
|
+
@algo = args.first
|
79
|
+
@algo = SupportedDigest.instance.default_digest if is_empty?(@algo)
|
80
|
+
raise DigestError, "Given digest '#{@algo}' is not supported.\nPossible digest algo including: #{SupportedDigest.instance.supported.join(", ")}" if not SupportedDigest.instance.is_supported?(@algo)
|
81
|
+
|
82
|
+
logger.debug "Digest algo in init : #{@algo}"
|
83
|
+
|
84
|
+
@digest = Ccrypto::AlgoFactory.engine(Ccrypto::DigestConfig).digest(@algo)
|
85
|
+
|
86
|
+
#@digest = OpenSSL::Digest.new(Digest.to_digest_string(@algo))
|
87
|
+
|
88
|
+
salt = args[1]
|
89
|
+
if not_empty?(salt)
|
90
|
+
logger.debug "Salt given #{salt} / #{salt.length}"
|
91
|
+
|
92
|
+
case salt
|
93
|
+
when :random_salt, :random
|
94
|
+
saltLen = args[2] || 16
|
95
|
+
sre = Ccrypto::AlgoFactory.engine(Ccrypto::SecureRandomConfig)
|
96
|
+
@salt = sre.random_bytes(saltLen)
|
97
|
+
@digest.digest_update(@salt)
|
98
|
+
else
|
99
|
+
if salt.is_a?(String)
|
100
|
+
@salt = salt
|
101
|
+
@digest.digest_update(@salt)
|
102
|
+
else
|
103
|
+
raise DigestError, "Unknown option '#{salt}' for salt"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
if block
|
109
|
+
instance_eval(&block)
|
110
|
+
digest_final
|
111
|
+
else
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
def digest_update(val)
|
118
|
+
raise DigestError, "Please call digest_init first before call update() (#{@digest.inspect})" if @digest.nil?
|
119
|
+
@digest.digest_update(val)
|
120
|
+
end
|
121
|
+
|
122
|
+
def digest_final
|
123
|
+
|
124
|
+
raise DigestError, "Please call digest_init first before call final() (#{@digest.inspect})" if @digest.nil?
|
125
|
+
|
126
|
+
@digestVal = @digest.digest_final
|
127
|
+
@digest = nil
|
128
|
+
|
129
|
+
write_to_output(@digestVal)
|
130
|
+
|
131
|
+
#ts = Encoding::ASN1Encoder.instance(:digest)
|
132
|
+
ts = BinStruct.instance.struct(:digest)
|
133
|
+
ts.digest_algo = BTag.constant_value(@algo)
|
134
|
+
if not_empty?(@salt)
|
135
|
+
ts.salt = @salt
|
136
|
+
else
|
137
|
+
ts.salt = ""
|
138
|
+
end
|
139
|
+
|
140
|
+
if is_attach_mode?
|
141
|
+
tsd = BinStruct.instance.struct(:digest_attached)
|
142
|
+
#tsd = Encoding::ASN1Encoder.instance(:digest_attached)
|
143
|
+
tsd.digest_config = ts.encoded
|
144
|
+
tsd.digest_value = @digestVal
|
145
|
+
res = tsd.encoded
|
146
|
+
else
|
147
|
+
res = ts.encoded
|
148
|
+
end
|
149
|
+
|
150
|
+
res
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.to_digest_string(sym)
|
155
|
+
if not_empty?(sym)
|
156
|
+
sym.to_s.gsub("_","-")
|
157
|
+
else
|
158
|
+
sym
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
#def self.from_digest_engine_to_symbol(str)
|
163
|
+
# if not_empty?(str)
|
164
|
+
# str.gsub("-","_").to_sym
|
165
|
+
# else
|
166
|
+
# str
|
167
|
+
# end
|
168
|
+
#end
|
169
|
+
|
170
|
+
#def self.init_native_digest_object(digest)
|
171
|
+
# OpenSSL::Digest.new(to_digest_string(digest))
|
172
|
+
#end
|
173
|
+
|
174
|
+
private
|
175
|
+
def logger
|
176
|
+
Digest.logger
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module Digest
|
6
|
+
|
7
|
+
class SupportedDigest
|
8
|
+
include Singleton
|
9
|
+
attr_reader :supported, :possible, :default_digest
|
10
|
+
def initialize
|
11
|
+
#@possible = [:sha1, :sha224, :sha256, :sha384, :sha512, :sha3_224, :sha3_256, :sha3_384, :sha3_512, :shake128, :shake256]
|
12
|
+
#@supported = []
|
13
|
+
#test_algo
|
14
|
+
|
15
|
+
@dig = Ccrypto::AlgoFactory.engine(Ccrypto::DigestConfig)
|
16
|
+
|
17
|
+
@possible = @dig.engineKeys.keys
|
18
|
+
@supported = @possible
|
19
|
+
|
20
|
+
if @dig.is_supported?(:sha3_256)
|
21
|
+
@default_digest = :sha3_256
|
22
|
+
elsif @dig.is_supported?(:sha256)
|
23
|
+
@default_digest = :sha256
|
24
|
+
else
|
25
|
+
raise DigestError, "Failed to set default digest"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def is_supported?(algo)
|
30
|
+
#@supported.include?(algo)
|
31
|
+
@dig.is_supported?(algo)
|
32
|
+
end
|
33
|
+
|
34
|
+
#def test_algo
|
35
|
+
# @possible.each do |dig|
|
36
|
+
# begin
|
37
|
+
# OpenSSL::Digest.new(Digest.to_digest_string(dig))
|
38
|
+
# @supported << dig
|
39
|
+
# rescue NotImplementedError => e
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#end
|
43
|
+
|
44
|
+
end # class SupportedDigest
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|