ruby-stix2 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +2 -1
- data/Gemfile.lock +5 -1
- data/README.md +1 -1
- data/lib/stix2/bool.rb +5 -0
- data/lib/stix2/bundle.rb +1 -1
- data/lib/stix2/common.rb +40 -38
- data/lib/stix2/custom_object.rb +16 -12
- data/lib/stix2/cyberobservable_objects/artifact.rb +12 -1
- data/lib/stix2/cyberobservable_objects/email_message.rb +1 -1
- data/lib/stix2/cyberobservable_objects/file.rb +12 -1
- data/lib/stix2/cyberobservable_objects/ipv4_addr.rb +12 -1
- data/lib/stix2/cyberobservable_objects/ipv6_addr.rb +12 -1
- data/lib/stix2/cyberobservable_objects/network_traffic.rb +1 -1
- data/lib/stix2/cyberobservable_objects/process.rb +1 -1
- data/lib/stix2/cyberobservable_objects/user_account.rb +4 -4
- data/lib/stix2/cyberobservable_objects/x509_certificate.rb +13 -2
- data/lib/stix2/domain_objects/indicator.rb +13 -1
- data/lib/stix2/domain_objects/infrastructure.rb +12 -1
- data/lib/stix2/domain_objects/intrusion-set.rb +12 -1
- data/lib/stix2/domain_objects/malware.rb +31 -5
- data/lib/stix2/domain_objects/report.rb +12 -1
- data/lib/stix2/domain_objects/threat_actor.rb +30 -4
- data/lib/stix2/domain_objects/tool.rb +12 -1
- data/lib/stix2/exception.rb +131 -0
- data/lib/stix2/extension_definition.rb +12 -1
- data/lib/stix2/extensions/alternate_data_stream_type.rb +12 -1
- data/lib/stix2/extensions/icmp.rb +18 -2
- data/lib/stix2/extensions/pdf.rb +1 -1
- data/lib/stix2/extensions/socket.rb +3 -3
- data/lib/stix2/extensions/tcp.rb +18 -2
- data/lib/stix2/extensions/windows_pe_optional_header_type.rb +48 -7
- data/lib/stix2/extensions/windows_pe_section_type.rb +12 -1
- data/lib/stix2/extensions/windows_pebinary.rb +30 -4
- data/lib/stix2/extensions/windows_process.rb +2 -2
- data/lib/stix2/external_reference.rb +12 -1
- data/lib/stix2/identifier.rb +2 -2
- data/lib/stix2/meta_objects/data_markings/marking_definition.rb +10 -4
- data/lib/stix2/meta_objects/data_markings/object_marking.rb +2 -2
- data/lib/stix2/meta_objects/language_content.rb +12 -1
- data/lib/stix2/relationship_objects/relationship.rb +7 -2
- data/lib/stix2/relationship_objects/sighting.rb +1 -1
- data/lib/stix2/validators/array.rb +11 -0
- data/lib/stix2/validators/hashes.rb +11 -0
- data/lib/stix2/validators/hex.rb +10 -0
- data/lib/stix2/version.rb +1 -1
- data/lib/stix2.rb +8 -10
- data/ruby-stix2.gemspec +2 -0
- metadata +35 -2
@@ -0,0 +1,131 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Exception
|
3
|
+
class Base < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class PropertyMissing < Base
|
7
|
+
def initialize(property_name)
|
8
|
+
@property_name = property_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def message
|
12
|
+
"Property '#{@property_name}' is missing"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class MessageUnsupported < Base
|
17
|
+
def initialize(type)
|
18
|
+
@type = type
|
19
|
+
end
|
20
|
+
|
21
|
+
def message
|
22
|
+
"Message unsupported: '#{@type}'"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class BadType < Base
|
27
|
+
def initialize(type)
|
28
|
+
@type = type
|
29
|
+
end
|
30
|
+
|
31
|
+
def message
|
32
|
+
"Property 'type' must be '#{@type}'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class InvalidValues < Base
|
37
|
+
def initialize(values)
|
38
|
+
@values = Array(values)
|
39
|
+
end
|
40
|
+
|
41
|
+
def message
|
42
|
+
pluralized_value = "value"
|
43
|
+
pluralized_value += "s" if @values.size > 1
|
44
|
+
"Invalid #{pluralized_value}: #{@values.join(", ")}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class StorageInactive < Base
|
49
|
+
def message
|
50
|
+
"Stix2::Storage must be active to use toplevel-property-extension"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class InvalidExtensionNameFormat < Base
|
55
|
+
def initialize(name)
|
56
|
+
@name = name
|
57
|
+
end
|
58
|
+
|
59
|
+
def message
|
60
|
+
"Invalid extension name format: #{@name}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class CustomExtensionFormat < Base
|
65
|
+
def initialize(value)
|
66
|
+
@value = value
|
67
|
+
end
|
68
|
+
|
69
|
+
def message
|
70
|
+
"Custom extension value must be Hash. Got: #{@value}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class PropertyInvalidName < Base
|
75
|
+
def initialize(property_name)
|
76
|
+
@property_name = property_name
|
77
|
+
end
|
78
|
+
|
79
|
+
def message
|
80
|
+
"Invalid property name: #{@property_name}. Valid chars: a-z, 0-9 and _"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class PropertyInvalidSize < Base
|
85
|
+
def initialize(property_name)
|
86
|
+
@property_name = property_name
|
87
|
+
end
|
88
|
+
|
89
|
+
def message
|
90
|
+
"Invalid property size for #{@property_name}. Size must be > 3 and < 250"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class InvalidIdentifier < Base
|
95
|
+
def initialize(value)
|
96
|
+
@value = value
|
97
|
+
end
|
98
|
+
|
99
|
+
def message
|
100
|
+
"Invalid identifier: #{@value}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class PropertyDefinitionSize < Base
|
105
|
+
def initialize(size)
|
106
|
+
@size = size
|
107
|
+
end
|
108
|
+
|
109
|
+
def message
|
110
|
+
"Property 'definition' must contain a single key. Got #{size} instead"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class PropertyDefinitionMatching < Base
|
115
|
+
def message
|
116
|
+
"Property 'definition_type' and 'definition' must have a matching key"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class InvalidRange < Base
|
121
|
+
def initialize(valid_range, value)
|
122
|
+
@valid_range = valid_range
|
123
|
+
@value = value
|
124
|
+
end
|
125
|
+
|
126
|
+
def message
|
127
|
+
"Invalid value #{@value} for range #{@valid_range}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -4,7 +4,18 @@ module Stix2
|
|
4
4
|
property :description, coerce: String
|
5
5
|
property :schema, required: true, coerce: String
|
6
6
|
property :version, required: true, coerce: String
|
7
|
-
property :extension_types, required: true, coerce:
|
7
|
+
property :extension_types, required: true, coerce: [String]
|
8
8
|
property :extension_properties, coerce: [String]
|
9
|
+
|
10
|
+
def initialize(args = {})
|
11
|
+
super
|
12
|
+
validate_extension_types!
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def validate_extension_types!
|
18
|
+
Stix2::Validators::Array.new(extension_types, Stix2::EXTENSION_TYPE_ENUM)
|
19
|
+
end
|
9
20
|
end
|
10
21
|
end
|
@@ -2,8 +2,19 @@ module Stix2
|
|
2
2
|
module Extensions
|
3
3
|
class AlternateDataStreamType < Stix2::Base
|
4
4
|
property :name, required: true, coerce: String
|
5
|
-
property :hashes, coerce:
|
5
|
+
property :hashes, coerce: Hash
|
6
6
|
property :size, coerce: Integer
|
7
|
+
|
8
|
+
def initialize(args = {})
|
9
|
+
super
|
10
|
+
validate_hashes! if @strict
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def validate_hashes!
|
16
|
+
Stix2::Validators::Hashes.new(hashes)
|
17
|
+
end
|
7
18
|
end
|
8
19
|
end
|
9
20
|
end
|
@@ -1,8 +1,24 @@
|
|
1
1
|
module Stix2
|
2
2
|
module Extensions
|
3
3
|
class Icmp < Stix2::Base
|
4
|
-
property :icmp_type_hex, required: true, coerce:
|
5
|
-
property :icmp_code_hex, required: true, coerce:
|
4
|
+
property :icmp_type_hex, required: true, coerce: String
|
5
|
+
property :icmp_code_hex, required: true, coerce: String
|
6
|
+
|
7
|
+
def initialize(args = {})
|
8
|
+
super
|
9
|
+
validate_icmp_type_hex! if @strict
|
10
|
+
validate_icmp_code_hex! if @strict
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def validate_icmp_type_hex!
|
16
|
+
Stix2::Validators::Hex.new(icmp_type_hex)
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate_icmp_code_hex!
|
20
|
+
Stix2::Validators::Hex.new(icmp_code_hex)
|
21
|
+
end
|
6
22
|
end
|
7
23
|
end
|
8
24
|
end
|
data/lib/stix2/extensions/pdf.rb
CHANGED
@@ -2,7 +2,7 @@ module Stix2
|
|
2
2
|
module Extensions
|
3
3
|
class Pdf < Stix2::Base
|
4
4
|
property :version, coerce: String
|
5
|
-
property :is_optimized, coerce:
|
5
|
+
property :is_optimized, coerce: Stix2.bool
|
6
6
|
property :document_info_dict, {String => String}
|
7
7
|
property :pdfid0, coerce: String
|
8
8
|
property :pdfid1, coerce: String
|
@@ -2,9 +2,9 @@ module Stix2
|
|
2
2
|
module Extensions
|
3
3
|
class Socket < Stix2::Base
|
4
4
|
property :address_family, required: true, values: NETWORK_SOCKET_ADDRESS_FAMILY_ENUM
|
5
|
-
property :is_blocking, coerce:
|
6
|
-
property :is_listening, coerce:
|
7
|
-
property :options, coerce:
|
5
|
+
property :is_blocking, coerce: Stix2.bool
|
6
|
+
property :is_listening, coerce: Stix2.bool
|
7
|
+
property :options, coerce: {String => Integer}
|
8
8
|
property :socket_type, values: NETWORK_SOCKET_TYPE_ENUM
|
9
9
|
property :socket_descriptor, coerce: Integer
|
10
10
|
property :socket_handle, coerce: Integer
|
data/lib/stix2/extensions/tcp.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
module Stix2
|
2
2
|
module Extensions
|
3
3
|
class Tcp < Stix2::Base
|
4
|
-
property :src_flags_hex, coerce:
|
5
|
-
property :dst_flags_hex, coerce:
|
4
|
+
property :src_flags_hex, coerce: String
|
5
|
+
property :dst_flags_hex, coerce: String
|
6
|
+
|
7
|
+
def initialize(args = {})
|
8
|
+
super
|
9
|
+
validate_src_flags_hex! if @strict
|
10
|
+
validate_dst_flags_hex! if @strict
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def validate_src_flags_hex!
|
16
|
+
Stix2::Validators::Hex.new(src_flags_hex)
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate_dst_flags_hex!
|
20
|
+
Stix2::Validators::Hex.new(dst_flags_hex)
|
21
|
+
end
|
6
22
|
end
|
7
23
|
end
|
8
24
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Stix2
|
2
2
|
module Extensions
|
3
3
|
class WindowsPeOptionalHeaderType < Stix2::Base
|
4
|
-
property :magic_hex, coerce:
|
4
|
+
property :magic_hex, coerce: String
|
5
5
|
property :major_linker_version, coerce: Integer
|
6
6
|
property :minor_linker_version, coerce: Integer
|
7
7
|
property :size_of_code, coerce: Integer
|
@@ -19,19 +19,60 @@ module Stix2
|
|
19
19
|
property :minor_image_version, coerce: Integer
|
20
20
|
property :major_subsystem_version, coerce: Integer
|
21
21
|
property :minor_subsystem_version, coerce: Integer
|
22
|
-
property :win32_version_value_hex, coerce:
|
22
|
+
property :win32_version_value_hex, coerce: String
|
23
23
|
property :size_of_image, coerce: Integer
|
24
24
|
property :size_of_headers, coerce: Integer
|
25
|
-
property :checksum_hex, coerce:
|
26
|
-
property :subsystem_hex, coerce:
|
27
|
-
property :dll_characteristics_hex, coerce:
|
25
|
+
property :checksum_hex, coerce: String
|
26
|
+
property :subsystem_hex, coerce: String
|
27
|
+
property :dll_characteristics_hex, coerce: String
|
28
28
|
property :size_of_stack_reserve, coerce: Integer
|
29
29
|
property :size_of_stack_commit, coerce: Integer
|
30
30
|
property :size_of_heap_reserve, coerce: Integer
|
31
31
|
property :size_of_heap_commit, coerce: Integer
|
32
|
-
property :loader_flags_hex, coerce:
|
32
|
+
property :loader_flags_hex, coerce: String
|
33
33
|
property :number_of_rva_and_sizes, coerce: Integer
|
34
|
-
property :hashes, coerce:
|
34
|
+
property :hashes, coerce: Hash
|
35
|
+
|
36
|
+
def initialize(args = {})
|
37
|
+
super
|
38
|
+
validate_hashes! if @strict
|
39
|
+
validate_magic_hex! if @strict
|
40
|
+
validate_win32_version_value_hex! if @strict
|
41
|
+
validate_checksum_hex! if @strict
|
42
|
+
validate_subsystem_hex! if @strict
|
43
|
+
validate_dll_characteristics_hex! if @strict
|
44
|
+
validate_loader_flags_hex! if @strict
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def validate_hashes!
|
50
|
+
Stix2::Validators::Hashes.new(hashes)
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_magic_hex!
|
54
|
+
Stix2::Validators::Hex.new(magic_hex)
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate_win32_version_value_hex!
|
58
|
+
Stix2::Validators::Hex.new(win32_version_value_hex)
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_checksum_hex!
|
62
|
+
Stix2::Validators::Hex.new(checksum_hex)
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_subsystem_hex!
|
66
|
+
Stix2::Validators::Hex.new(subsystem_hex)
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_dll_characteristics_hex!
|
70
|
+
Stix2::Validators::Hex.new(dll_characteristics_hex)
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate_loader_flags_hex!
|
74
|
+
Stix2::Validators::Hex.new(loader_flags_hex)
|
75
|
+
end
|
35
76
|
end
|
36
77
|
end
|
37
78
|
end
|
@@ -4,7 +4,18 @@ module Stix2
|
|
4
4
|
property :name, required: true, coerce: String
|
5
5
|
property :size, coerce: Integer
|
6
6
|
property :entropy, coerce: Float
|
7
|
-
property :hashes, coerce:
|
7
|
+
property :hashes, coerce: Hash
|
8
|
+
|
9
|
+
def initialize(args = {})
|
10
|
+
super
|
11
|
+
validate_hashes! if @strict
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_hashes!
|
17
|
+
Stix2::Validators::Hashes.new(hashes)
|
18
|
+
end
|
8
19
|
end
|
9
20
|
end
|
10
21
|
end
|
@@ -6,16 +6,42 @@ module Stix2
|
|
6
6
|
class WindowsPebinary < Stix2::Base
|
7
7
|
property :pe_type, required: true, values: WINDOWS_PEBINARY_TYPE_OV
|
8
8
|
property :imphash, coerce: String
|
9
|
-
property :machine_hex, coerce:
|
9
|
+
property :machine_hex, coerce: String
|
10
10
|
property :number_of_sections, coerce: Integer
|
11
11
|
property :time_date_stamp, coerce: Time
|
12
|
-
property :pointer_to_symbol_table_hex, coerce:
|
12
|
+
property :pointer_to_symbol_table_hex, coerce: String
|
13
13
|
property :number_of_symbols, coerce: Integer
|
14
14
|
property :size_of_optional_header, coerce: Integer
|
15
|
-
property :characteristics_hex, coerce:
|
16
|
-
property :file_header_hashes, coerce:
|
15
|
+
property :characteristics_hex, coerce: String
|
16
|
+
property :file_header_hashes, coerce: Hash
|
17
17
|
property :optional_header, coerce: WindowsPeOptionalHeaderType
|
18
18
|
property :sections, coerce: [WindowsPeSectionType]
|
19
|
+
|
20
|
+
def initialize(args = {})
|
21
|
+
super
|
22
|
+
validate_file_header_hashes! if @strict
|
23
|
+
validate_machine_hex! if @strict
|
24
|
+
validate_pointer_to_symbol_table_hex! if @strict
|
25
|
+
validate_characteristics_hex! if @strict
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def validate_file_header_hashes!
|
31
|
+
Stix2::Validators::Hashes.new(file_header_hashes)
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_machine_hex!
|
35
|
+
Stix2::Validators::Hex.new(machine_hex)
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_pointer_to_symbol_table_hex!
|
39
|
+
Stix2::Validators::Hex.new(pointer_to_symbol_table_hex)
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate_characteristics_hex!
|
43
|
+
Stix2::Validators::Hex.new(characteristics_hex)
|
44
|
+
end
|
19
45
|
end
|
20
46
|
end
|
21
47
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Stix2
|
2
2
|
module Extensions
|
3
3
|
class WindowsProcess < Stix2::Base
|
4
|
-
property :aslr_enabled, coerce:
|
5
|
-
property :dep_enabled, coerce:
|
4
|
+
property :aslr_enabled, coerce: Stix2.bool
|
5
|
+
property :dep_enabled, coerce: Stix2.bool
|
6
6
|
property :priority, coerce: String
|
7
7
|
property :owner_sid, coerce: String
|
8
8
|
property :window_title, coerce: String
|
@@ -3,7 +3,18 @@ module Stix2
|
|
3
3
|
property :source_name, coerce: String, required: true
|
4
4
|
property :description, coerce: String
|
5
5
|
property :url, coerce: String
|
6
|
-
property :hashes, coerce:
|
6
|
+
property :hashes, coerce: Hash
|
7
7
|
property :external_id, coerce: String
|
8
|
+
|
9
|
+
def initialize(args = {})
|
10
|
+
super
|
11
|
+
validate_hashes! if @strict
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_hashes!
|
17
|
+
Stix2::Validators::Hashes.new(hashes)
|
18
|
+
end
|
8
19
|
end
|
9
20
|
end
|
data/lib/stix2/identifier.rb
CHANGED
@@ -6,11 +6,17 @@ module Stix2
|
|
6
6
|
property :definition_type, required: true, coerce: String
|
7
7
|
property :definition, required: true, coerce: {String => String}
|
8
8
|
|
9
|
-
def initialize(args)
|
10
|
-
super
|
11
|
-
|
9
|
+
def initialize(args = {})
|
10
|
+
super
|
11
|
+
validate_definitions!
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_definitions!
|
17
|
+
raise(Exception::PropertyDefinitionSize.new(definition.size)) if definition.size > 1
|
12
18
|
if definition_type != definition.keys.first
|
13
|
-
raise(
|
19
|
+
raise(Exception::PropertyDefinitionMatching.new)
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -3,8 +3,8 @@ module Stix2
|
|
3
3
|
module DataMarking
|
4
4
|
class ObjectMarking < String
|
5
5
|
def initialize(value)
|
6
|
-
value.match(/marking-definition--.*/) || raise(
|
7
|
-
super
|
6
|
+
value.match(/marking-definition--.*/) || raise(Exception::InvalidValues.new(value))
|
7
|
+
super
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -3,7 +3,18 @@ module Stix2
|
|
3
3
|
class LanguageContent < Base
|
4
4
|
property :object_ref, coerce: Identifier
|
5
5
|
property :object_modified, coerce: Time
|
6
|
-
property :contents, coerce:
|
6
|
+
property :contents, coerce: Hash
|
7
|
+
|
8
|
+
def initialize(args = {})
|
9
|
+
super
|
10
|
+
validate_content! if @strict
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def validate_content!
|
16
|
+
Stix2::Validators::Array.new(contents.keys, Stix2::RFC5646_LANGUAGE_TAGS.keys) if contents
|
17
|
+
end
|
7
18
|
end
|
8
19
|
end
|
9
20
|
end
|
@@ -8,7 +8,7 @@ module Stix2
|
|
8
8
|
property :start_time, coerce: Time
|
9
9
|
property :stop_time, coerce: Time
|
10
10
|
|
11
|
-
def initialize(args)
|
11
|
+
def initialize(args = {})
|
12
12
|
if !args[:relationship_type] && args[:source_ref] && args[:target_ref]
|
13
13
|
objects = DOMAIN_OBJECTS + CYBEROBSERVABLE_OBJECTS
|
14
14
|
source_type = type_by_id(args[:source_ref])
|
@@ -18,7 +18,8 @@ module Stix2
|
|
18
18
|
args[:relationship_type] = relationships.first unless relationships.empty?
|
19
19
|
end
|
20
20
|
|
21
|
-
super
|
21
|
+
super
|
22
|
+
validate_relationship_type! if @strict
|
22
23
|
end
|
23
24
|
|
24
25
|
COMMON_RELATIONSHIPS = ["related-to", "derived-from", "duplicate-of"].freeze
|
@@ -160,6 +161,10 @@ module Stix2
|
|
160
161
|
def type_by_id(id)
|
161
162
|
id.split("--").first
|
162
163
|
end
|
164
|
+
|
165
|
+
def validate_relationship_type!
|
166
|
+
relationship_type.match?(/[a-z0-9-]/) || raise(Exception::InvalidValues.new(relationship_type))
|
167
|
+
end
|
163
168
|
end
|
164
169
|
end
|
165
170
|
end
|
@@ -8,7 +8,7 @@ module Stix2
|
|
8
8
|
property :sighting_of_ref, required: true, coerce: String
|
9
9
|
property :observed_data_refs, coerce: [String]
|
10
10
|
property :where_sighted_refs, coerce: [String]
|
11
|
-
property :summary, coerce:
|
11
|
+
property :summary, coerce: Stix2.bool
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Validators
|
3
|
+
class Array
|
4
|
+
def initialize(values, array)
|
5
|
+
raise(ArgumentError.new("array argument must be an actual array. Got: #{array.class}")) if !array.is_a?(::Array)
|
6
|
+
excess = Array(values).map(&:to_s) - array.map(&:to_s)
|
7
|
+
raise(Exception::InvalidValues.new(excess)) if !excess.empty?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Validators
|
3
|
+
class Hashes
|
4
|
+
def initialize(hsh)
|
5
|
+
return if !hsh
|
6
|
+
raise(ArgumentError.new("hash argument must be an actual hash. Got: #{hsh.class}")) if !hsh.is_a?(::Hash)
|
7
|
+
Stix2::Validators::Array.new(hsh.keys, Stix2::HASH_ALGORITHM_OV)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/stix2/version.rb
CHANGED
data/lib/stix2.rb
CHANGED
@@ -3,6 +3,7 @@ require "json"
|
|
3
3
|
require "time"
|
4
4
|
|
5
5
|
require "stix2/version"
|
6
|
+
require "stix2/bool"
|
6
7
|
require "stix2/ov"
|
7
8
|
require "stix2/enum"
|
8
9
|
require "stix2/base"
|
@@ -11,10 +12,15 @@ require "stix2/external_reference"
|
|
11
12
|
require "stix2/identifier"
|
12
13
|
require "stix2/kill_chain_phase"
|
13
14
|
|
15
|
+
require "stix2/validators/array"
|
16
|
+
require "stix2/validators/hashes"
|
17
|
+
require "stix2/validators/hex"
|
18
|
+
|
14
19
|
require "stix2/meta_objects/data_markings/granular_marking"
|
15
20
|
require "stix2/meta_objects/data_markings/object_marking"
|
16
21
|
|
17
22
|
require "stix2/common"
|
23
|
+
require "stix2/exception"
|
18
24
|
require "stix2/domain_objects/base"
|
19
25
|
require "stix2/domain_objects/attack_pattern"
|
20
26
|
require "stix2/domain_objects/campaign"
|
@@ -105,7 +111,7 @@ module Stix2
|
|
105
111
|
end
|
106
112
|
Hashie.symbolize_keys!(options_)
|
107
113
|
type = options_[:type]
|
108
|
-
raise("
|
114
|
+
raise Exception::PropertyMissing.new("type") if !type
|
109
115
|
# Let's try to guess the domain of the object, among the known ones
|
110
116
|
[nil, "DomainObject", "RelationshipObject", "CyberobservableObject", "MetaObject",
|
111
117
|
"MetaObject::DataMarking"].each do |family|
|
@@ -116,14 +122,6 @@ module Stix2
|
|
116
122
|
end
|
117
123
|
return Module.const_get(class_name).new(options_) if Module.const_defined?(class_name)
|
118
124
|
end
|
119
|
-
raise(
|
120
|
-
end
|
121
|
-
|
122
|
-
def self.to_bool(value)
|
123
|
-
(value == true) || (value == "true")
|
124
|
-
end
|
125
|
-
|
126
|
-
def self.is_hex?(value)
|
127
|
-
value.match?(/^\h*$/)
|
125
|
+
raise Exception::MessageUnsupported.new(type)
|
128
126
|
end
|
129
127
|
end
|
data/ruby-stix2.gemspec
CHANGED
@@ -28,4 +28,6 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "irb", "~> 1.7.0"
|
29
29
|
spec.add_development_dependency "mutex_m", "~> 0.2.0"
|
30
30
|
spec.add_development_dependency "standardrb", "~> 1.0.1"
|
31
|
+
spec.add_development_dependency "ostruct", "~> 0.6.1"
|
32
|
+
spec.add_development_dependency "logger", "~> 1.6.5"
|
31
33
|
end
|