Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/cmd/tools/signer/main.go
2073 views
1
package main
2
3
import (
4
"crypto/sha256"
5
"encoding/hex"
6
"flag"
7
"os"
8
"path/filepath"
9
10
"github.com/projectdiscovery/gologger"
11
"github.com/projectdiscovery/gologger/levels"
12
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
13
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/disk"
14
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
15
"github.com/projectdiscovery/nuclei/v3/pkg/templates"
16
"github.com/projectdiscovery/nuclei/v3/pkg/templates/signer"
17
"github.com/projectdiscovery/nuclei/v3/pkg/types"
18
fileutil "github.com/projectdiscovery/utils/file"
19
folderutil "github.com/projectdiscovery/utils/folder"
20
)
21
22
var (
23
appConfigDir = folderutil.AppConfigDirOrDefault(".config", "nuclei")
24
defaultCertFile = filepath.Join(appConfigDir, "keys", "nuclei-user.crt")
25
defaultPrivKey = filepath.Join(appConfigDir, "keys", "nuclei-user-private-key.pem")
26
)
27
28
var (
29
template string
30
cert string
31
privKey string
32
)
33
34
func main() {
35
flag.StringVar(&template, "template", "", "template to sign (file only)")
36
flag.StringVar(&cert, "cert", defaultCertFile, "certificate file")
37
flag.StringVar(&privKey, "priv-key", defaultPrivKey, "private key file")
38
flag.Parse()
39
40
config.DefaultConfig.LogAllEvents = true
41
gologger.DefaultLogger.SetMaxLevel(levels.LevelVerbose)
42
43
if template == "" {
44
gologger.Fatal().Msg("template is required")
45
}
46
if !fileutil.FileExists(template) {
47
gologger.Fatal().Msgf("template file %s does not exist or not a file", template)
48
}
49
50
// get signer
51
tmplSigner, err := signer.NewTemplateSignerFromFiles(cert, privKey)
52
if err != nil {
53
gologger.Fatal().Msgf("failed to create signer: %s", err)
54
}
55
gologger.Info().Msgf("Template Signer: %v\n", tmplSigner.Identifier())
56
57
// read file
58
bin, err := os.ReadFile(template)
59
if err != nil {
60
gologger.Fatal().Msgf("failed to read template file %s: %s", template, err)
61
}
62
63
// extract signature and content
64
sig, content := signer.ExtractSignatureAndContent(bin)
65
hash := sha256.Sum256(content)
66
67
gologger.Info().Msgf("Signature Details:")
68
gologger.Info().Msgf("----------------")
69
gologger.Info().Msgf("Signature: %s", sig)
70
gologger.Info().Msgf("Content Hash (SHA256): %s\n", hex.EncodeToString(hash[:]))
71
72
execOpts := defaultExecutorOpts(template)
73
74
tmpl, err := templates.Parse(template, nil, execOpts)
75
if err != nil {
76
gologger.Fatal().Msgf("failed to parse template: %s", err)
77
}
78
gologger.Info().Msgf("Template Verified: %v\n", tmpl.Verified)
79
80
if !tmpl.Verified {
81
gologger.Info().Msgf("------------------------")
82
gologger.Info().Msg("Template is not verified, signing template")
83
if err := templates.SignTemplate(tmplSigner, template); err != nil {
84
gologger.Fatal().Msgf("Failed to sign template: %s", err)
85
}
86
// verify again by reading file what the new signature and hash is
87
bin2, err := os.ReadFile(template)
88
if err != nil {
89
gologger.Fatal().Msgf("failed to read signed template file %s: %s", template, err)
90
}
91
sig2, content2 := signer.ExtractSignatureAndContent(bin2)
92
hash2 := sha256.Sum256(content2)
93
94
gologger.Info().Msgf("Updated Signature Details:")
95
gologger.Info().Msgf("------------------------")
96
gologger.Info().Msgf("Signature: %s", sig2)
97
gologger.Info().Msgf("Content Hash (SHA256): %s\n", hex.EncodeToString(hash2[:]))
98
}
99
gologger.Info().Msgf("✓ Template signed & verified successfully")
100
}
101
102
func defaultExecutorOpts(templatePath string) *protocols.ExecutorOptions {
103
// use parsed options when initializing signer instead of default options
104
options := types.DefaultOptions()
105
templates.UseOptionsForSigner(options)
106
catalog := disk.NewCatalog(filepath.Dir(templatePath))
107
executerOpts := &protocols.ExecutorOptions{
108
Catalog: catalog,
109
Options: options,
110
TemplatePath: templatePath,
111
Parser: templates.NewParser(),
112
}
113
return executerOpts
114
}
115
116