ruby-stix2 0.1.3 → 0.1.4
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/.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
|