sqreen 0.1.0.pre → 0.7.01461158029
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/CODE_OF_CONDUCT.md +22 -0
- data/README.md +77 -0
- data/Rakefile +40 -0
- data/lib/sqreen.rb +67 -0
- data/lib/sqreen/binding_accessor.rb +184 -0
- data/lib/sqreen/ca.crt +72 -0
- data/lib/sqreen/callback_tree.rb +78 -0
- data/lib/sqreen/callbacks.rb +120 -0
- data/lib/sqreen/capped_queue.rb +23 -0
- data/lib/sqreen/condition_evaluator.rb +169 -0
- data/lib/sqreen/conditionable.rb +50 -0
- data/lib/sqreen/configuration.rb +151 -0
- data/lib/sqreen/context.rb +22 -0
- data/lib/sqreen/deliveries/batch.rb +80 -0
- data/lib/sqreen/deliveries/simple.rb +36 -0
- data/lib/sqreen/detect.rb +14 -0
- data/lib/sqreen/detect/shell_injection.rb +61 -0
- data/lib/sqreen/detect/sql_injection.rb +115 -0
- data/lib/sqreen/event.rb +16 -0
- data/lib/sqreen/events/attack.rb +60 -0
- data/lib/sqreen/events/remote_exception.rb +53 -0
- data/lib/sqreen/exception.rb +31 -0
- data/lib/sqreen/frameworks.rb +40 -0
- data/lib/sqreen/frameworks/generic.rb +243 -0
- data/lib/sqreen/frameworks/rails.rb +155 -0
- data/lib/sqreen/frameworks/rails3.rb +36 -0
- data/lib/sqreen/frameworks/sinatra.rb +34 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +26 -0
- data/lib/sqreen/instrumentation.rb +504 -0
- data/lib/sqreen/log.rb +116 -0
- data/lib/sqreen/metrics.rb +6 -0
- data/lib/sqreen/metrics/average.rb +39 -0
- data/lib/sqreen/metrics/base.rb +41 -0
- data/lib/sqreen/metrics/collect.rb +22 -0
- data/lib/sqreen/metrics/sum.rb +20 -0
- data/lib/sqreen/metrics_store.rb +94 -0
- data/lib/sqreen/parsers/sql.rb +98 -0
- data/lib/sqreen/parsers/sql_tokenizer.rb +266 -0
- data/lib/sqreen/parsers/unix.rb +110 -0
- data/lib/sqreen/payload_creator.rb +132 -0
- data/lib/sqreen/performance_notifications.rb +86 -0
- data/lib/sqreen/performance_notifications/log.rb +36 -0
- data/lib/sqreen/performance_notifications/metrics.rb +36 -0
- data/lib/sqreen/performance_notifications/newrelic.rb +36 -0
- data/lib/sqreen/remote_command.rb +82 -0
- data/lib/sqreen/rule_attributes.rb +25 -0
- data/lib/sqreen/rule_callback.rb +97 -0
- data/lib/sqreen/rules.rb +116 -0
- data/lib/sqreen/rules_callbacks.rb +29 -0
- data/lib/sqreen/rules_callbacks/binding_accessor_metrics.rb +79 -0
- data/lib/sqreen/rules_callbacks/count_http_codes.rb +18 -0
- data/lib/sqreen/rules_callbacks/crawler_user_agent_matches.rb +24 -0
- data/lib/sqreen/rules_callbacks/crawler_user_agent_matches_metrics.rb +25 -0
- data/lib/sqreen/rules_callbacks/execjs.rb +136 -0
- data/lib/sqreen/rules_callbacks/headers_insert.rb +20 -0
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +20 -0
- data/lib/sqreen/rules_callbacks/matcher_rule.rb +103 -0
- data/lib/sqreen/rules_callbacks/rails_parameters.rb +14 -0
- data/lib/sqreen/rules_callbacks/record_request_context.rb +23 -0
- data/lib/sqreen/rules_callbacks/reflected_xss.rb +40 -0
- data/lib/sqreen/rules_callbacks/regexp_rule.rb +36 -0
- data/lib/sqreen/rules_callbacks/shell.rb +33 -0
- data/lib/sqreen/rules_callbacks/shell_env.rb +32 -0
- data/lib/sqreen/rules_callbacks/sql.rb +41 -0
- data/lib/sqreen/rules_callbacks/system_shell.rb +25 -0
- data/lib/sqreen/rules_callbacks/url_matches.rb +25 -0
- data/lib/sqreen/rules_callbacks/user_agent_matches.rb +22 -0
- data/lib/sqreen/rules_signature.rb +142 -0
- data/lib/sqreen/runner.rb +312 -0
- data/lib/sqreen/runtime_infos.rb +127 -0
- data/lib/sqreen/session.rb +340 -0
- data/lib/sqreen/stats.rb +18 -0
- data/lib/sqreen/version.rb +6 -0
- metadata +95 -34
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
class RailsParametersCB < RuleCB
|
9
|
+
def pre(_inst, *_args, &_block)
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Save request context for handling further down
|
9
|
+
class RecordRequestContext < RuleCB
|
10
|
+
def pre(_inst, *args, &_block)
|
11
|
+
framework.store_request(args[0])
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(_rv, _inst, *_args, &_block)
|
15
|
+
framework.clean_request
|
16
|
+
end
|
17
|
+
|
18
|
+
def failing(_exception, _inst, *_args, &_block)
|
19
|
+
framework.clean_request
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
require 'sqreen/rules_callbacks/regexp_rule'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
module Rules
|
10
|
+
# look for reflected XSS
|
11
|
+
class ReflectedXSSCB < RegexpRuleCB
|
12
|
+
def pre(_inst, *args, &_block)
|
13
|
+
value = args[0]
|
14
|
+
return if value.nil?
|
15
|
+
# If the value is not marked as html_safe, it will be escaped later
|
16
|
+
return unless value.html_safe?
|
17
|
+
|
18
|
+
# Sqreen::log.debug value
|
19
|
+
# Sqreen::log.debug params
|
20
|
+
|
21
|
+
return unless framework.params_include?(value)
|
22
|
+
|
23
|
+
Sqreen.log.debug { format('Found unescaped user param: %s', value) }
|
24
|
+
|
25
|
+
saved_value = value.dup
|
26
|
+
# potential XSS! let's escape
|
27
|
+
args[0].replace(CGI.escape_html(value)) if block
|
28
|
+
# The remaining code is only to find out if user entry was an attack,
|
29
|
+
# and record it. Since we don't rely on it to respond to user, it would
|
30
|
+
# be better to do it in background.
|
31
|
+
found = match_regexp(saved_value)
|
32
|
+
|
33
|
+
return unless found
|
34
|
+
infos = { :found => found }
|
35
|
+
record_event(infos)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Generic regexp based matching
|
9
|
+
class RegexpRuleCB < RuleCB
|
10
|
+
def initialize(*args)
|
11
|
+
super(*args)
|
12
|
+
prepare
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
@patterns = []
|
17
|
+
raw_patterns = @data['values']
|
18
|
+
if raw_patterns.nil?
|
19
|
+
msg = "no key 'values' in data (had #{@data.keys})"
|
20
|
+
raise Sqreen::Exception, msg
|
21
|
+
end
|
22
|
+
|
23
|
+
@patterns = raw_patterns.map do |pattern|
|
24
|
+
Regexp.compile(pattern, Regexp::IGNORECASE)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def match_regexp(str)
|
29
|
+
@patterns.each do |pattern|
|
30
|
+
return pattern if pattern.match(str)
|
31
|
+
end
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
require 'sqreen/detect'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Rules
|
9
|
+
# Look for Shell injections
|
10
|
+
class ShellCB < RuleCB
|
11
|
+
def pre(_inst, *args, &_block)
|
12
|
+
Sqreen.log.debug { "<< #{@klass} #{@method} #{Thread.current}" }
|
13
|
+
Sqreen.log.debug { args.inspect }
|
14
|
+
|
15
|
+
cmd = args[0]
|
16
|
+
params = framework.request_params
|
17
|
+
return if params.nil? || params == {}
|
18
|
+
Sqreen.log.debug { 'Searching injection in:' }
|
19
|
+
Sqreen.log.debug { 'command: ' + cmd }
|
20
|
+
Sqreen.log.debug { 'params: ' + params.inspect }
|
21
|
+
|
22
|
+
# FIXME: Handle IFS coming from spawn/exec/system ENV argument
|
23
|
+
inj = Sqreen::Detect::ShellInjection.new
|
24
|
+
shi = inj.user_escape?(cmd, params)
|
25
|
+
Sqreen.log.warn { "presence of a shell injection: #{shi}" }
|
26
|
+
return unless shi
|
27
|
+
infos = { :sh_cmd => cmd }
|
28
|
+
record_event(infos)
|
29
|
+
{ :status => :raise }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/regexp_rule'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Callback that detect nifty env in system calls
|
9
|
+
class ShellEnvCB < RegexpRuleCB
|
10
|
+
def pre(_inst, *args, &_block)
|
11
|
+
return if args.size == 0
|
12
|
+
env = args.first
|
13
|
+
return unless env.is_a?(Hash)
|
14
|
+
return if env.size == 0
|
15
|
+
found = nil
|
16
|
+
var, value = env.find do |_, val|
|
17
|
+
next unless val.is_a?(String)
|
18
|
+
found = match_regexp(val)
|
19
|
+
end
|
20
|
+
return unless var
|
21
|
+
infos = {
|
22
|
+
:variable_name => var,
|
23
|
+
:variable_value => value,
|
24
|
+
:found => found,
|
25
|
+
}
|
26
|
+
Sqreen.log.warn "presence of a shell env tampering: #{infos.inspect}"
|
27
|
+
record_event(infos)
|
28
|
+
{ :status => :raise }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
require 'sqreen/detect'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Rules
|
9
|
+
# Look for SQL injections
|
10
|
+
class SQLCB < RuleCB
|
11
|
+
def pre(inst, *args, &_block)
|
12
|
+
Sqreen.log.debug { "<< #{@klass} #{@method} #{Thread.current}" }
|
13
|
+
Sqreen.log.debug { args.inspect }
|
14
|
+
|
15
|
+
request = args[0]
|
16
|
+
params = framework.request_params
|
17
|
+
return if params.nil? || params == {}
|
18
|
+
Sqreen.log.debug { 'Searching injection in:' }
|
19
|
+
Sqreen.log.debug { 'request: ' + request }
|
20
|
+
Sqreen.log.debug { 'params: ' + params.inspect }
|
21
|
+
|
22
|
+
db_type, db_infos = framework.db_settings(:connection_adapter => inst)
|
23
|
+
if db_type.nil?
|
24
|
+
Sqreen.log.debug { "Database '#{db_infos[:name]}' not supported yet" }
|
25
|
+
return
|
26
|
+
end
|
27
|
+
inj = Sqreen::Detect::SQLInjection.new(db_type, db_infos)
|
28
|
+
sqli = inj.user_escape?(request, params)
|
29
|
+
Sqreen.log.info { "presence of an SQLi: #{sqli}" }
|
30
|
+
return unless sqli
|
31
|
+
infos = {
|
32
|
+
:db_request => request,
|
33
|
+
:db_type => db_type,
|
34
|
+
:db_infos => db_infos,
|
35
|
+
}
|
36
|
+
record_event(infos)
|
37
|
+
{ :status => :raise }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/shell'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Look for Shell injections in system like calls
|
9
|
+
class SystemShellCB < ShellCB
|
10
|
+
alias initial_pre pre
|
11
|
+
def pre(inst, *args, &block)
|
12
|
+
return if args.size == 0
|
13
|
+
cmd = args[0]
|
14
|
+
if cmd.is_a?(Hash)
|
15
|
+
# skip optional env arguments
|
16
|
+
return unless args.size > 1
|
17
|
+
cmd = args[1]
|
18
|
+
end
|
19
|
+
# skip [cmd, argv0] arguments
|
20
|
+
return if cmd.is_a?(Array)
|
21
|
+
initial_pre(inst, cmd, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/regexp_rule'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# FIXME: Tune this as Rack capable callback?
|
9
|
+
# If:
|
10
|
+
# - we have a 404
|
11
|
+
# - the path is a typical bot scanning request
|
12
|
+
# Then we deny the ressource and record the attack.
|
13
|
+
class URLMatchesCB < RegexpRuleCB
|
14
|
+
def post(rv, _inst, *args, &_block)
|
15
|
+
return unless rv.is_a?(Array) && rv.size > 0 && rv[0] == 404
|
16
|
+
env = args[0]
|
17
|
+
path = env['SCRIPT_NAME'].to_s + env['PATH_INFO'].to_s
|
18
|
+
found = match_regexp(path)
|
19
|
+
infos = { :path => path, :found => found }
|
20
|
+
record_event(infos) if found
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/regexp_rule'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Look for badly behaved clients
|
9
|
+
class UserAgentMatchesCB < RegexpRuleCB
|
10
|
+
def pre(_inst, *_args, &_block)
|
11
|
+
ua = framework.client_user_agent
|
12
|
+
return unless ua
|
13
|
+
found = match_regexp(ua)
|
14
|
+
return unless found
|
15
|
+
Sqreen.log.debug { "Found UA #{ua} - found: #{found}" }
|
16
|
+
infos = { :found => found }
|
17
|
+
record_event(infos)
|
18
|
+
{ :status => :raise, :data => found }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks'
|
5
|
+
require 'sqreen/exception'
|
6
|
+
|
7
|
+
require 'set'
|
8
|
+
require 'openssl'
|
9
|
+
require 'base64'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
## Rules signature
|
13
|
+
module Sqreen
|
14
|
+
# Perform an EC + digest verification of a message.
|
15
|
+
class SignatureVerifier
|
16
|
+
def initialize(key, digest)
|
17
|
+
@pub_key = OpenSSL::PKey.read(key)
|
18
|
+
@digest = digest
|
19
|
+
end
|
20
|
+
|
21
|
+
def verify(sig, val)
|
22
|
+
hashed_val = @digest.digest(val)
|
23
|
+
@pub_key.dsa_verify_asn1(hashed_val, sig)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Normalize and verify a rule
|
28
|
+
class SqreenSignedVerifier
|
29
|
+
REQUIRED_SIGNED_KEYS = %w(hookpoint name callbacks conditions).freeze
|
30
|
+
SIGNATURE_KEY = 'signature'.freeze
|
31
|
+
SIGNATURE_VALUE_KEY = 'value'.freeze
|
32
|
+
SIGNED_KEYS_KEY = 'signed_keys'.freeze
|
33
|
+
SIGNATURE_VERSION = 'v0_9'.freeze
|
34
|
+
PUBLIC_KEY = <<-END.gsub(/^ */, '').freeze
|
35
|
+
-----BEGIN PUBLIC KEY-----
|
36
|
+
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA39oWMHR8sxb9LRaM5evZ7mw03iwJ
|
37
|
+
WNHuDeGqgPo1HmvuMfLnAyVLwaMXpGPuvbqhC1U65PG90bTJLpvNokQf0VMA5Tpi
|
38
|
+
m+NXwl7bjqa03vO/HErLbq3zBRysrZnC4OhJOF1jazkAg0psQOea2r5HcMcPHgMK
|
39
|
+
fnWXiKWnZX+uOWPuerE=
|
40
|
+
-----END PUBLIC KEY-----
|
41
|
+
END
|
42
|
+
|
43
|
+
attr_accessor :pub_key
|
44
|
+
attr_accessor :required_signed_keys
|
45
|
+
attr_accessor :digest
|
46
|
+
|
47
|
+
def initialize(required_keys = REQUIRED_SIGNED_KEYS,
|
48
|
+
public_key = PUBLIC_KEY,
|
49
|
+
digest = OpenSSL::Digest::SHA512.new)
|
50
|
+
@required_signed_keys = required_keys
|
51
|
+
@signature_verifier = SignatureVerifier.new(public_key, digest)
|
52
|
+
end
|
53
|
+
|
54
|
+
def normalize_val(val, level)
|
55
|
+
raise Sqreen::Exception, 'recursion level too deep' if level == 0
|
56
|
+
|
57
|
+
case val
|
58
|
+
when Hash
|
59
|
+
normalize(val, nil, level - 1)
|
60
|
+
when Array
|
61
|
+
ary = val.map do |i|
|
62
|
+
normalize_val(i, level - 1)
|
63
|
+
end
|
64
|
+
"[#{ary.join(',')}]"
|
65
|
+
when String, Integer
|
66
|
+
JSON.dump(val)
|
67
|
+
else
|
68
|
+
msg = "JSON hash parsing error (wrong value type: #{val.class})"
|
69
|
+
raise Sqreen::Exception.new, msg
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def normalize_key(key)
|
74
|
+
case key
|
75
|
+
when String, Integer
|
76
|
+
JSON.dump(key)
|
77
|
+
else
|
78
|
+
msg = "JSON hash parsing error (wrong key type: #{key.class})"
|
79
|
+
raise Sqreen::Exception, msg
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def normalize(hash_rule, signed_keys = nil, level = 20)
|
84
|
+
# Normalize the provided hash to a string:
|
85
|
+
# - sort keys lexicographically, recursively
|
86
|
+
# - convert each scalar to its JSON representation
|
87
|
+
# - convert hash to '{key:value}'
|
88
|
+
# - convert array [v1,v2] to '[v1,v2]' and [] to '[]'
|
89
|
+
# Two hash with different key ordering should have the same normalized
|
90
|
+
# value.
|
91
|
+
|
92
|
+
raise Sqreen::Exception, 'recursion level too deep' if level == 0
|
93
|
+
unless hash_rule.is_a?(Hash)
|
94
|
+
raise Sqreen::Exception, "wrong hash type #{hash_rule.class}"
|
95
|
+
end
|
96
|
+
|
97
|
+
res = []
|
98
|
+
hash_rule.sort.each do |k, v|
|
99
|
+
# Only keep signed keys
|
100
|
+
next if signed_keys && !signed_keys.include?(k)
|
101
|
+
|
102
|
+
k = normalize_key(k)
|
103
|
+
v = normalize_val(v, level - 1)
|
104
|
+
|
105
|
+
res << "#{k}:#{v}"
|
106
|
+
end
|
107
|
+
"{#{res.join(',')}}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_sig_infos_or_fail(hash_rule)
|
111
|
+
raise Sqreen::Exception, 'non hash argument' unless hash_rule.is_a?(Hash)
|
112
|
+
|
113
|
+
sigs = hash_rule[SIGNATURE_KEY]
|
114
|
+
raise Sqreen::Exception, 'no signature found' unless sigs
|
115
|
+
|
116
|
+
sig = sigs[SIGNATURE_VERSION]
|
117
|
+
msg = "signature #{SIGNATURE_VERSION} not found"
|
118
|
+
raise Sqreen::Exception, msg unless sig
|
119
|
+
|
120
|
+
sig_value = sig[SIGNATURE_VALUE_KEY]
|
121
|
+
raise Sqreen::Exception, 'no signature value found' unless sig_value
|
122
|
+
|
123
|
+
signed_keys = sig[SIGNED_KEYS_KEY]
|
124
|
+
raise Sqreen::Exception, 'no signed keys found' unless signed_keys
|
125
|
+
|
126
|
+
inc = Set.new(signed_keys).superset?(Set.new(@required_signed_keys))
|
127
|
+
raise Sqreen::Exception, 'signed keys miss equired keys' unless inc
|
128
|
+
|
129
|
+
[signed_keys, sig_value]
|
130
|
+
end
|
131
|
+
|
132
|
+
def verify(hash_rule)
|
133
|
+
signed_keys, sig_value = get_sig_infos_or_fail(hash_rule)
|
134
|
+
|
135
|
+
norm_str = normalize(hash_rule, signed_keys)
|
136
|
+
bin_sig = Base64.decode64(sig_value)
|
137
|
+
@signature_verifier.verify(bin_sig, norm_str)
|
138
|
+
rescue OpenSSL::PKey::ECError
|
139
|
+
false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|