Skip to content

Commit d345787

Browse files
Add CI workflow, LICENSE, and fix code formatting
- Add GitHub Actions CI workflow with build, test, and lint - Add MIT LICENSE file - Apply gofmt formatting to all Go files - Prepare for v0.2.0 release
1 parent 96c916e commit d345787

14 files changed

Lines changed: 278 additions & 195 deletions

File tree

.github/workflows/ci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v5
17+
with:
18+
go-version: '1.21'
19+
20+
- name: Verify dependencies
21+
run: go mod verify
22+
23+
- name: Build
24+
run: go build -v ./...
25+
26+
- name: Run go vet
27+
run: go vet ./...
28+
29+
- name: Check formatting
30+
run: |
31+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
32+
echo "Code is not formatted. Run 'gofmt -s -w .'"
33+
gofmt -s -l .
34+
exit 1
35+
fi
36+
37+
- name: Run tests
38+
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
39+
40+
- name: Upload coverage
41+
uses: codecov/codecov-action@v4
42+
with:
43+
file: ./coverage.txt
44+
flags: unittests
45+
continue-on-error: true
46+
47+
golangci-lint:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v4
51+
52+
- name: Set up Go
53+
uses: actions/setup-go@v5
54+
with:
55+
go-version: '1.21'
56+
57+
- name: golangci-lint
58+
uses: golangci/golangci-lint-action@v4
59+
with:
60+
version: latest
61+
args: --timeout=5m
62+
continue-on-error: true

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 CyberSecurity NonProfit (CSNP)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

cmd/tlsanalyzer/main.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@ var (
2727

2828
// CLI flags
2929
var (
30-
outputFormat string
31-
outputFile string
32-
timeout int
33-
noColor bool
34-
jsonCompact bool
35-
port int
36-
sni string
37-
skipVulns bool
38-
skipQuantum bool
39-
skipCNSA2 bool
40-
policyName string
41-
policyFile string
42-
targetsFile string
43-
concurrency int
44-
showPolicies bool
30+
outputFormat string
31+
outputFile string
32+
timeout int
33+
noColor bool
34+
jsonCompact bool
35+
port int
36+
sni string
37+
skipVulns bool
38+
skipQuantum bool
39+
skipCNSA2 bool
40+
policyName string
41+
policyFile string
42+
targetsFile string
43+
concurrency int
44+
showPolicies bool
4545
)
4646

4747
func main() {

internal/analyzer/cnsa2.go

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,68 +19,68 @@ func NewCNSA2Analyzer() *CNSA2Analyzer {
1919
var (
2020
// Approved algorithms for CNSA 2.0
2121
CNSA2ApprovedKeyExchange = map[string]bool{
22-
"ML-KEM-768": true,
23-
"ML-KEM-1024": true,
24-
"X25519MLKEM768": true,
25-
"SecP256r1MLKEM768": true,
26-
"SecP384r1MLKEM1024": true,
22+
"ML-KEM-768": true,
23+
"ML-KEM-1024": true,
24+
"X25519MLKEM768": true,
25+
"SecP256r1MLKEM768": true,
26+
"SecP384r1MLKEM1024": true,
2727
}
2828

2929
CNSA2ApprovedSignatures = map[string]bool{
30-
"ML-DSA-65": true,
31-
"ML-DSA-87": true,
32-
"SLH-DSA-SHA2-128s": true,
33-
"SLH-DSA-SHA2-128f": true,
34-
"SLH-DSA-SHA2-192s": true,
35-
"SLH-DSA-SHA2-192f": true,
36-
"SLH-DSA-SHA2-256s": true,
37-
"SLH-DSA-SHA2-256f": true,
38-
"SLH-DSA-SHAKE-128s": true,
39-
"SLH-DSA-SHAKE-128f": true,
40-
"SLH-DSA-SHAKE-192s": true,
41-
"SLH-DSA-SHAKE-192f": true,
42-
"SLH-DSA-SHAKE-256s": true,
43-
"SLH-DSA-SHAKE-256f": true,
30+
"ML-DSA-65": true,
31+
"ML-DSA-87": true,
32+
"SLH-DSA-SHA2-128s": true,
33+
"SLH-DSA-SHA2-128f": true,
34+
"SLH-DSA-SHA2-192s": true,
35+
"SLH-DSA-SHA2-192f": true,
36+
"SLH-DSA-SHA2-256s": true,
37+
"SLH-DSA-SHA2-256f": true,
38+
"SLH-DSA-SHAKE-128s": true,
39+
"SLH-DSA-SHAKE-128f": true,
40+
"SLH-DSA-SHAKE-192s": true,
41+
"SLH-DSA-SHAKE-192f": true,
42+
"SLH-DSA-SHAKE-256s": true,
43+
"SLH-DSA-SHAKE-256f": true,
4444
}
4545

4646
CNSA2ApprovedSymmetric = map[string]bool{
47-
"AES-256": true,
48-
"AES-256-GCM": true,
47+
"AES-256": true,
48+
"AES-256-GCM": true,
4949
}
5050

5151
CNSA2ApprovedHash = map[string]bool{
52-
"SHA-384": true,
53-
"SHA-512": true,
54-
"SHA3-384": true,
55-
"SHA3-512": true,
52+
"SHA-384": true,
53+
"SHA-512": true,
54+
"SHA3-384": true,
55+
"SHA3-512": true,
5656
}
5757

5858
// Transitional algorithms (allowed until deadline)
5959
CNSA2Transitional = map[string]string{
60-
"RSA-3072": "2030",
61-
"RSA-4096": "2030",
62-
"ECDSA-P384": "2030",
63-
"ECDH-P384": "2030",
64-
"X25519": "2030", // Only in hybrid mode
65-
"SHA-256": "2030",
60+
"RSA-3072": "2030",
61+
"RSA-4096": "2030",
62+
"ECDSA-P384": "2030",
63+
"ECDH-P384": "2030",
64+
"X25519": "2030", // Only in hybrid mode
65+
"SHA-256": "2030",
6666
}
6767

6868
// Deprecated algorithms (should be phased out)
6969
CNSA2Deprecated = map[string]string{
70-
"RSA-2048": "Immediately",
71-
"ECDSA-P256": "2027",
72-
"ECDH-P256": "2027",
73-
"SHA-1": "Immediately",
74-
"3DES": "Immediately",
75-
"RC4": "Immediately",
70+
"RSA-2048": "Immediately",
71+
"ECDSA-P256": "2027",
72+
"ECDH-P256": "2027",
73+
"SHA-1": "Immediately",
74+
"3DES": "Immediately",
75+
"RC4": "Immediately",
7676
}
7777
)
7878

7979
// Milestones defines CNSA 2.0 timeline.
8080
var CNSA2Milestones = []struct {
81-
Name string
82-
Deadline time.Time
83-
Description string
81+
Name string
82+
Deadline time.Time
83+
Description string
8484
Requirements []string
8585
}{
8686
{
@@ -416,19 +416,19 @@ func (a *CNSA2Analyzer) calculateTimelineScore(timeline *types.CNSA2Timeline) in
416416
score := 0
417417

418418
weights := map[string]int{
419-
"Preparation Phase": 10,
420-
"New NSS Systems": 30,
421-
"TLS 1.3 Required": 25,
422-
"Legacy System Update": 20,
423-
"Full PQC Transition": 15,
419+
"Preparation Phase": 10,
420+
"New NSS Systems": 30,
421+
"TLS 1.3 Required": 25,
422+
"Legacy System Update": 20,
423+
"Full PQC Transition": 15,
424424
}
425425

426426
statusScores := map[string]int{
427-
"compliant": 100,
428-
"partial": 60,
429-
"in-progress": 40,
430-
"non-compliant": 0,
431-
"not-applicable": 100, // Future requirements don't penalize
427+
"compliant": 100,
428+
"partial": 60,
429+
"in-progress": 40,
430+
"non-compliant": 0,
431+
"not-applicable": 100, // Future requirements don't penalize
432432
}
433433

434434
for _, m := range timeline.Milestones {

internal/reporter/html.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ type HTMLReporter struct {
1818
// Report writes the scan result as HTML.
1919
func (r *HTMLReporter) Report(w io.Writer, result *types.ScanResult) error {
2020
tmpl, err := template.New("report").Funcs(template.FuncMap{
21-
"gradeClass": gradeClass,
21+
"gradeClass": gradeClass,
2222
"severityClass": severityClass,
23-
"riskClass": riskClass,
24-
"formatTime": formatTime,
25-
"progressBar": progressBar,
26-
"statusIcon": statusIcon,
23+
"riskClass": riskClass,
24+
"formatTime": formatTime,
25+
"progressBar": progressBar,
26+
"statusIcon": statusIcon,
2727
}).Parse(htmlTemplate)
2828
if err != nil {
2929
return fmt.Errorf("failed to parse template: %w", err)

internal/reporter/sarif.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ type sarifDriver struct {
3535
}
3636

3737
type sarifRule struct {
38-
ID string `json:"id"`
39-
Name string `json:"name"`
40-
ShortDescription sarifMessage `json:"shortDescription"`
41-
FullDescription sarifMessage `json:"fullDescription,omitempty"`
42-
Help sarifMessage `json:"help,omitempty"`
43-
DefaultConfig sarifRuleConfig `json:"defaultConfiguration"`
44-
Properties sarifProperties `json:"properties,omitempty"`
38+
ID string `json:"id"`
39+
Name string `json:"name"`
40+
ShortDescription sarifMessage `json:"shortDescription"`
41+
FullDescription sarifMessage `json:"fullDescription,omitempty"`
42+
Help sarifMessage `json:"help,omitempty"`
43+
DefaultConfig sarifRuleConfig `json:"defaultConfiguration"`
44+
Properties sarifProperties `json:"properties,omitempty"`
4545
}
4646

4747
type sarifRuleConfig struct {

internal/scanner/grade.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ func quantumScoreToLetter(score int) string {
251251
case score >= 80:
252252
return "Q+" // Quantum ready
253253
case score >= 50:
254-
return "Q" // Partially quantum ready
254+
return "Q" // Partially quantum ready
255255
case score >= 20:
256256
return "Q-" // Limited quantum protection
257257
default:

internal/scanner/quantum.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ var QuantumVulnerableAlgorithms = map[string]string{
1515

1616
// QuantumSafeAlgorithms lists post-quantum safe algorithms.
1717
var QuantumSafeAlgorithms = map[string]string{
18-
"ML-KEM": "NIST FIPS 203 - Key Encapsulation",
19-
"ML-DSA": "NIST FIPS 204 - Digital Signatures",
20-
"SLH-DSA": "NIST FIPS 205 - Stateless Hash-Based Signatures",
21-
"AES-256": "Symmetric - Grover's algorithm requires 2^128 operations",
22-
"AES-128": "Symmetric - Grover's algorithm requires 2^64 operations (marginal)",
23-
"ChaCha20": "Symmetric - Quantum resistant",
24-
"SHA-256": "Hash - Grover's provides only quadratic speedup",
25-
"SHA-384": "Hash - Grover's provides only quadratic speedup",
26-
"SHA-512": "Hash - Grover's provides only quadratic speedup",
18+
"ML-KEM": "NIST FIPS 203 - Key Encapsulation",
19+
"ML-DSA": "NIST FIPS 204 - Digital Signatures",
20+
"SLH-DSA": "NIST FIPS 205 - Stateless Hash-Based Signatures",
21+
"AES-256": "Symmetric - Grover's algorithm requires 2^128 operations",
22+
"AES-128": "Symmetric - Grover's algorithm requires 2^64 operations (marginal)",
23+
"ChaCha20": "Symmetric - Quantum resistant",
24+
"SHA-256": "Hash - Grover's provides only quadratic speedup",
25+
"SHA-384": "Hash - Grover's provides only quadratic speedup",
26+
"SHA-512": "Hash - Grover's provides only quadratic speedup",
2727
}
2828

2929
// HybridKeyExchanges maps hybrid PQC key exchange names to components.

internal/scanner/quantum_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ func TestAssessQuantumRisk(t *testing.T) {
8282
result: &types.ScanResult{
8383
KeyExchanges: []types.KeyExchange{
8484
{
85-
Name: "X25519MLKEM768",
86-
Type: "hybrid",
85+
Name: "X25519MLKEM768",
86+
Type: "hybrid",
8787
HybridClassical: "X25519",
88-
PQCAlgorithm: "ML-KEM-768",
88+
PQCAlgorithm: "ML-KEM-768",
8989
},
9090
},
9191
Certificate: &types.Certificate{

internal/scanner/scanner.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ type Scanner struct {
2525

2626
// Config holds scanner configuration.
2727
type Config struct {
28-
Timeout time.Duration
29-
ConnectTimeout time.Duration
30-
Concurrency int
31-
SkipCertVerify bool
32-
SNI string
33-
CheckVulns bool
34-
CheckQuantum bool
35-
MinTLSVersion uint16
36-
MaxTLSVersion uint16
28+
Timeout time.Duration
29+
ConnectTimeout time.Duration
30+
Concurrency int
31+
SkipCertVerify bool
32+
SNI string
33+
CheckVulns bool
34+
CheckQuantum bool
35+
MinTLSVersion uint16
36+
MaxTLSVersion uint16
3737
}
3838

3939
// DefaultConfig returns sensible defaults.

0 commit comments

Comments
 (0)