Skip to content

feat: add cryptographic asset model and parser#10970

Open
knqyf263 wants to merge 3 commits into
aquasecurity:mainfrom
knqyf263:feat/crypto-asset-foundation
Open

feat: add cryptographic asset model and parser#10970
knqyf263 wants to merge 3 commits into
aquasecurity:mainfrom
knqyf263:feat/crypto-asset-foundation

Conversation

@knqyf263

Copy link
Copy Markdown
Collaborator

Description

Add the format-neutral cryptographic asset foundation for container image CBOM support.

This PR:

  • introduces format-neutral models for cryptographic assets, identities, occurrences, and relationships under pkg/crypto
  • carries cryptographic assets through fanal analysis results and image artifact types
  • adds case-insensitive file selection for common cryptographic file extensions
  • parses X.509 certificates, public keys, plaintext private keys, and encrypted PKCS#8 containers from PEM and DER input

The parser returns only public metadata for plaintext private keys and does not retain private-key material in its results. Encrypted PKCS#8 containers are treated as opaque assets and identified by their SHA-256 digest.

This PR does not add user-facing scanner behavior. Analyzer and extractor integration, scanner registration, and CycloneDX output will be implemented in follow-up PRs.

Related issues

Related discussion

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

@knqyf263 knqyf263 added the kind/feature Categorizes issue or PR as related to a new feature. label Jul 16, 2026
@knqyf263 knqyf263 self-assigned this Jul 16, 2026
@knqyf263
knqyf263 force-pushed the feat/crypto-asset-foundation branch from f9f77cf to 0e856fc Compare July 16, 2026 08:47
@knqyf263
knqyf263 force-pushed the feat/crypto-asset-foundation branch from 0e856fc to fea60fe Compare July 16, 2026 08:59
@knqyf263
knqyf263 marked this pull request as ready for review July 16, 2026 10:24
@knqyf263
knqyf263 requested a review from DmitriyLewen as a code owner July 16, 2026 10:24
Comment thread pkg/crypto/asset.go
}

// Asset describes a format-neutral cryptographic asset.
type Asset struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered moving Asset and everything related to it into fanal/types?
All the fields in AnalysisResult are fields from ftypes:

OS ftypes.OS
Repository *ftypes.Repository
PackageInfos []ftypes.PackageInfo
Applications []ftypes.Application
Misconfigurations []ftypes.Misconfiguration
Secrets []ftypes.Secret
Licenses []ftypes.LicenseFile

On top of that, we use Asset as an analysis result, which also fits this change.
The fields of Asset and the other structs are exported, so there shouldn't be any problems with this move.
I understand that the amount of code involved in this package is many times larger than for any type in fanal/types, but in that case we could think about creating a subpackage.
In addition, this would get rid of the circular import problem with layers.

But I might have missed something.

Comment on lines +17 to +31
{name: "lowercase PEM", filePath: "certificates/server.pem", want: true},
{name: "uppercase PEM", filePath: "certificates/server.PEM", want: true},
{name: "mixed-case PEM", filePath: "certificates/server.PeM", want: true},
{name: "lowercase DER", filePath: "certificates/server.der", want: true},
{name: "uppercase DER", filePath: "certificates/server.DER", want: true},
{name: "mixed-case DER", filePath: "certificates/server.DeR", want: true},
{name: "lowercase CRT", filePath: "certificates/server.crt", want: true},
{name: "uppercase CRT", filePath: "certificates/server.CRT", want: true},
{name: "mixed-case CRT", filePath: "certificates/server.CrT", want: true},
{name: "lowercase CER", filePath: "certificates/server.cer", want: true},
{name: "uppercase CER", filePath: "certificates/server.CER", want: true},
{name: "mixed-case CER", filePath: "certificates/server.CeR", want: true},
{name: "lowercase KEY", filePath: "certificates/server.key", want: true},
{name: "uppercase KEY", filePath: "certificates/server.KEY", want: true},
{name: "mixed-case KEY", filePath: "certificates/server.KeY", want: true},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have the tests for the Contains() function from set.NewCaseInsensitive.
So I think checking each ext once will be enough.

})

// Cryptographic assets
sort.SliceStable(r.CryptoAssets, func(i, j int) bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain in more detail why sort.SliceStable is needed here?
If we have assets with the same FilePath and Descriptor and we don't remove them as duplicates, then it might make sense to add more values for comparison.
I don't think we'll have enough entries to worry about the speed difference between sort.Slice and sort.SliceStable, but from a code consistency perspective, we could go with sort.Slice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature Categorizes issue or PR as related to a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants