class Sqreen::SqreenSignedVerifier
Normalize and verify a rule
Constants
- PUBLIC_KEY
- REQUIRED_SIGNED_KEYS
- SIGNATURE_KEY
- SIGNATURE_VALUE_KEY
- SIGNATURE_VERSION
- SIGNED_KEYS_KEY
Attributes
digest[RW]
pub_key[RW]
required_signed_keys[RW]
use_oj[RW]
Public Class Methods
new(required_keys = REQUIRED_SIGNED_KEYS, public_key = PUBLIC_KEY, digest = OpenSSL::Digest::SHA512.new, use_oj_gem = nil)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 47 def initialize(required_keys = REQUIRED_SIGNED_KEYS, public_key = PUBLIC_KEY, digest = OpenSSL::Digest::SHA512.new, use_oj_gem = nil) @required_signed_keys = required_keys @signature_verifier = SignatureVerifier.new(public_key, digest) @use_oj = use_oj_gem.nil? ? OJ_LOADED : use_oj_gem end
Public Instance Methods
get_sig_infos_or_fail(hash_rule)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 121 def get_sig_infos_or_fail(hash_rule) raise Sqreen::Exception, 'non hash argument' unless hash_rule.is_a?(Hash) sigs = hash_rule[SIGNATURE_KEY] raise Sqreen::Exception, 'no signature found' unless sigs sig = sigs[SIGNATURE_VERSION] msg = "signature #{SIGNATURE_VERSION} not found (#{sigs})" raise Sqreen::Exception, msg unless sig sig_value = sig[SIGNATURE_VALUE_KEY] raise Sqreen::Exception, 'no signature value found' unless sig_value signed_keys = sig[SIGNED_KEYS_KEY] raise Sqreen::Exception, "no signed keys found (#{sig})" unless signed_keys inc = Set.new(signed_keys).superset?(Set.new(@required_signed_keys)) raise Sqreen::Exception, 'signed keys miss equired keys' unless inc [signed_keys, sig_value] end
normalize(hash_rule, signed_keys = nil, level = 20)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 94 def normalize(hash_rule, signed_keys = nil, level = 20) # Normalize the provided hash to a string: # - sort keys lexicographically, recursively # - convert each scalar to its JSON representation # - convert hash to '{key:value}' # - convert array [v1,v2] to '[v1,v2]' and [] to '[]' # Two hash with different key ordering should have the same normalized # value. raise Sqreen::Exception, 'recursion level too deep' if level == 0 unless hash_rule.is_a?(Hash) raise Sqreen::Exception, "wrong hash type #{hash_rule.class}" end res = [] hash_rule.sort.each do |k, v| # Only keep signed keys next if signed_keys && !signed_keys.include?(k) k = normalize_key(k) v = normalize_val(v, level - 1) res << "#{k}:#{v}" end "{#{res.join(',')}}" end
normalize_key(key)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 79 def normalize_key(key) case key when String, Integer return Oj.dump(key, :mode => :compat, :escape_mode => :json) if use_oj begin JSON.dump(key) rescue JSON::GeneratorError JSON.generate(key, :quirks_mode => true) end else msg = "JSON hash parsing error (wrong key type: #{key.class})" raise Sqreen::Exception, msg end end
normalize_val(val, level)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 55 def normalize_val(val, level) raise Sqreen::Exception, 'recursion level too deep' if level == 0 case val when Hash normalize(val, nil, level - 1) when Array ary = val.map do |i| normalize_val(i, level - 1) end "[#{ary.join(',')}]" when String, Integer return Oj.dump(val, :mode => :compat, :escape_mode => :json) if use_oj begin JSON.dump(val) rescue JSON::GeneratorError JSON.generate(val, :quirks_mode => true) end else msg = "JSON hash parsing error (wrong value type: #{val.class})" raise Sqreen::Exception.new, msg end end
verify(hash_rule)
click to toggle source
# File lib/sqreen/sqreen_signed_verifier.rb, line 143 def verify(hash_rule) # Return true if rule signature is correct, else false signed_keys, sig_value = get_sig_infos_or_fail(hash_rule) norm_str = normalize(hash_rule, signed_keys) bin_sig = Base64.decode64(sig_value) @signature_verifier.verify(bin_sig, norm_str) rescue OpenSSL::PKey::ECError false end