Skip to content

Commit 7a92228

Browse files
committed
added support for custom properties
1 parent 1fbd639 commit 7a92228

File tree

52 files changed

+1065
-141
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1065
-141
lines changed

defs/defs.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ const (
2828
TIME_RFC_3339_MILLI = "2006-01-02T15:04:05.999Z07:00"
2929
TIME_RFC_3339_MICRO = "2006-01-02T15:04:05.999999Z07:00"
3030

31-
STRICT_TYPES = true
31+
STRICT_TYPES = true
32+
KEEP_RAW_DATA = false
3233
)

examples/stix/06-decode-custom-properties.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ func main() {
2020
if err != nil {
2121
fmt.Println(err)
2222
}
23+
fmt.Println(o)
2324

25+
fmt.Println("Just the custom properties:")
2426
fmt.Println(o.Custom)
2527

2628
// Since we know the data is a string, lets create a variable to unmarshal the data to
2729
var foo string
2830
json.Unmarshal(o.Custom["some_custom_property"], &foo)
2931
fmt.Println(foo)
3032

33+
data2, _ := o.EncodeToString()
34+
fmt.Println(data2)
35+
3136
}
3237

3338
func getdata() string {
@@ -40,7 +45,8 @@ func getdata() string {
4045
"modified": "2018-06-05T18:25:15.917Z",
4146
"name": "Phishing",
4247
"aliases": ["Banking1", "ATM2"],
43-
"some_custom_property": "some_custom_value"
48+
"some_custom_property": "some_custom_value",
49+
"some_custom_property1": "some_custom_value1"
4450
}
4551
`
4652
return s

examples/stix/07-use-custom-properties.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func main() {
2424
// customAP.AttackPattern = o
2525

2626
customAP.SomeCustomProperty = "some custom string data"
27+
customAP.SetName("Phishing 123")
2728

2829
data2, err1 := json.MarshalIndent(customAP, "", " ")
2930
if err1 != nil {

objects/attackpattern/json.go

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package attackpattern
77

88
import (
99
"encoding/json"
10+
11+
"github.com/freetaxii/libstix2/defs"
1012
)
1113

1214
// ----------------------------------------------------------------------
@@ -19,50 +21,20 @@ object along with any errors. */
1921
func Decode(data []byte) (*AttackPattern, error) {
2022
var o AttackPattern
2123

22-
err := json.Unmarshal(data, &o)
23-
if err != nil {
24+
if err := json.Unmarshal(data, &o); err != nil {
2425
return nil, err
2526
}
2627

27-
o.SetRawData(data)
28-
2928
return &o, nil
3029
}
3130

32-
/* UnmarshalJSON - This method will over right the default UnmarshalJSON method
31+
/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
3332
to enable custom properties that this library does not know about. It will store
34-
them as map of byte arrays. This way a tool that does know how to deal with them
35-
can then further process them after this is done. */
33+
them as map where the value of each key is a byte arrays. This way a tool that
34+
does know how to deal with them can then further process them after this is
35+
done. This will also allow the storage of the raw JSON data. */
3636
func (o *AttackPattern) UnmarshalJSON(b []byte) error {
37-
// First thing is to capture all of the properties in a map so we can remove
38-
// what we know about. This will leave us with just the custom properties.
39-
var customProperties map[string]*json.RawMessage
40-
if err := json.Unmarshal(b, &customProperties); err != nil {
41-
return err
42-
}
4337

44-
// Now delete the properties we know about
45-
delete(customProperties, "type")
46-
delete(customProperties, "spec_version")
47-
delete(customProperties, "id")
48-
delete(customProperties, "created_by_ref")
49-
delete(customProperties, "created")
50-
delete(customProperties, "modified")
51-
delete(customProperties, "revoked")
52-
delete(customProperties, "labels")
53-
delete(customProperties, "confidence")
54-
delete(customProperties, "lang")
55-
delete(customProperties, "external_references")
56-
delete(customProperties, "object_marking_refs")
57-
delete(customProperties, "granular_markings")
58-
59-
delete(customProperties, "name")
60-
delete(customProperties, "description")
61-
delete(customProperties, "aliases")
62-
delete(customProperties, "kill_chain_phases")
63-
64-
// Unmarshal the properties that we understand. We need to alias the object
65-
// so that we do not recursively call Unmarshal on this object.
6638
type alias AttackPattern
6739
temp := &struct {
6840
*alias
@@ -73,13 +45,19 @@ func (o *AttackPattern) UnmarshalJSON(b []byte) error {
7345
return err
7446
}
7547

76-
// If there are any custom properties left store them in the custom property
77-
if len(customProperties) > 0 {
78-
o.Custom = make(map[string][]byte)
79-
for k, v := range customProperties {
80-
o.Custom[k] = *v
81-
}
48+
// This will create a map of all of the custom properties and store them in a
49+
// property called o.Custom
50+
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
51+
return err
52+
}
53+
54+
// This will store a complete copy of the original JSON in a byte array called
55+
// o.Raw. This could be useful if you need to digitally sign the JSON or do
56+
// verification on what was actually received.
57+
if defs.KEEP_RAW_DATA == true {
58+
o.SetRawData(b)
8259
}
60+
8361
return nil
8462
}
8563

objects/attackpattern/model.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ type AttackPattern struct {
2626
properties.KillChainPhasesProperty
2727
}
2828

29+
/* GetProperties - This method will return a list of all of the properties that
30+
are unique to this object. This is used by the custom UnmarshalJSON for this
31+
object. It is defined here in this file to make it easy to keep in sync. */
32+
func (o *AttackPattern) GetPropertyList() []string {
33+
return []string{"name", "description", "aliases", "kill_chain_phases"}
34+
}
35+
2936
// ----------------------------------------------------------------------
3037
// Initialization Functions
3138
// ----------------------------------------------------------------------
@@ -38,7 +45,3 @@ func New() *AttackPattern {
3845
obj.InitSDO("attack-pattern")
3946
return &obj
4047
}
41-
42-
func (o AttackPattern) New() {
43-
o.InitSDO("attack-pattern")
44-
}

objects/campaign/json.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55

66
package campaign
77

8-
import "encoding/json"
8+
import (
9+
"encoding/json"
10+
11+
"github.com/freetaxii/libstix2/defs"
12+
)
913

1014
// ----------------------------------------------------------------------
1115
// Public Functions - JSON Decoder
@@ -17,16 +21,46 @@ object along with any errors. */
1721
func Decode(data []byte) (*Campaign, error) {
1822
var o Campaign
1923

20-
err := json.Unmarshal(data, &o)
21-
if err != nil {
24+
if err := json.Unmarshal(data, &o); err != nil {
2225
return nil, err
2326
}
2427

25-
o.SetRawData(data)
26-
2728
return &o, nil
2829
}
2930

31+
/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
32+
to enable custom properties that this library does not know about. It will store
33+
them as map where the value of each key is a byte arrays. This way a tool that
34+
does know how to deal with them can then further process them after this is
35+
done. This will also allow the storage of the raw JSON data. */
36+
func (o *Campaign) UnmarshalJSON(b []byte) error {
37+
38+
type alias Campaign
39+
temp := &struct {
40+
*alias
41+
}{
42+
alias: (*alias)(o),
43+
}
44+
if err := json.Unmarshal(b, &temp); err != nil {
45+
return err
46+
}
47+
48+
// This will create a map of all of the custom properties and store them in a
49+
// property called o.Custom
50+
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
51+
return err
52+
}
53+
54+
// This will store a complete copy of the original JSON in a byte array called
55+
// o.Raw. This could be useful if you need to digitally sign the JSON or do
56+
// verification on what was actually received.
57+
if defs.KEEP_RAW_DATA == true {
58+
o.SetRawData(b)
59+
}
60+
61+
return nil
62+
}
63+
3064
// ----------------------------------------------------------------------
3165
// Public Methods JSON Encoders
3266
// The encoding is done here at the individual object level instead of at

objects/campaign/model.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ type Campaign struct {
2727
Objective string `json:"objective,omitempty"`
2828
}
2929

30+
/* GetProperties - This method will return a list of all of the properties that
31+
are unique to this object. This is used by the custom UnmarshalJSON for this
32+
object. It is defined here in this file to make it easy to keep in sync. */
33+
func (o *Campaign) GetPropertyList() []string {
34+
return []string{"name", "description", "aliases", "first_seen", "last_seen", "objective"}
35+
}
36+
3037
// ----------------------------------------------------------------------
3138
// Initialization Functions
3239
// ----------------------------------------------------------------------

objects/courseofaction/json.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55

66
package courseofaction
77

8-
import "encoding/json"
8+
import (
9+
"encoding/json"
10+
11+
"github.com/freetaxii/libstix2/defs"
12+
)
913

1014
// ----------------------------------------------------------------------
1115
// Public Functions - JSON Decoder
@@ -17,16 +21,46 @@ object along with any errors. */
1721
func Decode(data []byte) (*CourseOfAction, error) {
1822
var o CourseOfAction
1923

20-
err := json.Unmarshal(data, &o)
21-
if err != nil {
24+
if err := json.Unmarshal(data, &o); err != nil {
2225
return nil, err
2326
}
2427

25-
o.SetRawData(data)
26-
2728
return &o, nil
2829
}
2930

31+
/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
32+
to enable custom properties that this library does not know about. It will store
33+
them as map where the value of each key is a byte arrays. This way a tool that
34+
does know how to deal with them can then further process them after this is
35+
done. This will also allow the storage of the raw JSON data. */
36+
func (o *CourseOfAction) UnmarshalJSON(b []byte) error {
37+
38+
type alias CourseOfAction
39+
temp := &struct {
40+
*alias
41+
}{
42+
alias: (*alias)(o),
43+
}
44+
if err := json.Unmarshal(b, &temp); err != nil {
45+
return err
46+
}
47+
48+
// This will create a map of all of the custom properties and store them in a
49+
// property called o.Custom
50+
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
51+
return err
52+
}
53+
54+
// This will store a complete copy of the original JSON in a byte array called
55+
// o.Raw. This could be useful if you need to digitally sign the JSON or do
56+
// verification on what was actually received.
57+
if defs.KEEP_RAW_DATA == true {
58+
o.SetRawData(b)
59+
}
60+
61+
return nil
62+
}
63+
3064
// ----------------------------------------------------------------------
3165
// Public Methods JSON Encoders
3266
// The encoding is done here at the individual object level instead of at

objects/courseofaction/model.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ type CourseOfAction struct {
2626

2727
// TODO Finish fleshing out this model to 2.1
2828

29+
/* GetProperties - This method will return a list of all of the properties that
30+
are unique to this object. This is used by the custom UnmarshalJSON for this
31+
object. It is defined here in this file to make it easy to keep in sync. */
32+
func (o *CourseOfAction) GetPropertyList() []string {
33+
return []string{"name", "description"}
34+
}
35+
2936
// ----------------------------------------------------------------------
3037
// Initialization Functions
3138
// ----------------------------------------------------------------------

objects/grouping/json.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package grouping
77

88
import (
99
"encoding/json"
10+
11+
"github.com/freetaxii/libstix2/defs"
1012
)
1113

1214
// ----------------------------------------------------------------------
@@ -19,16 +21,46 @@ object along with any errors. */
1921
func Decode(data []byte) (*Grouping, error) {
2022
var o Grouping
2123

22-
err := json.Unmarshal(data, &o)
23-
if err != nil {
24+
if err := json.Unmarshal(data, &o); err != nil {
2425
return nil, err
2526
}
2627

27-
o.SetRawData(data)
28-
2928
return &o, nil
3029
}
3130

31+
/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
32+
to enable custom properties that this library does not know about. It will store
33+
them as map where the value of each key is a byte arrays. This way a tool that
34+
does know how to deal with them can then further process them after this is
35+
done. This will also allow the storage of the raw JSON data. */
36+
func (o *Grouping) UnmarshalJSON(b []byte) error {
37+
38+
type alias Grouping
39+
temp := &struct {
40+
*alias
41+
}{
42+
alias: (*alias)(o),
43+
}
44+
if err := json.Unmarshal(b, &temp); err != nil {
45+
return err
46+
}
47+
48+
// This will create a map of all of the custom properties and store them in a
49+
// property called o.Custom
50+
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
51+
return err
52+
}
53+
54+
// This will store a complete copy of the original JSON in a byte array called
55+
// o.Raw. This could be useful if you need to digitally sign the JSON or do
56+
// verification on what was actually received.
57+
if defs.KEEP_RAW_DATA == true {
58+
o.SetRawData(b)
59+
}
60+
61+
return nil
62+
}
63+
3264
// ----------------------------------------------------------------------
3365
// Public Methods JSON Encoders
3466
// The encoding is done here at the individual object level instead of at

0 commit comments

Comments
 (0)