lib/ccrypto/java/engines/hmac_engine.rb in ccrypto-java-0.1.0 vs lib/ccrypto/java/engines/hmac_engine.rb in ccrypto-java-0.2.0

- old
+ new

@@ -5,27 +5,114 @@ module Java class HMACEngine include TR::CondUtils include DataConversion - include TeLogger::TeLogHelper - teLogger_tag :j_hmac + class HMACEngineError < StandardError; end + class SupportedHMACList + include InMemoryRecord + def initialize + #define_search_key(:algo) + end + end + + def self.supported_hmac + + if @supported.nil? + @supported = SupportedHMACList.new + Ccrypto::Java::DigestEngine.supported.each do |v| + begin + prov = v.provider_config[:jceProvider] + digestAlgo = v.provider_config[:algo_name] + if digestAlgo =~ /^SHA-/ + digestAlgo = digestAlgo.gsub("-","") + end + algo = "HMAC#{digestAlgo}" + if not_empty?(prov) + logger.debug "Initializing HMAC algo '#{algo}' with provider '#{prov}'" + javax.crypto.Mac.getInstance(algo, prov) + else + logger.debug "Initializing HMAC algo '#{algo}' with null provider" + javax.crypto.Mac.getInstance(algo) + end + + conf = Ccrypto::HMACConfig.new(v.dup) + conf.provider_config = { hmac_algo: algo, jce_provider: prov } + @supported.register(conf, { tag_under: :algo, tag_value: digestAlgo }) + #@supported[algo] = conf + rescue Exception => ex + logger.debug "HMAC algo '#{algo}' failed. Error was : #{ex.message}" + #logger.error ex.backtrace.join("\n") + end + end + end + + @supported + + end + class << self + alias_method :supported_hmac_configs, :supported_hmac + end + + def self.find_supported_hmac_by_digest(digest) + case digest + when Symbol, String + supported_hmac.find( algo: digest ) + when Ccrypto::DigestConfig + supported_hmac.select { |hm| hm.digest_config.algo.to_s.downcase == digest.algo.to_s.downcase } + else + raise HMACEngineException, "Unsupported parameter for digest. Expected Ccrypto::DigestConfig, symbol or string. Got '#{digest.class}'" + end + end + + def self.default_hmac_digest_algo + primary = find_supported_hmac_by_digest_algo("sha3-256").first + if is_empty?(primary) + secondary = find_supported_hmac_by_digest_algo("sha256").first + if is_empty?(secondary) + first = supported_hmac.values.first + logger.debug "Both SHA3-256 and SHA256 are not supported. Default to '#{first.inspect}'" + first + else + secondary + end + else + primary + end + end + + private + def self.logger + Ccrypto::Java.logger(:hmac_eng_c) + end + + public def initialize(*args, &block) @config = args.first + logger.debug "HMAC Config : #{@config.inspect}" + raise HMACEngineException, "HMAC config is expected" if not @config.is_a?(Ccrypto::HMACConfig) - raise HMACEngineException, "Signing key is required" if is_empty?(@config.key) - raise HMACEngineException, "Secret key as signing key is required. Given #{@config.key.class}" if not @config.key.is_a?(Ccrypto::SecretKey) + raise HMACEngineException, "Signing key is required" if is_empty?(@config.ccrypto_key) + raise HMACEngineException, "Ccrypto:SecretKey is required. Given #{@config.ccrypto_key.class}" if not @config.ccrypto_key.is_a?(Ccrypto::SecretKey) - teLogger.debug "Config : #{@config.inspect}" begin - macAlgo = to_jce_spec(@config) - teLogger.debug "Mac algo : #{macAlgo}" - @hmac = javax.crypto.Mac.getInstance(to_jce_spec(@config)) - @hmac.init(@config.key.to_jce_secret_key) + macAlgo = @config.provider_config[:hmac_algo] + prov = @config.provider_config[:jce_provider] + if not_empty?(prov) + logger.debug "Mac algo : #{macAlgo} with provider '#{prov}'" + @hmac = javax.crypto.Mac.getInstance(macAlgo, prov) + else + logger.debug "Mac algo : #{macAlgo} with null provider" + @hmac = javax.crypto.Mac.getInstance(macAlgo) + end + + logger.debug "Initialize the Mac with ccrypto_key" + @hmac.init(@config.ccrypto_key.native_key) + rescue Exception => ex raise HMACEngineException, ex end end @@ -52,24 +139,12 @@ end end private - def to_jce_spec(config) - res = [] - res << "HMAC" - - salgo = config.digest.to_s - if salgo =~ /_/ - res << salgo.gsub("_","-").upcase - else - res << salgo.upcase - end - - res.join - + def logger + Ccrypto::Java.logger(:hmac_eng) end - end end end