Skip to content
This repository was archived by the owner on Dec 5, 2025. It is now read-only.

Commit a5ca143

Browse files
committed
[client] Introduce bundle sequence based on depth
1 parent 071381b commit a5ca143

File tree

5 files changed

+16
-149
lines changed

5 files changed

+16
-149
lines changed

pycti/connector/opencti_connector_helper.py

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -862,64 +862,6 @@ def _send_bundle(self, channel, bundle, **kwargs) -> None:
862862
logging.error("Unable to send bundle, retry...%s", e)
863863
self._send_bundle(channel, bundle, **kwargs)
864864

865-
def split_stix2_bundle(self, bundle) -> list:
866-
"""splits a valid stix2 bundle into a list of bundles
867-
868-
:param bundle: valid stix2 bundle
869-
:type bundle:
870-
:raises Exception: if data is not valid JSON
871-
:return: returns a list of bundles
872-
:rtype: list
873-
"""
874-
875-
self.cache_index = {}
876-
self.cache_added = []
877-
try:
878-
bundle_data = json.loads(bundle)
879-
except Exception as e:
880-
raise Exception("File data is not a valid JSON") from e
881-
882-
# validation = validate_parsed_json(bundle_data)
883-
# if not validation.is_valid:
884-
# raise ValueError('The bundle is not a valid STIX2 JSON:' + bundle)
885-
886-
# Index all objects by id
887-
for item in bundle_data["objects"]:
888-
self.cache_index[item["id"]] = item
889-
890-
bundles = []
891-
# Reports must be handled because of object_refs
892-
for item in bundle_data["objects"]:
893-
if item["type"] == "report":
894-
items_to_send = self.stix2_deduplicate_objects(
895-
self.stix2_get_report_objects(item)
896-
)
897-
for item_to_send in items_to_send:
898-
self.cache_added.append(item_to_send["id"])
899-
bundles.append(self.stix2_create_bundle(items_to_send))
900-
901-
# Relationships not added in previous reports
902-
for item in bundle_data["objects"]:
903-
if item["type"] == "relationship" and item["id"] not in self.cache_added:
904-
items_to_send = self.stix2_deduplicate_objects(
905-
self.stix2_get_relationship_objects(item)
906-
)
907-
for item_to_send in items_to_send:
908-
self.cache_added.append(item_to_send["id"])
909-
bundles.append(self.stix2_create_bundle(items_to_send))
910-
911-
# Entities not added in previous reports and relationships
912-
for item in bundle_data["objects"]:
913-
if item["type"] != "relationship" and item["id"] not in self.cache_added:
914-
items_to_send = self.stix2_deduplicate_objects(
915-
self.stix2_get_entity_objects(item)
916-
)
917-
for item_to_send in items_to_send:
918-
self.cache_added.append(item_to_send["id"])
919-
bundles.append(self.stix2_create_bundle(items_to_send))
920-
921-
return bundles
922-
923865
def stix2_get_embedded_objects(self, item) -> Dict:
924866
"""gets created and marking refs for a stix2 item
925867
@@ -1045,7 +987,7 @@ def stix2_create_bundle(items) -> Optional[str]:
1045987
bundle = {
1046988
"type": "bundle",
1047989
"id": f"bundle--{uuid.uuid4()}",
1048-
"spec_version": "2.0",
990+
"spec_version": "2.1",
1049991
"objects": items,
1050992
}
1051993
return json.dumps(bundle)

pycti/entities/opencti_stix_cyber_observable.py

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -270,24 +270,6 @@ def __init__(self, opencti, file):
270270
data
271271
data_type
272272
}
273-
... on X509V3ExtensionsType {
274-
basic_constraints
275-
name_constraints
276-
policy_constraints
277-
key_usage
278-
extended_key_usage
279-
subject_key_identifier
280-
authority_key_identifier
281-
subject_alternative_name
282-
issuer_alternative_name
283-
subject_directory_attributes
284-
crl_distribution_points
285-
inhibit_any_policy
286-
private_key_usage_period_not_before
287-
private_key_usage_period_not_after
288-
certificate_policies
289-
policy_mappings
290-
}
291273
... on CryptographicKey {
292274
value
293275
}
@@ -668,7 +650,6 @@ def create(self, **kwargs):
668650
$UserAccount: UserAccountAddInput,
669651
$WindowsRegistryKey: WindowsRegistryKeyAddInput,
670652
$WindowsRegistryValueType: WindowsRegistryValueTypeAddInput,
671-
$X509V3ExtensionsType: X509V3ExtensionsTypeAddInput,
672653
$CryptographicKey: CryptographicKeyAddInput,
673654
$CryptocurrencyWallet: CryptocurrencyWalletAddInput,
674655
$Hostname: HostnameAddInput
@@ -705,7 +686,6 @@ def create(self, **kwargs):
705686
UserAccount: $UserAccount,
706687
WindowsRegistryKey: $WindowsRegistryKey,
707688
WindowsRegistryValueType: $WindowsRegistryValueType,
708-
X509V3ExtensionsType: $X509V3ExtensionsType,
709689
CryptographicKey: $CryptographicKey,
710690
CryptocurrencyWallet: $CryptocurrencyWallet,
711691
Hostname: $Hostname,
@@ -1057,71 +1037,6 @@ def create(self, **kwargs):
10571037
if "data_type" in observable_data
10581038
else None,
10591039
}
1060-
elif type == "X509-V3-Extensions-Type":
1061-
input_variables["X509V3ExtensionsType"] = {
1062-
"basic_constraints": observable_data["basic_constraints"]
1063-
if "basic_constraints" in observable_data
1064-
else None,
1065-
"name_constraints": observable_data["name_constraints"]
1066-
if "name_constraints" in observable_data
1067-
else None,
1068-
"policy_constraints": observable_data["policy_constraints"]
1069-
if "policy_constraints" in observable_data
1070-
else None,
1071-
"key_usage": observable_data["key_usage"]
1072-
if "key_usage" in observable_data
1073-
else None,
1074-
"extended_key_usage": observable_data["extended_key_usage"]
1075-
if "extended_key_usage" in observable_data
1076-
else None,
1077-
"subject_key_identifier": observable_data["subject_key_identifier"]
1078-
if "subject_key_identifier" in observable_data
1079-
else None,
1080-
"authority_key_identifier": observable_data[
1081-
"authority_key_identifier"
1082-
]
1083-
if "authority_key_identifier" in observable_data
1084-
else None,
1085-
"subject_alternative_name": observable_data[
1086-
"subject_alternative_name"
1087-
]
1088-
if "subject_alternative_name" in observable_data
1089-
else None,
1090-
"issuer_alternative_name": observable_data[
1091-
"issuer_alternative_name"
1092-
]
1093-
if "issuer_alternative_name" in observable_data
1094-
else None,
1095-
"subject_directory_attributes": observable_data[
1096-
"subject_directory_attributes"
1097-
]
1098-
if "subject_directory_attributes" in observable_data
1099-
else None,
1100-
"crl_distribution_points": observable_data[
1101-
"crl_distribution_points"
1102-
]
1103-
if "crl_distribution_points" in observable_data
1104-
else None,
1105-
"inhibit_any_policy": observable_data["inhibit_any_policy"]
1106-
if "inhibit_any_policy" in observable_data
1107-
else None,
1108-
"private_key_usage_period_not_before": observable_data[
1109-
"private_key_usage_period_not_before"
1110-
]
1111-
if "private_key_usage_period_not_before" in observable_data
1112-
else None,
1113-
"private_key_usage_period_not_after": observable_data[
1114-
"private_key_usage_period_not_after"
1115-
]
1116-
if "private_key_usage_period_not_after" in observable_data
1117-
else None,
1118-
"certificate_policies": observable_data["certificate_policies"]
1119-
if "certificate_policies" in observable_data
1120-
else None,
1121-
"policy_mappings": observable_data["policy_mappings"]
1122-
if "policy_mappings" in observable_data
1123-
else None,
1124-
}
11251040
elif type == "Cryptographic-Key":
11261041
input_variables["CryptographicKey"] = {
11271042
"value": observable_data["value"]

pycti/utils/constants.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class StixCyberObservableTypes(Enum):
2525
USER_ACCOUNT = "User-Account"
2626
WINDOWS_REGISTRY_KEY = "Windows-Registry-Key"
2727
WINDOWS_REGISTRY_VALUE_TYPE = "Windows-Registry-Value-Type"
28-
X509_V3_EXTENSIONS_TYPE = "X509-V3-Extensions-Type"
2928
HOSTNAME = "Hostname"
3029
CRYPTOGRAPHIC_KEY = "Cryptographic-Key"
3130
CRYPTOCURRENCY_WALLET = "Cryptocurrency-Wallet"

pycti/utils/opencti_stix2_splitter.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ def split_bundle(self, bundle, use_json=True, event_version=None) -> list:
5555

5656
if "objects" not in bundle_data:
5757
raise Exception("File data is not a valid bundle")
58+
if "id" not in bundle_data:
59+
bundle_data["id"] = "bundle--" + str(uuid.uuid4())
5860

5961
raw_data = {}
6062
# Build flat list of elements
@@ -71,11 +73,19 @@ def by_dep_size(elem):
7173

7274
self.elements.sort(key=by_dep_size)
7375
for entity in self.elements:
74-
bundles.append(self.stix2_create_bundle([entity], use_json, event_version))
76+
bundles.append(
77+
self.stix2_create_bundle(
78+
bundle_data["id"],
79+
entity["nb_deps"],
80+
[entity],
81+
use_json,
82+
event_version,
83+
)
84+
)
7585
return bundles
7686

7787
@staticmethod
78-
def stix2_create_bundle(items, use_json, event_version=None):
88+
def stix2_create_bundle(bundle_id, bundle_seq, items, use_json, event_version=None):
7989
"""create a stix2 bundle with items
8090
8191
:param items: valid stix2 items
@@ -88,8 +98,9 @@ def stix2_create_bundle(items, use_json, event_version=None):
8898

8999
bundle = {
90100
"type": "bundle",
91-
"id": "bundle--" + str(uuid.uuid4()),
101+
"id": bundle_id,
92102
"spec_version": "2.1",
103+
"x_opencti_seq": bundle_seq,
93104
"objects": items,
94105
}
95106
if event_version is not None:

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
def api_client():
1515
return OpenCTIApiClient(
1616
"https://demo.opencti.io",
17-
"62c2bdf5-d3ae-4093-9d35-48e5b27a5b6f",
17+
"7e663f91-d048-4a8b-bdfa-cdb55597942b",
1818
ssl_verify=True,
1919
)
2020

0 commit comments

Comments
 (0)