Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to match new CCC structs #28

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 71 additions & 33 deletions cmd/generate-raid.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,44 @@ import (
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)

type ComponentDefinition struct {
type ControlCatalog struct {
CategoryIDFriendly string
ServiceName string
Metadata Metadata `yaml:"metadata"`
Controls []Control `yaml:"controls"`
Features []Feature `yaml:"features"`
Threats []Threat `yaml:"threats"`
}
Tactics map[string][]string

type Control struct {
IDFriendly string
ID string `yaml:"id"`
Title string `yaml:"title"`
Objective string `yaml:"objective"`
ControlFamily string `yaml:"control_family"`
Threats []string `yaml:"threats"`
NISTCSF string `yaml:"nist_csf"`
MITREATTACK string `yaml:"mitre_attack"`
ControlMappings map[string]interface{} `yaml:"control_mappings"`
TestRequirements map[string]string `yaml:"test_requirements"`
Metadata Metadata `yaml:"metadata"`

Controls []Control `yaml:"controls"`
Features []Feature `yaml:"features"`
Threats []Threat `yaml:"threats"`

LatestReleaseDetails ReleaseDetails `yaml:"latest_release_details"`
}

// Metadata is a struct that represents the metadata.yaml file
type Metadata struct {
Title string `yaml:"title"`
ID string `yaml:"id"`
Description string `yaml:"description"`
AssuranceLevel string `yaml:"assurance_level"`
ThreatModelAuthor string `yaml:"threat_model_author"`
ThreatModelURL string `yaml:"threat_model_url"`
RedTeam string `yaml:"red_team"`
RedTeamExercizeURL string `yaml:"red_team_exercise_url"`
Title string `yaml:"title"`
ID string `yaml:"id"`
Description string `yaml:"description"`
ReleaseDetails []ReleaseDetails `yaml:"release_details"`
}

type ReleaseDetails struct {
Version string `yaml:"version"`
AssuranceLevel string `yaml:"assurance_level"`
ThreatModelURL string `yaml:"threat_model_url"`
ThreatModelAuthor string `yaml:"threat_model_author"`
RedTeam string `yaml:"red_team"`
RedTeamExerciseURL string `yaml:"red_team_exercise_url"`
ReleaseManager ReleaseManager `yaml:"release_manager"`
ChangeLog []string `yaml:"change_log"`
}

type ReleaseManager struct {
Name string `yaml:"name"`
GithubId string `yaml:"github_id"`
Company string `yaml:"company"`
Summary string `yaml:"summary"`
}

type Feature struct {
Expand All @@ -63,6 +68,26 @@ type Threat struct {
MITRE []string `yaml:"mitre_attack"`
}

type Control struct {
IDFriendly string
ID string `yaml:"id"`
Title string `yaml:"title"`
Objective string `yaml:"objective"`
ControlFamily string `yaml:"control_family"`
Threats []string `yaml:"threats"`
NISTCSF string `yaml:"nist_csf"`
MITREATTACK string `yaml:"mitre_attack"`
ControlMappings map[string]interface{} `yaml:"control_mappings"`
TestRequirements []TestRequirement `yaml:"test_requirements"`
}

type TestRequirement struct {
IDFriendly string
ID string `yaml:"id"`
Text string `yaml:"text"`
TLPLevels []string `yaml:"tlp_levels"`
}

var TemplatesDir string
var SourcePath string
var OutputDir string
Expand Down Expand Up @@ -164,7 +189,7 @@ func setupTemplatesDir() error {
return err
}

func generateFileFromTemplate(data ComponentDefinition, templatePath, OutputDir string) error {
func generateFileFromTemplate(data ControlCatalog, templatePath, OutputDir string) error {
tmpl, err := template.ParseFiles(templatePath)
if err != nil {
return fmt.Errorf("error parsing template file %s: %w", templatePath, err)
Expand Down Expand Up @@ -194,7 +219,7 @@ func generateFileFromTemplate(data ComponentDefinition, templatePath, OutputDir
return nil
}

func readData() (data ComponentDefinition, err error) {
func readData() (data ControlCatalog, err error) {
if strings.HasPrefix(SourcePath, "http") {
data, err = readYAMLURL()
} else {
Expand All @@ -204,19 +229,32 @@ func readData() (data ComponentDefinition, err error) {
return
}

data.Tactics = make(map[string][]string)
data.CategoryIDFriendly = strings.ReplaceAll(data.Metadata.ID, ".", "_")

for i := range data.Controls {
fmt.Println(data.Controls[i].ID)
data.Controls[i].IDFriendly = strings.ReplaceAll(data.Controls[i].ID, ".", "_")
// loop over objectives in test_requirements and replace newlines with empty string
for k, v := range data.Controls[i].TestRequirements {
data.Controls[i].TestRequirements[k] = strings.TrimSpace(strings.ReplaceAll(v, "\n", " "))
for j, testReq := range data.Controls[i].TestRequirements {
// Some test requirements have newlines in them, which breaks the template
data.Controls[i].TestRequirements[j].Text = strings.TrimSpace(strings.ReplaceAll(testReq.Text, "\n", " "))
// Replace periods with underscores for the friendly ID
data.Controls[i].TestRequirements[j].IDFriendly = strings.ReplaceAll(testReq.ID, ".", "_")

// Add the test ID to the tactics map for each TLP level
for _, tlpLevel := range testReq.TLPLevels {
if data.Tactics[tlpLevel] == nil {
data.Tactics[tlpLevel] = []string{}
}
data.Tactics[tlpLevel] = append(data.Tactics[tlpLevel], strings.ReplaceAll(testReq.ID, ".", "_"))
}
}

}
return
}

func readYAMLURL() (data ComponentDefinition, err error) {
func readYAMLURL() (data ControlCatalog, err error) {
resp, err := http.Get(SourcePath)
if err != nil {
logger.Error("Failed to fetch URL: %v", err)
Expand All @@ -239,7 +277,7 @@ func readYAMLURL() (data ComponentDefinition, err error) {
return
}

func readYAMLFile() (data ComponentDefinition, err error) {
func readYAMLFile() (data ControlCatalog, err error) {
yamlFile, err := os.ReadFile(SourcePath)
if err != nil {
logger.Error(fmt.Sprintf("Error reading local source file: %s (%v)", SourcePath, err))
Expand Down
Loading