Skip to content

Commit

Permalink
added support for custom properties
Browse files Browse the repository at this point in the history
  • Loading branch information
jordan2175 committed Jan 15, 2020
1 parent 1fbd639 commit 7a92228
Show file tree
Hide file tree
Showing 52 changed files with 1,065 additions and 141 deletions.
3 changes: 2 additions & 1 deletion defs/defs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ const (
TIME_RFC_3339_MILLI = "2006-01-02T15:04:05.999Z07:00"
TIME_RFC_3339_MICRO = "2006-01-02T15:04:05.999999Z07:00"

STRICT_TYPES = true
STRICT_TYPES = true
KEEP_RAW_DATA = false
)
8 changes: 7 additions & 1 deletion examples/stix/06-decode-custom-properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ func main() {
if err != nil {
fmt.Println(err)
}
fmt.Println(o)

fmt.Println("Just the custom properties:")
fmt.Println(o.Custom)

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

data2, _ := o.EncodeToString()
fmt.Println(data2)

}

func getdata() string {
Expand All @@ -40,7 +45,8 @@ func getdata() string {
"modified": "2018-06-05T18:25:15.917Z",
"name": "Phishing",
"aliases": ["Banking1", "ATM2"],
"some_custom_property": "some_custom_value"
"some_custom_property": "some_custom_value",
"some_custom_property1": "some_custom_value1"
}
`
return s
Expand Down
1 change: 1 addition & 0 deletions examples/stix/07-use-custom-properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func main() {
// customAP.AttackPattern = o

customAP.SomeCustomProperty = "some custom string data"
customAP.SetName("Phishing 123")

data2, err1 := json.MarshalIndent(customAP, "", " ")
if err1 != nil {
Expand Down
60 changes: 19 additions & 41 deletions objects/attackpattern/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package attackpattern

import (
"encoding/json"

"github.com/freetaxii/libstix2/defs"
)

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

err := json.Unmarshal(data, &o)
if err != nil {
if err := json.Unmarshal(data, &o); err != nil {
return nil, err
}

o.SetRawData(data)

return &o, nil
}

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

// Now delete the properties we know about
delete(customProperties, "type")
delete(customProperties, "spec_version")
delete(customProperties, "id")
delete(customProperties, "created_by_ref")
delete(customProperties, "created")
delete(customProperties, "modified")
delete(customProperties, "revoked")
delete(customProperties, "labels")
delete(customProperties, "confidence")
delete(customProperties, "lang")
delete(customProperties, "external_references")
delete(customProperties, "object_marking_refs")
delete(customProperties, "granular_markings")

delete(customProperties, "name")
delete(customProperties, "description")
delete(customProperties, "aliases")
delete(customProperties, "kill_chain_phases")

// Unmarshal the properties that we understand. We need to alias the object
// so that we do not recursively call Unmarshal on this object.
type alias AttackPattern
temp := &struct {
*alias
Expand All @@ -73,13 +45,19 @@ func (o *AttackPattern) UnmarshalJSON(b []byte) error {
return err
}

// If there are any custom properties left store them in the custom property
if len(customProperties) > 0 {
o.Custom = make(map[string][]byte)
for k, v := range customProperties {
o.Custom[k] = *v
}
// This will create a map of all of the custom properties and store them in a
// property called o.Custom
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
return err
}

// This will store a complete copy of the original JSON in a byte array called
// o.Raw. This could be useful if you need to digitally sign the JSON or do
// verification on what was actually received.
if defs.KEEP_RAW_DATA == true {
o.SetRawData(b)
}

return nil
}

Expand Down
11 changes: 7 additions & 4 deletions objects/attackpattern/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ type AttackPattern struct {
properties.KillChainPhasesProperty
}

/* GetProperties - This method will return a list of all of the properties that
are unique to this object. This is used by the custom UnmarshalJSON for this
object. It is defined here in this file to make it easy to keep in sync. */
func (o *AttackPattern) GetPropertyList() []string {
return []string{"name", "description", "aliases", "kill_chain_phases"}
}

// ----------------------------------------------------------------------
// Initialization Functions
// ----------------------------------------------------------------------
Expand All @@ -38,7 +45,3 @@ func New() *AttackPattern {
obj.InitSDO("attack-pattern")
return &obj
}

func (o AttackPattern) New() {
o.InitSDO("attack-pattern")
}
44 changes: 39 additions & 5 deletions objects/campaign/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

package campaign

import "encoding/json"
import (
"encoding/json"

"github.com/freetaxii/libstix2/defs"
)

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

err := json.Unmarshal(data, &o)
if err != nil {
if err := json.Unmarshal(data, &o); err != nil {
return nil, err
}

o.SetRawData(data)

return &o, nil
}

/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
to enable custom properties that this library does not know about. It will store
them as map where the value of each key is a byte arrays. This way a tool that
does know how to deal with them can then further process them after this is
done. This will also allow the storage of the raw JSON data. */
func (o *Campaign) UnmarshalJSON(b []byte) error {

type alias Campaign
temp := &struct {
*alias
}{
alias: (*alias)(o),
}
if err := json.Unmarshal(b, &temp); err != nil {
return err
}

// This will create a map of all of the custom properties and store them in a
// property called o.Custom
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
return err
}

// This will store a complete copy of the original JSON in a byte array called
// o.Raw. This could be useful if you need to digitally sign the JSON or do
// verification on what was actually received.
if defs.KEEP_RAW_DATA == true {
o.SetRawData(b)
}

return nil
}

// ----------------------------------------------------------------------
// Public Methods JSON Encoders
// The encoding is done here at the individual object level instead of at
Expand Down
7 changes: 7 additions & 0 deletions objects/campaign/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ type Campaign struct {
Objective string `json:"objective,omitempty"`
}

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

// ----------------------------------------------------------------------
// Initialization Functions
// ----------------------------------------------------------------------
Expand Down
44 changes: 39 additions & 5 deletions objects/courseofaction/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

package courseofaction

import "encoding/json"
import (
"encoding/json"

"github.com/freetaxii/libstix2/defs"
)

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

err := json.Unmarshal(data, &o)
if err != nil {
if err := json.Unmarshal(data, &o); err != nil {
return nil, err
}

o.SetRawData(data)

return &o, nil
}

/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
to enable custom properties that this library does not know about. It will store
them as map where the value of each key is a byte arrays. This way a tool that
does know how to deal with them can then further process them after this is
done. This will also allow the storage of the raw JSON data. */
func (o *CourseOfAction) UnmarshalJSON(b []byte) error {

type alias CourseOfAction
temp := &struct {
*alias
}{
alias: (*alias)(o),
}
if err := json.Unmarshal(b, &temp); err != nil {
return err
}

// This will create a map of all of the custom properties and store them in a
// property called o.Custom
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
return err
}

// This will store a complete copy of the original JSON in a byte array called
// o.Raw. This could be useful if you need to digitally sign the JSON or do
// verification on what was actually received.
if defs.KEEP_RAW_DATA == true {
o.SetRawData(b)
}

return nil
}

// ----------------------------------------------------------------------
// Public Methods JSON Encoders
// The encoding is done here at the individual object level instead of at
Expand Down
7 changes: 7 additions & 0 deletions objects/courseofaction/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ type CourseOfAction struct {

// TODO Finish fleshing out this model to 2.1

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

// ----------------------------------------------------------------------
// Initialization Functions
// ----------------------------------------------------------------------
Expand Down
40 changes: 36 additions & 4 deletions objects/grouping/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package grouping

import (
"encoding/json"

"github.com/freetaxii/libstix2/defs"
)

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

err := json.Unmarshal(data, &o)
if err != nil {
if err := json.Unmarshal(data, &o); err != nil {
return nil, err
}

o.SetRawData(data)

return &o, nil
}

/* UnmarshalJSON - This method will over write the default UnmarshalJSON method
to enable custom properties that this library does not know about. It will store
them as map where the value of each key is a byte arrays. This way a tool that
does know how to deal with them can then further process them after this is
done. This will also allow the storage of the raw JSON data. */
func (o *Grouping) UnmarshalJSON(b []byte) error {

type alias Grouping
temp := &struct {
*alias
}{
alias: (*alias)(o),
}
if err := json.Unmarshal(b, &temp); err != nil {
return err
}

// This will create a map of all of the custom properties and store them in a
// property called o.Custom
if err := o.FindCustomProperties(b, o.GetPropertyList()); err != nil {
return err
}

// This will store a complete copy of the original JSON in a byte array called
// o.Raw. This could be useful if you need to digitally sign the JSON or do
// verification on what was actually received.
if defs.KEEP_RAW_DATA == true {
o.SetRawData(b)
}

return nil
}

// ----------------------------------------------------------------------
// Public Methods JSON Encoders
// The encoding is done here at the individual object level instead of at
Expand Down
7 changes: 7 additions & 0 deletions objects/grouping/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ type Grouping struct {
properties.ObjectRefsProperty
}

/* GetProperties - This method will return a list of all of the properties that
are unique to this object. This is used by the custom UnmarshalJSON for this
object. It is defined here in this file to make it easy to keep in sync. */
func (o *Grouping) GetPropertyList() []string {
return []string{"name", "description", "context", "object_refs"}
}

// ----------------------------------------------------------------------
// Initialization Functions
// ----------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 7a92228

Please sign in to comment.