From d4bacccf365be9faceb4141fb62af217015e7b78 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Wed, 26 Apr 2023 12:14:16 +0200 Subject: [PATCH] feat: add support for ingesting VEX documents in CSAF format Signed-off-by: Ulf Lilleengen --- go.mod | 5 +- go.sum | 8 +- .../testdata/exampledata/rhsa-csaf.json | 942 ++++++++++++++++++ internal/testing/testdata/testdata.go | 57 ++ pkg/assembler/assembler.go | 13 + pkg/assembler/clients/helpers/assembler.go | 58 ++ pkg/handler/processor/csaf/csaf.go | 57 ++ pkg/handler/processor/guesser/guesser_test.go | 10 + pkg/handler/processor/guesser/type_csaf.go | 38 + pkg/handler/processor/guesser/type_guesser.go | 1 + pkg/handler/processor/process/process.go | 2 + pkg/handler/processor/processor.go | 1 + pkg/ingestor/parser/csaf/parser_csaf.go | 253 +++++ pkg/ingestor/parser/csaf/parser_csaf_test.go | 71 ++ pkg/ingestor/parser/parser.go | 2 + 15 files changed, 1514 insertions(+), 4 deletions(-) create mode 100644 internal/testing/testdata/exampledata/rhsa-csaf.json create mode 100644 pkg/handler/processor/csaf/csaf.go create mode 100644 pkg/handler/processor/guesser/type_csaf.go create mode 100644 pkg/ingestor/parser/csaf/parser_csaf.go create mode 100644 pkg/ingestor/parser/csaf/parser_csaf_test.go diff --git a/go.mod b/go.mod index f841f215bf..e921bc86f9 100644 --- a/go.mod +++ b/go.mod @@ -124,7 +124,7 @@ require ( github.com/sergi/go-diff v1.2.0 // indirect github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.2 // indirect github.com/skeema/knownhosts v1.1.0 // indirect github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89 // indirect github.com/spf13/afero v1.9.3 // indirect @@ -172,6 +172,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/nats-io/nats-server/v2 v2.9.17 github.com/nats-io/nats.go v1.25.0 + github.com/openvex/go-vex v0.2.0 github.com/ossf/scorecard/v4 v4.10.5 github.com/package-url/packageurl-go v0.1.1-0.20220428063043-89078438f170 github.com/pkg/errors v0.9.1 @@ -184,3 +185,5 @@ require ( golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 gopkg.in/yaml.v3 v3.0.1 ) + +replace github.com/openvex/go-vex => github.com/openvex/go-vex v0.2.1-0.20230519031452-e31eaf94ec95 diff --git a/go.sum b/go.sum index 814b406c5c..ae883fd712 100644 --- a/go.sum +++ b/go.sum @@ -1738,6 +1738,8 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openvex/go-vex v0.2.1-0.20230519031452-e31eaf94ec95 h1:KaiVXuu3VOhiuDXhe4OiJ+GKpoy1M+ZQEu84If/LEIA= +github.com/openvex/go-vex v0.2.1-0.20230519031452-e31eaf94ec95/go.mod h1:Efz888wbK/6oFFyJfhfz6MbJs4fOmZmT+Hmmedw5Wmk= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/ossf/scorecard/v4 v4.10.5 h1:V3ZxLj2rEwAllytkIfVQXEWr3Nl9Ad9NkxZSMaS/+iA= github.com/ossf/scorecard/v4 v4.10.5/go.mod h1:3s+OtLNXoqpQCyBpV0XuCjV95uJHMUhRjwEg9xIKZ+k= @@ -1909,8 +1911,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1980,7 +1982,7 @@ github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= diff --git a/internal/testing/testdata/exampledata/rhsa-csaf.json b/internal/testing/testdata/exampledata/rhsa-csaf.json new file mode 100644 index 0000000000..cb71eb7a8b --- /dev/null +++ b/internal/testing/testdata/exampledata/rhsa-csaf.json @@ -0,0 +1,942 @@ +{ + "document": { + "aggregate_severity": { + "namespace": "https://access.redhat.com/security/updates/classification/", + "text": "Important" + }, + "category": "csaf_vex", + "csaf_version": "2.0", + "distribution": { + "text": "Copyright \u00a9 2023 Red Hat, Inc. All rights reserved.", + "tlp": { + "label": "WHITE", + "url": "https://www.first.org/tlp/" + } + }, + "lang": "en", + "notes": [ + { + "category": "summary", + "text": "An update for openssl is now available for Red Hat Enterprise Linux 8.6 Extended Update Support.\n\nRed Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.", + "title": "Topic" + }, + { + "category": "general", + "text": "OpenSSL is a toolkit that implements the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols, as well as a full-strength general-purpose cryptography library.\n\nSecurity Fix(es):\n\n* openssl: X.400 address type confusion in X.509 GeneralName (CVE-2023-0286)\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.", + "title": "Details" + }, + { + "category": "legal_disclaimer", + "text": "This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original.", + "title": "Terms of Use" + } + ], + "publisher": { + "category": "vendor", + "contact_details": "https://access.redhat.com/security/team/contact/", + "issuing_authority": "Red Hat Product Security is responsible for vulnerability handling across all Red Hat offerings.", + "name": "Red Hat Product Security", + "namespace": "https://www.redhat.com" + }, + "references": [ + { + "category": "self", + "summary": "https://access.redhat.com/errata/RHSA-2023:1441", + "url": "https://access.redhat.com/errata/RHSA-2023:1441" + }, + { + "category": "external", + "summary": "https://access.redhat.com/security/updates/classification/#important", + "url": "https://access.redhat.com/security/updates/classification/#important" + }, + { + "category": "self", + "summary": "Canonical URL", + "url": "https://access.redhat.com/security/data/csaf/v2/advisories/2023/rhsa-2023_1441.json" + } + ], + "title": "Red Hat Security Advisory: openssl security update", + "tracking": { + "current_release_date": "2023-03-23T11:14:00Z", + "generator": { + "date": "2023-03-23T16:14:00Z", + "engine": { + "name": "Red Hat SDEngine", + "version": "3.12.2" + } + }, + "id": "RHSA-2023:1441", + "initial_release_date": "2023-03-23T11:14:00Z", + "revision_history": [ + { + "date": "2023-03-23T11:14:00Z", + "number": "1", + "summary": "Current version" + } + ], + "status": "final", + "version": "1" + } + }, + "product_tree": { + "branches": [ + { + "branches": [ + { + "branches": [ + { + "category": "product_name", + "name": "Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product": { + "name": "Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS", + "product_identification_helper": { + "cpe": "cpe:/o:redhat:rhel_eus:8.6::baseos" + } + } + } + ], + "category": "product_family", + "name": "Red Hat Enterprise Linux" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-1:1.1.1k-8.el8_6.src", + "product": { + "name": "openssl-1:1.1.1k-8.el8_6.src", + "product_id": "openssl-1:1.1.1k-8.el8_6.src" + } + } + ], + "category": "architecture", + "name": "src" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-debugsource-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-devel-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-libs-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64" + } + }, + { + "category": "product_version", + "name": "openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "product": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "product_id": "openssl-perl-1:1.1.1k-8.el8_6.aarch64" + } + } + ], + "category": "architecture", + "name": "aarch64" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-devel-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-libs-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le" + } + }, + { + "category": "product_version", + "name": "openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "product": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "product_id": "openssl-perl-1:1.1.1k-8.el8_6.ppc64le" + } + } + ], + "category": "architecture", + "name": "ppc64le" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-1:1.1.1k-7.el8_6.x86_64", + "product": { + "name": "openssl-1:1.1.1k-7.el8_6.x86_64", + "product_id": "openssl-1:1.1.1k-7.el8_6.x86_64", + "product_identification_helper": { + "purl": "pkg:rpm/redhat/openssl@1.1.1k-7.el8_6?arch=x86_64&epoch=1" + } + } + }, + { + "category": "product_version", + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-debugsource-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-devel-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-libs-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64" + } + }, + { + "category": "product_version", + "name": "openssl-perl-1:1.1.1k-8.el8_6.x86_64", + "product": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.x86_64", + "product_id": "openssl-perl-1:1.1.1k-8.el8_6.x86_64" + } + } + ], + "category": "architecture", + "name": "x86_64" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "product": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "product_id": "openssl-debuginfo-1:1.1.1k-8.el8_6.i686" + } + }, + { + "category": "product_version", + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "product": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "product_id": "openssl-debugsource-1:1.1.1k-8.el8_6.i686" + } + }, + { + "category": "product_version", + "name": "openssl-devel-1:1.1.1k-8.el8_6.i686", + "product": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.i686", + "product_id": "openssl-devel-1:1.1.1k-8.el8_6.i686" + } + }, + { + "category": "product_version", + "name": "openssl-libs-1:1.1.1k-8.el8_6.i686", + "product": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.i686", + "product_id": "openssl-libs-1:1.1.1k-8.el8_6.i686" + } + }, + { + "category": "product_version", + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "product": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "product_id": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686" + } + } + ], + "category": "architecture", + "name": "i686" + }, + { + "branches": [ + { + "category": "product_version", + "name": "openssl-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-debuginfo-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-debugsource-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-devel-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-devel-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-libs-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-libs-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x" + } + }, + { + "category": "product_version", + "name": "openssl-perl-1:1.1.1k-8.el8_6.s390x", + "product": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.s390x", + "product_id": "openssl-perl-1:1.1.1k-8.el8_6.s390x" + } + } + ], + "category": "architecture", + "name": "s390x" + } + ], + "category": "vendor", + "name": "Red Hat" + } + ], + "relationships": [ + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-8.el8_6.src as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.src" + }, + "product_reference": "openssl-1:1.1.1k-8.el8_6.src", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-7.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-7.el8_6.x86_64" + }, + "product_reference": "openssl-1:1.1.1k-7.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.i686 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.i686" + }, + "product_reference": "openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.i686 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.i686" + }, + "product_reference": "openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-debugsource-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.i686 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.i686" + }, + "product_reference": "openssl-devel-1:1.1.1k-8.el8_6.i686", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-devel-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-devel-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.i686 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.i686" + }, + "product_reference": "openssl-libs-1:1.1.1k-8.el8_6.i686", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-libs-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686" + }, + "product_reference": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.aarch64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.aarch64" + }, + "product_reference": "openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.ppc64le as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.ppc64le" + }, + "product_reference": "openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.s390x as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.s390x" + }, + "product_reference": "openssl-perl-1:1.1.1k-8.el8_6.s390x", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + }, + { + "category": "default_component_of", + "full_product_name": { + "name": "openssl-perl-1:1.1.1k-8.el8_6.x86_64 as a component of Red Hat Enterprise Linux BaseOS EUS (v.8.6)", + "product_id": "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.x86_64" + }, + "product_reference": "openssl-perl-1:1.1.1k-8.el8_6.x86_64", + "relates_to_product_reference": "BaseOS-8.6.0.Z.EUS" + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2023-0286", + "cwe": { + "id": "CWE-704", + "name": "Incorrect Type Conversion or Cast" + }, + "discovery_date": "2023-01-25T00:00:00Z", + "ids": [ + { + "system_name": "Red Hat Bugzilla", + "text": "https://bugzilla.redhat.com/show_bug.cgi?id=2164440" + } + ], + "notes": [ + { + "category": "general", + "text": "The CVSS score(s) listed for this vulnerability do not reflect the associated product's status, and are included for informational purposes to better understand the severity of this vulnerability.", + "title": "CVSS score applicability" + }, + { + "category": "description", + "text": "A type confusion vulnerability was found in OpenSSL when OpenSSL X.400 addresses processing inside an X.509 GeneralName. When CRL checking is enabled (for example, the application sets the X509_V_FLAG_CRL_CHECK flag), this vulnerability may allow an attacker to pass arbitrary pointers to a memcmp call, enabling them to read memory contents or cause a denial of service. In most cases, the attack requires the attacker to provide both the certificate chain and CRL, of which neither needs a valid signature. If the attacker only controls one of these inputs, the other input must already contain an X.400 address as a CRL distribution point, which is uncommon. In this case, this vulnerability is likely only to affect applications that have implemented their own functionality for retrieving CRLs over a network.", + "title": "Vulnerability description" + }, + { + "category": "summary", + "text": "openssl: X.400 address type confusion in X.509 GeneralName", + "title": "Vulnerability summary" + } + ], + "product_status": { + "known_affected": [ + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-7.el8_6.x86_64" + ], + "fixed": [ + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.src", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.x86_64" + ] + }, + "references": [ + { + "category": "external", + "summary": "https://www.openssl.org/news/secadv/20230207.txt", + "url": "https://www.openssl.org/news/secadv/20230207.txt" + }, + { + "category": "external", + "summary": "CVE-2023-0286", + "url": "https://access.redhat.com/security/cve/CVE-2023-0286" + }, + { + "category": "external", + "summary": "bz#2164440: CVE-2023-0286 openssl: X.400 address type confusion in X.509 GeneralName", + "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2164440" + } + ], + "release_date": "2023-02-07T00:00:00Z", + "remediations": [ + { + "category": "vendor_fix", + "details": "For details on how to apply this update, which includes the changes described in this advisory, refer to:\n\nhttps://access.redhat.com/articles/11258\n\nFor the update to take effect, all services linked to the OpenSSL library must be restarted, or the system rebooted.", + "product_ids": [ + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.src", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-7.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.x86_64" + ], + "url": "https://access.redhat.com/errata/RHSA-2023:1441" + } + ], + "scores": [ + { + "cvss_v3": { + "attackComplexity": "HIGH", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 7.4, + "baseSeverity": "HIGH", + "confidentialityImpact": "HIGH", + "integrityImpact": "NONE", + "privilegesRequired": "NONE", + "scope": "UNCHANGED", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H", + "version": "3.1" + }, + "products": [ + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.src", + "BaseOS-8.6.0.Z.EUS:openssl-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-debugsource-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-devel-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.i686", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-libs-debuginfo-1:1.1.1k-8.el8_6.x86_64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.aarch64", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.ppc64le", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.s390x", + "BaseOS-8.6.0.Z.EUS:openssl-perl-1:1.1.1k-8.el8_6.x86_64" + ] + } + ], + "threats": [ + { + "category": "impact", + "date": "2023-01-25T00:00:00Z", + "details": "Important" + } + ], + "title": "CVE-2023-0286 openssl: X.400 address type confusion in X.509 GeneralName" + } + ] +} diff --git a/internal/testing/testdata/testdata.go b/internal/testing/testdata/testdata.go index 25f0a154d0..d7600e3f5d 100644 --- a/internal/testing/testdata/testdata.go +++ b/internal/testing/testdata/testdata.go @@ -1884,6 +1884,55 @@ var ( }, "UpdateTime":"2022-11-21T17:45:50.52Z" }` + + // CSAF + //go:embed exampledata/rhsa-csaf.json + CsafExampleRedHat []byte + + CsafVexIngest = []assembler.VexIngest{ + { + Pkg: &model.PkgInputSpec{ + Type: "rpm", + Namespace: strP("redhat"), + Name: "openssl", + Version: strP("1.1.1k-7.el8_6"), + Qualifiers: []model.PackageQualifierInputSpec{{Key: "arch", Value: "x86_64"}, {Key: "epoch", Value: "1"}}, + Subpath: strP(""), + }, + CVE: &model.CVEInputSpec{Year: 2023, CveId: "CVE-2023-0286"}, + VexData: &model.VexStatementInputSpec{ + Status: "AFFECTED", + VexJustification: "NOT_PROVIDED", + Statement: `For details on how to apply this update, which includes the changes described in this advisory, refer to: + +https://access.redhat.com/articles/11258 + +For the update to take effect, all services linked to the OpenSSL library must be restarted, or the system rebooted.`, + + KnownSince: parseRfc3339("2023-03-23T11:14:00Z"), + Origin: "RHSA-2023:1441", + }, + }, + } + CsafCertifyVulnIngest = []assembler.CertifyVulnIngest{ + { + Pkg: &model.PkgInputSpec{ + Type: "rpm", + Namespace: strP("redhat"), + Name: "openssl", + Version: strP("1.1.1k-7.el8_6"), + Qualifiers: []model.PackageQualifierInputSpec{ + {Key: "arch", Value: "x86_64"}, + {Key: "epoch", Value: "1"}, + }, + Subpath: strP(""), + }, + CVE: &model.CVEInputSpec{Year: 2023, CveId: "CVE-2023-0286"}, + VulnData: &model.VulnerabilityMetaDataInput{ + TimeScanned: parseRfc3339("2023-03-23T11:14:00Z"), + }, + }, + } ) func GuacNodeSliceEqual(slice1, slice2 []assembler.GuacNode) bool { @@ -2040,3 +2089,11 @@ func gLess(e1, e2 any) bool { func strP(s string) *string { return &s } + +func parseRfc3339(s string) time.Time { + time, err := time.Parse(time.RFC3339, s) + if err != nil { + panic(err) + } + return time +} diff --git a/pkg/assembler/assembler.go b/pkg/assembler/assembler.go index 0999f2d8e2..fec5dd65fe 100644 --- a/pkg/assembler/assembler.go +++ b/pkg/assembler/assembler.go @@ -157,6 +157,7 @@ type IngestPredicates struct { CertifyBad []CertifyBadIngest CertifyGood []CertifyGoodIngest HasSBOM []HasSBOMIngest + Vex []VexIngest } type CertifyScorecardIngest struct { @@ -247,5 +248,17 @@ type HasSBOMIngest struct { HasSBOM *generated.HasSBOMInputSpec } +type VexIngest struct { + // pkg or artifact is required + Pkg *generated.PkgInputSpec + Artifact *generated.ArtifactInputSpec + + // vulnerability should be either CVE or GHSA + CVE *generated.CVEInputSpec + GHSA *generated.GHSAInputSpec + + VexData *generated.VexStatementInputSpec +} + // AssemblerInput represents the inputs to add to the graph type AssemblerInput = IngestPredicates diff --git a/pkg/assembler/clients/helpers/assembler.go b/pkg/assembler/clients/helpers/assembler.go index 483626a5c2..8e60c605a1 100644 --- a/pkg/assembler/clients/helpers/assembler.go +++ b/pkg/assembler/clients/helpers/assembler.go @@ -80,6 +80,11 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble if err := ingestHasSBOM(ctx, gqlclient, p.HasSBOM); err != nil { return err } + + logger.Infof("assembling VEX : %v", len(p.Vex)) + if err := ingestVex(ctx, gqlclient, p.Vex); err != nil { + return err + } } return nil } @@ -212,6 +217,59 @@ func hasSourceAt(ctx context.Context, client graphql.Client, hsaList []assembler return nil } +func ingestVex(ctx context.Context, client graphql.Client, vis []assembler.VexIngest) error { + for _, vi := range vis { + if vi.CVE != nil && vi.GHSA != nil { + return fmt.Errorf("unable to create VexIngest with both CVE and GHSA specified") + } + + if vi.CVE == nil && vi.GHSA == nil { + return fmt.Errorf("unable to create VexIngest without either CVE or GHSA specified") + } + + if vi.Artifact != nil && vi.Pkg != nil { + return fmt.Errorf("unable to create VexIngest with both Pkg and Artifact specified") + } + + if vi.Artifact == nil && vi.Pkg == nil { + return fmt.Errorf("unable to create VexIngest without either Pkg or Artifact specified") + } + + if vi.CVE != nil { + if vi.Pkg != nil { + _, err := model.VexPackageAndCve(ctx, client, *vi.Pkg, *vi.CVE, *vi.VexData) + if err != nil { + return err + } + } + + if vi.Artifact != nil { + _, err := model.VexArtifactAndCve(ctx, client, *vi.Artifact, *vi.CVE, *vi.VexData) + if err != nil { + return err + } + } + } + + if vi.GHSA != nil { + if vi.Pkg != nil { + _, err := model.VEXPackageAndGhsa(ctx, client, *vi.Pkg, *vi.GHSA, *vi.VexData) + if err != nil { + return err + } + } + + if vi.Artifact != nil { + _, err := model.VexArtifactAndGhsa(ctx, client, *vi.Artifact, *vi.GHSA, *vi.VexData) + if err != nil { + return err + } + } + } + } + return nil +} + func ingestCertifyBad(ctx context.Context, client graphql.Client, badList []assembler.CertifyBadIngest) error { for _, bad := range badList { diff --git a/pkg/handler/processor/csaf/csaf.go b/pkg/handler/processor/csaf/csaf.go new file mode 100644 index 0000000000..202d5360cc --- /dev/null +++ b/pkg/handler/processor/csaf/csaf.go @@ -0,0 +1,57 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package csaf + +import ( + "encoding/json" + "fmt" + + "github.com/guacsec/guac/pkg/handler/processor" + "github.com/openvex/go-vex/pkg/csaf" +) + +// CSAFProcessor processes CSAF documents. +// Currently only supports CSAF 2.0 +type CSAFProcessor struct { +} + +func (p *CSAFProcessor) ValidateSchema(d *processor.Document) error { + if d.Type != processor.DocumentCsaf { + return fmt.Errorf("expected document type: %v, actual document type: %v", processor.DocumentCsaf, d.Type) + } + + switch d.Format { + case processor.FormatJSON: + var decoded csaf.CSAF + err := json.Unmarshal(d.Blob, &decoded) + return err + } + + return fmt.Errorf("unable to support parsing of SPDX document format: %v", d.Format) +} + +// Unpack takes in the document and tries to unpack it +// if there is a valid decomposition of sub-documents. +// +// Returns empty list and nil error if nothing to unpack +// Returns unpacked list and nil error if successfully unpacked +func (p *CSAFProcessor) Unpack(d *processor.Document) ([]*processor.Document, error) { + if d.Type != processor.DocumentCsaf { + return nil, fmt.Errorf("expected document type: %v, actual document type: %v", processor.DocumentCsaf, d.Type) + } + + return []*processor.Document{}, nil +} diff --git a/pkg/handler/processor/guesser/guesser_test.go b/pkg/handler/processor/guesser/guesser_test.go index 04c588ade3..49b89f81b8 100644 --- a/pkg/handler/processor/guesser/guesser_test.go +++ b/pkg/handler/processor/guesser/guesser_test.go @@ -199,6 +199,16 @@ func Test_GuessDocument(t *testing.T) { }, expectedType: processor.DocumentDepsDev, expectedFormat: processor.FormatJSON, + }, { + name: "valid CSAF Document", + document: &processor.Document{ + Blob: []byte(testdata.CsafExampleRedHat), + Type: processor.DocumentUnknown, + Format: processor.FormatUnknown, + SourceInformation: processor.SourceInformation{}, + }, + expectedType: processor.DocumentCsaf, + expectedFormat: processor.FormatJSON, }} for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/handler/processor/guesser/type_csaf.go b/pkg/handler/processor/guesser/type_csaf.go new file mode 100644 index 0000000000..ed38a3ee2c --- /dev/null +++ b/pkg/handler/processor/guesser/type_csaf.go @@ -0,0 +1,38 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package guesser + +import ( + "encoding/json" + + "github.com/guacsec/guac/pkg/handler/processor" + "github.com/openvex/go-vex/pkg/csaf" +) + +type csafTypeGuesser struct{} + +func (_ *csafTypeGuesser) GuessDocumentType(blob []byte, format processor.FormatType) processor.DocumentType { + switch format { + case processor.FormatJSON: + // Decode the BOM + var decoded csaf.CSAF + err := json.Unmarshal(blob, &decoded) + if err == nil && decoded.Document.Tracking.ID != "" { + return processor.DocumentCsaf + } + } + return processor.DocumentUnknown +} diff --git a/pkg/handler/processor/guesser/type_guesser.go b/pkg/handler/processor/guesser/type_guesser.go index 1252f17404..8988df372a 100644 --- a/pkg/handler/processor/guesser/type_guesser.go +++ b/pkg/handler/processor/guesser/type_guesser.go @@ -28,6 +28,7 @@ func init() { _ = RegisterDocumentTypeGuesser(&scorecardTypeGuesser{}, "scorecard") _ = RegisterDocumentTypeGuesser(&cycloneDXTypeGuesser{}, "cyclonedx") _ = RegisterDocumentTypeGuesser(&depsDevTypeGuesser{}, "deps.dev") + _ = RegisterDocumentTypeGuesser(&csafTypeGuesser{}, "csaf") } // DocumentTypeGuesser guesses the document type based on the blob and format given diff --git a/pkg/handler/processor/process/process.go b/pkg/handler/processor/process/process.go index f7330b4cb6..1262e8d322 100644 --- a/pkg/handler/processor/process/process.go +++ b/pkg/handler/processor/process/process.go @@ -23,6 +23,7 @@ import ( uuid "github.com/gofrs/uuid" "github.com/guacsec/guac/pkg/emitter" "github.com/guacsec/guac/pkg/handler/processor" + "github.com/guacsec/guac/pkg/handler/processor/csaf" "github.com/guacsec/guac/pkg/handler/processor/cyclonedx" "github.com/guacsec/guac/pkg/handler/processor/deps_dev" "github.com/guacsec/guac/pkg/handler/processor/dsse" @@ -43,6 +44,7 @@ func init() { _ = RegisterDocumentProcessor(&ite6.ITE6Processor{}, processor.DocumentITE6Vul) _ = RegisterDocumentProcessor(&dsse.DSSEProcessor{}, processor.DocumentDSSE) _ = RegisterDocumentProcessor(&spdx.SPDXProcessor{}, processor.DocumentSPDX) + _ = RegisterDocumentProcessor(&csaf.CSAFProcessor{}, processor.DocumentCsaf) _ = RegisterDocumentProcessor(&scorecard.ScorecardProcessor{}, processor.DocumentScorecard) _ = RegisterDocumentProcessor(&cyclonedx.CycloneDXProcessor{}, processor.DocumentCycloneDX) _ = RegisterDocumentProcessor(&deps_dev.DepsDev{}, processor.DocumentDepsDev) diff --git a/pkg/handler/processor/processor.go b/pkg/handler/processor/processor.go index 40b629961c..d310e256f0 100644 --- a/pkg/handler/processor/processor.go +++ b/pkg/handler/processor/processor.go @@ -61,6 +61,7 @@ const ( DocumentScorecard DocumentType = "SCORECARD" DocumentCycloneDX DocumentType = "CycloneDX" DocumentDepsDev DocumentType = "DEPS_DEV" + DocumentCsaf DocumentType = "CSAF" DocumentUnknown DocumentType = "UNKNOWN" ) diff --git a/pkg/ingestor/parser/csaf/parser_csaf.go b/pkg/ingestor/parser/csaf/parser_csaf.go new file mode 100644 index 0000000000..73d14fa3ef --- /dev/null +++ b/pkg/ingestor/parser/csaf/parser_csaf.go @@ -0,0 +1,253 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package csaf + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/guacsec/guac/pkg/assembler" + "github.com/guacsec/guac/pkg/assembler/clients/generated" + "github.com/guacsec/guac/pkg/assembler/helpers" + "github.com/guacsec/guac/pkg/handler/processor" + "github.com/guacsec/guac/pkg/ingestor/parser/common" + "github.com/guacsec/guac/pkg/logging" + + "github.com/openvex/go-vex/pkg/csaf" +) + +var ( + justificationsMap = map[string]generated.VexJustification{ + "component_not_present": generated.VexJustificationComponentNotPresent, + "vulnerable_code_not_present": generated.VexJustificationVulnerableCodeNotPresent, + "vulnerable_code_not_in_execute_path": generated.VexJustificationVulnerableCodeNotInExecutePath, + "vulnerable_code_cannot_be_controlled_by_adversary": generated.VexJustificationVulnerableCodeCannotBeControlledByAdversary, + "inline_mitigations_already_exist": generated.VexJustificationInlineMitigationsAlreadyExist, + } + + vexStatusMap = map[string]generated.VexStatus{ + "known_not_affected": generated.VexStatusNotAffected, + "known_affected": generated.VexStatusAffected, + "fixed": generated.VexStatusFixed, + "first_fixed": generated.VexStatusFixed, + "under_investigation": generated.VexStatusUnderInvestigation, + "first_affected": generated.VexStatusAffected, + "last_affected": generated.VexStatusAffected, + "recommended": generated.VexStatusAffected, + } +) + +type csafParser struct { + doc *processor.Document + identifierStrings *common.IdentifierStrings + + csaf *csaf.CSAF +} + +func NewCsafParser() common.DocumentParser { + return &csafParser{ + identifierStrings: &common.IdentifierStrings{}, + } +} + +// Parse breaks out the document into the graph components +func (c *csafParser) Parse(ctx context.Context, doc *processor.Document) error { + c.doc = doc + err := json.Unmarshal(doc.Blob, &c.csaf) + if err != nil { + return fmt.Errorf("failed to parse CSAF: %w", err) + } + + return nil +} + +// GetIdentities gets the identity node from the document if they exist +func (c *csafParser) GetIdentities(ctx context.Context) []common.TrustInformation { + return nil +} + +func (c *csafParser) GetIdentifiers(ctx context.Context) (*common.IdentifierStrings, error) { + return nil, fmt.Errorf("not yet implemented") +} + +func findPurl(ctx context.Context, tree csaf.ProductBranch, product_ref string) *string { + if tree.Name == product_ref { + purl := tree.Product.IdentificationHelper["purl"] + return &purl + } + + for _, b := range tree.Branches { + purl := findPurl(ctx, b, product_ref) + if purl != nil { + return purl + } + } + + return nil +} + +func findProductRef(ctx context.Context, tree csaf.ProductBranch, product_id string) *string { + for _, r := range tree.Relationships { + if r.FullProductName.ID == product_id { + return &r.ProductRef + } + } + + for _, b := range tree.Branches { + pref := findProductRef(ctx, b, product_id) + if pref != nil { + return pref + } + } + return nil +} + +func findActionStatement(tree *csaf.Vulnerability, product_id string) *string { + for _, r := range tree.Remediations { + for _, p := range r.ProductIDs { + if p == product_id { + return &r.Details + } + } + } + return nil +} + +func findImpactStatement(tree *csaf.Vulnerability, product_id string) *string { + for _, t := range tree.Threats { + if t.Category == "impact" { + for _, p := range t.ProductIDs { + if p == product_id { + return &t.Details + } + } + } + } + return nil +} + +func (c *csafParser) findPkgSpec(ctx context.Context, product_id string) (*generated.PkgInputSpec, error) { + pref := findProductRef(ctx, c.csaf.ProductTree, product_id) + if pref == nil { + return nil, fmt.Errorf("unable to locate product reference for id %s", product_id) + } + + purl := findPurl(ctx, c.csaf.ProductTree, *pref) + if purl == nil { + return nil, fmt.Errorf("unable to locate product url for reference %s", *pref) + } + + return helpers.PurlToPkg(*purl) +} + +func (c *csafParser) generateVexIngest(ctx context.Context, cve *generated.CVEInputSpec, ghsa *generated.GHSAInputSpec, vuln *csaf.Vulnerability, status string, product_id string) *assembler.VexIngest { + logger := logging.FromContext(ctx) + vi := &assembler.VexIngest{} + + vd := generated.VexStatementInputSpec{} + vd.KnownSince = c.csaf.Document.Tracking.CurrentReleaseDate + vd.Origin = c.csaf.Document.Tracking.ID + vd.VexJustification = generated.VexJustificationNotProvided + + if vexStatus, ok := vexStatusMap[status]; ok { + vd.Status = vexStatus + } + + var statement *string + if vd.Status == generated.VexStatusNotAffected { + statement = findImpactStatement(vuln, product_id) + } else { + statement = findActionStatement(vuln, product_id) + } + + if statement != nil { + vd.Statement = *statement + } + + for _, flag := range vuln.Flags { + found := false + for _, pid := range flag.ProductIDs { + if pid == product_id { + found = true + } + } + if found { + if just, ok := justificationsMap[flag.Label]; ok { + vd.VexJustification = just + } + } + } + + vi.VexData = &vd + vi.CVE = cve + vi.GHSA = ghsa + + pkg, err := c.findPkgSpec(ctx, product_id) + if err != nil { + logger.Warnf("[csaf] unable to locate package for not-affected product %s", product_id) + return nil + } + vi.Pkg = pkg + + return vi +} + +func (c *csafParser) GetPredicates(ctx context.Context) *assembler.IngestPredicates { + rv := &assembler.IngestPredicates{} + var vis []assembler.VexIngest + var cvs []assembler.CertifyVulnIngest + + if len(c.csaf.Vulnerabilities) > 0 { + + for _, v := range c.csaf.Vulnerabilities { + cve, ghsa, err := helpers.OSVToGHSACVE(v.CVE) + if err != nil { + return nil + } + + statuses := []string{"fixed", "known_not_affected", "known_affected", "first_affected", "first_fixed", "last_affected", "recommended", "under_investigation"} + for _, status := range statuses { + products := v.ProductStatus[status] + if len(products) > 0 { + for _, product := range products { + vi := c.generateVexIngest(ctx, cve, ghsa, &v, status, product) + if vi == nil { + continue + } + + if status == "known_affected" || status == "under_investigation" { + vulnData := generated.VulnerabilityMetaDataInput{ + TimeScanned: c.csaf.Document.Tracking.CurrentReleaseDate, + } + cv := assembler.CertifyVulnIngest{ + Pkg: vi.Pkg, + CVE: cve, + GHSA: ghsa, + VulnData: &vulnData, + } + cvs = append(cvs, cv) + } + vis = append(vis, *vi) + } + } + } + } + } + rv.Vex = vis + rv.CertifyVuln = cvs + return rv +} diff --git a/pkg/ingestor/parser/csaf/parser_csaf_test.go b/pkg/ingestor/parser/csaf/parser_csaf_test.go new file mode 100644 index 0000000000..a3e581f19d --- /dev/null +++ b/pkg/ingestor/parser/csaf/parser_csaf_test.go @@ -0,0 +1,71 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package csaf + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/guacsec/guac/internal/testing/testdata" + "github.com/guacsec/guac/pkg/assembler" + "github.com/guacsec/guac/pkg/handler/processor" + "github.com/guacsec/guac/pkg/logging" +) + +func Test_csafParser(t *testing.T) { + ctx := logging.WithLogger(context.Background()) + tests := []struct { + name string + doc *processor.Document + wantPredicates *assembler.IngestPredicates + wantErr bool + }{{ + name: "valid big CSAF document", + doc: &processor.Document{ + Blob: testdata.CsafExampleRedHat, + Format: processor.FormatJSON, + Type: processor.DocumentCsaf, + SourceInformation: processor.SourceInformation{ + Collector: "TestCollector", + Source: "TestSource", + }, + }, + wantPredicates: &assembler.IngestPredicates{ + Vex: testdata.CsafVexIngest, + CertifyVuln: testdata.CsafCertifyVulnIngest, + }, + wantErr: false, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := NewCsafParser() + err := s.Parse(ctx, tt.doc) + if (err != nil) != tt.wantErr { + t.Errorf("csafParse.Parse() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + + preds := s.GetPredicates(ctx) + if d := cmp.Diff(tt.wantPredicates, preds, testdata.IngestPredicatesCmpOpts...); len(d) != 0 { + t.Errorf("csaf.GetPredicate mismatch values (+got, -expected): %s", d) + } + }) + } +} diff --git a/pkg/ingestor/parser/parser.go b/pkg/ingestor/parser/parser.go index 13cbe7127d..86d365b1da 100644 --- a/pkg/ingestor/parser/parser.go +++ b/pkg/ingestor/parser/parser.go @@ -25,6 +25,7 @@ import ( "github.com/guacsec/guac/pkg/emitter" "github.com/guacsec/guac/pkg/handler/processor" "github.com/guacsec/guac/pkg/ingestor/parser/common" + "github.com/guacsec/guac/pkg/ingestor/parser/csaf" "github.com/guacsec/guac/pkg/ingestor/parser/cyclonedx" "github.com/guacsec/guac/pkg/ingestor/parser/deps_dev" "github.com/guacsec/guac/pkg/ingestor/parser/dsse" @@ -43,6 +44,7 @@ func init() { _ = RegisterDocumentParser(cyclonedx.NewCycloneDXParser, processor.DocumentCycloneDX) _ = RegisterDocumentParser(scorecard.NewScorecardParser, processor.DocumentScorecard) _ = RegisterDocumentParser(deps_dev.NewDepsDevParser, processor.DocumentDepsDev) + _ = RegisterDocumentParser(csaf.NewCsafParser, processor.DocumentCsaf) } var (