stidantic 0.1.3__py3-none-any.whl

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.

Potentially problematic release.


This version of stidantic might be problematic. Click here for more details.

stidantic/bundle.py ADDED
@@ -0,0 +1,29 @@
1
+ from typing import Annotated
2
+ from pydantic import Field
3
+ from stidantic.types import StixCore, Identifier, StixCommon
4
+ from stidantic.sdo import SDOs
5
+ from stidantic.sco import SCOs
6
+ from stidantic.sro import SROs
7
+ from stidantic.language import LanguageContent
8
+ from stidantic.marking import MarkingDefinition
9
+ from stidantic.extension import ExtensionDefinition
10
+
11
+
12
+ # 8. Stix Bundle
13
+ class StixBundle(StixCore):
14
+ id: Identifier
15
+ type: str = "bundle"
16
+ objects: list[
17
+ Annotated[
18
+ (
19
+ SROs
20
+ | SDOs
21
+ | SCOs
22
+ | MarkingDefinition
23
+ | LanguageContent
24
+ | ExtensionDefinition
25
+ ),
26
+ Field(discriminator="type"),
27
+ ]
28
+ | StixCommon
29
+ ]
stidantic/extension.py ADDED
@@ -0,0 +1,115 @@
1
+ from typing import Literal, Annotated, Self
2
+ from pydantic import Field
3
+ from pydantic.functional_validators import model_validator
4
+ from stidantic.types import StixExtension, ExtensionType, StixProp
5
+
6
+
7
+ # 7.3 Extension Definition
8
+ class ExtensionDefinition(StixExtension):
9
+ """
10
+ The STIX Extension Definition object allows producers of threat intelligence to extend existing STIX objects or
11
+ to create entirely new STIX objects in a standardized way. This object contains detailed information about the
12
+ extension and any additional properties and or objects that it defines. This extension mechanism MUST NOT be used
13
+ to redefine existing standardized objects or properties.
14
+
15
+ If a producer does not include the STIX Extension Definition object with the STIX objects that use it,
16
+ consumers should refer to section 3.3 for information in resolving references.
17
+
18
+ There are three ways to extend STIX using STIX Extensions.
19
+ - Define one or more new STIX Object types.
20
+ - Define additional properties for an existing STIX Object type as a nested property extension. This is
21
+ typically done to represent a sub-component or module of one or more STIX Object types.
22
+ - Define additional properties for an existing STIX Object type at the object's top-level. This can be done to
23
+ represent properties that form an inherent part of the definition of an object type.
24
+
25
+ When defining a new STIX Object (e.g., SDO, SCO, or SRO) all common properties associated with that type of
26
+ object (SDO, SCO, SRO) MUST be included in the schema or definition of that new STIX Object type.
27
+ Extensions that create new STIX objects MUST follow all conformance requirements for that object type
28
+ (SDO, SCO, SRO) including all of the requirements for the common properties associated with that object type.
29
+
30
+ When defining a STIX extension using the nested property extension mechanism the extensions property MUST include
31
+ the extension definition's UUID that defines the extension definition object and the extension_type property
32
+ as defined in section 3.2.
33
+
34
+ IMPORTANT NOTE: Producers using top-level property extensions should be mindful that another producer could also
35
+ define a top-level property extension using the same property names but for different purposes causing name
36
+ conflicts when both extensions are used in the same environment. This standard does not define any name conflict
37
+ resolution for new STIX Objects or for top-level properties created by this extension mechanism. However,
38
+ producers SHOULD follow industry best practices such as using unique property names that are guaranteed to avoid
39
+ duplicates across all organizations to avoid naming conflicts.
40
+ IMPORTANT NOTE: Producers using STIX extensions should be mindful that future versions of the STIX specification
41
+ MAY define objects and or properties that conflict with existing non-standardized extensions. In these cases the
42
+ meaning as defined in the STIX specification will override any and all conflicting extensions.
43
+
44
+ Specific extensions, as with specific Custom Properties, MAY NOT be supported across implementations.
45
+ A consumer that receives STIX content containing a STIX extension that it does not understand MAY refuse to
46
+ process the content or MAY ignore that extension and continue processing the content.
47
+
48
+ The 3 uses of this extension facility MAY be combined into a single Extension Definition object when appropriate.
49
+
50
+ The following example highlights where this may be useful.
51
+
52
+ Hybrid Extension Example
53
+ An intelligence producer has a monitoring network of sensors that collect a variety of cybersecurity telemetry
54
+ from each sensor where those sensors have unique data not currently defined in STIX 2.1.
55
+ The producer wishes to create an extension that other downstream consumers can receive both the high-level
56
+ summarization object but also the individual categorized telemetry from each sensor.
57
+ a) A new SDO representing the statistical summarization object.
58
+ b) A list of new properties to be added to the standard Observed Data object representing additional meta-data
59
+ information associated with the telemetry.
60
+ c) A new SCO representing a new cyber observable data type.
61
+
62
+ In this case, the producer creates a single extension that contains the following extension types:
63
+ "extension_types": [ "new-sdo", "new-sco", "property-extension" ]
64
+
65
+ Therefore, producers MAY use the hybrid extension mechanism when they wish to define a single extension that
66
+ encompasses new SDO and/or sub-component or top-level property extension properties in a related extension.
67
+
68
+ Producers SHOULD NOT use the hybrid extension mechanism if the extensions are not related to each other.
69
+ If the extensions are independent features then a producer SHOULD consider creating separate extension definitions.
70
+ """
71
+
72
+ type: Literal["extension-definition"] = "extension-definition" # pyright: ignore[reportIncompatibleVariableOverride]
73
+ # A name used for display purposes during execution, development, or debugging.
74
+ name: str
75
+ # A detailed explanation of what data the extension conveys and how it is intended to be used.
76
+ # While the description property is optional this property SHOULD be populated.
77
+ # Note that the schema property is the normative definition of the extension, and this property, if present,
78
+ # is for documentation purposes only.
79
+ description: str | None = None
80
+ # The normative definition of the extension, either as a URL or as plain text explaining the definition.
81
+ # A URL SHOULD point to a JSON schema or a location that contains information about the schema
82
+ json_schema: Annotated[str, Field(alias="schema")]
83
+ # The version of this extension. Producers of STIX extensions are encouraged to follow standard semantic
84
+ # versioning procedures where the version number follows the pattern, MAJOR.MINOR.PATCH. This will allow
85
+ # consumers to distinguish between the three different levels of compatibility typically identified by
86
+ # such versioning strings.
87
+ version: str
88
+ # This property specifies one or more extension types contained within this extension.
89
+ # When this property includes toplevel-property-extension then the extension_properties property
90
+ # SHOULD include one or more property names.
91
+ extension_types: list[ExtensionType]
92
+ # This property contains the list of new property names that are added to an object by an extension.
93
+ # This property MUST only be used when the extension_types property includes a value of toplevel-property-extension.
94
+ # In other words, when new properties are being added at the top-level of an existing object.
95
+ # The property names used in Extension STIX Object MUST be in ASCII and MUST only contain the characters a–z
96
+ # (lowercase ASCII), 0–9, and underscore (_).
97
+ # The name of a property of a Extension STIX Object MUST have a minimum length of 3 ASCII characters.
98
+ # The name of a property of a Extension STIX Object MUST be no longer than 250 ASCII characters in length.
99
+ extension_properties: list[StixProp] | None = None
100
+
101
+ @model_validator(mode="after")
102
+ def validate_extension_properties(self) -> Self:
103
+ """
104
+ extension_properties MUST only be used when the extension_types property includes a value of
105
+ toplevel-property-extension. In other words, when new properties are being added at the
106
+ top-level of an existing object.
107
+ """
108
+ if (
109
+ self.extension_properties
110
+ and ExtensionType.toplevel_property_extension not in self.extension_types
111
+ ):
112
+ raise ValueError(
113
+ "extension_types property can't be used without toplevel-property-extension in extension_types."
114
+ )
115
+ return self
@@ -0,0 +1,66 @@
1
+ from enum import Enum
2
+ from typing import Literal
3
+ from datetime import datetime, timezone
4
+
5
+ from stidantic.extension import ExtensionDefinition
6
+ from stidantic.types import (
7
+ Extension,
8
+ ExtensionType,
9
+ Identifier,
10
+ )
11
+ from stidantic.marking import MarkingDefinition
12
+
13
+
14
+ STIX_PAP_EXT_CREATION_DATE = datetime(2022, 11, 28, 00, 00, 00, 00, tzinfo=timezone.utc)
15
+ CISA = Identifier("identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01")
16
+
17
+ PAPExtensionDefinition = ExtensionDefinition(
18
+ id=Identifier(
19
+ "extension-definition--f8d78575-edfd-406e-8e84-6162a8450f5b",
20
+ ),
21
+ name="pap",
22
+ version="1.0.0",
23
+ created=STIX_PAP_EXT_CREATION_DATE,
24
+ modified=STIX_PAP_EXT_CREATION_DATE,
25
+ created_by_ref=CISA,
26
+ json_schema="https://github.com/oasis-open/cti-stix-common-objects/blob/main/extension-definition-specifications/pap-marking-definition-f8d/extension-definition--f8d78575-edfd-406e-8e84-6162a8450f5b.json",
27
+ extension_types=[ExtensionType.property_extension],
28
+ )
29
+
30
+
31
+ class PAPExtension(Extension):
32
+ extension_type: ExtensionType | None = ExtensionType.property_extension
33
+ pap: Literal["white", "clear", "green", "red", "amber"]
34
+
35
+
36
+ class PAP(Enum):
37
+ white = MarkingDefinition(
38
+ id=Identifier("marking-definition--a3bea94c-b469-41dc-9cfe-d6e7daba7730"),
39
+ name="PAP:WHITE",
40
+ created=datetime(2022, 10, 1, 00, 00, 00, 00, tzinfo=timezone.utc),
41
+ extensions={PAPExtensionDefinition.id: PAPExtension(pap="white")},
42
+ )
43
+ clear = MarkingDefinition(
44
+ id=Identifier("marking-definition--ad15a0cd-55b6-4588-a14c-a66105329b92"),
45
+ name="PAP:CLEAR",
46
+ created=datetime(2022, 10, 1, 00, 00, 00, 00, tzinfo=timezone.utc),
47
+ extensions={PAPExtensionDefinition.id: PAPExtension(pap="clear")},
48
+ )
49
+ green = MarkingDefinition(
50
+ id=Identifier("marking-definition--c43594d1-4b11-4c59-93ab-1c9b14d53ce9"),
51
+ name="PAP:GREEN",
52
+ created=datetime(2022, 10, 9, 00, 00, 00, 00, tzinfo=timezone.utc),
53
+ extensions={PAPExtensionDefinition.id: PAPExtension(pap="green")},
54
+ )
55
+ red = MarkingDefinition(
56
+ id=Identifier("marking-definition--740d36e5-7714-4c30-961a-3ae632ceee0e"),
57
+ name="PAP:RED",
58
+ created=datetime(2022, 10, 6, 00, 00, 00, 00, tzinfo=timezone.utc),
59
+ extensions={PAPExtensionDefinition.id: PAPExtension(pap="red")},
60
+ )
61
+ amber = MarkingDefinition(
62
+ id=Identifier("marking-definition--60f8932b-e51e-4458-b265-a2e8be9a80ab"),
63
+ name="PAP:AMBER",
64
+ created=datetime(2022, 10, 2, 00, 00, 00, 00, tzinfo=timezone.utc),
65
+ extensions={PAPExtensionDefinition.id: PAPExtension(pap="amber")},
66
+ )
stidantic/language.py ADDED
@@ -0,0 +1,35 @@
1
+ from datetime import datetime
2
+ from typing import Literal
3
+ from stidantic.types import Identifier, StixLanguage
4
+
5
+
6
+ # 7.1 Language Content
7
+ class LanguageContent(StixLanguage):
8
+ type: Literal["language-content"] = "language-content" # pyright: ignore[reportIncompatibleVariableOverride]
9
+ # The object_ref property identifies the id of the object that this Language Content applies to.
10
+ # It MUST be the identifier for a STIX Object.
11
+ object_ref: Identifier
12
+ # The object_modified property identifies the modified time of the object that this Language Content applies to.
13
+ # It MUST be an exact match for the modified time of the STIX Object being referenced.
14
+ object_modified: datetime | None = None
15
+ # The contents property contains the actual Language Content (translation).
16
+ # The keys in the dictionary MUST be RFC 5646 language codes for which language content is being provided [RFC5646].
17
+ # The values each consist of a dictionary that mirrors the properties in the target object
18
+ # (identified by object_ref and object_modified). For example, to provide a translation of the name property
19
+ # on the target object the key in the dictionary would be name.
20
+ # For each key in the nested dictionary:
21
+ # ● If the original property is a string, the corresponding property in the language content object
22
+ # MUST contain a string with the content for that property in the language of the top-level key.
23
+ # ● If the original property is a list, the corresponding property in the translation object must also be
24
+ # a list. Each item in this list recursively maps to the item at the same position in the list contained in the
25
+ # target object. The lists MUST have the same length.
26
+ # ● In the event that translations are only provided for some list items, the untranslated list items MUST
27
+ # be represented by an empty string (""). This indicates to a consumer of the Language Content object that they
28
+ # should interpolate the translated list items in the Language Content object with the corresponding (untranslated)
29
+ # list items from the original object as indicated by the object_ref property.
30
+ # ● If the original property is an object (including dictionaries), the corresponding location in the
31
+ # translation object must also be an object. Each key/value field in this object recursively maps to the object
32
+ # with the same key in the original.
33
+ # The translation object MAY contain only a subset of the translatable fields of the original. Keys that point to
34
+ # non-translatable properties in the target or to properties that do not exist in the target object MUST be ignored.
35
+ contents: dict[str, dict[str, str]]
stidantic/marking.py ADDED
@@ -0,0 +1,118 @@
1
+ from typing import Literal, Self
2
+ from enum import Enum
3
+ from datetime import datetime, timezone
4
+
5
+ from pydantic.functional_validators import model_validator
6
+ from stidantic.types import (
7
+ StixCore,
8
+ StixMarking,
9
+ Identifier,
10
+ )
11
+
12
+
13
+ # 7.2.1.3 Statement Marking
14
+ class StatementMarking(StixCore):
15
+ """
16
+ The Statement marking type defines the representation of a textual marking statement (e.g., copyright, terms of use,
17
+ etc.) in a definition. The value of the definition_type property MUST be statement when using this marking type.
18
+ Statement markings are generally not machine-readable, and this specification does not define any behavior or
19
+ actions based on their values.
20
+
21
+ Content may be marked with multiple statements of use. In other words, the same content can be marked both with a
22
+ statement saying "Copyright 2019" and a statement saying, "Terms of use are ..." and both statements apply.
23
+ """
24
+
25
+ # A Statement (e.g., copyright, terms of use) applied to the content marked by this marking definition.
26
+ statement: str
27
+
28
+
29
+ # 7.2.1.4 TLP Marking
30
+ class TLPMarking(StixCore):
31
+ """
32
+ The TLP marking type defines how you would represent a Traffic Light Protocol (TLP) marking in a definition
33
+ property. The value of the definition_type property MUST be tlp when using this marking type.
34
+ """
35
+
36
+ # The TLP level [TLP] of the content marked by this marking definition, as defined in this section.
37
+ tlp: str
38
+
39
+
40
+ # 7.2.1 Marking Definition
41
+ class MarkingDefinition(StixMarking):
42
+ """
43
+ The marking-definition object represents a specific marking. Data markings typically represent handling or
44
+ sharing requirements for data and are applied in the object_marking_refs and granular_markings properties on
45
+ STIX Objects, which reference a list of IDs for marking-definition objects.
46
+
47
+ Two marking definition types are defined in this specification: TLP, to capture TLP markings, and Statement,
48
+ to capture text marking statements. In addition, it is expected that the FIRST Information Exchange Policy (IEP)
49
+ will be included in a future version once a machine-usable specification for it has been defined.
50
+
51
+ Unlike other STIX Objects, Marking Definition objects cannot be versioned because it would allow for indirect
52
+ changes to the markings on a STIX Object. For example, if a Statement marking is changed from "Reuse Allowed" to
53
+ "Reuse Prohibited", all STIX Objects marked with that Statement marking would effectively have an updated marking
54
+ without being updated themselves. Instead, a new Statement marking with the new text should be created and the
55
+ marked objects updated to point to the new marking.
56
+ """
57
+
58
+ type: Literal["marking-definition"] = "marking-definition" # pyright: ignore[reportIncompatibleVariableOverride]
59
+ # A name used to identify the Marking Definition.
60
+ name: str | None = None
61
+ # The definition_type property identifies the type of Marking Definition. The value of the definition_type property
62
+ # SHOULD be one of the types defined in the subsections below: statement or tlp (see sections 7.2.1.3 and 7.2.1.4).
63
+ # Any new marking definitions SHOULD be specified using the extension facility described in section 7.3.
64
+ # If the extensions property is not present, this property MUST be present.
65
+ definition_type: str | None = None
66
+ # The definition property contains the marking object itself (e.g., the TLP marking as defined in section 7.2.1.4,
67
+ # the Statement marking as defined in section 7.2.1.3).
68
+ # Any new marking definitions SHOULD be specified using the extension facility described in section 7.3.
69
+ # If the extensions property is not present, this property MUST be present.
70
+ definition: TLPMarking | StatementMarking | None = None
71
+
72
+ @model_validator(mode="after")
73
+ def definition_if_no_extensions(self) -> Self:
74
+ if not self.extensions and (not self.definition and not self.definition_type):
75
+ raise ValueError(
76
+ "If the extensions property is not present, definition_type and definition properties MUST be present."
77
+ )
78
+ return self
79
+
80
+
81
+ STIX_ZERO_DATE = datetime(2017, 1, 20, 00, 00, 00, 00, tzinfo=timezone.utc)
82
+
83
+
84
+ class TLP(Enum):
85
+ """
86
+ The following standard marking definitions MUST be used to reference or represent TLP markings.
87
+ Other instances of tlp-marking MUST NOT be used or created (the only instances of TLP marking definitions
88
+ permitted are those defined here).
89
+ """
90
+
91
+ white = MarkingDefinition(
92
+ id=Identifier("marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"),
93
+ definition_type="tlp",
94
+ definition=TLPMarking(tlp="white"),
95
+ name="TLP:WHITE",
96
+ created=STIX_ZERO_DATE,
97
+ )
98
+ green = MarkingDefinition(
99
+ id=Identifier("marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da"),
100
+ definition_type="tlp",
101
+ definition=TLPMarking(tlp="green"),
102
+ name="TLP:GREEN",
103
+ created=STIX_ZERO_DATE,
104
+ )
105
+ amber = MarkingDefinition(
106
+ id=Identifier("marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"),
107
+ definition_type="tlp",
108
+ definition=TLPMarking(tlp="amber"),
109
+ name="TLP:AMBER",
110
+ created=STIX_ZERO_DATE,
111
+ )
112
+ red = MarkingDefinition(
113
+ id=Identifier("marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed"),
114
+ definition_type="tlp",
115
+ definition=TLPMarking(tlp="red"),
116
+ name="TLP:RED",
117
+ created=STIX_ZERO_DATE,
118
+ )