From 62f689824c8d8f820d0eee1dbf753fa430704b8b Mon Sep 17 00:00:00 2001 From: Sirish Bathina Date: Thu, 24 Aug 2023 03:49:59 -1000 Subject: [PATCH] Detect golang boring crypto and fipsonly modules (#2021) * Extending build info to include crypto settings Signed-off-by: Sirish Bathina * Use kasten fork for goversion module Signed-off-by: Sirish Bathina * go mod tidy Signed-off-by: Sirish Bathina * change key to GoCryptoSettings and lint fix Signed-off-by: Sirish Bathina * Addressing feedback Signed-off-by: Sirish Bathina --------- Signed-off-by: Sirish Bathina --- go.mod | 1 + go.sum | 2 + internal/constants.go | 2 +- schema/json/schema-10.0.1.json | 1929 +++++++++++++++++ syft/pkg/cataloger/golang/package.go | 3 +- syft/pkg/cataloger/golang/parse_go_binary.go | 8 +- .../cataloger/golang/parse_go_binary_test.go | 303 +-- syft/pkg/cataloger/golang/scan_binary.go | 43 +- syft/pkg/cataloger/golang/scan_binary_test.go | 70 + syft/pkg/golang_metadata.go | 1 + 10 files changed, 2215 insertions(+), 147 deletions(-) create mode 100644 schema/json/schema-10.0.1.json diff --git a/go.mod b/go.mod index 4fdfd2d7655..ab4219ff04f 100644 --- a/go.mod +++ b/go.mod @@ -69,6 +69,7 @@ require ( github.com/google/go-containerregistry v0.16.1 github.com/google/licensecheck v0.3.1 github.com/invopop/jsonschema v0.7.0 + github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b github.com/opencontainers/go-digest v1.0.0 github.com/saferwall/pe v1.4.4 diff --git a/go.sum b/go.sum index e483614ab9c..ae40a3b0f62 100644 --- a/go.sum +++ b/go.sum @@ -428,6 +428,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 h1:WdAeg/imY2JFPc/9CST4bZ80nNJbiBFCAdSZCSgrS5Y= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953/go.mod h1:6o+UrvuZWc4UTyBhQf0LGjW9Ld7qJxLz/OqvSOWWlEc= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= diff --git a/internal/constants.go b/internal/constants.go index 354a54274e6..259b2d77c8f 100644 --- a/internal/constants.go +++ b/internal/constants.go @@ -6,5 +6,5 @@ const ( // JSONSchemaVersion is the current schema version output by the JSON encoder // This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment. - JSONSchemaVersion = "10.0.0" + JSONSchemaVersion = "10.0.1" ) diff --git a/schema/json/schema-10.0.1.json b/schema/json/schema-10.0.1.json new file mode 100644 index 00000000000..730db95eb65 --- /dev/null +++ b/schema/json/schema-10.0.1.json @@ -0,0 +1,1929 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "anchore.io/schema/syft/json/10.0.1/document", + "$ref": "#/$defs/Document", + "$defs": { + "AlpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "gid": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "size": { + "type": "string" + }, + "link": { + "type": "string" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object" + }, + "AlpmMetadata": { + "properties": { + "basepackage": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "packager": { + "type": "string" + }, + "url": { + "type": "string" + }, + "validation": { + "type": "string" + }, + "reason": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "backup": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "basepackage", + "package", + "version", + "description", + "architecture", + "size", + "packager", + "url", + "validation", + "reason", + "files", + "backup" + ] + }, + "ApkFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "ownerUid": { + "type": "string" + }, + "ownerGid": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "ApkMetadata": { + "properties": { + "package": { + "type": "string" + }, + "originPackage": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "version": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "url": { + "type": "string" + }, + "description": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "installedSize": { + "type": "integer" + }, + "pullDependencies": { + "items": { + "type": "string" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pullChecksum": { + "type": "string" + }, + "gitCommitOfApkPort": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/ApkFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "originPackage", + "maintainer", + "version", + "architecture", + "url", + "description", + "size", + "installedSize", + "pullDependencies", + "provides", + "pullChecksum", + "gitCommitOfApkPort", + "files" + ] + }, + "BinaryMetadata": { + "properties": { + "matches": { + "items": { + "$ref": "#/$defs/ClassifierMatch" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "matches" + ] + }, + "CargoPackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + }, + "checksum": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "checksum", + "dependencies" + ] + }, + "ClassifierMatch": { + "properties": { + "classifier": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Location" + } + }, + "type": "object", + "required": [ + "classifier", + "location" + ] + }, + "CocoapodsMetadata": { + "properties": { + "checksum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "checksum" + ] + }, + "ConanLockMetadata": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + }, + "prev": { + "type": "string" + }, + "requires": { + "type": "string" + }, + "build_requires": { + "type": "string" + }, + "py_requires": { + "type": "string" + }, + "options": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "ConanMetadata": { + "properties": { + "ref": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "Coordinates": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "DartPubMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "hosted_url": { + "type": "string" + }, + "vcs_url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Descriptor": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "configuration": true + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Digest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "Document": { + "properties": { + "artifacts": { + "items": { + "$ref": "#/$defs/Package" + }, + "type": "array" + }, + "artifactRelationships": { + "items": { + "$ref": "#/$defs/Relationship" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/File" + }, + "type": "array" + }, + "secrets": { + "items": { + "$ref": "#/$defs/Secrets" + }, + "type": "array" + }, + "source": { + "$ref": "#/$defs/Source" + }, + "distro": { + "$ref": "#/$defs/LinuxRelease" + }, + "descriptor": { + "$ref": "#/$defs/Descriptor" + }, + "schema": { + "$ref": "#/$defs/Schema" + } + }, + "type": "object", + "required": [ + "artifacts", + "artifactRelationships", + "source", + "distro", + "descriptor", + "schema" + ] + }, + "DotnetDepsMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "path": { + "type": "string" + }, + "sha512": { + "type": "string" + }, + "hashPath": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "path", + "sha512", + "hashPath" + ] + }, + "DotnetPortableExecutableMetadata": { + "properties": { + "assemblyVersion": { + "type": "string" + }, + "legalCopyright": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "internalName": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "productName": { + "type": "string" + }, + "productVersion": { + "type": "string" + } + }, + "type": "object", + "required": [ + "assemblyVersion", + "legalCopyright", + "companyName", + "productName", + "productVersion" + ] + }, + "DpkgFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "isConfigFile": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "path", + "isConfigFile" + ] + }, + "DpkgMetadata": { + "properties": { + "package": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/DpkgFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "source", + "version", + "sourceVersion", + "architecture", + "maintainer", + "installedSize", + "files" + ] + }, + "File": { + "properties": { + "id": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Coordinates" + }, + "metadata": { + "$ref": "#/$defs/FileMetadataEntry" + }, + "contents": { + "type": "string" + }, + "digests": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "id", + "location" + ] + }, + "FileMetadataEntry": { + "properties": { + "mode": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "linkDestination": { + "type": "string" + }, + "userID": { + "type": "integer" + }, + "groupID": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "mode", + "type", + "userID", + "groupID", + "mimeType", + "size" + ] + }, + "GemMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "GolangBinMetadata": { + "properties": { + "goBuildSettings": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "goCompiledVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "h1Digest": { + "type": "string" + }, + "mainModule": { + "type": "string" + }, + "goCryptoSettings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "goCompiledVersion", + "architecture" + ] + }, + "GolangModMetadata": { + "properties": { + "h1Digest": { + "type": "string" + } + }, + "type": "object" + }, + "HackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "snapshotURL": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "IDLikes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "JavaManifest": { + "properties": { + "main": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "namedSections": { + "patternProperties": { + ".*": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "JavaMetadata": { + "properties": { + "virtualPath": { + "type": "string" + }, + "manifest": { + "$ref": "#/$defs/JavaManifest" + }, + "pomProperties": { + "$ref": "#/$defs/PomProperties" + }, + "pomProject": { + "$ref": "#/$defs/PomProject" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "virtualPath" + ] + }, + "KbPackageMetadata": { + "properties": { + "product_id": { + "type": "string" + }, + "kb": { + "type": "string" + } + }, + "type": "object", + "required": [ + "product_id", + "kb" + ] + }, + "License": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "urls": { + "items": { + "type": "string" + }, + "type": "array" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type", + "urls", + "locations" + ] + }, + "LinuxKernelMetadata": { + "properties": { + "name": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extendedVersion": { + "type": "string" + }, + "buildTime": { + "type": "string" + }, + "author": { + "type": "string" + }, + "format": { + "type": "string" + }, + "rwRootFS": { + "type": "boolean" + }, + "swapDevice": { + "type": "integer" + }, + "rootDevice": { + "type": "integer" + }, + "videoMode": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "architecture", + "version" + ] + }, + "LinuxKernelModuleMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "license": { + "type": "string" + }, + "kernelVersion": { + "type": "string" + }, + "versionMagic": { + "type": "string" + }, + "parameters": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/LinuxKernelModuleParameter" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "LinuxKernelModuleParameter": { + "properties": { + "type": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "type": "object" + }, + "LinuxRelease": { + "properties": { + "prettyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "idLike": { + "$ref": "#/$defs/IDLikes" + }, + "version": { + "type": "string" + }, + "versionID": { + "type": "string" + }, + "versionCodename": { + "type": "string" + }, + "buildID": { + "type": "string" + }, + "imageID": { + "type": "string" + }, + "imageVersion": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "variantID": { + "type": "string" + }, + "homeURL": { + "type": "string" + }, + "supportURL": { + "type": "string" + }, + "bugReportURL": { + "type": "string" + }, + "privacyPolicyURL": { + "type": "string" + }, + "cpeName": { + "type": "string" + }, + "supportEnd": { + "type": "string" + } + }, + "type": "object" + }, + "Location": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + }, + "annotations": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "MixLockMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "NixStoreMetadata": { + "properties": { + "outputHash": { + "type": "string" + }, + "output": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "outputHash", + "files" + ] + }, + "NpmPackageJSONMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "private": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "homepage", + "description", + "url", + "private" + ] + }, + "NpmPackageLockJSONMetadata": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "Package": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "foundBy": { + "type": "string" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + }, + "licenses": { + "$ref": "#/$defs/licenses" + }, + "language": { + "type": "string" + }, + "cpes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "purl": { + "type": "string" + }, + "metadataType": { + "type": "string" + }, + "metadata": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/AlpmMetadata" + }, + { + "$ref": "#/$defs/ApkMetadata" + }, + { + "$ref": "#/$defs/BinaryMetadata" + }, + { + "$ref": "#/$defs/CargoPackageMetadata" + }, + { + "$ref": "#/$defs/CocoapodsMetadata" + }, + { + "$ref": "#/$defs/ConanLockMetadata" + }, + { + "$ref": "#/$defs/ConanMetadata" + }, + { + "$ref": "#/$defs/DartPubMetadata" + }, + { + "$ref": "#/$defs/DotnetDepsMetadata" + }, + { + "$ref": "#/$defs/DotnetPortableExecutableMetadata" + }, + { + "$ref": "#/$defs/DpkgMetadata" + }, + { + "$ref": "#/$defs/GemMetadata" + }, + { + "$ref": "#/$defs/GolangBinMetadata" + }, + { + "$ref": "#/$defs/GolangModMetadata" + }, + { + "$ref": "#/$defs/HackageMetadata" + }, + { + "$ref": "#/$defs/JavaMetadata" + }, + { + "$ref": "#/$defs/KbPackageMetadata" + }, + { + "$ref": "#/$defs/LinuxKernelMetadata" + }, + { + "$ref": "#/$defs/LinuxKernelModuleMetadata" + }, + { + "$ref": "#/$defs/MixLockMetadata" + }, + { + "$ref": "#/$defs/NixStoreMetadata" + }, + { + "$ref": "#/$defs/NpmPackageJSONMetadata" + }, + { + "$ref": "#/$defs/NpmPackageLockJSONMetadata" + }, + { + "$ref": "#/$defs/PhpComposerJSONMetadata" + }, + { + "$ref": "#/$defs/PortageMetadata" + }, + { + "$ref": "#/$defs/PythonPackageMetadata" + }, + { + "$ref": "#/$defs/PythonPipfileLockMetadata" + }, + { + "$ref": "#/$defs/PythonRequirementsMetadata" + }, + { + "$ref": "#/$defs/RDescriptionFileMetadata" + }, + { + "$ref": "#/$defs/RebarLockMetadata" + }, + { + "$ref": "#/$defs/RpmMetadata" + }, + { + "$ref": "#/$defs/SwiftPackageManagerMetadata" + } + ] + } + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "foundBy", + "locations", + "licenses", + "language", + "cpes", + "purl" + ] + }, + "PhpComposerAuthors": { + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "PhpComposerExternalReference": { + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "shasum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "type", + "url", + "reference" + ] + }, + "PhpComposerJSONMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PomParent": { + "properties": { + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object", + "required": [ + "groupId", + "artifactId", + "version" + ] + }, + "PomProject": { + "properties": { + "path": { + "type": "string" + }, + "parent": { + "$ref": "#/$defs/PomParent" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "groupId", + "artifactId", + "version", + "name" + ] + }, + "PomProperties": { + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "extraFields": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "name", + "groupId", + "artifactId", + "version" + ] + }, + "PortageFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PortageMetadata": { + "properties": { + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/PortageFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "installedSize", + "files" + ] + }, + "PythonDirectURLOriginInfo": { + "properties": { + "url": { + "type": "string" + }, + "commitId": { + "type": "string" + }, + "vcs": { + "type": "string" + } + }, + "type": "object", + "required": [ + "url" + ] + }, + "PythonFileDigest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "PythonFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/PythonFileDigest" + }, + "size": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonPackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/PythonFileRecord" + }, + "type": "array" + }, + "sitePackagesRootPath": { + "type": "string" + }, + "topLevelPackages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "directUrlOrigin": { + "$ref": "#/$defs/PythonDirectURLOriginInfo" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "platform", + "sitePackagesRootPath" + ] + }, + "PythonPipfileLockMetadata": { + "properties": { + "hashes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "index": { + "type": "string" + } + }, + "type": "object", + "required": [ + "hashes", + "index" + ] + }, + "PythonRequirementsMetadata": { + "properties": { + "name": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + }, + "versionConstraint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "markers": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "versionConstraint" + ] + }, + "RDescriptionFileMetadata": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "url": { + "items": { + "type": "string" + }, + "type": "array" + }, + "repository": { + "type": "string" + }, + "built": { + "type": "string" + }, + "needsCompilation": { + "type": "boolean" + }, + "imports": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "suggests": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "RebarLockMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "Relationship": { + "properties": { + "parent": { + "type": "string" + }, + "child": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "parent", + "child", + "type" + ] + }, + "RpmMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmdbFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "modularityLabel", + "files" + ] + }, + "RpmdbFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "userName": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "flags": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "mode", + "size", + "digest", + "userName", + "groupName", + "flags" + ] + }, + "Schema": { + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "version", + "url" + ] + }, + "SearchResult": { + "properties": { + "classification": { + "type": "string" + }, + "lineNumber": { + "type": "integer" + }, + "lineOffset": { + "type": "integer" + }, + "seekPosition": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "classification", + "lineNumber", + "lineOffset", + "seekPosition", + "length" + ] + }, + "Secrets": { + "properties": { + "location": { + "$ref": "#/$defs/Coordinates" + }, + "secrets": { + "items": { + "$ref": "#/$defs/SearchResult" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "location", + "secrets" + ] + }, + "Source": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "metadata" + ] + }, + "SwiftPackageManagerMetadata": { + "properties": { + "revision": { + "type": "string" + } + }, + "type": "object", + "required": [ + "revision" + ] + }, + "licenses": { + "items": { + "$ref": "#/$defs/License" + }, + "type": "array" + } + } +} diff --git a/syft/pkg/cataloger/golang/package.go b/syft/pkg/cataloger/golang/package.go index 30ba083b48f..37942563bf3 100644 --- a/syft/pkg/cataloger/golang/package.go +++ b/syft/pkg/cataloger/golang/package.go @@ -11,7 +11,7 @@ import ( "github.com/anchore/syft/syft/pkg" ) -func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, locations ...file.Location) pkg.Package { +func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, cryptoSettings []string, locations ...file.Location) pkg.Package { if dep.Replace != nil { dep = dep.Replace } @@ -36,6 +36,7 @@ func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debu Architecture: architecture, BuildSettings: buildSettings, MainModule: mainModule, + GoCryptoSettings: cryptoSettings, }, } diff --git a/syft/pkg/cataloger/golang/parse_go_binary.go b/syft/pkg/cataloger/golang/parse_go_binary.go index 89ed4ba0742..6da185839e3 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary.go +++ b/syft/pkg/cataloger/golang/parse_go_binary.go @@ -66,7 +66,7 @@ func (c *goBinaryCataloger) parseGoBinary(resolver file.Resolver, _ *generic.Env return pkgs, nil, nil } -func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *debug.BuildInfo, arch string, location file.Location) pkg.Package { +func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location) pkg.Package { gbs := getBuildSettings(mod.Settings) main := c.newGoBinaryPackage( resolver, @@ -75,6 +75,7 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *debug mod.GoVersion, arch, gbs, + mod.cryptoSettings, location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ) @@ -153,7 +154,7 @@ func extractVersionFromLDFlags(ldflags string) (majorVersion string, fullVersion // getArchs finds a binary architecture by two ways: // 1) reading build info from binaries compiled by go1.18+ // 2) reading file headers from binaries compiled by < go1.18 -func getArchs(readers []io.ReaderAt, builds []*debug.BuildInfo) []string { +func getArchs(readers []io.ReaderAt, builds []*extendedBuildInfo) []string { if len(readers) != len(builds) { log.Trace("golang cataloger: bin parsing: number of builds and readers doesn't match") return nil @@ -255,7 +256,7 @@ func createMainModuleFromPath(path string) (mod debug.Module) { return } -func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file.Location, mod *debug.BuildInfo, arch string) []pkg.Package { +func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file.Location, mod *extendedBuildInfo, arch string) []pkg.Package { var pkgs []pkg.Package if mod == nil { return pkgs @@ -277,6 +278,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file mod.GoVersion, arch, nil, + mod.cryptoSettings, location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ) if pkg.IsValid(&p) { diff --git a/syft/pkg/cataloger/golang/parse_go_binary_test.go b/syft/pkg/cataloger/golang/parse_go_binary_test.go index d578b46adaa..9014445649c 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary_test.go +++ b/syft/pkg/cataloger/golang/parse_go_binary_test.go @@ -155,7 +155,7 @@ func TestBuildGoPkgInfo(t *testing.T) { tests := []struct { name string - mod *debug.BuildInfo + mod *extendedBuildInfo arch string expected []pkg.Package }{ @@ -166,16 +166,18 @@ func TestBuildGoPkgInfo(t *testing.T) { }, { name: "package without name", - mod: &debug.BuildInfo{ - Deps: []*debug.Module{ - { - Path: "github.com/adrg/xdg", - }, - { - Path: "", - Version: "v0.2.1", + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + Deps: []*debug.Module{ + { + Path: "github.com/adrg/xdg", + }, + { + Path: "", + Version: "v0.2.1", + }, }, - }, + }, nil, }, expected: []pkg.Package{ { @@ -198,26 +200,28 @@ func TestBuildGoPkgInfo(t *testing.T) { }, { name: "buildGoPkgInfo parses a blank mod and returns no packages", - mod: &debug.BuildInfo{}, + mod: &extendedBuildInfo{&debug.BuildInfo{}, nil}, expected: []pkg.Package(nil), }, { name: "parse a mod without main module", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - }, - Deps: []*debug.Module{ - { - Path: "github.com/adrg/xdg", - Version: "v0.2.1", - Sum: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=", + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, }, - }, + Deps: []*debug.Module{ + { + Path: "github.com/adrg/xdg", + Version: "v0.2.1", + Sum: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=", + }, + }, + }, nil, }, expected: []pkg.Package{ { @@ -246,14 +250,16 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse a mod with path but no main module", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - }, - Path: "github.com/a/b/c", + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + }, + Path: "github.com/a/b/c", + }, []string{"boringcrypto + fips"}, }, expected: []pkg.Package{ { @@ -280,7 +286,8 @@ func TestBuildGoPkgInfo(t *testing.T) { "GOARCH": "amd64", "GOOS": "darwin", }, - MainModule: "github.com/a/b/c", + MainModule: "github.com/a/b/c", + GoCryptoSettings: []string{"boringcrypto + fips"}, }, }, }, @@ -288,31 +295,35 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse a mod without packages", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + }, + }, nil, }, expected: []pkg.Package{unmodifiedMain}, }, { name: "parse main mod and replace devel pseudo version and ldflags exists (but contains no version)", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, - {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, - {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, + {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, + {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -349,17 +360,19 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse main mod and replace devel version with one from ldflags with vcs. build settings", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, - {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, - {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, + {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, + {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -396,15 +409,17 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse main mod and replace devel version with one from ldflags without any vcs. build settings", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -439,15 +454,17 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse main mod and replace devel version with one from ldflags main.version without any vcs. build settings", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -482,15 +499,17 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse main mod and replace devel version with one from ldflags main.Version without any vcs. build settings", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -525,16 +544,18 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse main mod and replace devel version with a pseudo version", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, - {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, - }, + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + {Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"}, + {Key: "vcs.time", Value: "2022-10-14T19:54:57Z"}, + }, + }, nil, }, expected: []pkg.Package{ { @@ -570,26 +591,28 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse a populated mod string and returns packages but no source info", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - }, - Deps: []*debug.Module{ - { - Path: "github.com/adrg/xdg", - Version: "v0.2.1", - Sum: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=", + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, }, - { - Path: "github.com/anchore/client-go", - Version: "v0.0.0-20210222170800-9c70f9b80bcf", - Sum: "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=", + Deps: []*debug.Module{ + { + Path: "github.com/adrg/xdg", + Version: "v0.2.1", + Sum: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=", + }, + { + Path: "github.com/anchore/client-go", + Version: "v0.0.0-20210222170800-9c70f9b80bcf", + Sum: "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=", + }, }, - }, + }, nil, }, expected: []pkg.Package{ { @@ -642,31 +665,33 @@ func TestBuildGoPkgInfo(t *testing.T) { { name: "parse a populated mod string and returns packages when a replace directive exists", arch: archDetails, - mod: &debug.BuildInfo{ - GoVersion: goCompiledVersion, - Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, - Settings: []debug.BuildSetting{ - {Key: "GOARCH", Value: archDetails}, - {Key: "GOOS", Value: "darwin"}, - {Key: "GOAMD64", Value: "v1"}, - }, - Deps: []*debug.Module{ - { - Path: "golang.org/x/sys", - Version: "v0.0.0-20211006194710-c8a6f5223071", - Sum: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=", + mod: &extendedBuildInfo{ + &debug.BuildInfo{ + GoVersion: goCompiledVersion, + Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"}, + Settings: []debug.BuildSetting{ + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, }, - { - Path: "golang.org/x/term", - Version: "v0.0.0-20210927222741-03fcf44c2211", - Sum: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=", - Replace: &debug.Module{ + Deps: []*debug.Module{ + { + Path: "golang.org/x/sys", + Version: "v0.0.0-20211006194710-c8a6f5223071", + Sum: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=", + }, + { Path: "golang.org/x/term", - Version: "v0.0.0-20210916214954-140adaaadfaf", - Sum: "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=", + Version: "v0.0.0-20210927222741-03fcf44c2211", + Sum: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=", + Replace: &debug.Module{ + Path: "golang.org/x/term", + Version: "v0.0.0-20210916214954-140adaaadfaf", + Sum: "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=", + }, }, }, - }, + }, nil, }, expected: []pkg.Package{ { diff --git a/syft/pkg/cataloger/golang/scan_binary.go b/syft/pkg/cataloger/golang/scan_binary.go index c010b2a884e..b19e242740f 100644 --- a/syft/pkg/cataloger/golang/scan_binary.go +++ b/syft/pkg/cataloger/golang/scan_binary.go @@ -6,12 +6,19 @@ import ( "io" "runtime/debug" + "github.com/kastenhq/goversion/version" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/pkg/cataloger/internal/unionreader" ) +type extendedBuildInfo struct { + *debug.BuildInfo + cryptoSettings []string +} + // scanFile scans file to try to report the Go and module versions. -func scanFile(reader unionreader.UnionReader, filename string) ([]*debug.BuildInfo, []string) { +func scanFile(reader unionreader.UnionReader, filename string) ([]*extendedBuildInfo, []string) { // NOTE: multiple readers are returned to cover universal binaries, which are files // with more than one binary readers, err := unionreader.GetReaders(reader) @@ -20,7 +27,7 @@ func scanFile(reader unionreader.UnionReader, filename string) ([]*debug.BuildIn return nil, nil } - var builds []*debug.BuildInfo + var builds []*extendedBuildInfo for _, r := range readers { bi, err := getBuildInfo(r) if err != nil { @@ -30,7 +37,14 @@ func scanFile(reader unionreader.UnionReader, filename string) ([]*debug.BuildIn if bi == nil { continue } - builds = append(builds, bi) + + v, err := getCryptoInformation(r) + if err != nil { + log.WithFields("file", filename, "error", err).Trace("unable to read golang version info") + continue + } + + builds = append(builds, &extendedBuildInfo{bi, v}) } archs := getArchs(readers, builds) @@ -38,6 +52,29 @@ func scanFile(reader unionreader.UnionReader, filename string) ([]*debug.BuildIn return builds, archs } +func getCryptoInformation(reader io.ReaderAt) ([]string, error) { + v, err := version.ReadExeFromReader(reader) + if err != nil { + return nil, err + } + + return getCryptoSettingsFromVersion(v), nil +} + +func getCryptoSettingsFromVersion(v version.Version) []string { + cryptoSettings := []string{} + if v.StandardCrypto { + cryptoSettings = append(cryptoSettings, "standard-crypto") + } + if v.BoringCrypto { + cryptoSettings = append(cryptoSettings, "boring-crypto") + } + if v.FIPSOnly { + cryptoSettings = append(cryptoSettings, "crypto/tls/fipsonly") + } + return cryptoSettings +} + func getBuildInfo(r io.ReaderAt) (bi *debug.BuildInfo, err error) { defer func() { if r := recover(); r != nil { diff --git a/syft/pkg/cataloger/golang/scan_binary_test.go b/syft/pkg/cataloger/golang/scan_binary_test.go index 8a55411377f..a1c8dad7e94 100644 --- a/syft/pkg/cataloger/golang/scan_binary_test.go +++ b/syft/pkg/cataloger/golang/scan_binary_test.go @@ -6,6 +6,7 @@ import ( "runtime/debug" "testing" + "github.com/kastenhq/goversion/version" "github.com/stretchr/testify/assert" ) @@ -38,3 +39,72 @@ func Test_getBuildInfo(t *testing.T) { }) } } + +func Test_getCryptoSettingsFromVersion(t *testing.T) { + for _, tt := range []struct { + name string + version version.Version + result []string + }{ + { + name: "standard crypto", + version: version.Version{ + StandardCrypto: true, + }, + result: []string{"standard-crypto"}, + }, + { + name: "boring crypto", + version: version.Version{ + BoringCrypto: true, + }, + result: []string{"boring-crypto"}, + }, + { // Should never see this. Boring crypto is required for fipsonly + name: "fipsonly", + version: version.Version{ + FIPSOnly: true, + }, + result: []string{"crypto/tls/fipsonly"}, + }, + { + name: "boring crypto and fipsonly", + version: version.Version{ + BoringCrypto: true, + FIPSOnly: true, + }, + result: []string{"boring-crypto", "crypto/tls/fipsonly"}, + }, + { // Should never see this. + name: "boring and standard crypto!", + version: version.Version{ + BoringCrypto: true, + StandardCrypto: true, + }, + result: []string{"boring-crypto", "standard-crypto"}, + }, + { // Should never see this. Boring crypto is required for fipsonly + name: "fipsonly and standard crypto!", + version: version.Version{ + FIPSOnly: true, + StandardCrypto: true, + }, + result: []string{"crypto/tls/fipsonly", "standard-crypto"}, + }, + + { // Should never see this. Boring crypto is required for fipsonly + name: "fipsonly boringcrypto and standard crypto!", + version: version.Version{ + FIPSOnly: true, + StandardCrypto: true, + BoringCrypto: true, + }, + result: []string{"crypto/tls/fipsonly", "standard-crypto", "boring-crypto"}, + }, + } { + t.Run(tt.name, func(t *testing.T) { + res := getCryptoSettingsFromVersion(tt.version) + assert.ElementsMatch(t, res, tt.result) + }) + } +} diff --git a/syft/pkg/golang_metadata.go b/syft/pkg/golang_metadata.go index fd7309588bb..791b7fcc3f1 100644 --- a/syft/pkg/golang_metadata.go +++ b/syft/pkg/golang_metadata.go @@ -7,6 +7,7 @@ type GolangBinMetadata struct { Architecture string `json:"architecture" cyclonedx:"architecture"` H1Digest string `json:"h1Digest,omitempty" cyclonedx:"h1Digest"` MainModule string `json:"mainModule,omitempty" cyclonedx:"mainModule"` + GoCryptoSettings []string `json:"goCryptoSettings,omitempty" cyclonedx:"goCryptoSettings"` } // GolangModMetadata represents all captured data for a Golang source scan with go.mod/go.sum