ccipher_factory 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|