ccrypto-java 0.1.0 → 0.2.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 +4 -4
- data/.java-version +1 -1
- data/.release_history.yml +4 -0
- data/.ruby-version +1 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +68 -53
- data/Rakefile +2 -1
- data/bin/console +14 -0
- data/jars/bcjmail-jdk18on-172.jar +0 -0
- data/jars/bcmail-jdk18on-172.jar +0 -0
- data/jars/bcpg-jdk18on-172.1.jar +0 -0
- data/jars/bcpkix-jdk18on-172.jar +0 -0
- data/jars/bcprov-ext-jdk18on-172.jar +0 -0
- data/jars/bcprov-jdk18on-172.jar +0 -0
- data/jars/bctls-jdk18on-172.jar +0 -0
- data/jars/bcutil-jdk18on-172.jar +0 -0
- data/lib/ccrypto/java/bc_const_mapping.rb +42 -0
- data/lib/ccrypto/java/data_conversion.rb +23 -2
- data/lib/ccrypto/java/engines/argon2_engine.rb +95 -0
- data/lib/ccrypto/java/engines/asn1_engine.rb +2 -1
- data/lib/ccrypto/java/engines/bcrypt_engine.rb +56 -0
- data/lib/ccrypto/java/engines/cipher_engine.rb +462 -130
- data/lib/ccrypto/java/engines/compression_engine.rb +7 -28
- data/lib/ccrypto/java/engines/crystal_dilithium_engine.rb +226 -0
- data/lib/ccrypto/java/engines/crystal_kyber_engine.rb +260 -0
- data/lib/ccrypto/java/engines/decompression_engine.rb +5 -4
- data/lib/ccrypto/java/engines/digest_engine.rb +221 -139
- data/lib/ccrypto/java/engines/ecc_engine.rb +249 -96
- data/lib/ccrypto/java/engines/ed25519_engine.rb +211 -0
- data/lib/ccrypto/java/engines/hkdf_engine.rb +82 -23
- data/lib/ccrypto/java/engines/hmac_engine.rb +98 -23
- data/lib/ccrypto/java/engines/pbkdf2_engine.rb +82 -33
- data/lib/ccrypto/java/engines/pkcs7_engine.rb +44 -33
- data/lib/ccrypto/java/engines/rsa_engine.rb +85 -31
- data/lib/ccrypto/java/engines/scrypt_engine.rb +12 -3
- data/lib/ccrypto/java/engines/secret_key_engine.rb +77 -12
- data/lib/ccrypto/java/engines/secret_sharing_engine.rb +17 -2
- data/lib/ccrypto/java/engines/x25519_engine.rb +249 -0
- data/lib/ccrypto/java/engines/x509_csr_engine.rb +141 -0
- data/lib/ccrypto/java/engines/x509_engine.rb +365 -71
- data/lib/ccrypto/java/ext/secret_key.rb +37 -25
- data/lib/ccrypto/java/ext/x509_cert.rb +429 -5
- data/lib/ccrypto/java/ext/x509_csr.rb +151 -0
- data/lib/ccrypto/java/jce_provider.rb +0 -11
- data/lib/ccrypto/java/keystore/jce_keystore.rb +205 -0
- data/lib/ccrypto/java/keystore/jks_keystore.rb +52 -0
- data/lib/ccrypto/java/keystore/keystore.rb +97 -0
- data/lib/ccrypto/java/keystore/pem_keystore.rb +147 -0
- data/lib/ccrypto/java/keystore/pkcs12_keystore.rb +56 -0
- data/lib/ccrypto/java/utils/comparator.rb +25 -2
- data/lib/ccrypto/java/version.rb +1 -1
- data/lib/ccrypto/java.rb +46 -0
- data/lib/ccrypto/provider.rb +139 -3
- metadata +40 -24
- data/ccrypto-java.gemspec +0 -44
- data/jars/bcmail-jdk15on-165.jar +0 -0
- data/jars/bcpg-jdk15on-165.jar +0 -0
- data/jars/bcpkix-jdk15on-165.jar +0 -0
- data/jars/bcprov-ext-jdk15on-165.jar +0 -0
- data/jars/bcprov-jdk15on-165.jar +0 -0
- data/jars/bctls-jdk15on-165.jar +0 -0
- data/lib/ccrypto/java/keybundle_store/pkcs12.rb +0 -125
@@ -7,45 +7,99 @@ module Ccrypto
|
|
7
7
|
include DataConversion
|
8
8
|
include TR::CondUtils
|
9
9
|
|
10
|
+
class HKDFEngineError < StandardError; end
|
11
|
+
|
12
|
+
class HKDFSupportedDigest
|
13
|
+
include InMemoryRecord
|
14
|
+
def initialize
|
15
|
+
#define_search_key(:algo)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.supported_hkdf_configs
|
20
|
+
if ENV[Java::ENV_PROBE_DIGEST_KEY] == "true"
|
21
|
+
@_supportedHkdf = HKDFSupportedDigest.new
|
22
|
+
else
|
23
|
+
@_supportedHkdf = HKDFSupportedDigest.load_from_storage("supported_hkdf")
|
24
|
+
end
|
25
|
+
|
26
|
+
if @_supportedHkdf.empty?
|
27
|
+
@_supportedHkdf = HKDFSupportedDigest.new
|
28
|
+
Ccrypto::Java::DigestEngine.supported.each do |dig|
|
29
|
+
bcDig = Ccrypto::Java::DigestEngine.to_bc_digest_inst(dig)
|
30
|
+
if not bcDig.nil?
|
31
|
+
logger.debug "Digest #{dig.inspect} has BC instance #{bcDig}"
|
32
|
+
conf = Ccrypto::HKDFConfig.new
|
33
|
+
conf.digest = dig
|
34
|
+
conf.provider_config = { bc_digest: bcDig }
|
35
|
+
@_supportedHkdf.register(conf, { tag_under: :calgo, tag_value: dig.algo })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@_supportedHkdf.save_to_storage("supported_hkdf")
|
39
|
+
end
|
40
|
+
|
41
|
+
@_supportedHkdf
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.find_hkdf_config_by_digest(algo)
|
45
|
+
supported_hkdf_configs.find({ calgo: algo })
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def self.logger
|
50
|
+
Ccrypto::Java.logger(:cj_hkdf_eng_c)
|
51
|
+
end
|
52
|
+
|
53
|
+
public
|
10
54
|
def initialize(*args, &block)
|
11
55
|
@config = args.first
|
12
56
|
|
13
|
-
raise KDFEngineException, "
|
57
|
+
raise KDFEngineException, "HKDF config is expected. Given #{@config}" if not @config.is_a?(Ccrypto::HKDFConfig)
|
14
58
|
raise KDFEngineException, "Output bit length (outBitLength) value is not given or not a positive value (#{@config.outBitLength})" if is_empty?(@config.outBitLength) or @config.outBitLength <= 0
|
15
59
|
|
16
|
-
|
17
|
-
@config.salt = SecureRandom.random_bytes(16) if is_empty?(@config.salt)
|
18
60
|
end
|
19
61
|
|
20
62
|
def derive(input, output = :binary)
|
21
63
|
begin
|
22
64
|
|
65
|
+
logger.debug "HKDF config : #{@config.inspect}"
|
66
|
+
|
23
67
|
case @config.digest
|
24
|
-
when
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
when
|
29
|
-
|
30
|
-
when :sha384
|
31
|
-
dig = org.bouncycastle.crypto.digests.SHA384Digest.new
|
32
|
-
when :sha512
|
33
|
-
dig = org.bouncycastle.crypto.digests.SHA512Digest.new
|
34
|
-
when :sha3_224
|
35
|
-
dig = org.bouncycastle.crypto.digests.SHA3Digest.new(224)
|
36
|
-
when :sha3_256
|
37
|
-
dig = org.bouncycastle.crypto.digests.SHA3Digest.new(256)
|
38
|
-
when :sha3_384
|
39
|
-
dig = org.bouncycastle.crypto.digests.SHA3Digest.new(384)
|
40
|
-
when :sha3_512
|
41
|
-
dig = org.bouncycastle.crypto.digests.SHA3Digest.new(512)
|
68
|
+
when Symbol, String
|
69
|
+
hkdfConf = self.class.find_hkdf_config_by_digest(@config.digest)
|
70
|
+
raise HKDFEngineError, "Unsupported digest '#{@config.digest}'" if is_empty?(hkdfConf)
|
71
|
+
digest = hkdfConf.first.digest
|
72
|
+
when Ccrypto::DigestConfig
|
73
|
+
digest = @config.digest
|
42
74
|
else
|
43
|
-
raise
|
75
|
+
raise HKDFEngineError, "Unsupported digest '#{@config.digest}'"
|
76
|
+
end
|
77
|
+
|
78
|
+
logger.debug "Digest for HKDF : #{digest.inspect}"
|
79
|
+
|
80
|
+
begin
|
81
|
+
dig = Ccrypto::Java::DigestEngine.instance(digest)
|
82
|
+
rescue Exception => ex
|
83
|
+
raise KDFEngineException, "Failed to initialize digest engine. Error was : #{ex}"
|
44
84
|
end
|
45
85
|
|
86
|
+
#bcDigest = Ccrypto::Java::DigestEngine.to_bc_digest_inst(digest.provider_config[:algo_name])
|
87
|
+
#raise KDFEngineException, "Digest '#{digest.algo}' not supported. Please report to library owner for further verification" if bcDigest.nil?
|
88
|
+
|
89
|
+
bcDigest = eval(@config.provider_config[:bc_digest])
|
90
|
+
|
91
|
+
# https://soatok.blog/2021/11/17/understanding-hkdf/
|
92
|
+
# info field should be the randomness entrophy compare to salt
|
93
|
+
# HKDf can have fix or null salt but better have additional info for each purposes
|
46
94
|
@config.info = "" if @config.info.nil?
|
47
95
|
|
48
|
-
|
96
|
+
logger.debug "Salt length : #{@config.salt.nil? ? "0" : @config.salt.length}"
|
97
|
+
logger.debug "Info length : #{@config.info.nil? ? "0" : @config.info.length}"
|
98
|
+
logger.debug "Digest : #{bcDigest}"
|
99
|
+
|
100
|
+
logger.warn "Salt is empty!" if is_empty?(@config.salt)
|
101
|
+
|
102
|
+
hkdf = org.bouncycastle.crypto.generators.HKDFBytesGenerator.new(bcDigest)
|
49
103
|
hkdfParam = org.bouncycastle.crypto.params.HKDFParameters.new(to_java_bytes(input), to_java_bytes(@config.salt) ,to_java_bytes(@config.info))
|
50
104
|
hkdf.init(hkdfParam)
|
51
105
|
|
@@ -67,6 +121,11 @@ module Ccrypto
|
|
67
121
|
|
68
122
|
end
|
69
123
|
|
124
|
+
private
|
125
|
+
def logger
|
126
|
+
Ccrypto::Java.logger(:cj_hkdf_eng)
|
127
|
+
end
|
128
|
+
|
70
129
|
end
|
71
130
|
end
|
72
131
|
end
|
@@ -7,23 +7,110 @@ module Ccrypto
|
|
7
7
|
include TR::CondUtils
|
8
8
|
include DataConversion
|
9
9
|
|
10
|
-
|
11
|
-
teLogger_tag :j_hmac
|
10
|
+
class HMACEngineError < StandardError; end
|
12
11
|
|
12
|
+
class SupportedHMACList
|
13
|
+
include InMemoryRecord
|
14
|
+
def initialize
|
15
|
+
#define_search_key(:algo)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.supported_hmac
|
20
|
+
|
21
|
+
if @supported.nil?
|
22
|
+
@supported = SupportedHMACList.new
|
23
|
+
Ccrypto::Java::DigestEngine.supported.each do |v|
|
24
|
+
begin
|
25
|
+
prov = v.provider_config[:jceProvider]
|
26
|
+
digestAlgo = v.provider_config[:algo_name]
|
27
|
+
if digestAlgo =~ /^SHA-/
|
28
|
+
digestAlgo = digestAlgo.gsub("-","")
|
29
|
+
end
|
30
|
+
algo = "HMAC#{digestAlgo}"
|
31
|
+
if not_empty?(prov)
|
32
|
+
logger.debug "Initializing HMAC algo '#{algo}' with provider '#{prov}'"
|
33
|
+
javax.crypto.Mac.getInstance(algo, prov)
|
34
|
+
else
|
35
|
+
logger.debug "Initializing HMAC algo '#{algo}' with null provider"
|
36
|
+
javax.crypto.Mac.getInstance(algo)
|
37
|
+
end
|
38
|
+
|
39
|
+
conf = Ccrypto::HMACConfig.new(v.dup)
|
40
|
+
conf.provider_config = { hmac_algo: algo, jce_provider: prov }
|
41
|
+
@supported.register(conf, { tag_under: :algo, tag_value: digestAlgo })
|
42
|
+
#@supported[algo] = conf
|
43
|
+
rescue Exception => ex
|
44
|
+
logger.debug "HMAC algo '#{algo}' failed. Error was : #{ex.message}"
|
45
|
+
#logger.error ex.backtrace.join("\n")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
@supported
|
51
|
+
|
52
|
+
end
|
53
|
+
class << self
|
54
|
+
alias_method :supported_hmac_configs, :supported_hmac
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.find_supported_hmac_by_digest(digest)
|
58
|
+
case digest
|
59
|
+
when Symbol, String
|
60
|
+
supported_hmac.find( algo: digest )
|
61
|
+
when Ccrypto::DigestConfig
|
62
|
+
supported_hmac.select { |hm| hm.digest_config.algo.to_s.downcase == digest.algo.to_s.downcase }
|
63
|
+
else
|
64
|
+
raise HMACEngineException, "Unsupported parameter for digest. Expected Ccrypto::DigestConfig, symbol or string. Got '#{digest.class}'"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.default_hmac_digest_algo
|
69
|
+
primary = find_supported_hmac_by_digest_algo("sha3-256").first
|
70
|
+
if is_empty?(primary)
|
71
|
+
secondary = find_supported_hmac_by_digest_algo("sha256").first
|
72
|
+
if is_empty?(secondary)
|
73
|
+
first = supported_hmac.values.first
|
74
|
+
logger.debug "Both SHA3-256 and SHA256 are not supported. Default to '#{first.inspect}'"
|
75
|
+
first
|
76
|
+
else
|
77
|
+
secondary
|
78
|
+
end
|
79
|
+
else
|
80
|
+
primary
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
def self.logger
|
86
|
+
Ccrypto::Java.logger(:hmac_eng_c)
|
87
|
+
end
|
88
|
+
|
89
|
+
public
|
13
90
|
def initialize(*args, &block)
|
14
91
|
@config = args.first
|
15
92
|
|
93
|
+
logger.debug "HMAC Config : #{@config.inspect}"
|
94
|
+
|
16
95
|
raise HMACEngineException, "HMAC config is expected" if not @config.is_a?(Ccrypto::HMACConfig)
|
17
96
|
|
18
|
-
raise HMACEngineException, "Signing key is required" if is_empty?(@config.
|
19
|
-
raise HMACEngineException, "
|
97
|
+
raise HMACEngineException, "Signing key is required" if is_empty?(@config.ccrypto_key)
|
98
|
+
raise HMACEngineException, "Ccrypto:SecretKey is required. Given #{@config.ccrypto_key.class}" if not @config.ccrypto_key.is_a?(Ccrypto::SecretKey)
|
20
99
|
|
21
|
-
teLogger.debug "Config : #{@config.inspect}"
|
22
100
|
begin
|
23
|
-
macAlgo =
|
24
|
-
|
25
|
-
|
26
|
-
|
101
|
+
macAlgo = @config.provider_config[:hmac_algo]
|
102
|
+
prov = @config.provider_config[:jce_provider]
|
103
|
+
if not_empty?(prov)
|
104
|
+
logger.debug "Mac algo : #{macAlgo} with provider '#{prov}'"
|
105
|
+
@hmac = javax.crypto.Mac.getInstance(macAlgo, prov)
|
106
|
+
else
|
107
|
+
logger.debug "Mac algo : #{macAlgo} with null provider"
|
108
|
+
@hmac = javax.crypto.Mac.getInstance(macAlgo)
|
109
|
+
end
|
110
|
+
|
111
|
+
logger.debug "Initialize the Mac with ccrypto_key"
|
112
|
+
@hmac.init(@config.ccrypto_key.native_key)
|
113
|
+
|
27
114
|
rescue Exception => ex
|
28
115
|
raise HMACEngineException, ex
|
29
116
|
end
|
@@ -54,22 +141,10 @@ module Ccrypto
|
|
54
141
|
|
55
142
|
|
56
143
|
private
|
57
|
-
def
|
58
|
-
|
59
|
-
res << "HMAC"
|
60
|
-
|
61
|
-
salgo = config.digest.to_s
|
62
|
-
if salgo =~ /_/
|
63
|
-
res << salgo.gsub("_","-").upcase
|
64
|
-
else
|
65
|
-
res << salgo.upcase
|
66
|
-
end
|
67
|
-
|
68
|
-
res.join
|
69
|
-
|
144
|
+
def logger
|
145
|
+
Ccrypto::Java.logger(:hmac_eng)
|
70
146
|
end
|
71
147
|
|
72
|
-
|
73
148
|
end
|
74
149
|
end
|
75
150
|
end
|
@@ -3,43 +3,104 @@ require_relative '../data_conversion'
|
|
3
3
|
|
4
4
|
module Ccrypto
|
5
5
|
module Java
|
6
|
-
|
6
|
+
|
7
7
|
class PBKDF2Engine
|
8
8
|
include TR::CondUtils
|
9
9
|
include DataConversion
|
10
10
|
|
11
|
+
class PBKDF2EngineException < KDFEngineException; end
|
12
|
+
|
13
|
+
class SupportedPBKDF2HMAC
|
14
|
+
include Ccrypto::InMemoryRecord
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.supported_pbkdf2_digests
|
18
|
+
|
19
|
+
if @supportedHmac.nil?
|
20
|
+
@supportedHmac = SupportedPBKDF2HMAC.load("cj_pbkdf2")
|
21
|
+
logger.debug "supported hmac : #{@supportedHmac.empty?}"
|
22
|
+
if @supportedHmac.empty?
|
23
|
+
HMACEngine.supported_hmac_configs.each do |hm|
|
24
|
+
begin
|
25
|
+
algo = "PBKDF2With#{hm.provider_config[:hmac_algo]}"
|
26
|
+
prov = hm.provider_config[:jce_provider]
|
27
|
+
javax.crypto.SecretKeyFactory.getInstance(algo, prov)
|
28
|
+
|
29
|
+
logger.debug "PBKDF2 algo #{algo} is good"
|
30
|
+
hm.provider_config[:hmac_algo] = algo
|
31
|
+
logger.debug "Registering PBKDF2 config #{hm.inspect}"
|
32
|
+
@supportedHmac.register(hm, { tag_under: :algo, tag_value: hm.digest_config.algo })
|
33
|
+
#@supportedHmac[algo] = hm
|
34
|
+
rescue Exception => ex
|
35
|
+
logger.debug "HMAC algo #{algo} failed with PBKDF2 with error #{ex}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@supportedHmac.save("cj_pbkdf2")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
@supportedHmac
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.find_supported_hmac_by_digest(algo)
|
46
|
+
supported_pbkdf2_digests.find( algo: algo )
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def self.logger
|
51
|
+
Ccrypto::Java.logger(:pbkdf2_eng_c)
|
52
|
+
end
|
53
|
+
|
54
|
+
public
|
11
55
|
def initialize(*args, &block)
|
12
56
|
@config = args.first
|
13
57
|
|
14
|
-
raise
|
15
|
-
raise
|
58
|
+
raise PBKDF2EngineException, "KDF config is expected. Given #{@config}" if not @config.is_a?(Ccrypto::PBKDF2Config)
|
59
|
+
raise PBKDF2EngineException, "Output bit length (outBitLength) value is not given or not a positive value (#{@config.outBitLength})" if is_empty?(@config.outBitLength) or @config.outBitLength <= 0
|
16
60
|
|
17
|
-
|
61
|
+
if is_empty?(@config.digest)
|
62
|
+
@config.digest = default_digest
|
63
|
+
else
|
18
64
|
|
19
|
-
|
65
|
+
case @config.digest
|
66
|
+
when String, Symbol
|
67
|
+
dig = self.class.find_supported_hmac_by_digest(@config.digest)
|
68
|
+
raise PBKDF2EngineException, "Cannot find digest '#{@config.digest}'" if is_empty?(dig)
|
69
|
+
logger.warn "More than 1 result for supported hmac by digest found. Found #{dig.length}" if dig.length > 1
|
70
|
+
@config.digest = dig.first
|
71
|
+
|
72
|
+
when Ccrypto::HMACConfig
|
73
|
+
|
74
|
+
else
|
75
|
+
raise PBKDF2EngineException, "HMACConfig is expected instead got '#{@config.digest.class}'"
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
raise PBKDF2EngineException, "HMACConfig is required to be provider initialized HMACConfig. Please get the HMACConfig via the supported_hmac from PBKDF2" if is_empty?(@config.digest.provider_config[:hmac_algo])
|
80
|
+
end
|
81
|
+
|
82
|
+
#@config.salt = SecureRandom.random_bytes(16) if is_empty?(@config.salt)
|
20
83
|
|
21
|
-
@config.salt = SecureRandom.random_bytes(16) if is_empty?(@config.salt)
|
22
84
|
end
|
23
85
|
|
24
86
|
def derive(input, output = :binary)
|
25
|
-
|
87
|
+
|
88
|
+
cinput = java.lang.String.new(to_java_bytes(input))
|
89
|
+
|
90
|
+
#raise KDFEngineException, "Given input is not a String" if not input.is_a?(String)
|
91
|
+
|
26
92
|
begin
|
27
93
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
else
|
33
|
-
pass = to_hex(to_java_bytes(input)).to_java.toCharArray
|
34
|
-
end
|
35
|
-
when ::Java::byte[]
|
36
|
-
pass = to_hex(to_java_bytes(input)).to_java.toCharArray
|
94
|
+
algo = @config.digest.provider_config[:hmac_algo]
|
95
|
+
prov = @config.digest.provider_config[:jce_provider]
|
96
|
+
if not_empty?(prov)
|
97
|
+
skf = javax.crypto.SecretKeyFactory.getInstance(algo, prov)
|
37
98
|
else
|
38
|
-
|
99
|
+
skf = javax.crypto.SecretKeyFactory.getInstance(algo)
|
39
100
|
end
|
40
101
|
|
41
|
-
|
42
|
-
keySpec = javax.crypto.spec.PBEKeySpec.new(
|
102
|
+
# Java API 1st parameter is char[]
|
103
|
+
keySpec = javax.crypto.spec.PBEKeySpec.new(cinput.to_java.toCharArray, to_java_bytes(@config.salt), @config.iter, @config.outBitLength)
|
43
104
|
|
44
105
|
sk = skf.generateSecret(keySpec)
|
45
106
|
out = sk.encoded
|
@@ -60,24 +121,12 @@ module Ccrypto
|
|
60
121
|
end
|
61
122
|
|
62
123
|
def default_digest
|
63
|
-
|
124
|
+
self.class.find_supported_hmac_by_digest("sha256").first
|
64
125
|
end
|
65
126
|
|
66
127
|
private
|
67
128
|
def logger
|
68
|
-
|
69
|
-
@logger = TeLogger::Tlogger.new
|
70
|
-
@logger.tag = :j_pbkdf2
|
71
|
-
end
|
72
|
-
@logger
|
73
|
-
end
|
74
|
-
|
75
|
-
def is_digest_supported?(dig)
|
76
|
-
supported_digest.include?(dig)
|
77
|
-
end
|
78
|
-
|
79
|
-
def supported_digest
|
80
|
-
[:sha1, :sha256, :sha224, :sha384, :sha512]
|
129
|
+
Ccrypto::Java.logger(:pbkdf2_eng)
|
81
130
|
end
|
82
131
|
|
83
132
|
|
@@ -10,9 +10,6 @@ module Ccrypto
|
|
10
10
|
include TR::CondUtils
|
11
11
|
include DataConversion
|
12
12
|
|
13
|
-
include TeLogger::TeLogHelper
|
14
|
-
teLogger_tag :j_p7
|
15
|
-
|
16
13
|
def initialize(config)
|
17
14
|
raise PKCS7EngineException, "Ccrypto::PKCS7Config is expected. Given #{config}" if not config.is_a?(Ccrypto::PKCS7Config)
|
18
15
|
@config = config
|
@@ -94,16 +91,16 @@ module Ccrypto
|
|
94
91
|
begin
|
95
92
|
|
96
93
|
if attached
|
97
|
-
|
94
|
+
logger.debug "Initiated attached sign"
|
98
95
|
else
|
99
|
-
|
96
|
+
logger.debug "Initiated detached sign"
|
100
97
|
end
|
101
98
|
|
102
99
|
sos = gen.open(os, attached)
|
103
100
|
|
104
101
|
case val
|
105
102
|
when java.io.InputStream
|
106
|
-
|
103
|
+
logger.debug "InputStream data-to-be-signed detected"
|
107
104
|
buf = ::Java::Byte[readBufSize].new
|
108
105
|
read = 0
|
109
106
|
processed = 0
|
@@ -113,7 +110,7 @@ module Ccrypto
|
|
113
110
|
block.call(:processed, processed) if block
|
114
111
|
end
|
115
112
|
else
|
116
|
-
|
113
|
+
logger.debug "Byte array data-to-be-signed detected"
|
117
114
|
ba = to_java_bytes(val)
|
118
115
|
if ba.is_a?(::Java::byte[])
|
119
116
|
sos.write(ba)
|
@@ -155,28 +152,28 @@ module Ccrypto
|
|
155
152
|
case srcData
|
156
153
|
when java.io.File
|
157
154
|
data = org.bouncycastle.cms.CMSProcessableFile.new(val)
|
158
|
-
|
155
|
+
logger.debug "Given original data is a java.io.File"
|
159
156
|
else
|
160
157
|
if not_empty?(srcData)
|
161
158
|
ba = to_java_bytes(srcData)
|
162
159
|
if ba.is_a?(::Java::byte[])
|
163
160
|
data = org.bouncycastle.cms.CMSProcessableByteArray.new(ba)
|
164
|
-
|
161
|
+
logger.debug "Given original data is a byte array"
|
165
162
|
else
|
166
163
|
raise PKCS7EngineException, "Failed to read original data. Given #{srcData}"
|
167
164
|
end
|
168
165
|
else
|
169
|
-
|
166
|
+
logger.debug "Original data for signing is not given."
|
170
167
|
end
|
171
168
|
end
|
172
169
|
|
173
170
|
case val
|
174
171
|
when java.io.InputStream
|
175
172
|
if data.nil?
|
176
|
-
|
173
|
+
logger.debug "Attached signature with java.io.InputStream signature detected during verification"
|
177
174
|
signed = org.bouncycastle.cms.CMSSignedData.new(val)
|
178
175
|
else
|
179
|
-
|
176
|
+
logger.debug "Detached signature with java.io.InputStream signature detected during verification"
|
180
177
|
signed = org.bouncycastle.cms.CMSSignedData.new(data, val)
|
181
178
|
end
|
182
179
|
else
|
@@ -184,10 +181,10 @@ module Ccrypto
|
|
184
181
|
ba = to_java_bytes(val)
|
185
182
|
if ba.is_a?(::Java::byte[])
|
186
183
|
if data.nil?
|
187
|
-
|
184
|
+
logger.debug "Attached signature with byte array signature detected during verification"
|
188
185
|
signed = org.bouncycastle.cms.CMSSignedData.new(ba)
|
189
186
|
else
|
190
|
-
|
187
|
+
logger.debug "Detached signature with byte array signature detected during verification"
|
191
188
|
signed = org.bouncycastle.cms.CMSSignedData.new(data, ba)
|
192
189
|
end
|
193
190
|
else
|
@@ -211,27 +208,27 @@ module Ccrypto
|
|
211
208
|
if block
|
212
209
|
certVerified = block.call(:verify_certificate, c)
|
213
210
|
if certVerified.nil?
|
214
|
-
|
211
|
+
logger.debug "Certificate with subject #{c.subject} / Issuer : #{c.issuer} / SN : #{c.serial_number.to_s(16)} passed through (no checking by application)"
|
215
212
|
certVerified = true
|
216
213
|
elsif is_bool?(certVerified)
|
217
214
|
if certVerified
|
218
|
-
|
215
|
+
logger.debug "Certificate with subject #{c.subject} / Issuer : #{c.issuer} / SN : #{c.serial_number.to_s(16)} accepted by application"
|
219
216
|
else
|
220
|
-
|
217
|
+
logger.debug "Certificate with subject #{c.subject} / Issuer : #{c.issuer} / SN : #{c.serial_number.to_s(16)} rejected by application"
|
221
218
|
end
|
222
219
|
else
|
223
|
-
|
220
|
+
logger.debug "Certificate with subject #{c.subject} / Issuer : #{c.issuer} / SN : #{c.serial_number.to_s(16)} passed through (no checking by application. Given #{certVerified})"
|
224
221
|
end
|
225
222
|
else
|
226
|
-
|
223
|
+
logger.debug "Certificate with subject #{c.subject} / Issuer : #{c.issuer} / SN : #{c.serial_number.to_s(16)} passed through (no checking by application)"
|
227
224
|
end
|
228
225
|
|
229
226
|
if certVerified
|
230
227
|
|
231
|
-
|
228
|
+
logger.debug "Verifing signature against certificate '#{c.subject}'"
|
232
229
|
verifier = org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder.new.setProvider(prov).build(c)
|
233
230
|
if signer.verify(verifier)
|
234
|
-
|
231
|
+
logger.debug "Signer with #{c.subject} verified!"
|
235
232
|
if block
|
236
233
|
block.call(:verification_result, true)
|
237
234
|
if data.nil?
|
@@ -242,19 +239,19 @@ module Ccrypto
|
|
242
239
|
signatureVerified = true
|
243
240
|
|
244
241
|
else
|
245
|
-
|
242
|
+
logger.debug "Signer with #{c.subject} failed. Retry with subsequent certificate"
|
246
243
|
signatureVerified = false
|
247
244
|
end
|
248
245
|
|
249
246
|
end
|
250
247
|
rescue ::Java::OrgBouncycastleCms::CMSSignerDigestMismatchException => ex
|
251
|
-
|
248
|
+
logger.error "Signer digest mismatch exception : #{ex.message}"
|
252
249
|
signatureVerified = false
|
253
250
|
break
|
254
251
|
rescue Exception => ex
|
255
|
-
|
256
|
-
|
257
|
-
|
252
|
+
logger.error ex
|
253
|
+
logger.error ex.message
|
254
|
+
logger.error ex.backtrace.join("\n")
|
258
255
|
end
|
259
256
|
end
|
260
257
|
# end certs.getMatches
|
@@ -278,7 +275,7 @@ module Ccrypto
|
|
278
275
|
intBufSize = 1024000
|
279
276
|
if block
|
280
277
|
cipher = block.call(:cipher)
|
281
|
-
|
278
|
+
logger.debug "Application given cipher #{cipher}"
|
282
279
|
|
283
280
|
prov = block.call(:jce_provider)
|
284
281
|
intBufSize = block.call(:int_buffer_size)
|
@@ -288,7 +285,17 @@ module Ccrypto
|
|
288
285
|
end
|
289
286
|
end
|
290
287
|
|
291
|
-
|
288
|
+
if cipher.nil?
|
289
|
+
cipher = CipherEngine.get_cipher_config(:aes, 256, :cbc)
|
290
|
+
if not_empty?(cipher)
|
291
|
+
cipher = cipher.first
|
292
|
+
else
|
293
|
+
raise PKCS7EngineException, "Not able to get AES/256/CBC from CipherEngine"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
#cipher = Ccrypto::DirectCipherConfig.new({ algo: :aes, keysize: 256, mode: :cbc }) if cipher.nil?
|
292
299
|
prov = Ccrypto::Java::JCEProvider::DEFProv if is_empty?(prov)
|
293
300
|
intBufSize = 1024000 if is_empty?(intBufSize)
|
294
301
|
|
@@ -381,7 +388,7 @@ module Ccrypto
|
|
381
388
|
encIs = r.getContentStream(kt).getContentStream
|
382
389
|
rescue Exception => ex
|
383
390
|
lastEx = ex
|
384
|
-
|
391
|
+
logger.debug "Got exception : #{ex.message}. Retry with another envelope"
|
385
392
|
next
|
386
393
|
end
|
387
394
|
|
@@ -432,10 +439,10 @@ module Ccrypto
|
|
432
439
|
|
433
440
|
case obj
|
434
441
|
when java.security.Certificate
|
435
|
-
|
442
|
+
logger.debug "Given recipient info is java.security.Certificate"
|
436
443
|
org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator.new(obj).setProvider(prov)
|
437
444
|
when Ccrypto::X509Cert
|
438
|
-
|
445
|
+
logger.debug "Given recipient info is Ccrypto::X509Cert"
|
439
446
|
org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator.new(obj.nativeX509).setProvider(prov)
|
440
447
|
else
|
441
448
|
raise PKCS7EngineException, "Unknown object to conver to CMS recipient info. Given #{obj}"
|
@@ -483,9 +490,10 @@ module Ccrypto
|
|
483
490
|
end # to_cms_recipient_info
|
484
491
|
|
485
492
|
def cipher_to_bc_cms_algo(cipher)
|
493
|
+
p cipher
|
486
494
|
case cipher
|
487
495
|
when Ccrypto::CipherConfig
|
488
|
-
case cipher.algo
|
496
|
+
case cipher.algo.downcase.to_sym
|
489
497
|
when :seed
|
490
498
|
eval("org.bouncycastle.cms.CMSAlgorithm::#{cipher.algo.to_s.upcase}_#{cipher.mode.to_s.upcase}")
|
491
499
|
else
|
@@ -549,8 +557,11 @@ module Ccrypto
|
|
549
557
|
# raise GcryptoBcCms::Error, "Unsupported object for decryption recipient object conversion '#{obj.class}'"
|
550
558
|
#end
|
551
559
|
|
552
|
-
|
560
|
+
end
|
553
561
|
|
562
|
+
def logger
|
563
|
+
Ccrypto::Java.logger(:pkcs7_eng)
|
564
|
+
end
|
554
565
|
|
555
566
|
end
|
556
567
|
|