Fixed all issues brought up in issue #305 by Chris Lenk

master
Zach Rush 2019-11-22 13:24:09 -05:00
parent 388d95d456
commit 46f1778d04
6 changed files with 59 additions and 1 deletions

View File

@ -363,6 +363,10 @@ class DictionaryProperty(Property):
"underscore (_)" "underscore (_)"
) )
raise DictionaryKeyError(k, msg) raise DictionaryKeyError(k, msg)
if len(dictified) < 1:
raise ValueError("must not be empty.")
return dictified return dictified
@ -381,6 +385,7 @@ HASHES_REGEX = {
"SHA3512": (r"^[a-fA-F0-9]{128}$", "SHA3-512"), "SHA3512": (r"^[a-fA-F0-9]{128}$", "SHA3-512"),
"SSDEEP": (r"^[a-zA-Z0-9/+:.]{1,128}$", "ssdeep"), "SSDEEP": (r"^[a-zA-Z0-9/+:.]{1,128}$", "ssdeep"),
"WHIRLPOOL": (r"^[a-fA-F0-9]{128}$", "WHIRLPOOL"), "WHIRLPOOL": (r"^[a-fA-F0-9]{128}$", "WHIRLPOOL"),
"TLSH": (r"^[a-fA-F0-9]{70}$", "TLSH"),
} }

View File

@ -22,6 +22,7 @@ EXPECTED_BUNDLE = """{
], ],
"pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", "pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
"pattern_type": "stix", "pattern_type": "stix",
"pattern_version": "2.1",
"valid_from": "2017-01-01T12:34:56Z" "valid_from": "2017-01-01T12:34:56Z"
}, },
{ {
@ -61,6 +62,7 @@ EXPECTED_BUNDLE_DICT = {
"modified": "2017-01-01T12:34:56.000Z", "modified": "2017-01-01T12:34:56.000Z",
"pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", "pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
"pattern_type": "stix", "pattern_type": "stix",
"pattern_version": "2.1",
"valid_from": "2017-01-01T12:34:56Z", "valid_from": "2017-01-01T12:34:56Z",
"indicator_types": [ "indicator_types": [
"malicious-activity", "malicious-activity",

View File

@ -19,6 +19,7 @@ EXPECTED_INDICATOR = """{
], ],
"pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", "pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
"pattern_type": "stix", "pattern_type": "stix",
"pattern_version": "2.1",
"valid_from": "1970-01-01T00:00:01Z" "valid_from": "1970-01-01T00:00:01Z"
}""" }"""
@ -31,6 +32,7 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join("""
indicator_types=['malicious-activity'], indicator_types=['malicious-activity'],
pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
pattern_type='stix', pattern_type='stix',
pattern_version='2.1',
valid_from='1970-01-01T00:00:01Z' valid_from='1970-01-01T00:00:01Z'
""".split()) + ")" """.split()) + ")"

View File

@ -1366,6 +1366,17 @@ def test_x509_certificate_example():
assert x509.subject == "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=baccala@freesoft.org" # noqa assert x509.subject == "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=baccala@freesoft.org" # noqa
def test_x509_certificate_error():
with pytest.raises(stix2.exceptions.PropertyPresenceError) as excinfo:
stix2.v21.X509Certificate(
defanged=True,
)
assert excinfo.value.cls == stix2.v21.X509Certificate
assert "X.509 Certificate objects must contain at least one object specific property" in str(excinfo.value)
def test_new_version_with_related_objects(): def test_new_version_with_related_objects():
data = stix2.v21.ObservedData( data = stix2.v21.ObservedData(
first_observed="2016-03-12T12:00:00Z", first_observed="2016-03-12T12:00:00Z",

View File

@ -12,7 +12,8 @@ import warnings
from ..base import _Extension, _Observable, _STIXBase from ..base import _Extension, _Observable, _STIXBase
from ..custom import _custom_extension_builder, _custom_observable_builder from ..custom import _custom_extension_builder, _custom_observable_builder
from ..exceptions import ( from ..exceptions import (
AtLeastOnePropertyError, DependentPropertiesError, STIXDeprecationWarning, AtLeastOnePropertyError, DependentPropertiesError, PropertyPresenceError,
STIXDeprecationWarning,
) )
from ..properties import ( from ..properties import (
BinaryProperty, BooleanProperty, CallableValues, DictionaryProperty, BinaryProperty, BooleanProperty, CallableValues, DictionaryProperty,
@ -592,6 +593,18 @@ class SocketExt(_Extension):
('socket_handle', IntegerProperty()), ('socket_handle', IntegerProperty()),
]) ])
def _check_object_constraints(self):
super(SocketExt, self)._check_object_constraints()
options = self.get('options')
if options is not None:
for key, val in options.items():
if key[:3] != "SO_":
raise ValueError("Incorrect options key")
if not isinstance(val, int):
raise ValueError("Options value must be an integer")
class TCPExt(_Extension): class TCPExt(_Extension):
# TODO: Add link # TODO: Add link
@ -986,6 +999,26 @@ class X509Certificate(_Observable):
]) ])
_id_contributing_properties = ["hashes", "serial_number"] _id_contributing_properties = ["hashes", "serial_number"]
def _check_object_constraints(self):
super(X509Certificate, self)._check_object_constraints()
if (
self.get('is_self_signed') is None and
self.get('hashes') is None and
self.get('version') is None and
self.get('serial_number') is None and
self.get('signature_algorithm') is None and
self.get('issuer') is None and
self.get('validity_not_before') is None and
self.get('validity_not_after') is None and
self.get('subject') is None and
self.get('subject_public_key_algorithm') is None and
self.get('subject_public_key_modulus') is None and
self.get('subject_public_key_exponent') is None and
self.get('x509_v3_extensions') is None
):
raise PropertyPresenceError("X.509 Certificate objects must contain at least one object specific property", X509Certificate)
def CustomObservable(type='x-custom-observable', properties=None): def CustomObservable(type='x-custom-observable', properties=None):
"""Custom STIX Cyber Observable Object type decorator. """Custom STIX Cyber Observable Object type decorator.

View File

@ -220,11 +220,16 @@ class Indicator(STIXDomainObject):
valid_from = self.get('valid_from') valid_from = self.get('valid_from')
valid_until = self.get('valid_until') valid_until = self.get('valid_until')
pattern_type = self.get('pattern_type')
pattern_version = self.get('pattern_version')
if valid_from and valid_until and valid_until <= valid_from: if valid_from and valid_until and valid_until <= valid_from:
msg = "{0.id} 'valid_until' must be greater than 'valid_from'" msg = "{0.id} 'valid_until' must be greater than 'valid_from'"
raise ValueError(msg.format(self)) raise ValueError(msg.format(self))
if not pattern_version and pattern_type == 'stix':
self._inner['pattern_version'] = self.get('spec_version')
class Infrastructure(STIXDomainObject): class Infrastructure(STIXDomainObject):
# TODO: Add link # TODO: Add link