diff --git a/stix2/__init__.py b/stix2/__init__.py index 55911a4..db14aa7 100644 --- a/stix2/__init__.py +++ b/stix2/__init__.py @@ -59,8 +59,9 @@ from .patterns import (AndBooleanExpression, AndObservationExpression, StartStopQualifier, StringConstant, TimestampConstant, WithinQualifier) from .sdo import (AttackPattern, Campaign, CourseOfAction, CustomObject, - Identity, Indicator, IntrusionSet, Malware, ObservedData, - Report, ThreatActor, Tool, Vulnerability) + Identity, Indicator, IntrusionSet, Location, Malware, Note, + ObservedData, Opinion, Report, ThreatActor, Tool, + Vulnerability) from .sources import CompositeDataSource from .sources.filesystem import (FileSystemSink, FileSystemSource, FileSystemStore) diff --git a/stix2/common.py b/stix2/common.py index 449cd54..0d624ff 100644 --- a/stix2/common.py +++ b/stix2/common.py @@ -4,13 +4,15 @@ from collections import OrderedDict from .base import _STIXBase from .markings import _MarkingsMixin -from .properties import (HashesProperty, IDProperty, ListProperty, Property, - ReferenceProperty, SelectorProperty, StringProperty, - TimestampProperty, TypeProperty) +from .properties import (BooleanProperty, DictionaryProperty, HashesProperty, + IDProperty, ListProperty, Property, ReferenceProperty, + SelectorProperty, StringProperty, TimestampProperty, + TypeProperty) from .utils import NOW, get_dict class ExternalReference(_STIXBase): + _properties = OrderedDict() _properties.update([ ('source_name', StringProperty(required=True)), @@ -26,6 +28,7 @@ class ExternalReference(_STIXBase): class KillChainPhase(_STIXBase): + _properties = OrderedDict() _properties.update([ ('kill_chain_name', StringProperty(required=True)), @@ -34,15 +37,43 @@ class KillChainPhase(_STIXBase): class GranularMarking(_STIXBase): + _properties = OrderedDict() _properties.update([ - ('marking_ref', ReferenceProperty(required=True, type="marking-definition")), + ('lang', StringProperty()), + ('marking_ref', ReferenceProperty(type="marking-definition")), # TODO: In 2.0 is required, not in 2.1 ('selectors', ListProperty(SelectorProperty, required=True)), ]) + def _check_object_constraints(self): + super(GranularMarking, self)._check_object_constraints() + self._check_at_least_one_property(["lang", "marking_ref"]) + + +class LanguageContent(_STIXBase): + _type = 'language-content' + _properties = OrderedDict() + _properties.update([ + ('type', TypeProperty(_type)), + ('id', IDProperty(_type)), + ('created_by_ref', ReferenceProperty(type="identity")), + ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('object_ref', ReferenceProperty(required=True)), + # TODO: 'object_modified' it MUST be an exact match for the modified time of the STIX Object (SRO or SDO) being referenced. + ('object_modified', TimestampProperty(required=True)), + # TODO: 'contents' https://docs.google.com/document/d/1ShNq4c3e1CkfANmD9O--mdZ5H0O_GLnjN28a_yrEaco/edit#heading=h.cfz5hcantmvx + ('contents', DictionaryProperty(required=True)), + ('revoked', BooleanProperty()), + ('labels', ListProperty(StringProperty)), + ('external_references', ListProperty(ExternalReference)), + ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), + ('granular_markings', ListProperty(GranularMarking)), + ]) + class TLPMarking(_STIXBase): - # TODO: don't allow the creation of any other TLPMarkings than the ones below + _type = 'tlp' _properties = OrderedDict() _properties.update([ @@ -51,6 +82,7 @@ class TLPMarking(_STIXBase): class StatementMarking(_STIXBase): + _type = 'statement' _properties = OrderedDict() _properties.update([ @@ -78,6 +110,7 @@ class MarkingProperty(Property): class MarkingDefinition(_STIXBase, _MarkingsMixin): + _type = 'marking-definition' _properties = OrderedDict() _properties.update([ @@ -135,6 +168,7 @@ def CustomMarking(type='x-custom-marking', properties=None): def custom_builder(cls): class _Custom(cls, _STIXBase): + _type = type _properties = OrderedDict() @@ -153,6 +187,8 @@ def CustomMarking(type='x-custom-marking', properties=None): return custom_builder +# TODO: don't allow the creation of any other TLPMarkings than the ones below + TLP_WHITE = MarkingDefinition( id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", created="2017-01-20T00:00:00.000Z", diff --git a/stix2/confidence/__init__.py b/stix2/confidence/__init__.py new file mode 100644 index 0000000..4bae011 --- /dev/null +++ b/stix2/confidence/__init__.py @@ -0,0 +1,3 @@ +""" +Functions to operate with STIX 2 Confidence scales. +""" diff --git a/stix2/confidence/scales.py b/stix2/confidence/scales.py new file mode 100644 index 0000000..6d8882d --- /dev/null +++ b/stix2/confidence/scales.py @@ -0,0 +1,479 @@ +"""Functions to perform conversions between the different Confidence scales. +As specified in STIX™ Version 2.1. Part 1: STIX Core Concepts - Appendix B""" + + +def none_low_med_high_to_value(scale_value): + """ + This method will transform a string value from the None / Low / Med / + High scale to its confidence integer representation. + + The scale for this confidence representation is the following: + ==================== ===================== + None/ Low/ Med/ High STIX Confidence Value + ==================== ===================== + Not Specified Not Specified + None 0 + Low 15 + Med 50 + High 85 + ==================== ===================== + + Args: + scale_value: A string value from the scale. Accepted strings are + "None", "Low", "Med" and "High". Argument is case sensitive. + + Returns: + int: The numerical representation corresponding to values in the None / + Low / Med / High scale. + + Raises: + ValueError: If `scale_value` is not within the accepted strings. + """ + if scale_value == "None": + return 0 + elif scale_value == "Low": + return 15 + elif scale_value == "Med": + return 50 + elif scale_value == "High": + return 85 + else: + raise ValueError("STIX Confidence value cannot be determined for %s" % scale_value) + + +def value_to_none_low_medium_high(confidence_value): + """ + This method will transform an integer value into the None / Low / Med / + High scale string representation. + + The scale for this confidence representation is the following: + =============== ==================== + Range of Values None/ Low/ Med/ High + =============== ==================== + 0 None + 1-29 Low + 30-69 Med + 70-100 High + =============== ==================== + + Args: + confidence_value: An integer value between 0 and 100. + + Returns: + str: A string corresponding to the None / Low / Med / High scale. + + Raises: + ValueError: If `confidence_value` is out of bounds. + + """ + if confidence_value == 0: + return "None" + elif 29 >= confidence_value >= 1: + return "Low" + elif 69 >= confidence_value >= 30: + return "Med" + elif 100 >= confidence_value >= 70: + return "High" + else: + raise ValueError("Range of values out of bounds: %s" % confidence_value) + + +def zero_ten_to_value(scale_value): + """ + This method will transform a string value from the 0-10 scale to its + confidence integer representation. + + The scale for this confidence representation is the following: + ==================== ===================== + 0-10 Scale STIX Confidence Value + ==================== ===================== + 0 0 + 1 10 + 2 20 + 3 30 + 4 40 + 5 50 + 6 60 + 7 70 + 8 80 + 9 90 + 10 100 + ==================== ===================== + + Args: + scale_value: A string value from the scale. Accepted strings are "0" + through "10" inclusive. + + Returns: + int: The numerical representation corresponding to values in the 0-10 + scale. + + Raises: + ValueError: If `scale_value` is not within the accepted strings. + + """ + if scale_value == "0": + return 0 + elif scale_value == "1": + return 10 + elif scale_value == "2": + return 20 + elif scale_value == "3": + return 30 + elif scale_value == "4": + return 40 + elif scale_value == "5": + return 50 + elif scale_value == "6": + return 60 + elif scale_value == "7": + return 70 + elif scale_value == "8": + return 80 + elif scale_value == "9": + return 90 + elif scale_value == "10": + return 100 + else: + raise ValueError("STIX Confidence value cannot be determined for %s" % scale_value) + + +def value_to_zero_ten(confidence_value): + """ + This method will transform an integer value into the 0-10 scale string + representation. + + The scale for this confidence representation is the following: + =============== ========== + Range of Values 0-10 Scale + =============== ========== + 0-4 0 + 5-14 1 + 15-24 2 + 25-34 3 + 35-44 4 + 45-54 5 + 55-64 6 + 65-74 7 + 75-84 8 + 85-94 9 + 95-100 10 + =============== ========== + + Args: + confidence_value: An integer value between 0 and 100. + + Returns: + str: A string corresponding to the 0-10 scale. + + Raises: + ValueError: If `confidence_value` is out of bounds. + + """ + if 4 >= confidence_value >= 0: + return "0" + elif 14 >= confidence_value >= 5: + return "1" + elif 24 >= confidence_value >= 15: + return "2" + elif 34 >= confidence_value >= 25: + return "3" + elif 44 >= confidence_value >= 35: + return "4" + elif 54 >= confidence_value >= 45: + return "5" + elif 64 >= confidence_value >= 55: + return "6" + elif 74 >= confidence_value >= 65: + return "7" + elif 84 >= confidence_value >= 75: + return "8" + elif 94 >= confidence_value >= 85: + return "9" + elif 100 >= confidence_value >= 95: + return "10" + else: + raise ValueError("Range of values out of bounds: %s" % confidence_value) + + +def admiralty_credibility_to_value(scale_value): + """ + This method will transform a string value from the Admiralty Credibility + scale to its confidence integer representation. + + The scale for this confidence representation is the following: + ============================== ===================== + Admiralty Credibility STIX Confidence Value + ============================== ===================== + 6 - Truth cannot be judged (Not present) + 5 - Improbable 10 + 4 - Doubtful 30 + 3 - Possibly True 50 + 2 - Probably True 70 + 1 - Confirmed by other sources 90 + ============================== ===================== + + Args: + scale_value: A string value from the scale. Accepted strings are + "6 - Truth cannot be judged", "5 - Improbable", "4 - Doubtful", + "3 - Possibly True", "2 - Probably True" and + "1 - Confirmed by other sources". Argument is case sensitive. + + Returns: + int: The numerical representation corresponding to values in the + Admiralty Credibility scale. + + Raises: + ValueError: If `scale_value` is not within the accepted strings. + + """ + if scale_value == "6 - Truth cannot be judged": + pass # TODO: Ask what happens here! + elif scale_value == "5 - Improbable": + return 10 + elif scale_value == "4 - Doubtful": + return 30 + elif scale_value == "3 - Possibly True": + return 50 + elif scale_value == "2 - Probably True": + return 70 + elif scale_value == "1 - Confirmed by other sources": + return 90 + else: + raise ValueError("STIX Confidence value cannot be determined for %s" % scale_value) + + +def value_to_admiralty_credibility(confidence_value): + """ + This method will transform an integer value into the Admiralty Credibility + scale string representation. + + The scale for this confidence representation is the following: + =============== ============================== + Range of Values Admiralty Credibility + =============== ============================== + N/A 6 - Truth cannot be judged + 0-19 5 - Improbable + 20-39 4 - Doubtful + 40-59 3 - Possibly True + 60-79 2 - Probably True + 80-100 1 - Confirmed by other sources + =============== ============================== + + Args: + confidence_value: An integer value between 0 and 100. + + Returns: + str: A string corresponding to the Admiralty Credibility scale. + + Raises: + ValueError: If `confidence_value` is out of bounds. + + """ + # TODO: Ask what happens with "6 - Truth cannot be judged" ! + if 19 >= confidence_value >= 0: + return "5 - Improbable" + elif 39 >= confidence_value >= 20: + return "4 - Doubtful" + elif 59 >= confidence_value >= 40: + return "3 - Possibly True" + elif 79 >= confidence_value >= 60: + return "2 - Probably True" + elif 100 >= confidence_value >= 80: + return "1 - Confirmed by other sources" + else: + raise ValueError("Range of values out of bounds: %s" % confidence_value) + + +def wep_to_value(scale_value): + """ + This method will transform a string value from the WEP scale to its + confidence integer representation. + + The scale for this confidence representation is the following: + ==================================== ===================== + WEP STIX Confidence Value + ==================================== ===================== + Impossible 0 + Highly Unlikely/Almost Certainly Not 10 + Unlikely/Probably Not 20 + Even Chance 50 + Likely/Probable 70 + Highly likely/Almost Certain 90 + Certain 100 + ==================================== ===================== + + Args: + scale_value: A string value from the scale. Accepted strings are + "Impossible", "Highly Unlikely/Almost Certainly Not", + "Unlikely/Probably Not", "Even Chance", "Likely/Probable", + "Highly likely/Almost Certain" and "Certain". Argument is case + sensitive. + + Returns: + int: The numerical representation corresponding to values in the WEP + scale. + + Raises: + ValueError: If `scale_value` is not within the accepted strings. + + """ + if scale_value == "Impossible": + return 0 + elif scale_value == "Highly Unlikely/Almost Certainly Not": + return 10 + elif scale_value == "Unlikely/Probably Not": + return 30 + elif scale_value == "Even Chance": + return 50 + elif scale_value == "Likely/Probable": + return 70 + elif scale_value == "Highly likely/Almost Certain": + return 90 + elif scale_value == "Certain": + return 100 + else: + raise ValueError("STIX Confidence value cannot be determined for %s" % scale_value) + + +def value_to_wep(confidence_value): + """ + This method will transform an integer value into the WEP scale string + representation. + + The scale for this confidence representation is the following: + =============== ==================================== + Range of Values WEP + =============== ==================================== + 0 Impossible + 1-19 Highly Unlikely/Almost Certainly Not + 20-39 Unlikely/Probably Not + 40-59 Even Chance + 60-79 Likely/Probable + 80-99 Highly likely/Almost Certain + 100 Certain + =============== ==================================== + + Args: + confidence_value: An integer value between 0 and 100. + + Returns: + str: A string corresponding to the WEP scale. + + Raises: + ValueError: If `confidence_value` is out of bounds. + + """ + if confidence_value == 0: + return "Impossible" + elif 19 >= confidence_value >= 1: + return "Highly Unlikely/Almost Certainly Not" + elif 39 >= confidence_value >= 20: + return "Unlikely/Probably Not" + elif 59 >= confidence_value >= 40: + return "Even Chance" + elif 79 >= confidence_value >= 60: + return "Likely/Probable" + elif 99 >= confidence_value >= 80: + return "Highly likely/Almost Certain" + elif confidence_value == 100: + return "Certain" + else: + raise ValueError("Range of values out of bounds: %s" % confidence_value) + + +def dni_to_value(scale_value): + """ + This method will transform a string value from the DNI scale to its + confidence integer representation. + + The scale for this confidence representation is the following: + ======================================= ===================== + DNI Scale STIX Confidence Value + ======================================= ===================== + Almost No Chance / Remote 5 + Very Unlikely / Highly Improbable 15 + Unlikely / Improbable 30 + Roughly Even Change / Roughly Even Odds 50 + Likely / Probable 70 + Very Likely / Highly Probable 85 + Almost Certain / Nearly Certain 95 + ======================================= ===================== + + Args: + scale_value: A string value from the scale. Accepted strings are + "Almost No Chance / Remote", "Very Unlikely / Highly Improbable", + "Unlikely / Improbable", "Roughly Even Change / Roughly Even Odds", + "Likely / Probable", "Very Likely / Highly Probable" and + "Almost Certain / Nearly Certain". Argument is case sensitive. + + Returns: + int: The numerical representation corresponding to values in the DNI + scale. + + Raises: + ValueError: If `scale_value` is not within the accepted strings. + + """ + if scale_value == "Almost No Chance / Remote": + return 5 + elif scale_value == "Very Unlikely / Highly Improbable": + return 15 + elif scale_value == "Unlikely / Improbable": + return 30 + elif scale_value == "Roughly Even Change / Roughly Even Odds": + return 50 + elif scale_value == "Likely / Probable": + return 70 + elif scale_value == "Very Likely / Highly Probable": + return 85 + elif scale_value == "Almost Certain / Nearly Certain": + return 95 + else: + raise ValueError("STIX Confidence value cannot be determined for %s" % scale_value) + + +def value_to_dni(confidence_value): + """ + This method will transform an integer value into the DNI scale string + representation. + + The scale for this confidence representation is the following: + =============== ======================================= + Range of Values DNI Scale + =============== ======================================= + 0-9 Almost No Chance / Remote + 10-19 Very Unlikely / Highly Improbable + 20-39 Unlikely / Improbable + 40-59 Roughly Even Change / Roughly Even Odds + 60-79 Likely / Probable + 80-89 Very Likely / Highly Probable + 90-100 Almost Certain / Nearly Certain + =============== ======================================= + + Args: + confidence_value: An integer value between 0 and 100. + + Returns: + str: A string corresponding to the DNI scale. + + Raises: + ValueError: If `confidence_value` is out of bounds. + + """ + if 9 >= confidence_value >= 0: + return "Almost No Chance / Remote" + elif 19 >= confidence_value >= 10: + return "Very Unlikely / Highly Improbable" + elif 39 >= confidence_value >= 20: + return "Unlikely / Improbable" + elif 59 >= confidence_value >= 40: + return "Roughly Even Change / Roughly Even Odds" + elif 79 >= confidence_value >= 60: + return "Likely / Probable" + elif 89 >= confidence_value >= 80: + return "Very Likely / Highly Probable" + elif 100 >= confidence_value >= 90: + return "Almost Certain / Nearly Certain" + else: + raise ValueError("Range of values out of bounds: %s" % confidence_value) diff --git a/stix2/core.py b/stix2/core.py index 8ee11f5..cd0523e 100644 --- a/stix2/core.py +++ b/stix2/core.py @@ -7,8 +7,8 @@ from .base import _STIXBase from .common import MarkingDefinition from .properties import IDProperty, ListProperty, Property, TypeProperty from .sdo import (AttackPattern, Campaign, CourseOfAction, Identity, Indicator, - IntrusionSet, Malware, ObservedData, Report, ThreatActor, - Tool, Vulnerability) + IntrusionSet, Location, Malware, Note, ObservedData, Opinion, + Report, ThreatActor, Tool, Vulnerability) from .sro import Relationship, Sighting from .utils import get_dict @@ -70,9 +70,12 @@ OBJ_MAP = { 'identity': Identity, 'indicator': Indicator, 'intrusion-set': IntrusionSet, + 'location': Location, 'malware': Malware, + 'note': Note, 'marking-definition': MarkingDefinition, 'observed-data': ObservedData, + 'opinion': Opinion, 'report': Report, 'relationship': Relationship, 'threat-actor': ThreatActor, diff --git a/stix2/observables.py b/stix2/observables.py index 57add29..45c3066 100644 --- a/stix2/observables.py +++ b/stix2/observables.py @@ -98,7 +98,7 @@ class AutonomousSystem(_Observable): _properties = OrderedDict() _properties.update([ ('type', TypeProperty(_type)), - ('number', IntegerProperty()), + ('number', IntegerProperty(required=True)), ('name', StringProperty()), ('rir', StringProperty()), ('extensions', ExtensionsProperty(enclosing_type=_type)), @@ -459,6 +459,8 @@ class SocketExt(_Extension): "SOCK_RDM", "SOCK_SEQPACKET", ])), + ('socket_descriptor', IntegerProperty()), + ('socket_handle', IntegerProperty()) ]) diff --git a/stix2/sdo.py b/stix2/sdo.py index 8dad686..d5d093e 100644 --- a/stix2/sdo.py +++ b/stix2/sdo.py @@ -8,9 +8,10 @@ from .base import _STIXBase from .common import ExternalReference, GranularMarking, KillChainPhase from .markings import _MarkingsMixin from .observables import ObservableProperty -from .properties import (BooleanProperty, IDProperty, IntegerProperty, - ListProperty, PatternProperty, ReferenceProperty, - StringProperty, TimestampProperty, TypeProperty) +from .properties import (BooleanProperty, EnumProperty, FloatProperty, + IDProperty, IntegerProperty, ListProperty, + PatternProperty, ReferenceProperty, StringProperty, + TimestampProperty, TypeProperty) from .utils import NOW @@ -33,6 +34,8 @@ class AttackPattern(STIXDomainObject): ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -57,6 +60,8 @@ class Campaign(STIXDomainObject): ('objective', StringProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -77,6 +82,8 @@ class CourseOfAction(STIXDomainObject): ('description', StringProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -100,6 +107,8 @@ class Identity(STIXDomainObject): ('contact_information', StringProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -124,6 +133,8 @@ class Indicator(STIXDomainObject): ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty, required=True)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -151,6 +162,38 @@ class IntrusionSet(STIXDomainObject): ('secondary_motivations', ListProperty(StringProperty)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), + ('external_references', ListProperty(ExternalReference)), + ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), + ('granular_markings', ListProperty(GranularMarking)), + ]) + + +class Location(STIXDomainObject): + + _type = 'location' + _properties = OrderedDict() + _properties.update([ + ('type', TypeProperty(_type)), + ('id', IDProperty(_type)), + ('created_by_ref', ReferenceProperty(type="identity")), + ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('description', StringProperty()), + ('latitude', FloatProperty()), + ('longitude', FloatProperty()), + ('precision', FloatProperty()), + ('region', StringProperty()), + ('country', StringProperty()), + ('administrative_area', StringProperty()), + ('city', StringProperty()), + ('street_address', StringProperty()), + ('postal_code', StringProperty()), + ('revoked', BooleanProperty()), + ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -172,6 +215,32 @@ class Malware(STIXDomainObject): ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty, required=True)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), + ('external_references', ListProperty(ExternalReference)), + ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), + ('granular_markings', ListProperty(GranularMarking)), + ]) + + +class Note(STIXDomainObject): + + _type = 'note' + _properties = OrderedDict() + _properties.update([ + ('type', TypeProperty(_type)), + ('id', IDProperty(_type)), + ('created_by_ref', ReferenceProperty(type="identity")), + ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('summary', StringProperty()), + ('description', StringProperty(required=True)), + ('authors', ListProperty(StringProperty)), + ('object_refs', ListProperty(ReferenceProperty, required=True)), + ('revoked', BooleanProperty()), + ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -194,6 +263,38 @@ class ObservedData(STIXDomainObject): ('objects', ObservableProperty(required=True)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), + ('external_references', ListProperty(ExternalReference)), + ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), + ('granular_markings', ListProperty(GranularMarking)), + ]) + + +class Opinion(STIXDomainObject): + + _type = 'opinion' + _properties = OrderedDict() + _properties.update([ + ('type', TypeProperty(_type)), + ('id', IDProperty(_type)), + ('created_by_ref', ReferenceProperty(type="identity")), + ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('description', StringProperty), + ('authors', ListProperty(StringProperty)), + ('object_refs', ListProperty(ReferenceProperty, required=True)), + ('opinion', EnumProperty(allowed=[ + 'strongly-disagree', + 'disagree', + 'neutral', + 'agree', + 'strongly-agree' + ], required=True)), + ('revoked', BooleanProperty()), + ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -216,6 +317,8 @@ class Report(STIXDomainObject): ('object_refs', ListProperty(ReferenceProperty, required=True)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty, required=True)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -244,6 +347,8 @@ class ThreatActor(STIXDomainObject): ('personal_motivations', ListProperty(StringProperty)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty, required=True)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -266,6 +371,8 @@ class Tool(STIXDomainObject): ('tool_version', StringProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty, required=True)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -286,6 +393,8 @@ class Vulnerability(STIXDomainObject): ('description', StringProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -320,6 +429,7 @@ def CustomObject(type='x-custom-type', properties=None): def custom_builder(cls): class _Custom(cls, STIXDomainObject): + _type = type _properties = OrderedDict() _properties.update([ @@ -339,6 +449,8 @@ def CustomObject(type='x-custom-type', properties=None): _properties.update([ ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), diff --git a/stix2/sro.py b/stix2/sro.py index 60f99f5..6e86d59 100644 --- a/stix2/sro.py +++ b/stix2/sro.py @@ -31,6 +31,8 @@ class Relationship(STIXRelationshipObject): ('target_ref', ReferenceProperty(required=True)), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)), @@ -51,6 +53,7 @@ class Relationship(STIXRelationshipObject): class Sighting(STIXRelationshipObject): + _type = 'sighting' _properties = OrderedDict() _properties.update([ @@ -68,6 +71,8 @@ class Sighting(STIXRelationshipObject): ('summary', BooleanProperty()), ('revoked', BooleanProperty()), ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))), ('granular_markings', ListProperty(GranularMarking)),