Class: Sqreen::SqreenSignedVerifier
- Inherits:
-
Object
- Object
- Sqreen::SqreenSignedVerifier
- Defined in:
- lib/sqreen/sqreen_signed_verifier.rb
Overview
Normalize and verify a rule
Constant Summary collapse
- REQUIRED_SIGNED_KEYS =
%w[hookpoint name callbacks conditions].freeze
- SIGNATURE_KEY =
'signature'.freeze
- SIGNATURE_VALUE_KEY =
'value'.freeze
- SIGNED_KEYS_KEY =
'keys'.freeze
- SIGNATURE_VERSION =
'v0_9'.freeze
- PUBLIC_KEY =
<<-KEY.gsub(/^ */, '').freeze -----BEGIN PUBLIC KEY----- MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA39oWMHR8sxb9LRaM5evZ7mw03iwJ WNHuDeGqgPo1HmvuMfLnAyVLwaMXpGPuvbqhC1U65PG90bTJLpvNokQf0VMA5Tpi m+NXwl7bjqa03vO/HErLbq3zBRysrZnC4OhJOF1jazkAg0psQOea2r5HcMcPHgMK fnWXiKWnZX+uOWPuerE= -----END PUBLIC KEY----- KEY
Instance Attribute Summary collapse
-
#digest ⇒ Object
Returns the value of attribute digest.
-
#pub_key ⇒ Object
Returns the value of attribute pub_key.
-
#required_signed_keys ⇒ Object
Returns the value of attribute required_signed_keys.
-
#use_oj ⇒ Object
Returns the value of attribute use_oj.
Instance Method Summary collapse
- #get_sig_infos_or_fail(hash_rule) ⇒ Object
-
#initialize(required_keys = REQUIRED_SIGNED_KEYS, public_key = PUBLIC_KEY, digest = OpenSSL::Digest::SHA512.new, use_oj_gem = nil) ⇒ SqreenSignedVerifier
constructor
A new instance of SqreenSignedVerifier.
- #normalize(hash_rule, signed_keys = nil, level = 20) ⇒ Object
- #normalize_key(key) ⇒ Object
- #normalize_val(val, level) ⇒ Object
- #verify(hash_rule) ⇒ Object
Constructor Details
#initialize(required_keys = REQUIRED_SIGNED_KEYS, public_key = PUBLIC_KEY, digest = OpenSSL::Digest::SHA512.new, use_oj_gem = nil) ⇒ SqreenSignedVerifier
Returns a new instance of SqreenSignedVerifier.
47 48 49 50 51 52 53 |
# 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 |
Instance Attribute Details
#digest ⇒ Object
Returns the value of attribute digest.
44 45 46 |
# File 'lib/sqreen/sqreen_signed_verifier.rb', line 44 def digest @digest end |
#pub_key ⇒ Object
Returns the value of attribute pub_key.
42 43 44 |
# File 'lib/sqreen/sqreen_signed_verifier.rb', line 42 def pub_key @pub_key end |
#required_signed_keys ⇒ Object
Returns the value of attribute required_signed_keys.
43 44 45 |
# File 'lib/sqreen/sqreen_signed_verifier.rb', line 43 def required_signed_keys @required_signed_keys end |
#use_oj ⇒ Object
Returns the value of attribute use_oj.
45 46 47 |
# File 'lib/sqreen/sqreen_signed_verifier.rb', line 45 def use_oj @use_oj end |
Instance Method Details
#get_sig_infos_or_fail(hash_rule) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# 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) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# 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) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# 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) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# 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) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 |
# 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 |