From 7b6bf06bbe17cc3af60775f8db1e874dc6413dfe Mon Sep 17 00:00:00 2001 From: Abdel Fane Date: Tue, 28 Jul 2026 10:22:18 -0600 Subject: [PATCH 1/3] Prepare the 1.4.0 release Cut the changelog's Unreleased section to 1.4.0 and record the limitations a user will meet in this build but that this release does not fix, so the release notes do not read wider than the change. The largest is a file filter that tests the absolute path of the scan target, so a checkout under a directory named docs scans zero files and exits 0. It is present in 1.3.0 as well, and the changelog now says how to notice it. No behaviour changes. Finding sets are identical to the pre-branch binary on five real trees carrying 110, 995, 494, 633 and 461 findings. The rest is hygiene the release surfaced: - gofmt on pkg/patterns/matcher.go, which the previous change left unformatted. CI does not catch this: there is no .golangci.yml, so golangci-lint runs its defaults and gofmt is not among them. - The copyright notice said 2025 on 35 Go files, LICENSE and the Makefile, while the repository has been edited through 2026. Now 2025-2026, matching the sibling repositories. - .gitignore no longer lists editor assistant files. They are in .git/info/exclude, so nothing becomes committable, and a public repository should not carry the list. --- .gitignore | 6 ------ CHANGELOG.md | 28 ++++++++++++++++++++++++++- LICENSE | 2 +- Makefile | 2 +- cmd/cryptoscan/main.go | 2 +- crypto-samples/crypto_samples.go | 2 +- internal/cli/root.go | 2 +- internal/cli/scan.go | 2 +- internal/cli/scan_test.go | 2 +- pkg/analyzer/analyzer.go | 2 +- pkg/analyzer/analyzer_test.go | 2 +- pkg/analyzer/context.go | 2 +- pkg/analyzer/context_test.go | 2 +- pkg/analyzer/dependencies.go | 2 +- pkg/analyzer/dependencies_test.go | 2 +- pkg/analyzer/remediation.go | 2 +- pkg/analyzer/scoring.go | 2 +- pkg/config/config.go | 2 +- pkg/config/config_test.go | 2 +- pkg/patterns/matcher.go | 14 +++++++------- pkg/patterns/matcher_test.go | 2 +- pkg/reporter/cbom.go | 2 +- pkg/reporter/cbom_schema_test.go | 2 +- pkg/reporter/csv.go | 2 +- pkg/reporter/json.go | 2 +- pkg/reporter/reporter.go | 2 +- pkg/reporter/reporter_test.go | 2 +- pkg/reporter/sarif.go | 2 +- pkg/reporter/text.go | 2 +- pkg/reporter/version_test.go | 2 +- pkg/scanner/determinism_test.go | 2 +- pkg/scanner/evidence.go | 2 +- pkg/scanner/evidence_property_test.go | 2 +- pkg/scanner/evidence_test.go | 2 +- pkg/scanner/scanner.go | 2 +- pkg/scanner/scanner_test.go | 2 +- pkg/types/types.go | 2 +- pkg/types/types_test.go | 2 +- pkg/version/version.go | 2 +- 39 files changed, 70 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index f2048d7..219c011 100644 --- a/.gitignore +++ b/.gitignore @@ -47,11 +47,5 @@ secrets.json *.p12 *.pfx -# AI assistant files -CLAUDE.md -.cursorrules -.aider* -.copilot/ - # Private/internal files .private/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ad6f35..22fa5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to CryptoScan are recorded here. This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.4.0] - 2026-07-28 ### Fixed @@ -100,6 +100,32 @@ All notable changes to CryptoScan are recorded here. This project follows - `tool` object in JSON output, carrying the scanner name and version. - `narrativeSuppressedCount` in the scan summary. +### Known limitations + +- **A `docs` directory anywhere in the absolute path of the scan target + suppresses the scan.** The file filter tests the absolute path rather than + the path relative to the scan target, so a checkout under, for example, + `~/work/docs/myproject` reports `Scanned: 0 files` and exits 0. A `-docs` + suffix anywhere in the path (`api-docs`, `user-docs`) is a second, separate + case: the files are read, and every finding is then discarded. Both are + present in 1.3.0 as well and are not introduced by this release. Until this + is fixed, check the `Scanned:` line, or the `filesScanned` field in JSON + output, against the number of files you expect. A fix is planned for 1.4.1. + +- Invalid values for `--format`, `--min-severity` and `--fail-on` are accepted + silently and the scan falls back to the text report. A typo in a CI pipeline + therefore uploads a text file where a machine format was intended, and the + job still passes. Also present in 1.3.0. + +- A scan target containing no cryptography reports a migration readiness of + `0.0% [CRITICAL]`. Nothing was measured, so the number describes an absence + of evidence rather than a risk. The recommendations printed underneath state + this correctly. + +- SARIF `ruleId` values are unique per occurrence rather than per pattern, so + GitHub Code Scanning cannot group results and a dismissal does not carry + across runs. + ## [1.3.0] See the [release notes](https://github.com/csnp/cryptoscan/releases) for diff --git a/LICENSE b/LICENSE index 6c626e6..d1e437e 100644 --- a/LICENSE +++ b/LICENSE @@ -175,7 +175,7 @@ END OF TERMS AND CONDITIONS - Copyright 2025 CyberSecurity NonProfit (CSNP) + Copyright 2025-2026 CyberSecurity NonProfit (CSNP) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index 2256d6d..0f033c6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # CryptoScan Makefile -# Copyright 2025 CyberSecurity NonProfit (CSNP) +# Copyright 2025-2026 CyberSecurity NonProfit (CSNP) BINARY_NAME=cryptoscan VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") diff --git a/cmd/cryptoscan/main.go b/cmd/cryptoscan/main.go index 01ca517..7a515aa 100644 --- a/cmd/cryptoscan/main.go +++ b/cmd/cryptoscan/main.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package main diff --git a/crypto-samples/crypto_samples.go b/crypto-samples/crypto_samples.go index ca4157c..bedc2b9 100644 --- a/crypto-samples/crypto_samples.go +++ b/crypto-samples/crypto_samples.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 //go:build ignore diff --git a/internal/cli/root.go b/internal/cli/root.go index 6dd94c7..4135dfa 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package cli diff --git a/internal/cli/scan.go b/internal/cli/scan.go index 1c1ac57..63455e7 100644 --- a/internal/cli/scan.go +++ b/internal/cli/scan.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package cli diff --git a/internal/cli/scan_test.go b/internal/cli/scan_test.go index c45c04d..c48a340 100644 --- a/internal/cli/scan_test.go +++ b/internal/cli/scan_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package cli diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index d5ddb8e..56bf3a1 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 // Package analyzer provides intelligent file analysis capabilities diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go index 90688b0..0afc9c4 100644 --- a/pkg/analyzer/analyzer_test.go +++ b/pkg/analyzer/analyzer_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/analyzer/context.go b/pkg/analyzer/context.go index ed81a9d..50000cd 100644 --- a/pkg/analyzer/context.go +++ b/pkg/analyzer/context.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/analyzer/context_test.go b/pkg/analyzer/context_test.go index 1aeee3e..e5d7aa7 100644 --- a/pkg/analyzer/context_test.go +++ b/pkg/analyzer/context_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/analyzer/dependencies.go b/pkg/analyzer/dependencies.go index 70c7784..86edfa0 100644 --- a/pkg/analyzer/dependencies.go +++ b/pkg/analyzer/dependencies.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/analyzer/dependencies_test.go b/pkg/analyzer/dependencies_test.go index d064caf..906622d 100644 --- a/pkg/analyzer/dependencies_test.go +++ b/pkg/analyzer/dependencies_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/analyzer/remediation.go b/pkg/analyzer/remediation.go index b5eb28c..cb5c205 100644 --- a/pkg/analyzer/remediation.go +++ b/pkg/analyzer/remediation.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 // Package analyzer provides analysis utilities for cryptographic findings. diff --git a/pkg/analyzer/scoring.go b/pkg/analyzer/scoring.go index 83958c1..d083381 100644 --- a/pkg/analyzer/scoring.go +++ b/pkg/analyzer/scoring.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package analyzer diff --git a/pkg/config/config.go b/pkg/config/config.go index 99b0efb..5084a71 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 // Package config handles configuration file loading for cryptoscan diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index e4392d5..3b08584 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package config diff --git a/pkg/patterns/matcher.go b/pkg/patterns/matcher.go index fa61a0b..e30817b 100644 --- a/pkg/patterns/matcher.go +++ b/pkg/patterns/matcher.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package patterns @@ -420,9 +420,9 @@ func (m *Matcher) loadPatterns() { // DES/3DES (Deprecated) // Note: Require mode suffix (CBC/ECB/CFB/OFB) or crypto context to avoid false positives m.patterns = append(m.patterns, Pattern{ - ID: "DES-001", - Name: "DES Algorithm", - Category: "Deprecated Algorithm", + ID: "DES-001", + Name: "DES Algorithm", + Category: "Deprecated Algorithm", // des.NewCipher is the Go standard library's only way to construct a // DES cipher, and it was not covered: \bDES\.(new|...)\b cannot match // "des.NewCipher" because the \b after "new" requires a non-word @@ -437,9 +437,9 @@ func (m *Matcher) loadPatterns() { }) m.patterns = append(m.patterns, Pattern{ - ID: "3DES-001", - Name: "Triple DES Algorithm", - Category: "Deprecated Algorithm", + ID: "3DES-001", + Name: "Triple DES Algorithm", + Category: "Deprecated Algorithm", // des.NewTripleDESCipher is the Go standard library constructor; the // \b(3DES|...)\b alternation cannot reach it. Regex: regexp.MustCompile(`(?i)\b(3DES|Triple[-_]?DES|DESede|TDEA)\b|\bdes\.NewTripleDESCipher\s*\(`), diff --git a/pkg/patterns/matcher_test.go b/pkg/patterns/matcher_test.go index 4db00c9..f2f3f6d 100644 --- a/pkg/patterns/matcher_test.go +++ b/pkg/patterns/matcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package patterns diff --git a/pkg/reporter/cbom.go b/pkg/reporter/cbom.go index 5ddc22b..df85681 100644 --- a/pkg/reporter/cbom.go +++ b/pkg/reporter/cbom.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/cbom_schema_test.go b/pkg/reporter/cbom_schema_test.go index 6638c95..a131eed 100644 --- a/pkg/reporter/cbom_schema_test.go +++ b/pkg/reporter/cbom_schema_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/csv.go b/pkg/reporter/csv.go index 8a8c4a6..30359e5 100644 --- a/pkg/reporter/csv.go +++ b/pkg/reporter/csv.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/json.go b/pkg/reporter/json.go index f480a29..05d0670 100644 --- a/pkg/reporter/json.go +++ b/pkg/reporter/json.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/reporter.go b/pkg/reporter/reporter.go index 728888a..bd6bd0c 100644 --- a/pkg/reporter/reporter.go +++ b/pkg/reporter/reporter.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/reporter_test.go b/pkg/reporter/reporter_test.go index e1c7520..038cdb4 100644 --- a/pkg/reporter/reporter_test.go +++ b/pkg/reporter/reporter_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/sarif.go b/pkg/reporter/sarif.go index be297b3..a315034 100644 --- a/pkg/reporter/sarif.go +++ b/pkg/reporter/sarif.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/text.go b/pkg/reporter/text.go index cc15186..054d0c8 100644 --- a/pkg/reporter/text.go +++ b/pkg/reporter/text.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/reporter/version_test.go b/pkg/reporter/version_test.go index 040a630..35a46f4 100644 --- a/pkg/reporter/version_test.go +++ b/pkg/reporter/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package reporter diff --git a/pkg/scanner/determinism_test.go b/pkg/scanner/determinism_test.go index b9ea34f..e25afac 100644 --- a/pkg/scanner/determinism_test.go +++ b/pkg/scanner/determinism_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/scanner/evidence.go b/pkg/scanner/evidence.go index d677f7b..ab9c512 100644 --- a/pkg/scanner/evidence.go +++ b/pkg/scanner/evidence.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/scanner/evidence_property_test.go b/pkg/scanner/evidence_property_test.go index 8bf373e..7cd84ff 100644 --- a/pkg/scanner/evidence_property_test.go +++ b/pkg/scanner/evidence_property_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/scanner/evidence_test.go b/pkg/scanner/evidence_test.go index f6b8c7d..0db5f92 100644 --- a/pkg/scanner/evidence_test.go +++ b/pkg/scanner/evidence_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/scanner/scanner.go b/pkg/scanner/scanner.go index 8943631..27acbb0 100644 --- a/pkg/scanner/scanner.go +++ b/pkg/scanner/scanner.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/scanner/scanner_test.go b/pkg/scanner/scanner_test.go index 44da79e..de0d674 100644 --- a/pkg/scanner/scanner_test.go +++ b/pkg/scanner/scanner_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package scanner diff --git a/pkg/types/types.go b/pkg/types/types.go index 7a05bed..6df1055 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 // Package types contains shared type definitions diff --git a/pkg/types/types_test.go b/pkg/types/types_test.go index 355b8d4..b5c3fa9 100644 --- a/pkg/types/types_test.go +++ b/pkg/types/types_test.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 package types diff --git a/pkg/version/version.go b/pkg/version/version.go index c01f192..39dd36a 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -1,4 +1,4 @@ -// Copyright 2025 CyberSecurity NonProfit (CSNP) +// Copyright 2025-2026 CyberSecurity NonProfit (CSNP) // SPDX-License-Identifier: Apache-2.0 // Package version holds the single source of truth for the CryptoScan version From 1ae7aad8112a512a044a46fcbe95999234f9d317 Mon Sep 17 00:00:00 2001 From: Abdel Fane Date: Tue, 28 Jul 2026 10:28:03 -0600 Subject: [PATCH 2/3] Bring the README in line with the CSNP writing standard - Remove 38 em-dashes. Label lists take a colon, prose takes a comma or a sentence break. No other file in the repository contained one. - The toolkit section still linked the pre-rename csnp/qramm-cryptodeps and csnp/qramm-tls-analyzer, which resolve only through GitHub's redirect. The table at the top of the same file already used the canonical names. - The subtitle said "Find every cryptographic algorithm in your codebase". The scanner has known coverage gaps and a path filter that can silence a whole scan, both recorded in the changelog, so "every" is not a claim this build meets. It now says "Inventory the cryptography in your codebase". Also, the version command's copyright line said 2025 while the file headers now say 2025-2026. Verified: remote Git URL scanning, the README's headline capability, reports 192 findings across 71 files on github.com/golang-jwt/jwt. Finding sets remain identical to the pre-branch binary on four real trees. --- README.md | 74 ++++++++++++++++++++++---------------------- internal/cli/root.go | 2 +- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index b8dfbb1..d1d2955 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

Cryptographic Discovery for the Post-Quantum Era

- Find every cryptographic algorithm in your codebase. Know your quantum risk. Get a Migration Readiness Score. Plan your migration. + Inventory the cryptography in your codebase. Know your quantum risk. Get a Migration Readiness Score. Plan your migration.

@@ -23,7 +23,7 @@ --- -> **Part of the QRAMM Toolkit** — Open-source tools for quantum readiness: +> **Part of the QRAMM Toolkit**. Open-source tools for quantum readiness: > > | Tool | Purpose | > |------|---------| @@ -37,11 +37,11 @@ ## The Quantum Computing Challenge -**Quantum computers will break RSA, ECDSA, and Diffie-Hellman within the next decade.** This isn't speculation—the NSA, NIST, and major technology companies are already migrating to post-quantum cryptography (PQC). +**Quantum computers will break RSA, ECDSA, and Diffie-Hellman within the next decade.** This isn't speculation. The NSA, NIST, and major technology companies are already migrating to post-quantum cryptography (PQC). The challenge? **You can't migrate what you can't find.** -Most organizations have no visibility into which cryptographic algorithms are used across their codebases, configurations, and dependencies. CryptoScan solves this by providing a complete cryptographic inventory in seconds—with full source code context so you know exactly what needs to change and where. +Most organizations have no visibility into which cryptographic algorithms are used across their codebases, configurations, and dependencies. CryptoScan solves this by providing a complete cryptographic inventory in seconds, with full source code context so you know exactly what needs to change and where. ## Why CryptoScan @@ -73,31 +73,31 @@ CryptoScan is purpose-built for quantum readiness assessment:

Click to expand capability descriptions -**Remote Git URL scanning** — Scan any public or private Git repository directly by URL without cloning it first. Just run `cryptoscan scan https://github.com/org/repo.git` and get results immediately. +**Remote Git URL scanning**: Scan any public or private Git repository directly by URL without cloning it first. Just run `cryptoscan scan https://github.com/org/repo.git` and get results immediately. -**Source code context** — Every finding includes the 3 lines before and after the match, so you can immediately understand the context without opening the file. Know if it's in a comment, test, or production code at a glance. +**Source code context**: Every finding includes the 3 lines before and after the match, so you can immediately understand the context without opening the file. Know if it's in a comment, test, or production code at a glance. -**Quantum risk classification** — Each finding is tagged with its quantum computing threat level: VULNERABLE (broken by Shor's algorithm), PARTIAL (weakened by Grover's algorithm), SAFE (quantum-resistant), or UNKNOWN. This tells you exactly what needs to migrate first. +**Quantum risk classification**: Each finding is tagged with its quantum computing threat level: VULNERABLE (broken by Shor's algorithm), PARTIAL (weakened by Grover's algorithm), SAFE (quantum-resistant), or UNKNOWN. This tells you exactly what needs to migrate first. -**Post-Quantum Crypto detection** — Detects NIST-standardized PQC algorithms including ML-KEM (FIPS 203), ML-DSA (FIPS 204), SLH-DSA (FIPS 205), and draft FN-DSA (FIPS 206). Also detects stateful hash-based signatures (XMSS, LMS per SP 800-208). Recognizes both new FIPS names and legacy names (Kyber, Dilithium, SPHINCS+). +**Post-Quantum Crypto detection**: Detects NIST-standardized PQC algorithms including ML-KEM (FIPS 203), ML-DSA (FIPS 204), SLH-DSA (FIPS 205), and draft FN-DSA (FIPS 206). Also detects stateful hash-based signatures (XMSS, LMS per SP 800-208). Recognizes both new FIPS names and legacy names (Kyber, Dilithium, SPHINCS+). -**Migration Readiness Score** — Get an instant percentage score showing how prepared your codebase is for the post-quantum transition. The score weighs quantum-safe algorithms (100%), hybrid implementations (80%), and partial safety (30%) against vulnerable and critical findings. Includes top-risk files to prioritize. +**Migration Readiness Score**: Get an instant percentage score showing how prepared your codebase is for the post-quantum transition. The score weighs quantum-safe algorithms (100%), hybrid implementations (80%), and partial safety (30%) against vulnerable and critical findings. Includes top-risk files to prioritize. -**Hybrid crypto recognition** — Identifies hybrid cryptographic implementations that combine classical and post-quantum algorithms for defense-in-depth. Detects patterns like X25519+ML-KEM key exchange and ECDSA+ML-DSA composite signatures—the recommended transition approach. +**Hybrid crypto recognition**: Identifies hybrid cryptographic implementations that combine classical and post-quantum algorithms for defense-in-depth. Detects patterns like X25519+ML-KEM key exchange and ECDSA+ML-DSA composite signatures, the recommended transition approach. -**QRAMM framework mapping** — Maps all findings to the Quantum Readiness Assurance Maturity Model (QRAMM) Dimension 1: Cryptographic Visibility & Inventory. Shows your maturity level for Discovery (Practice 1.1), Vulnerability Assessment (Practice 1.2), and Dependency Mapping (Practice 1.3). +**QRAMM framework mapping**: Maps all findings to the Quantum Readiness Assurance Maturity Model (QRAMM) Dimension 1: Cryptographic Visibility & Inventory. Shows your maturity level for Discovery (Practice 1.1), Vulnerability Assessment (Practice 1.2), and Dependency Mapping (Practice 1.3). -**Context-aware confidence** — Not all matches are equal. CryptoScan reduces confidence for findings in comments, documentation, log messages, and test files. High-confidence findings in production code are prioritized over low-confidence matches in docs. +**Context-aware confidence**: Not all matches are equal. CryptoScan reduces confidence for findings in comments, documentation, log messages, and test files. High-confidence findings in production code are prioritized over low-confidence matches in docs. -**CBOM output** — Generate a Cryptographic Bill of Materials—a machine-readable inventory of all cryptographic algorithms in your codebase. Required for federal compliance (OMB M-23-02) and essential for tracking quantum migration progress. +**CBOM output**: Generate a Cryptographic Bill of Materials, a machine-readable inventory of all cryptographic algorithms in your codebase. Required for federal compliance (OMB M-23-02) and essential for tracking quantum migration progress. -**SARIF for GitHub Security** — Output findings in SARIF format for direct integration with GitHub Code Scanning. See cryptographic issues as security alerts in your pull requests and repository Security tab. +**SARIF for GitHub Security**: Output findings in SARIF format for direct integration with GitHub Code Scanning. See cryptographic issues as security alerts in your pull requests and repository Security tab. -**Inline ignore comments** — Suppress false positives directly in your code with `// cryptoscan:ignore`. No need to maintain separate exclusion files or configure complex ignore rules. +**Inline ignore comments**: Suppress false positives directly in your code with `// cryptoscan:ignore`. No need to maintain separate exclusion files or configure complex ignore rules. -**Migration guidance** — Every finding includes specific remediation advice: which NIST PQC algorithm to migrate to (ML-KEM, ML-DSA, SLH-DSA), links to standards, and effort estimates. +**Migration guidance**: Every finding includes specific remediation advice: which NIST PQC algorithm to migrate to (ML-KEM, ML-DSA, SLH-DSA), links to standards, and effort estimates. -**Dependency scanning** — Scans package manifests (package.json, go.mod, requirements.txt, pom.xml, etc.) to identify crypto libraries in your dependencies. Covers 20+ package manager formats. +**Dependency scanning**: Scans package manifests (package.json, go.mod, requirements.txt, pom.xml, etc.) to identify crypto libraries in your dependencies. Covers 20+ package manager formats.
@@ -107,7 +107,7 @@ CryptoScan is purpose-built for quantum readiness assessment: #### Option 1: Build from Source -Requires **Go 1.21+** ([install Go](https://go.dev/dl/)) — always use the latest patch version for security fixes +Requires **Go 1.21+** ([install Go](https://go.dev/dl/)). Always use the latest patch version for security fixes. Copy and paste this entire block: @@ -394,12 +394,12 @@ legacyKey := oldCrypto.NewKey() ``` Supported directives: -- `cryptoscan:ignore` — Ignore all findings on this line, and only this line -- `cryptoscan:ignore RSA-001` — Ignore specific pattern ID -- `cryptoscan:ignore RSA-*` — Ignore pattern family (wildcard) -- `cryptoscan:ignore-next-line` — Ignore finding on the following line -- `crypto-scan:ignore` — Alternative format -- `noscan` — Quick ignore all +- `cryptoscan:ignore`: Ignore all findings on this line, and only this line +- `cryptoscan:ignore RSA-001`: Ignore specific pattern ID +- `cryptoscan:ignore RSA-*`: Ignore pattern family (wildcard) +- `cryptoscan:ignore-next-line`: Ignore finding on the following line +- `crypto-scan:ignore`: Alternative format +- `noscan`: Quick ignore all ### CI/CD Integration @@ -713,12 +713,12 @@ We believe that: ### QRAMM Toolkit -CryptoScan is part of the **Quantum Readiness Assurance Maturity Model (QRAMM)** toolkit—a suite of open-source tools designed to help organizations prepare for the post-quantum era: +CryptoScan is part of the **Quantum Readiness Assurance Maturity Model (QRAMM)** toolkit, a suite of open-source tools designed to help organizations prepare for the post-quantum era: -- **CryptoScan** — Cryptographic discovery scanner (this project) -- **[CryptoDeps](https://github.com/csnp/qramm-cryptodeps)** — Quantum-safe dependency analysis for your software supply chain -- **QRAMM Assessment** — Quantum readiness maturity assessment -- **[TLS Analyzer](https://github.com/csnp/qramm-tls-analyzer)** — TLS/SSL configuration analysis with CNSA 2.0 compliance tracking +- **CryptoScan**: Cryptographic discovery scanner (this project) +- **[CryptoDeps](https://github.com/csnp/cryptodeps)**: Quantum-safe dependency analysis for your software supply chain +- **QRAMM Assessment**: Quantum readiness maturity assessment +- **[TLS Analyzer](https://github.com/csnp/tls-analyzer)**: TLS/SSL configuration analysis with CNSA 2.0 compliance tracking Learn more at [qramm.org](https://qramm.org) and [csnp.org](https://csnp.org). @@ -726,12 +726,12 @@ Learn more at [qramm.org](https://qramm.org) and [csnp.org](https://csnp.org). ### NIST Post-Quantum Cryptography Standards -- [FIPS 203 - ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism)](https://csrc.nist.gov/pubs/fips/203/final) — Replaces RSA/ECDH for key exchange -- [FIPS 204 - ML-DSA (Module-Lattice-Based Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/204/final) — Replaces RSA/ECDSA for signatures -- [FIPS 205 - SLH-DSA (Stateless Hash-Based Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/205/final) — Alternative signature scheme -- [FIPS 206 - FN-DSA (FFT-Based Network Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/206/ipd) — Draft standard (formerly Falcon) -- [SP 800-208 - XMSS and LMS Hash-Based Signatures](https://csrc.nist.gov/pubs/sp/800/208/final) — Stateful hash-based signatures -- [NIST SP 800-131A Rev 2](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final) — Transitioning cryptographic algorithms and key lengths +- [FIPS 203 - ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism)](https://csrc.nist.gov/pubs/fips/203/final): Replaces RSA/ECDH for key exchange +- [FIPS 204 - ML-DSA (Module-Lattice-Based Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/204/final): Replaces RSA/ECDSA for signatures +- [FIPS 205 - SLH-DSA (Stateless Hash-Based Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/205/final): Alternative signature scheme +- [FIPS 206 - FN-DSA (FFT-Based Network Digital Signature Algorithm)](https://csrc.nist.gov/pubs/fips/206/ipd): Draft standard (formerly Falcon) +- [SP 800-208 - XMSS and LMS Hash-Based Signatures](https://csrc.nist.gov/pubs/sp/800/208/final): Stateful hash-based signatures +- [NIST SP 800-131A Rev 2](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final): Transitioning cryptographic algorithms and key lengths ### Additional Resources @@ -741,14 +741,14 @@ Learn more at [qramm.org](https://qramm.org) and [csnp.org](https://csnp.org). ## License -Apache License 2.0 — see [LICENSE](LICENSE) for details. +Apache License 2.0. See [LICENSE](LICENSE) for details. Copyright 2025 CyberSecurity NonProfit (CSNP) ---

- Built with purpose by CSNP — Advancing cybersecurity for everyone + Built with purpose by CSNP. Advancing cybersecurity for everyone

diff --git a/internal/cli/root.go b/internal/cli/root.go index 4135dfa..5e852f6 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -78,6 +78,6 @@ var versionCmd = &cobra.Command{ fmt.Printf(" built: %s\n", buildDate) } fmt.Printf("\nPart of QRAMM - https://qramm.org\n") - fmt.Printf("Copyright 2025 CSNP - https://csnp.org\n") + fmt.Printf("Copyright 2025-2026 CSNP - https://csnp.org\n") }, } From 2e8e684694cf9d493cfb0e4d0f1e01d9665c53b4 Mon Sep 17 00:00:00 2001 From: Abdel Fane Date: Tue, 28 Jul 2026 10:39:33 -0600 Subject: [PATCH 3/3] Stop the help text claiming detection the scanner does not have The fresh-user release test found four capability claims that are not true of this build. Every one was reproduced by hand against the release binary and against the released 1.3.0 binary, and all four are present in 1.3.0 as well, so none is new. What is new is that this release claims to be the one where outputs tell the truth, so shipping them undisclosed is not an option. - scan --help listed DSA under "Asymmetric algorithms". DSA.generate(2048) matches no pattern under any combination of flags, including --include-quantum-safe, --verbose and --include-imports. DSA is quantum vulnerable, so this is a false negative on the tool's core purpose. The list no longer claims it, and the help says plainly that it is not detected, along with the whole-word matching that also misses RSAPrivateKey and AESCipher. - The list also implied AES and SHA-256/384/512 were undetected, because a default scan reports none of them. They are detected and withheld as quantum-safe. The help now says that and names the flag. - --context, --max-depth and --git-history are accepted and ignored. Measured: --context 0 and --context 8 both render three source lines either side; --max-depth 1 scans the same six files as unlimited; --git-history finds nothing in a repository whose MD5 and RC4 exist only in an earlier commit. --group-by is the same for severity, category and quantum, which produce output byte-identical to an invalid value. --group-by file works. The changelog's determinism claim was also wider than the fix. The findings are in a stable order in every format, but the text report's "Categories Found" block is rendered from a map and differs on every run: six runs of the identical command produced six different hashes, on 1.3.0 and on this build. Anyone diffing a saved text report was being promised something untrue. The claim is now scoped and the limitation is recorded. The known-limitations section also gained the silent skip of unreadable files, the silently ignored malformed .cryptoscan.yaml, and the streaming total that disagrees with the final total. No behaviour changes. Finding sets identical to the pre-branch binary on five real trees carrying 110, 995, 494, 633 and 461 findings. --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++-- internal/cli/scan.go | 22 ++++++++++++++++------ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22fa5fd..8dd562d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,7 +92,10 @@ All notable changes to CryptoScan are recorded here. This project follows - **Finding order was nondeterministic.** Results were built by ranging over a map, so two scans of an unchanged tree emitted the same findings in a different order. This broke diffable CI output, golden-file tests and - reproducible CBOMs. + reproducible CBOMs. The findings themselves are now in a stable order in + every format, verified over repeated runs. The text report's "Categories + Found" summary block is a separate map and is still nondeterministic; see + the known limitations below. ### Added @@ -124,7 +127,37 @@ All notable changes to CryptoScan are recorded here. This project follows - SARIF `ruleId` values are unique per occurrence rather than per pattern, so GitHub Code Scanning cannot group results and a dismissal does not carry - across runs. + across runs. The same ids do not match the pattern ids `--ignore` accepts. + +- **DSA is not detected.** Standalone DSA key generation, such as + `DSA.generate(2048)`, matches no pattern under any combination of flags, so + a codebase using DSA is not told that it is quantum vulnerable. The help + text used to claim DSA support and no longer does. Detection also matches + whole words only, so compound identifiers such as `RSAPrivateKey` and + `AESCipher` are not matched. + +- **Four flags are accepted and ignored:** `--context`, `--max-depth`, + `--git-history`, and `--group-by` for the values `severity`, `category` and + `quantum`. Their help text now says so. `--group-by file` works. + +- **The text report's summary blocks are not reproducible.** The findings are + in a stable order, but "Categories Found" is rendered from a map, so + `cryptoscan scan . > report.txt` differs between two runs of an unchanged + tree. Use `--format json` for anything you intend to diff. Also present in + 1.3.0. + +- **A file the scanner cannot read is skipped silently.** An unreadable file + in a scanned tree produces no warning, nothing on stderr, and exit 0, so the + scan reports a clean result for code it never examined. Also present in + 1.3.0. + +- **A malformed auto-detected `.cryptoscan.yaml` is ignored silently,** so + suppression rules a user believes are active may not be. The same file + passed explicitly with `--config` fails with a clear error. + +- The text report's streaming line and its final total disagree, because + deduplication happens after streaming. The final total is the correct one + and is what every machine-readable format reports. ## [1.3.0] diff --git a/internal/cli/scan.go b/internal/cli/scan.go index 63455e7..2386880 100644 --- a/internal/cli/scan.go +++ b/internal/cli/scan.go @@ -52,13 +52,23 @@ var scanCmd = &cobra.Command{ Long: `Scan a local directory or Git repository for cryptographic patterns. The scanner detects: - - Asymmetric algorithms: RSA, DSA, ECDSA, Ed25519, DH, ECDH + - Asymmetric algorithms: RSA, ECDSA, Ed25519, ECDH (the elliptic-curve + ones are reported as ECC) - Symmetric algorithms: AES, DES, 3DES, Blowfish, ChaCha20, RC4 - - Hash functions: MD5, SHA-1, SHA-256, SHA-384, SHA-512, SHA-3 + - Hash functions: MD5, SHA-1, SHA-2, SHA-3 - Key sizes and configurations - TLS/SSL settings - Crypto library imports +Quantum-safe algorithms, including AES and the SHA-2 family, are detected but +withheld from the default report because they need no migration. Pass +--include-quantum-safe to see them. + +Not detected: DSA. Standalone DSA key generation is not matched by any +pattern, so a codebase using it will not be told that it is quantum +vulnerable. Detection is matched on whole words, so a compound identifier +such as RSAPrivateKey or AESCipher is not matched either. + Output formats: - text: Human-readable console output (default) - json: JSON format for programmatic processing @@ -98,14 +108,14 @@ func init() { scanCmd.Flags().StringVarP(&outputFile, "output", "o", "", "Output file (default: stdout)") scanCmd.Flags().StringVarP(&includeGlobs, "include", "i", "", "File patterns to include (comma-separated)") scanCmd.Flags().StringVarP(&excludeGlobs, "exclude", "e", "", "File patterns to exclude (comma-separated)") - scanCmd.Flags().IntVarP(&maxDepth, "max-depth", "d", 0, "Maximum directory depth (0 = unlimited)") + scanCmd.Flags().IntVarP(&maxDepth, "max-depth", "d", 0, "Maximum directory depth (0 = unlimited). NOT YET IMPLEMENTED: the value is accepted and ignored") scanCmd.Flags().BoolVarP(&showProgress, "progress", "p", false, "Show scan progress") scanCmd.Flags().StringVar(&minSeverity, "min-severity", "info", "Minimum severity to report: info, low, medium, high, critical") scanCmd.Flags().BoolVar(&noColor, "no-color", false, "Disable colored output") scanCmd.Flags().BoolVar(&jsonPretty, "pretty", false, "Pretty print JSON output") - scanCmd.Flags().BoolVar(&scanGitHistory, "git-history", false, "Scan Git history (slower)") - scanCmd.Flags().StringVarP(&groupBy, "group-by", "g", "", "Group output by: file, severity, category, quantum") - scanCmd.Flags().IntVarP(&contextLines, "context", "c", 3, "Number of context lines to show around findings") + scanCmd.Flags().BoolVar(&scanGitHistory, "git-history", false, "Scan Git history (slower). NOT YET IMPLEMENTED: only the working tree is scanned") + scanCmd.Flags().StringVarP(&groupBy, "group-by", "g", "", "Group output by: file. NOT YET IMPLEMENTED: severity, category and quantum are accepted and ignored") + scanCmd.Flags().IntVarP(&contextLines, "context", "c", 3, "Number of context lines to show around findings. NOT YET IMPLEMENTED: the report always shows 3") scanCmd.Flags().BoolVar(&streamFindings, "stream", true, "Show findings as they are discovered") scanCmd.Flags().BoolVar(&includeImports, "include-imports", false, "Include library import findings (normally suppressed as low-value)") scanCmd.Flags().BoolVar(&includeQuantumSafe, "include-quantum-safe", false, "Include quantum-safe algorithm findings (SHA-256, AES-256)")