mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Compare commits
87 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
586524a97e | ||
|
|
52ce6bcde6 | ||
|
|
9393271699 | ||
|
|
0630a9a64a | ||
|
|
502376ce3a | ||
|
|
c678a97d43 | ||
|
|
9a37a8ecfa | ||
|
|
d6bac95e45 | ||
|
|
5a1c2a0873 | ||
|
|
8dd4cb4fa8 | ||
|
|
9607f8db94 | ||
|
|
46118544be | ||
|
|
fb59a40609 | ||
|
|
cf9c62fcc0 | ||
|
|
b6281012f5 | ||
|
|
8740244dd8 | ||
|
|
6cc1d7a38f | ||
|
|
ffb1a31944 | ||
|
|
ef44c92f8b | ||
|
|
223570ac9b | ||
|
|
fc012fa820 | ||
|
|
f046ade489 | ||
|
|
c6bad42c24 | ||
|
|
05eae0a9ae | ||
|
|
e3d2a58528 | ||
|
|
04955d6fad | ||
|
|
0dbf822cbd | ||
|
|
bcb7c8be10 | ||
|
|
5c1b061255 | ||
|
|
d1f33ab27d | ||
|
|
187d114631 | ||
|
|
1a2a8fae9c | ||
|
|
f6927154bf | ||
|
|
1f1a2a4cbc | ||
|
|
fa8370bd60 | ||
|
|
7ab964a3e3 | ||
|
|
c7a284bf7f | ||
|
|
08ab318545 | ||
|
|
a2fab16d3b | ||
|
|
108e5f8620 | ||
|
|
100e4d395b | ||
|
|
7fc5600521 | ||
|
|
7f27a63e3c | ||
|
|
230e9f2d2b | ||
|
|
ae184eb189 | ||
|
|
4b4d6ed594 | ||
|
|
7935818600 | ||
|
|
c81f55a752 | ||
|
|
e7c08d05cd | ||
|
|
fc3837d655 | ||
|
|
dad4e54184 | ||
|
|
01c43d96ce | ||
|
|
ca54ba53be | ||
|
|
3262e2ec2a | ||
|
|
bcd34d9fba | ||
|
|
5fd5076f52 | ||
|
|
21ce19735b | ||
|
|
27e9519ed5 | ||
|
|
a7b1291be8 | ||
|
|
7b7d0c4dcb | ||
|
|
a6d0a0c790 | ||
|
|
d54e211ef3 | ||
|
|
c833c00f84 | ||
|
|
4066704c1a | ||
|
|
f154b78340 | ||
|
|
d5778f0755 | ||
|
|
5d37dd1339 | ||
|
|
d09db6635d | ||
|
|
3f4fe5cf18 | ||
|
|
02d4931152 | ||
|
|
9c62e89a23 | ||
|
|
062e145761 | ||
|
|
36aab33de4 | ||
|
|
1098c6add0 | ||
|
|
091854a248 | ||
|
|
ce886f138a | ||
|
|
6ac97810d0 | ||
|
|
cb291bb81b | ||
|
|
12cde3aa3c | ||
|
|
fa1861385a | ||
|
|
dcdbc5d49d | ||
|
|
34705f3c6e | ||
|
|
6955c4e37c | ||
|
|
fc64bf7165 | ||
|
|
161ec1f15c | ||
|
|
3ab00e8759 | ||
|
|
91b5b4543e |
56 changed files with 1399 additions and 575 deletions
4
.github/workflows/generate-markdown.yml
vendored
4
.github/workflows/generate-markdown.yml
vendored
|
|
@ -13,8 +13,8 @@ jobs:
|
|||
auto-update-readme:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v5
|
||||
- name: Markdown autodocs
|
||||
uses: dineshsonachalam/markdown-autodocs@v1.0.4
|
||||
uses: dineshsonachalam/markdown-autodocs@v1.0.7
|
||||
with:
|
||||
output_file_paths: '[./README.md, ./docs/*.md]'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
name: Go
|
||||
name: Go Test (oldstable)
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -12,10 +12,10 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 'oldstable'
|
||||
|
||||
36
.github/workflows/go.yml
vendored
36
.github/workflows/go.yml
vendored
|
|
@ -12,10 +12,11 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "stable"
|
||||
|
||||
|
|
@ -26,15 +27,36 @@ jobs:
|
|||
run: go vet ./...
|
||||
|
||||
- name: gofmt
|
||||
uses: Jerome1337/gofmt-action@v1.0.4
|
||||
uses: Jerome1337/gofmt-action@v1.0.5
|
||||
with:
|
||||
gofmt-flags: "-l -d"
|
||||
|
||||
- name: golint
|
||||
uses: Jerome1337/golint-action@v1.0.3
|
||||
|
||||
- name: Revive Action
|
||||
uses: morphy2k/revive-action@v2.7.4
|
||||
uses: morphy2k/revive-action@v2
|
||||
|
||||
- name: Tests
|
||||
run: go test -v ./...
|
||||
|
||||
run_modver:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build # Only run when build job was successful
|
||||
if: ${{ github.event_name == 'pull_request' && success() }}
|
||||
permissions:
|
||||
contents: read # Modver needs to read the repo content
|
||||
pull-requests: write # Modver needs to write comments/status on PRs
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Modver needs full history for comparison
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "stable"
|
||||
|
||||
- name: Modver
|
||||
uses: bobg/modver@v2.12.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pull_request_url: https://github.com/${{ github.repository }}/pull/${{ github.event.number }}
|
||||
|
|
|
|||
14
.github/workflows/itest.yml
vendored
14
.github/workflows/itest.yml
vendored
|
|
@ -5,19 +5,19 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '^1.23.6'
|
||||
go-version-file: "go.mod"
|
||||
check-latest: true
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
node-version: 24
|
||||
|
||||
- name: Execute the scripts
|
||||
run: |
|
||||
|
|
|
|||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
|
|
@ -7,17 +7,19 @@ on:
|
|||
jobs:
|
||||
releases-matrix:
|
||||
name: Release Go binaries
|
||||
# use oldest available ubuntu to be compatible with more libc.so revs.
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '^1.23.6'
|
||||
go-version: '^1.24.9'
|
||||
check-latest: true
|
||||
|
||||
- name: Build
|
||||
run: make dist
|
||||
|
|
|
|||
62
Makefile
62
Makefile
|
|
@ -12,15 +12,15 @@ SHELL = /bin/bash
|
|||
BUILD = go build
|
||||
MKDIR = mkdir -p
|
||||
|
||||
.PHONY: build build_linux build_win build_mac_amd64 build_mac_arm64 tag_checked_out mostlyclean
|
||||
.PHONY: build build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64 tag_checked_out mostlyclean
|
||||
|
||||
all:
|
||||
@echo choose a target from: build build_linux build_win build_mac_amd64 build_mac_arm64 mostlyclean
|
||||
@echo choose a target from: build build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64 mostlyclean
|
||||
@echo prepend \`make BUILDTAG=1\` to checkout the highest git tag before building
|
||||
@echo or set BUILDTAG to a specific tag
|
||||
|
||||
# Build all binaries
|
||||
build: build_linux build_win build_mac_amd64 build_mac_arm64
|
||||
build: build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64
|
||||
|
||||
# if BUILDTAG == 1 set it to the highest git tag
|
||||
ifeq ($(strip $(BUILDTAG)),1)
|
||||
|
|
@ -29,7 +29,7 @@ endif
|
|||
|
||||
ifdef BUILDTAG
|
||||
# add the git tag checkout to the requirements of our build targets
|
||||
build_linux build_win build_mac_amd64 build_mac_arm64: tag_checked_out
|
||||
build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64: tag_checked_out
|
||||
endif
|
||||
|
||||
tag_checked_out:
|
||||
|
|
@ -47,13 +47,18 @@ tag_checked_out:
|
|||
# In this case we might in some situations see an error like
|
||||
# `/bin/bash: line 1: 2b55bbb: value too great for base (error token is "2b55bbb")`
|
||||
# which can be ignored.
|
||||
GITDESC := $(shell git describe --tags --always)
|
||||
GITDESC := $(shell git describe --tags --always --dirty=-modified 2>/dev/null || true)
|
||||
CURRENT_FOLDER_NAME := $(notdir $(CURDIR))
|
||||
ifeq ($(strip $(GITDESC)),)
|
||||
SEMVER := $(CURRENT_FOLDER_NAME)
|
||||
else
|
||||
GITDESCPATCH := $(shell echo '$(GITDESC)' | sed -E 's/v?[0-9]+\.[0-9]+\.([0-9]+)[-+]?.*/\1/')
|
||||
SEMVERPATCH := $(shell echo $$(( $(GITDESCPATCH) + 1 )))
|
||||
# Hint: The second regexp in the next line only matches
|
||||
# if there is a hyphen (`-`) followed by a number,
|
||||
# by which we assume that git describe has added a string after the tag
|
||||
SEMVER := $(shell echo '$(GITDESC)' | sed -E -e 's/^v//' -e 's/([0-9]+\.[0-9]+\.)([0-9]+)(-[1-9].*)/\1$(SEMVERPATCH)\3/' )
|
||||
endif
|
||||
testsemver:
|
||||
@echo from \'$(GITDESC)\' transformed to \'$(SEMVER)\'
|
||||
|
||||
|
|
@ -64,31 +69,49 @@ LDFLAGS = -ldflags "-X github.com/gocsaf/csaf/v3/util.SemVersion=$(SEMVER)"
|
|||
# Build binaries and place them under bin-$(GOOS)-$(GOARCH)
|
||||
# Using 'Target-specific Variable Values' to specify the build target system
|
||||
|
||||
GOARCH = amd64
|
||||
build_linux: GOOS = linux
|
||||
build_win: GOOS = windows
|
||||
build_mac_amd64: GOOS = darwin
|
||||
build_linux: GOOS=linux
|
||||
build_linux: GOARCH=amd64
|
||||
|
||||
build_mac_arm64: GOARCH = arm64
|
||||
build_mac_arm64: GOOS = darwin
|
||||
build_win: GOOS=windows
|
||||
build_win: GOARCH=amd64
|
||||
|
||||
build_linux build_win build_mac_amd64 build_mac_arm64:
|
||||
build_mac_amd64: GOOS=darwin
|
||||
build_mac_amd64: GOARCH=amd64
|
||||
|
||||
build_mac_arm64: GOOS=darwin
|
||||
build_mac_arm64: GOARCH=arm64
|
||||
|
||||
build_linux_arm64: GOOS=linux
|
||||
build_linux_arm64: GOARCH=arm64
|
||||
|
||||
build_win_arm64: GOOS=windows
|
||||
build_win_arm64: GOARCH=arm64
|
||||
|
||||
build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64:
|
||||
$(eval BINDIR = bin-$(GOOS)-$(GOARCH)/ )
|
||||
$(MKDIR) $(BINDIR)
|
||||
env GOARCH=$(GOARCH) GOOS=$(GOOS) $(BUILD) -o $(BINDIR) $(LDFLAGS) -v ./cmd/...
|
||||
|
||||
|
||||
DISTDIR := csaf-$(SEMVER)
|
||||
dist: build_linux build_win build_mac_amd64 build_mac_arm64
|
||||
dist: build_linux build_linux_arm64 build_win build_win_arm64 build_mac_amd64 build_mac_arm64
|
||||
mkdir -p dist
|
||||
mkdir -p dist/$(DISTDIR)-windows-amd64/bin-windows-amd64
|
||||
mkdir -p dist/$(DISTDIR)-windows-arm64/bin-windows-arm64
|
||||
cp README.md dist/$(DISTDIR)-windows-amd64
|
||||
cp README.md dist/$(DISTDIR)-windows-arm64
|
||||
cp bin-windows-amd64/csaf_uploader.exe bin-windows-amd64/csaf_validator.exe \
|
||||
bin-windows-amd64/csaf_checker.exe bin-windows-amd64/csaf_downloader.exe \
|
||||
dist/$(DISTDIR)-windows-amd64/bin-windows-amd64/
|
||||
cp bin-windows-arm64/csaf_uploader.exe bin-windows-arm64/csaf_validator.exe \
|
||||
bin-windows-arm64/csaf_checker.exe bin-windows-arm64/csaf_downloader.exe \
|
||||
dist/$(DISTDIR)-windows-arm64/bin-windows-arm64/
|
||||
mkdir -p dist/$(DISTDIR)-windows-amd64/docs
|
||||
mkdir -p dist/$(DISTDIR)-windows-arm64/docs
|
||||
cp docs/csaf_uploader.md docs/csaf_validator.md docs/csaf_checker.md \
|
||||
docs/csaf_downloader.md dist/$(DISTDIR)-windows-amd64/docs
|
||||
cp docs/csaf_uploader.md docs/csaf_validator.md docs/csaf_checker.md \
|
||||
docs/csaf_downloader.md dist/$(DISTDIR)-windows-arm64/docs
|
||||
mkdir -p dist/$(DISTDIR)-macos/bin-darwin-amd64 \
|
||||
dist/$(DISTDIR)-macos/bin-darwin-arm64 \
|
||||
dist/$(DISTDIR)-macos/docs
|
||||
|
|
@ -98,9 +121,20 @@ dist: build_linux build_win build_mac_amd64 build_mac_arm64
|
|||
cp docs/$${f}.md dist/$(DISTDIR)-macos/docs ; \
|
||||
done
|
||||
mkdir dist/$(DISTDIR)-gnulinux-amd64
|
||||
cp -r README.md docs bin-linux-amd64 dist/$(DISTDIR)-gnulinux-amd64
|
||||
mkdir dist/$(DISTDIR)-gnulinux-arm64
|
||||
cp -r README.md bin-linux-amd64 dist/$(DISTDIR)-gnulinux-amd64
|
||||
cp -r README.md bin-linux-arm64 dist/$(DISTDIR)-gnulinux-arm64
|
||||
# adjust which docs to copy
|
||||
mkdir -p dist/tmp_docs
|
||||
cp -r docs/examples dist/tmp_docs
|
||||
cp docs/*.md dist/tmp_docs
|
||||
cp -r dist/tmp_docs dist/$(DISTDIR)-gnulinux-amd64/docs
|
||||
cp -r dist/tmp_docs dist/$(DISTDIR)-gnulinux-arm64/docs
|
||||
rm -rf dist/tmp_docs
|
||||
cd dist/ ; zip -r $(DISTDIR)-windows-amd64.zip $(DISTDIR)-windows-amd64/
|
||||
cd dist/ ; zip -r $(DISTDIR)-windows-arm64.zip $(DISTDIR)-windows-arm64/
|
||||
cd dist/ ; tar -cvmlzf $(DISTDIR)-gnulinux-amd64.tar.gz $(DISTDIR)-gnulinux-amd64/
|
||||
cd dist/ ; tar -cvmlzf $(DISTDIR)-gnulinux-arm64.tar.gz $(DISTDIR)-gnulinux-arm64/
|
||||
cd dist/ ; tar -cvmlzf $(DISTDIR)-macos.tar.gz $(DISTDIR)-macos
|
||||
|
||||
# Remove bin-*-* and dist directories
|
||||
|
|
|
|||
36
README.md
36
README.md
|
|
@ -9,14 +9,6 @@
|
|||
-->
|
||||
|
||||
|
||||
> [!IMPORTANT]
|
||||
> To avoid future breakage, if you still use `csaf-poc`:
|
||||
> 1. Adjust your HTML links.
|
||||
> 2. Adjust your go module paths, see [#579](https://github.com/gocsaf/csaf/issues/579#issuecomment-2497244379).
|
||||
>
|
||||
> (This repository was moved here on 2024-10-28. The old one is deprecated
|
||||
> and redirection will be switched off a few months later.)
|
||||
|
||||
|
||||
# csaf
|
||||
|
||||
|
|
@ -49,13 +41,20 @@ is a tool for testing a CSAF Trusted Provider according to [Section 7 of the CSA
|
|||
### [csaf_aggregator](docs/csaf_aggregator.md)
|
||||
is a CSAF Aggregator, to list or mirror providers.
|
||||
|
||||
## Other stuff
|
||||
|
||||
## Use as go library
|
||||
|
||||
The modules of this repository can be used as library by other Go applications. [ISDuBA](https://github.com/ISDuBA/ISDuBA) does so, for example.
|
||||
But there is only limited support and thus it is _not officially supported_.
|
||||
There are plans to change this without a concrete schedule within a future major release, e.g. see [#367](https://github.com/gocsaf/csaf/issues/367).
|
||||
|
||||
Initially envisioned as a toolbox, it was not constructed as a library,
|
||||
and to name one issue, exposes too many functions.
|
||||
This leads to problems like [#634](https://github.com/gocsaf/csaf/issues/634), where we have to accept that with 3.2.0 there was an unintended API change.
|
||||
|
||||
### [examples](./examples/README.md)
|
||||
are small examples of how to use `github.com/gocsaf/csaf`
|
||||
as an API. Currently this is a work in progress, as usage of this repository
|
||||
as a library to access is _not officially supported_, e.g.
|
||||
see https://github.com/gocsaf/csaf/issues/367 .
|
||||
are small examples of how to use `github.com/gocsaf/csaf` as an API. Currently this is a work in progress.
|
||||
|
||||
|
||||
## Setup
|
||||
Binaries for the server side are only available and tested
|
||||
|
|
@ -79,7 +78,8 @@ Download the binaries from the most recent release assets on Github.
|
|||
|
||||
### Build from sources
|
||||
|
||||
- A recent version of **Go** (1.23+) should be installed. [Go installation](https://go.dev/doc/install)
|
||||
- Needs a [supported version](docs/Development.md) of **Go** to be installed.
|
||||
[Go installation](https://go.dev/doc/install)
|
||||
|
||||
- Clone the repository `git clone https://github.com/gocsaf/csaf.git `
|
||||
|
||||
|
|
@ -107,6 +107,14 @@ Binaries will be placed in directories named like `bin-linux-amd64/` and `bin-wi
|
|||
|
||||
For further details of the development process consult our [development page](./docs/Development.md).
|
||||
|
||||
## Previous repo URLs
|
||||
|
||||
> [!NOTE]
|
||||
> To avoid future breakage, if you have `csaf-poc` in some of your URLs:
|
||||
> 1. Adjust your HTML links.
|
||||
> 2. Adjust your go module paths, see [#579](https://github.com/gocsaf/csaf/issues/579#issuecomment-2497244379).
|
||||
>
|
||||
> (This repository was moved here from https://github.com/csaf-poc/csaf_distribution on 2024-10-28. The old one is deprecated and redirection will be switched off sometime in 2025.)
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -25,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/csaf"
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ func (w *worker) checkInterims(
|
|||
if err := func() error {
|
||||
defer res.Body.Close()
|
||||
tee := io.TeeReader(res.Body, hasher)
|
||||
return json.NewDecoder(tee).Decode(&doc)
|
||||
return misc.StrictJSONParse(tee, &doc)
|
||||
}(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
|
|
@ -31,6 +30,7 @@ import (
|
|||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/csaf"
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ func (w *worker) mirrorInternal() (*csaf.AggregatorCSAFProvider, error) {
|
|||
// Collecting the categories per label.
|
||||
w.categories = map[string]util.Set[string]{}
|
||||
|
||||
base, err := url.Parse(w.loc)
|
||||
pmdURL, err := url.Parse(w.loc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ func (w *worker) mirrorInternal() (*csaf.AggregatorCSAFProvider, error) {
|
|||
w.client,
|
||||
w.expr,
|
||||
w.metadataProvider,
|
||||
base)
|
||||
pmdURL)
|
||||
|
||||
afp.AgeAccept = w.provider.ageAccept(w.processor.cfg)
|
||||
|
||||
|
|
@ -538,7 +538,7 @@ func (w *worker) mirrorFiles(tlpLabel csaf.TLPLabel, files []csaf.AdvisoryFile)
|
|||
|
||||
download := func(r io.Reader) error {
|
||||
tee := io.TeeReader(r, hasher)
|
||||
return json.NewDecoder(tee).Decode(&advisory)
|
||||
return misc.StrictJSONParse(tee, &advisory)
|
||||
}
|
||||
|
||||
if err := downloadJSON(w.client, file.URL(), download); err != nil {
|
||||
|
|
@ -627,7 +627,6 @@ func (w *worker) mirrorFiles(tlpLabel csaf.TLPLabel, files []csaf.AdvisoryFile)
|
|||
// If this fails it creates a signature itself with the configured key.
|
||||
func (w *worker) downloadSignatureOrSign(url, fname string, data []byte) error {
|
||||
sig, err := w.downloadSignature(url)
|
||||
|
||||
if err != nil {
|
||||
if err != errNotFound {
|
||||
w.log.Error("Could not find signature URL", "url", url, "err", err)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
|
|
@ -93,7 +95,12 @@ func (pgs pages) listed(
|
|||
return err
|
||||
}
|
||||
// Links may be relative
|
||||
abs := baseURL.ResolveReference(u).String()
|
||||
var abs string
|
||||
if u.IsAbs() {
|
||||
abs = u.String()
|
||||
} else {
|
||||
abs = misc.JoinURL(baseURL, u).String()
|
||||
}
|
||||
content.links.Add(abs)
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"crypto/sha512"
|
||||
"crypto/tls"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -29,6 +28,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
|
|
@ -251,14 +252,14 @@ func (p *processor) run(domains []string) (*Report, error) {
|
|||
p.reset()
|
||||
|
||||
if !p.checkProviderMetadata(d) {
|
||||
// We cannot build a report if the provider metadata cannot be parsed.
|
||||
log.Printf("Could not parse the Provider-Metadata.json of: %s\n", d)
|
||||
continue
|
||||
// We need to fail the domain if the PMD cannot be parsed.
|
||||
p.badProviderMetadata.use()
|
||||
p.badProviderMetadata.error("Could not parse the Provider-Metadata.json of: %s", d)
|
||||
|
||||
}
|
||||
if err := p.checkDomain(d); err != nil {
|
||||
log.Printf("Failed to find valid provider-metadata.json for domain %s: %v. "+
|
||||
"Continuing with next domain.", d, err)
|
||||
continue
|
||||
p.badProviderMetadata.use()
|
||||
p.badProviderMetadata.error("Failed to find valid provider-metadata.json for domain %s: %v. ", d, err)
|
||||
}
|
||||
domain := &Domain{Name: d}
|
||||
|
||||
|
|
@ -269,8 +270,10 @@ func (p *processor) run(domains []string) (*Report, error) {
|
|||
}
|
||||
|
||||
if domain.Role == nil {
|
||||
log.Printf("No role found in meta data. Ignoring domain %q\n", d)
|
||||
continue
|
||||
log.Printf("No role found in meta data for domain %q\n", d)
|
||||
// Assume trusted provider to continue report generation
|
||||
role := csaf.MetadataRoleTrustedProvider
|
||||
domain.Role = &role
|
||||
}
|
||||
|
||||
rules := roleRequirements(*domain.Role)
|
||||
|
|
@ -513,7 +516,7 @@ func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {
|
|||
return nil, nil, fmt.Errorf("%s: %v", feed, err)
|
||||
}
|
||||
var rolieDoc any
|
||||
err = json.NewDecoder(bytes.NewReader(all)).Decode(&rolieDoc)
|
||||
err = misc.StrictJSONParse(bytes.NewReader(all), &rolieDoc)
|
||||
return rfeed, rolieDoc, err
|
||||
}()
|
||||
if err != nil {
|
||||
|
|
@ -531,7 +534,7 @@ func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {
|
|||
if len(errors) > 0 {
|
||||
p.badProviderMetadata.error("%s: Validating against JSON schema failed:", feed)
|
||||
for _, msg := range errors {
|
||||
p.badProviderMetadata.error(strings.ReplaceAll(msg, `%`, `%%`))
|
||||
p.badProviderMetadata.error("%s", strings.ReplaceAll(msg, `%`, `%%`))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -623,15 +626,9 @@ var yearFromURL = regexp.MustCompile(`.*/(\d{4})/[^/]+$`)
|
|||
// mistakes, from conforming filenames to invalid advisories.
|
||||
func (p *processor) integrity(
|
||||
files []csaf.AdvisoryFile,
|
||||
base string,
|
||||
mask whereType,
|
||||
lg func(MessageType, string, ...any),
|
||||
) error {
|
||||
b, err := url.Parse(base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
makeAbs := makeAbsolute(b)
|
||||
client := p.httpClient()
|
||||
|
||||
var data bytes.Buffer
|
||||
|
|
@ -642,9 +639,8 @@ func (p *processor) integrity(
|
|||
lg(ErrorType, "Bad URL %s: %v", f, err)
|
||||
continue
|
||||
}
|
||||
fp = makeAbs(fp)
|
||||
|
||||
u := b.ResolveReference(fp).String()
|
||||
u := fp.String()
|
||||
|
||||
// Should this URL be ignored?
|
||||
if p.cfg.ignoreURL(u) {
|
||||
|
|
@ -699,7 +695,7 @@ func (p *processor) integrity(
|
|||
if err := func() error {
|
||||
defer res.Body.Close()
|
||||
tee := io.TeeReader(res.Body, hasher)
|
||||
return json.NewDecoder(tee).Decode(&doc)
|
||||
return misc.StrictJSONParse(tee, &doc)
|
||||
}(); err != nil {
|
||||
lg(ErrorType, "Reading %s failed: %v", u, err)
|
||||
continue
|
||||
|
|
@ -738,7 +734,7 @@ func (p *processor) integrity(
|
|||
|
||||
switch date, fault := p.extractTime(doc, `initial_release_date`, u); {
|
||||
case fault != "":
|
||||
p.badFolders.error(fault)
|
||||
p.badFolders.error("%s", fault)
|
||||
case folderYear == nil:
|
||||
p.badFolders.error("No year folder found in %s", u)
|
||||
case date.UTC().Year() != *folderYear:
|
||||
|
|
@ -746,7 +742,7 @@ func (p *processor) integrity(
|
|||
}
|
||||
current, fault := p.extractTime(doc, `current_release_date`, u)
|
||||
if fault != "" {
|
||||
p.badChanges.error(fault)
|
||||
p.badChanges.error("%s", fault)
|
||||
} else {
|
||||
p.timesAdv[f.URL()] = current
|
||||
}
|
||||
|
|
@ -776,8 +772,7 @@ func (p *processor) integrity(
|
|||
lg(ErrorType, "Bad URL %s: %v", x.url(), err)
|
||||
continue
|
||||
}
|
||||
hu = makeAbs(hu)
|
||||
hashFile := b.ResolveReference(hu).String()
|
||||
hashFile := hu.String()
|
||||
|
||||
p.checkTLS(hashFile)
|
||||
if res, err = client.Get(hashFile); err != nil {
|
||||
|
|
@ -817,7 +812,7 @@ func (p *processor) integrity(
|
|||
msgType = InfoType
|
||||
}
|
||||
for _, fetchError := range hashFetchErrors {
|
||||
p.badIntegrities.add(msgType, fetchError)
|
||||
p.badIntegrities.add(msgType, "%s", fetchError)
|
||||
}
|
||||
|
||||
// Check signature
|
||||
|
|
@ -826,8 +821,7 @@ func (p *processor) integrity(
|
|||
lg(ErrorType, "Bad URL %s: %v", f.SignURL(), err)
|
||||
continue
|
||||
}
|
||||
su = makeAbs(su)
|
||||
sigFile := b.ResolveReference(su).String()
|
||||
sigFile := su.String()
|
||||
p.checkTLS(sigFile)
|
||||
|
||||
p.badSignatures.use()
|
||||
|
|
@ -947,12 +941,13 @@ func (p *processor) checkIndex(base string, mask whereType) error {
|
|||
scanner := bufio.NewScanner(res.Body)
|
||||
for line := 1; scanner.Scan(); line++ {
|
||||
u := scanner.Text()
|
||||
if _, err := url.Parse(u); err != nil {
|
||||
up, err := url.Parse(u)
|
||||
if err != nil {
|
||||
p.badIntegrities.error("index.txt contains invalid URL %q in line %d", u, line)
|
||||
continue
|
||||
}
|
||||
|
||||
files = append(files, csaf.DirectoryAdvisoryFile{Path: u})
|
||||
files = append(files, csaf.DirectoryAdvisoryFile{Path: misc.JoinURL(bu, up).String()})
|
||||
}
|
||||
return files, scanner.Err()
|
||||
}()
|
||||
|
|
@ -967,7 +962,7 @@ func (p *processor) checkIndex(base string, mask whereType) error {
|
|||
// Block rolie checks.
|
||||
p.labelChecker.feedLabel = ""
|
||||
|
||||
return p.integrity(files, base, mask, p.badIndices.add)
|
||||
return p.integrity(files, mask, p.badIndices.add)
|
||||
}
|
||||
|
||||
// checkChanges fetches the "changes.csv" and calls the "checkTLS" method for HTTPs checks.
|
||||
|
|
@ -1034,9 +1029,13 @@ func (p *processor) checkChanges(base string, mask whereType) error {
|
|||
}
|
||||
path := r[pathColumn]
|
||||
|
||||
times, files =
|
||||
append(times, t),
|
||||
append(files, csaf.DirectoryAdvisoryFile{Path: path})
|
||||
pathURL, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
times, files = append(times, t),
|
||||
append(files, csaf.DirectoryAdvisoryFile{Path: misc.JoinURL(bu, pathURL).String()})
|
||||
p.timesChanges[path] = t
|
||||
}
|
||||
return times, files, nil
|
||||
|
|
@ -1051,7 +1050,7 @@ func (p *processor) checkChanges(base string, mask whereType) error {
|
|||
if p.cfg.Range != nil {
|
||||
filtered = " (maybe filtered out by time interval)"
|
||||
}
|
||||
p.badChanges.warn("no entries in changes.csv found" + filtered)
|
||||
p.badChanges.warn("%s", "no entries in changes.csv found"+filtered)
|
||||
}
|
||||
|
||||
if !sort.SliceIsSorted(times, func(i, j int) bool {
|
||||
|
|
@ -1063,7 +1062,7 @@ func (p *processor) checkChanges(base string, mask whereType) error {
|
|||
// Block rolie checks.
|
||||
p.labelChecker.feedLabel = ""
|
||||
|
||||
return p.integrity(files, base, mask, p.badChanges.add)
|
||||
return p.integrity(files, mask, p.badChanges.add)
|
||||
}
|
||||
|
||||
// empty checks if list of strings contains at least one none empty string.
|
||||
|
|
@ -1299,7 +1298,7 @@ func (p *processor) checkProviderMetadata(domain string) bool {
|
|||
|
||||
for i := range lpmd.Messages {
|
||||
p.badProviderMetadata.warn(
|
||||
"Unexpected situation while loading provider-metadata.json: " +
|
||||
"Unexpected situation while loading provider-metadata.json: %s",
|
||||
lpmd.Messages[i].Message)
|
||||
}
|
||||
|
||||
|
|
@ -1364,17 +1363,11 @@ func (p *processor) checkSecurityFolder(folder string) string {
|
|||
}
|
||||
|
||||
// Try to load
|
||||
up, err := url.Parse(u)
|
||||
_, err = url.Parse(u)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("CSAF URL '%s' invalid: %v", u, err)
|
||||
}
|
||||
|
||||
base, err := url.Parse(folder)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
u = base.ResolveReference(up).String()
|
||||
p.checkTLS(u)
|
||||
if res, err = client.Get(u); err != nil {
|
||||
return fmt.Sprintf("Cannot fetch %s from security.txt: %v", u, err)
|
||||
|
|
@ -1406,32 +1399,31 @@ func (p *processor) checkDNS(domain string) {
|
|||
res, err := client.Get(path)
|
||||
if err != nil {
|
||||
p.badDNSPath.add(ErrorType,
|
||||
fmt.Sprintf("Fetching %s failed: %v", path, err))
|
||||
"Fetching %s failed: %v", path, err)
|
||||
return
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
p.badDNSPath.add(ErrorType, fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
|
||||
path, res.StatusCode, res.Status))
|
||||
p.badDNSPath.add(ErrorType, "Fetching %s failed. Status code %d (%s)",
|
||||
path, res.StatusCode, res.Status)
|
||||
}
|
||||
hash := sha256.New()
|
||||
defer res.Body.Close()
|
||||
content, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
p.badDNSPath.add(ErrorType,
|
||||
fmt.Sprintf("Error while reading the response from %s", path))
|
||||
"Error while reading the response from %s", path)
|
||||
}
|
||||
hash.Write(content)
|
||||
if !bytes.Equal(hash.Sum(nil), p.pmd256) {
|
||||
p.badDNSPath.add(ErrorType,
|
||||
fmt.Sprintf("%s does not serve the same provider-metadata.json as previously found",
|
||||
path))
|
||||
"%s does not serve the same provider-metadata.json as previously found",
|
||||
path)
|
||||
}
|
||||
}
|
||||
|
||||
// checkWellknown checks if the provider-metadata.json file is
|
||||
// available under the /.well-known/csaf/ directory.
|
||||
func (p *processor) checkWellknown(domain string) {
|
||||
|
||||
p.badWellknownMetadata.use()
|
||||
client := p.httpClient()
|
||||
path := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
|
||||
|
|
@ -1439,11 +1431,12 @@ func (p *processor) checkWellknown(domain string) {
|
|||
res, err := client.Get(path)
|
||||
if err != nil {
|
||||
p.badWellknownMetadata.add(ErrorType,
|
||||
fmt.Sprintf("Fetching %s failed: %v", path, err))
|
||||
"Fetching %s failed: %v", path, err)
|
||||
return
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
p.badWellknownMetadata.add(ErrorType, fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
|
||||
path, res.StatusCode, res.Status))
|
||||
p.badWellknownMetadata.add(ErrorType, "Fetching %s failed. Status code %d (%s)",
|
||||
path, res.StatusCode, res.Status)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1480,13 +1473,13 @@ func (p *processor) checkWellknownSecurityDNS(domain string) error {
|
|||
// but found in the legacy location, and inform about finding it there (2).
|
||||
switch warnings {
|
||||
case 0:
|
||||
p.badSecurity.add(InfoType, sDMessage)
|
||||
p.badSecurity.add(InfoType, "%s", sDMessage)
|
||||
case 1:
|
||||
p.badSecurity.add(ErrorType, sDMessage)
|
||||
p.badSecurity.add(ErrorType, sLMessage)
|
||||
p.badSecurity.add(ErrorType, "%s", sDMessage)
|
||||
p.badSecurity.add(ErrorType, "%s", sLMessage)
|
||||
case 2:
|
||||
p.badSecurity.add(WarnType, sDMessage)
|
||||
p.badSecurity.add(InfoType, sLMessage)
|
||||
p.badSecurity.add(WarnType, "%s", sDMessage)
|
||||
p.badSecurity.add(InfoType, "%s", sLMessage)
|
||||
}
|
||||
|
||||
p.checkDNS(domain)
|
||||
|
|
@ -1522,11 +1515,6 @@ func (p *processor) checkPGPKeys(_ string) error {
|
|||
|
||||
client := p.httpClient()
|
||||
|
||||
base, err := url.Parse(p.pmdURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range keys {
|
||||
key := &keys[i]
|
||||
if key.URL == nil {
|
||||
|
|
@ -1539,10 +1527,11 @@ func (p *processor) checkPGPKeys(_ string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
u := base.ResolveReference(up).String()
|
||||
// Todo: refactor all methods to directly accept *url.URL
|
||||
u := up.String()
|
||||
p.checkTLS(u)
|
||||
|
||||
res, err := client.Get(u)
|
||||
res, err := client.Get(*key.URL)
|
||||
if err != nil {
|
||||
p.badPGPs.error("Fetching public OpenPGP key %s failed: %v.", u, err)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -216,11 +216,6 @@ func defaults[T any](p *T, def T) T {
|
|||
// processROLIEFeeds goes through all ROLIE feeds and checks their
|
||||
// integrity and completeness.
|
||||
func (p *processor) processROLIEFeeds(feeds [][]csaf.Feed) error {
|
||||
|
||||
base, err := url.Parse(p.pmdURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.badROLIEFeed.use()
|
||||
|
||||
advisories := map[*csaf.Feed][]csaf.AdvisoryFile{}
|
||||
|
|
@ -232,12 +227,11 @@ func (p *processor) processROLIEFeeds(feeds [][]csaf.Feed) error {
|
|||
if feed.URL == nil {
|
||||
continue
|
||||
}
|
||||
up, err := url.Parse(string(*feed.URL))
|
||||
feedBase, err := url.Parse(string(*feed.URL))
|
||||
if err != nil {
|
||||
p.badProviderMetadata.error("Invalid URL %s in feed: %v.", *feed.URL, err)
|
||||
continue
|
||||
}
|
||||
feedBase := base.ResolveReference(up)
|
||||
feedURL := feedBase.String()
|
||||
p.checkTLS(feedURL)
|
||||
|
||||
|
|
@ -264,13 +258,12 @@ func (p *processor) processROLIEFeeds(feeds [][]csaf.Feed) error {
|
|||
continue
|
||||
}
|
||||
|
||||
up, err := url.Parse(string(*feed.URL))
|
||||
feedURL, err := url.Parse(string(*feed.URL))
|
||||
if err != nil {
|
||||
p.badProviderMetadata.error("Invalid URL %s in feed: %v.", *feed.URL, err)
|
||||
continue
|
||||
}
|
||||
|
||||
feedURL := base.ResolveReference(up)
|
||||
feedBase, err := util.BaseURL(feedURL)
|
||||
if err != nil {
|
||||
p.badProviderMetadata.error("Bad base path: %v", err)
|
||||
|
|
@ -290,7 +283,7 @@ func (p *processor) processROLIEFeeds(feeds [][]csaf.Feed) error {
|
|||
// TODO: Issue a warning if we want check AMBER+ without an
|
||||
// authorizing client.
|
||||
|
||||
if err := p.integrity(files, feedBase, rolieMask, p.badProviderMetadata.add); err != nil {
|
||||
if err := p.integrity(files, rolieMask, p.badProviderMetadata.add); err != nil {
|
||||
if err != errContinue {
|
||||
return err
|
||||
}
|
||||
|
|
@ -319,13 +312,12 @@ func (p *processor) processROLIEFeeds(feeds [][]csaf.Feed) error {
|
|||
continue
|
||||
}
|
||||
|
||||
up, err := url.Parse(string(*feed.URL))
|
||||
feedBase, err := url.Parse(string(*feed.URL))
|
||||
if err != nil {
|
||||
p.badProviderMetadata.error("Invalid URL %s in feed: %v.", *feed.URL, err)
|
||||
continue
|
||||
}
|
||||
|
||||
feedBase := base.ResolveReference(up)
|
||||
makeAbs := makeAbsolute(feedBase)
|
||||
label := defaults(feed.TLPLabel, csaf.TLPLabelUnlabeled)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/csaf"
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -225,7 +226,7 @@ func (d *downloader) download(ctx context.Context, domain string) error {
|
|||
}
|
||||
}
|
||||
|
||||
base, err := url.Parse(lpmd.URL)
|
||||
pmdURL, err := url.Parse(lpmd.URL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid URL '%s': %v", lpmd.URL, err)
|
||||
}
|
||||
|
|
@ -235,7 +236,6 @@ func (d *downloader) download(ctx context.Context, domain string) error {
|
|||
if err := d.loadOpenPGPKeys(
|
||||
client,
|
||||
lpmd.Document,
|
||||
base,
|
||||
expr,
|
||||
); err != nil {
|
||||
return err
|
||||
|
|
@ -245,7 +245,7 @@ func (d *downloader) download(ctx context.Context, domain string) error {
|
|||
client,
|
||||
expr,
|
||||
lpmd.Document,
|
||||
base)
|
||||
pmdURL)
|
||||
|
||||
// Do we need time range based filtering?
|
||||
if d.cfg.Range != nil {
|
||||
|
|
@ -310,7 +310,6 @@ allFiles:
|
|||
func (d *downloader) loadOpenPGPKeys(
|
||||
client util.Client,
|
||||
doc any,
|
||||
base *url.URL,
|
||||
expr *util.PathEval,
|
||||
) error {
|
||||
src, err := expr.Eval("$.public_openpgp_keys", doc)
|
||||
|
|
@ -335,7 +334,7 @@ func (d *downloader) loadOpenPGPKeys(
|
|||
if key.URL == nil {
|
||||
continue
|
||||
}
|
||||
up, err := url.Parse(*key.URL)
|
||||
u, err := url.Parse(*key.URL)
|
||||
if err != nil {
|
||||
slog.Warn("Invalid URL",
|
||||
"url", *key.URL,
|
||||
|
|
@ -343,9 +342,7 @@ func (d *downloader) loadOpenPGPKeys(
|
|||
continue
|
||||
}
|
||||
|
||||
u := base.ResolveReference(up).String()
|
||||
|
||||
res, err := client.Get(u)
|
||||
res, err := client.Get(u.String())
|
||||
if err != nil {
|
||||
slog.Warn(
|
||||
"Fetching public OpenPGP key failed",
|
||||
|
|
@ -550,7 +547,7 @@ func (dc *downloadContext) downloadAdvisory(
|
|||
|
||||
tee := io.TeeReader(resp.Body, hasher)
|
||||
|
||||
if err := json.NewDecoder(tee).Decode(&doc); err != nil {
|
||||
if err := misc.StrictJSONParse(tee, &doc); err != nil {
|
||||
dc.stats.downloadFailed++
|
||||
slog.Warn("Downloading failed",
|
||||
"url", file.URL(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
|
@ -262,6 +263,14 @@ func loadConfig() (*config, error) {
|
|||
if cfg.CanonicalURLPrefix == "" {
|
||||
cfg.CanonicalURLPrefix = "https://" + os.Getenv("SERVER_NAME")
|
||||
}
|
||||
// Check if canonical url prefix is invalid
|
||||
parsedURL, err := url.ParseRequestURI(cfg.CanonicalURLPrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if parsedURL.Scheme != "https" && parsedURL.Scheme != "http" {
|
||||
return nil, fmt.Errorf("invalid canonical URL: %q", cfg.CanonicalURLPrefix)
|
||||
}
|
||||
|
||||
if cfg.TLPs == nil {
|
||||
cfg.TLPs = []tlp{tlpCSAF, tlpWhite, tlpGreen, tlpAmber, tlpRed}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -82,8 +81,9 @@ func (p *processor) create() error {
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var createError error
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
log.Printf("Create failed: %s\n", resp.Status)
|
||||
createError = fmt.Errorf("create failed: %s", resp.Status)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
|
|
@ -91,7 +91,7 @@ func (p *processor) create() error {
|
|||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
if err := misc.StrictJSONParse(resp.Body, &result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ func (p *processor) create() error {
|
|||
|
||||
writeStrings("Errors:", result.Errors)
|
||||
|
||||
return nil
|
||||
return createError
|
||||
}
|
||||
|
||||
// uploadRequest creates the request for uploading a csaf document by passing the filename.
|
||||
|
|
@ -115,7 +115,7 @@ func (p *processor) uploadRequest(filename string) (*http.Request, error) {
|
|||
|
||||
if !p.cfg.NoSchemaCheck {
|
||||
var doc any
|
||||
if err := json.NewDecoder(bytes.NewReader(data)).Decode(&doc); err != nil {
|
||||
if err := misc.StrictJSONParse(bytes.NewReader(data), &doc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
errs, err := csaf.ValidateCSAF(doc)
|
||||
|
|
@ -239,7 +239,7 @@ func (p *processor) process(filename string) error {
|
|||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
if err := misc.StrictJSONParse(resp.Body, &result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
|
@ -19,6 +18,7 @@ import (
|
|||
"github.com/jessevdk/go-flags"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/csaf"
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -301,7 +301,7 @@ func loadJSONFromFile(fname string) (any, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
var doc any
|
||||
if err = json.NewDecoder(f).Decode(&doc); err != nil {
|
||||
if err = misc.StrictJSONParse(f, &doc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return doc, err
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ type AdvisoryFileProcessor struct {
|
|||
client util.Client
|
||||
expr *util.PathEval
|
||||
doc any
|
||||
base *url.URL
|
||||
pmdURL *url.URL
|
||||
}
|
||||
|
||||
// NewAdvisoryFileProcessor constructs a filename extractor
|
||||
|
|
@ -104,13 +105,13 @@ func NewAdvisoryFileProcessor(
|
|||
client util.Client,
|
||||
expr *util.PathEval,
|
||||
doc any,
|
||||
base *url.URL,
|
||||
pmdURL *url.URL,
|
||||
) *AdvisoryFileProcessor {
|
||||
return &AdvisoryFileProcessor{
|
||||
client: client,
|
||||
expr: expr,
|
||||
doc: doc,
|
||||
base: base,
|
||||
pmdURL: pmdURL,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +180,7 @@ func (afp *AdvisoryFileProcessor) Process(
|
|||
|
||||
// Not found -> fall back to PMD url
|
||||
if empty(dirURLs) {
|
||||
baseURL, err := util.BaseURL(afp.base)
|
||||
baseURL, err := util.BaseURL(afp.pmdURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -261,8 +262,13 @@ func (afp *AdvisoryFileProcessor) loadChanges(
|
|||
continue
|
||||
}
|
||||
|
||||
pathURL, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = append(files,
|
||||
DirectoryAdvisoryFile{Path: base.JoinPath(path).String()})
|
||||
DirectoryAdvisoryFile{Path: misc.JoinURL(base, pathURL).String()})
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
|
@ -276,12 +282,11 @@ func (afp *AdvisoryFileProcessor) processROLIE(
|
|||
if feed.URL == nil {
|
||||
continue
|
||||
}
|
||||
up, err := url.Parse(string(*feed.URL))
|
||||
feedURL, err := url.Parse(string(*feed.URL))
|
||||
if err != nil {
|
||||
slog.Error("Invalid URL in feed", "feed", *feed.URL, "err", err)
|
||||
continue
|
||||
}
|
||||
feedURL := afp.base.ResolveReference(up)
|
||||
slog.Info("Got feed URL", "feed", feedURL)
|
||||
|
||||
fb, err := util.BaseURL(feedURL)
|
||||
|
|
@ -289,11 +294,6 @@ func (afp *AdvisoryFileProcessor) processROLIE(
|
|||
slog.Error("Invalid feed base URL", "url", fb, "err", err)
|
||||
continue
|
||||
}
|
||||
feedBaseURL, err := url.Parse(fb)
|
||||
if err != nil {
|
||||
slog.Error("Cannot parse feed base URL", "url", fb, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
res, err := afp.client.Get(feedURL.String())
|
||||
if err != nil {
|
||||
|
|
@ -325,7 +325,7 @@ func (afp *AdvisoryFileProcessor) processROLIE(
|
|||
slog.Error("Invalid URL", "url", u, "err", err)
|
||||
return ""
|
||||
}
|
||||
return feedBaseURL.ResolveReference(p).String()
|
||||
return p.String()
|
||||
}
|
||||
|
||||
rfeed.Entries(func(entry *Entry) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
)
|
||||
|
||||
// Acknowledgement reflects the 'acknowledgement' object in the list of acknowledgements.
|
||||
|
|
@ -383,7 +385,6 @@ type Relationship struct {
|
|||
FullProductName *FullProductName `json:"full_product_name"` // required
|
||||
ProductReference *ProductID `json:"product_reference"` // required
|
||||
RelatesToProductReference *ProductID `json:"relates_to_product_reference"` // required
|
||||
|
||||
}
|
||||
|
||||
// Relationships is a list of Relationship.
|
||||
|
|
@ -446,6 +447,7 @@ type Flag struct {
|
|||
Date *string `json:"date,omitempty"`
|
||||
GroupIDs *ProductGroups `json:"group_ids,omitempty"`
|
||||
Label *FlagLabel `json:"label"` // required
|
||||
//revive:disable-next-line:var-naming until new major version w fix
|
||||
ProductIds *Products `json:"product_ids,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -609,8 +611,10 @@ type Remediation struct {
|
|||
Date *string `json:"date,omitempty"`
|
||||
Details *string `json:"details"` // required
|
||||
Entitlements []*string `json:"entitlements,omitempty"`
|
||||
//revive:disable:var-naming until new major version w fix
|
||||
GroupIds *ProductGroups `json:"group_ids,omitempty"`
|
||||
ProductIds *Products `json:"product_ids,omitempty"`
|
||||
//revive:enable
|
||||
RestartRequired *RestartRequired `json:"restart_required,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
}
|
||||
|
|
@ -741,8 +745,10 @@ type Threat struct {
|
|||
Category *ThreatCategory `json:"category"` // required
|
||||
Date *string `json:"date,omitempty"`
|
||||
Details *string `json:"details"` // required
|
||||
//revive:disable:var-naming until new major version w fix
|
||||
GroupIds *ProductGroups `json:"group_ids,omitempty"`
|
||||
ProductIds *Products `json:"product_ids,omitempty"`
|
||||
//revive:enable
|
||||
}
|
||||
|
||||
// Threats is a list of Threat elements.
|
||||
|
|
@ -885,8 +891,8 @@ func (rs Revisions) Validate() error {
|
|||
|
||||
// Validate validates an Engine.
|
||||
func (e *Engine) Validate() error {
|
||||
if e.Version == nil {
|
||||
return errors.New("'version' is missing")
|
||||
if e.Name == nil {
|
||||
return errors.New("'name' is missing")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1391,7 +1397,7 @@ func LoadAdvisory(fname string) (*Advisory, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
var advisory Advisory
|
||||
if err := json.NewDecoder(f).Decode(&advisory); err != nil {
|
||||
if err := misc.StrictJSONParse(f, &advisory); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := advisory.Validate(); err != nil {
|
||||
|
|
|
|||
46
csaf/advisory_test.go
Normal file
46
csaf/advisory_test.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package csaf
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadAdvisory(t *testing.T) {
|
||||
type args struct {
|
||||
jsonDir string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Valid documents",
|
||||
args: args{jsonDir: "csaf-documents/valid"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Garbage trailing data",
|
||||
args: args{jsonDir: "csaf-documents/trailing-garbage-data"},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := filepath.Walk("../testdata/"+tt.args.jsonDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode().IsRegular() && filepath.Ext(info.Name()) == ".json" {
|
||||
if _, err := LoadAdvisory(path); (err != nil) != tt.wantErr {
|
||||
t.Errorf("LoadAdvisory() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,11 @@
|
|||
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
|
||||
|
||||
// Package csaf contains the core data models used by the csaf distribution.
|
||||
// Package csaf contains the core data models used by the csaf distribution
|
||||
// tools.
|
||||
//
|
||||
// See https://github.com/gocsaf/csaf/tab=readme-ov-file#use-as-go-library
|
||||
// about hints and limits for its use as a library.
|
||||
package csaf
|
||||
|
||||
//go:generate go run ./generate_cvss_enums.go -o cvss20enums.go -i ./schema/cvss-v2.0.json -p CVSS20
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
|
|
@ -22,6 +21,8 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
)
|
||||
|
||||
// We from Intevation consider the source code parts in the following
|
||||
|
|
@ -98,7 +99,7 @@ func loadSchema(filename string) (*schema, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
var s schema
|
||||
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
||||
if err := misc.StrictJSONParse(f, &s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &s, nil
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -575,7 +576,6 @@ func (d *Distribution) Validate() error {
|
|||
// Validate checks if the provider metadata is valid.
|
||||
// Returns an error if the validation fails otherwise nil.
|
||||
func (pmd *ProviderMetadata) Validate() error {
|
||||
|
||||
switch {
|
||||
case pmd.CanonicalURL == nil:
|
||||
return errors.New("canonical_url is mandatory")
|
||||
|
|
@ -695,8 +695,7 @@ func (pmd *ProviderMetadata) WriteTo(w io.Writer) (int64, error) {
|
|||
func LoadProviderMetadata(r io.Reader) (*ProviderMetadata, error) {
|
||||
|
||||
var pmd ProviderMetadata
|
||||
dec := json.NewDecoder(r)
|
||||
if err := dec.Decode(&pmd); err != nil {
|
||||
if err := misc.StrictJSONParse(r, &pmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ package csaf
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ type ProviderMetadataLoader struct {
|
|||
type ProviderMetadataLoadMessageType int
|
||||
|
||||
const (
|
||||
//JSONDecodingFailed indicates problems with JSON decoding
|
||||
// JSONDecodingFailed indicates problems with JSON decoding
|
||||
JSONDecodingFailed ProviderMetadataLoadMessageType = iota
|
||||
// SchemaValidationFailed indicates a general problem with schema validation.
|
||||
SchemaValidationFailed
|
||||
|
|
@ -149,7 +149,6 @@ func (pmdl *ProviderMetadataLoader) Enumerate(domain string) []*LoadedProviderMe
|
|||
}
|
||||
dnsURL := "https://csaf.data.security." + domain
|
||||
return []*LoadedProviderMetadata{pmdl.loadFromURL(dnsURL)}
|
||||
|
||||
}
|
||||
|
||||
// Load loads one valid provider metadata for a given path.
|
||||
|
|
@ -323,7 +322,7 @@ func (pmdl *ProviderMetadataLoader) loadFromURL(path string) *LoadedProviderMeta
|
|||
|
||||
var doc any
|
||||
|
||||
if err := json.NewDecoder(tee).Decode(&doc); err != nil {
|
||||
if err := misc.StrictJSONParse(tee, &doc); err != nil {
|
||||
result.Messages.Add(
|
||||
JSONDecodingFailed,
|
||||
fmt.Sprintf("JSON decoding failed: %v", err))
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
|
|
@ -180,7 +181,6 @@ func prepareCache(config string) (cache, error) {
|
|||
return create()
|
||||
}
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
db.Close()
|
||||
return nil, err
|
||||
|
|
@ -256,7 +256,7 @@ func deserialize(value []byte) (*RemoteValidationResult, error) {
|
|||
}
|
||||
defer r.Close()
|
||||
var rvr RemoteValidationResult
|
||||
if err := json.NewDecoder(r).Decode(&rvr); err != nil {
|
||||
if err := misc.StrictJSONParse(r, &rvr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rvr, nil
|
||||
|
|
@ -323,7 +323,7 @@ func (v *remoteValidator) Validate(doc any) (*RemoteValidationResult, error) {
|
|||
// no cache -> process directly.
|
||||
in = resp.Body
|
||||
}
|
||||
return json.NewDecoder(in).Decode(&rvr)
|
||||
return misc.StrictJSONParse(in, &rvr)
|
||||
}(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/gocsaf/csaf/v3/internal/misc"
|
||||
"github.com/gocsaf/csaf/v3/util"
|
||||
)
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ type ROLIEServiceDocument struct {
|
|||
// LoadROLIEServiceDocument loads a ROLIE service document from a reader.
|
||||
func LoadROLIEServiceDocument(r io.Reader) (*ROLIEServiceDocument, error) {
|
||||
var rsd ROLIEServiceDocument
|
||||
if err := json.NewDecoder(r).Decode(&rsd); err != nil {
|
||||
if err := misc.StrictJSONParse(r, &rsd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rsd, nil
|
||||
|
|
@ -122,7 +123,7 @@ func (rcd *ROLIECategoryDocument) Merge(categories ...string) bool {
|
|||
// LoadROLIECategoryDocument loads a ROLIE category document from a reader.
|
||||
func LoadROLIECategoryDocument(r io.Reader) (*ROLIECategoryDocument, error) {
|
||||
var rcd ROLIECategoryDocument
|
||||
if err := json.NewDecoder(r).Decode(&rcd); err != nil {
|
||||
if err := misc.StrictJSONParse(r, &rcd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rcd, nil
|
||||
|
|
@ -168,14 +169,22 @@ type Format struct {
|
|||
|
||||
// Entry for ROLIE.
|
||||
type Entry struct {
|
||||
Base *string `json:"base,omitempty"`
|
||||
LanguageTag *string `json:"lang,omitempty"`
|
||||
Author *json.RawMessage `json:"author,omitempty"`
|
||||
Category []ROLIECategory `json:"category,omitempty"`
|
||||
Content Content `json:"content"`
|
||||
Contributor *json.RawMessage `json:"contributor,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Titel string `json:"title"`
|
||||
Link []Link `json:"link"`
|
||||
Published TimeStamp `json:"published"`
|
||||
Updated TimeStamp `json:"updated"`
|
||||
Rights *json.RawMessage `json:"rights,omitempty"`
|
||||
Source *json.RawMessage `json:"source,omitempty"`
|
||||
Summary *Summary `json:"summary,omitempty"`
|
||||
Content Content `json:"content"`
|
||||
Titel string `json:"title"`
|
||||
Updated TimeStamp `json:"updated"`
|
||||
Format Format `json:"format"`
|
||||
Property *json.RawMessage `json:"property,omitempty"`
|
||||
}
|
||||
|
||||
// FeedData is the content of the ROLIE feed.
|
||||
|
|
@ -195,9 +204,8 @@ type ROLIEFeed struct {
|
|||
|
||||
// LoadROLIEFeed loads a ROLIE feed from a reader.
|
||||
func LoadROLIEFeed(r io.Reader) (*ROLIEFeed, error) {
|
||||
dec := json.NewDecoder(r)
|
||||
var rf ROLIEFeed
|
||||
if err := dec.Decode(&rf); err != nil {
|
||||
if err := misc.StrictJSONParse(r, &rf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rf, nil
|
||||
|
|
|
|||
|
|
@ -10,13 +10,17 @@ package csaf
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
_ "embed" // Used for embedding.
|
||||
"io"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
)
|
||||
|
||||
//go:embed schema/csaf_json_schema.json
|
||||
|
|
@ -64,13 +68,28 @@ var (
|
|||
compiledRolieSchema = compiledSchema{url: rolieSchemaURL}
|
||||
)
|
||||
|
||||
// loadURL loads the content of an URL from embedded data or
|
||||
// falls back to the global loader function of the jsonschema package.
|
||||
func loadURL(s string) (io.ReadCloser, error) {
|
||||
loader := func(data []byte) (io.ReadCloser, error) {
|
||||
return io.NopCloser(bytes.NewReader(data)), nil
|
||||
type schemaLoader http.Client
|
||||
|
||||
func (l *schemaLoader) loadHTTPURL(url string) (any, error) {
|
||||
client := (*http.Client)(l)
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch s {
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%s returned status code %d", url, resp.StatusCode)
|
||||
}
|
||||
|
||||
return jsonschema.UnmarshalJSON(resp.Body)
|
||||
}
|
||||
|
||||
// Load loads the schema from the specified url.
|
||||
func (l *schemaLoader) Load(url string) (any, error) {
|
||||
loader := func(data []byte) (any, error) {
|
||||
return jsonschema.UnmarshalJSON(bytes.NewReader(data))
|
||||
}
|
||||
switch url {
|
||||
case csafSchemaURL:
|
||||
return loader(csafSchema)
|
||||
case cvss20SchemaURL:
|
||||
|
|
@ -86,14 +105,27 @@ func loadURL(s string) (io.ReadCloser, error) {
|
|||
case rolieSchemaURL:
|
||||
return loader(rolieSchema)
|
||||
default:
|
||||
return jsonschema.LoadURL(s)
|
||||
// Fallback to http loader
|
||||
return l.loadHTTPURL(url)
|
||||
}
|
||||
}
|
||||
|
||||
func newSchemaLoader(insecure bool) *schemaLoader {
|
||||
httpLoader := schemaLoader(http.Client{
|
||||
Timeout: 15 * time.Second,
|
||||
})
|
||||
if insecure {
|
||||
httpLoader.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
}
|
||||
return &httpLoader
|
||||
}
|
||||
|
||||
func (cs *compiledSchema) compile() {
|
||||
c := jsonschema.NewCompiler()
|
||||
c.AssertFormat = true
|
||||
c.LoadURL = loadURL
|
||||
c.AssertFormat()
|
||||
c.UseLoader(newSchemaLoader(false))
|
||||
cs.compiled, cs.err = c.Compile(cs.url)
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +141,8 @@ func (cs *compiledSchema) validate(doc any) ([]string, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
valErr, ok := err.(*jsonschema.ValidationError)
|
||||
var valErr *jsonschema.ValidationError
|
||||
ok := errors.As(err, &valErr)
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -133,21 +166,21 @@ func (cs *compiledSchema) validate(doc any) ([]string, error) {
|
|||
if pi != pj {
|
||||
return pi < pj
|
||||
}
|
||||
return errs[i].Error < errs[j].Error
|
||||
return errs[i].Error.String() < errs[j].Error.String()
|
||||
})
|
||||
|
||||
res := make([]string, 0, len(errs))
|
||||
|
||||
for i := range errs {
|
||||
e := &errs[i]
|
||||
if e.Error == "" {
|
||||
if e.Error == nil {
|
||||
continue
|
||||
}
|
||||
loc := e.InstanceLocation
|
||||
if loc == "" {
|
||||
loc = e.AbsoluteKeywordLocation
|
||||
}
|
||||
res = append(res, loc+": "+e.Error)
|
||||
res = append(res, loc+": "+e.Error.String())
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
## Supported Go versions
|
||||
|
||||
We support the latest version and the one before
|
||||
the latest version of Go (currently 1.23 and 1.24).
|
||||
the latest version of Go (currently 1.24 and 1.25).
|
||||
|
||||
## Generated files
|
||||
|
||||
|
|
|
|||
|
|
@ -247,3 +247,9 @@ insecure = true
|
|||
In case you want to provide CSAF advisories from others
|
||||
that only qualify as CSAF publishers, see
|
||||
[how to use the `csaf_aggregator` as "CSAF proxy provider"](proxy-provider-for-aggregator.md).
|
||||
|
||||
Some providers may limit the rate of requests that may be sent to retrieve advisories.
|
||||
This may cause issues with the aggregator.
|
||||
In this case, the --rate option can be used to adjust the requests per second
|
||||
sent by each worker of the aggregator to an acceptable rate.
|
||||
(The rate that is considered acceptable depends on the provider.)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,13 @@ The option `timerange` allows to only check advisories from a given time
|
|||
interval. It can only be given once. See the
|
||||
[downloader documentation](csaf_downloader.md#timerange-option) for details.
|
||||
|
||||
Some providers may limit the rate of requests that may be sent to retrieve advisories.
|
||||
This may cause the checker to be unable to retrieve all advisories. In this case,
|
||||
the --rate option can be used to adjust the requests per second
|
||||
sent by the checker to an acceptable rate.
|
||||
(The rate that is considered acceptable depends on the provider.)
|
||||
|
||||
|
||||
You can ignore certain advisories while checking by specifying a list
|
||||
of regular expressions[^1] to match their URLs by using the `ignorepattern`
|
||||
option.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ to download more advisories at once. This may improve the overall speed of the d
|
|||
However, since this also increases the load on the servers, their administrators could
|
||||
have taken countermeasures to limit this.
|
||||
|
||||
For example, some providers may limit the rate of requests that may be sent to retrieve advisories.
|
||||
This may cause the downloader to be unable to retrieve all advisories.
|
||||
In this case, the --rate option can be used to adjust the requests per second
|
||||
sent by the downloader to an acceptable rate.
|
||||
(The rate that is considered acceptable depends on the provider.)
|
||||
|
||||
If no config file is explictly given the follwing places are searched for a config file:
|
||||
|
||||
```
|
||||
|
|
@ -69,7 +75,7 @@ insecure = false
|
|||
# client_cert # not set by default
|
||||
# client_key # not set by default
|
||||
# client_passphrase # not set by default
|
||||
ignoresigcheck = false
|
||||
ignore_sigcheck = false
|
||||
# rate # set to unlimited
|
||||
worker = 2
|
||||
# time_range # not set by default
|
||||
|
|
@ -104,8 +110,9 @@ ignorepattern = [".*white.*", ".*red.*"]
|
|||
|
||||
#### Timerange option
|
||||
|
||||
The `timerange` parameter enables downloading advisories which last changes falls
|
||||
into a given intervall. There are three possible notations:
|
||||
The `time_range` parameter enables downloading advisories
|
||||
which last changes falls into a given intervall.
|
||||
There are three possible notations:
|
||||
|
||||
1. Relative. If the given string follows the rules of a
|
||||
[Go duration](https://pkg.go.dev/time@go1.20.6#ParseDuration),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ The following example file documents all available configuration options:
|
|||
# The following shows an example of a manually set prefix:
|
||||
#canonical_url_prefix = "https://localhost"
|
||||
|
||||
# Require users to use a password and a valid Client Certificate for write access.
|
||||
# Require users to use both
|
||||
# (1) a password and (2) a valid Client Certificate for write access.
|
||||
#certificate_and_password = false
|
||||
|
||||
# Allow the user to send the request without having to send a passphrase
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ on a GNU/Linux operating system.
|
|||
|
||||
Create the folders:
|
||||
```(shell)
|
||||
curl https://192.168.56.102/cgi-bin/csaf_provider.go/create --cert-type p12 --cert {clientCertificat.p12}
|
||||
curl https://192.168.56.102/cgi-bin/csaf_provider.go/api/create --cert-type p12 --cert {clientCertificat.p12}
|
||||
```
|
||||
Replace {clientCertificate.p12} with the client certificate file
|
||||
in pkcs12 format which includes the corresponding key as well.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Scripts for assisting the Integration tests.
|
||||
They were written on Ubuntu 20.04 TLS amd64 and also tested with 24.04 TLS.
|
||||
They were written on Ubuntu 20.04 LTS amd64 and also tested with 24.04 LTS.
|
||||
|
||||
- `prepareUbuntuInstanceForITests.sh` installs the required packages for the csaf integration tests on a naked Ubuntu LTS amd64.
|
||||
|
||||
|
|
@ -8,9 +8,9 @@ and configures nginx for serving TLS connections.
|
|||
|
||||
- `TLSClientConfigsForITest.sh` generates client certificates by calling `createCCForITest.sh` which uses the root certificate initialized before with `createRootCAForITest.sh`. It configures nginx to enable the authentication with client certificate. (This assumes that the same folder name is used to create the root certificate)
|
||||
|
||||
- `setupProviderForITest.sh` builds the csaf_provider, writes the required nginx configurations and create the initial folders. IT calls `uploadToProvider.sh` to upload some csaf example files to the provider.
|
||||
- `setupProviderForITest.sh` builds the `csaf_provider`, writes the required nginx configurations and create the initial folders. IT calls `uploadToProvider.sh` to upload some csaf example files to the provider.
|
||||
|
||||
As creating the folders needs to authenticate with the csaf_provider, the configurations of TLS server and Client certificate authentication should be set. So it is recommended to call the scripts in this order: `TLSConfigsForITest.sh`, `TLSClientConfigsForITest.sh`, `setupProviderForITest.sh`
|
||||
As creating the folders needs to authenticate with the `csaf_provider`, the configurations of TLS server and Client certificate authentication should be set. So it is recommended to call the scripts in this order: `TLSConfigsForITest.sh`, `TLSClientConfigsForITest.sh`, `setupProviderForITest.sh`
|
||||
|
||||
Calling example (as user with sudo privileges):
|
||||
``` bash
|
||||
|
|
|
|||
34
go.mod
34
go.mod
|
|
@ -1,31 +1,33 @@
|
|||
module github.com/gocsaf/csaf/v3
|
||||
|
||||
go 1.22.9
|
||||
go 1.24.9
|
||||
|
||||
toolchain go1.25.3
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/BurntSushi/toml v1.5.0
|
||||
github.com/Intevation/gval v1.3.0
|
||||
github.com/Intevation/jsonpath v0.2.1
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.8.0
|
||||
github.com/PuerkitoBio/goquery v1.8.1
|
||||
github.com/gofrs/flock v0.12.1
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.9.0
|
||||
github.com/PuerkitoBio/goquery v1.11.0
|
||||
github.com/gofrs/flock v0.13.0
|
||||
github.com/jessevdk/go-flags v1.6.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
go.etcd.io/bbolt v1.3.11
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/term v0.26.0
|
||||
golang.org/x/time v0.8.0
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
|
||||
go.etcd.io/bbolt v1.4.3
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/term v0.38.0
|
||||
golang.org/x/time v0.14.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ProtonMail/go-crypto v1.1.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/cloudflare/circl v1.5.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
)
|
||||
|
|
|
|||
114
go.sum
114
go.sum
|
|
@ -1,28 +1,30 @@
|
|||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/Intevation/gval v1.3.0 h1:+Ze5sft5MmGbZrHj06NVUbcxCb67l9RaPTLMNr37mjw=
|
||||
github.com/Intevation/gval v1.3.0/go.mod h1:xmGyGpP5be12EL0P12h+dqiYG8qn2j3PJxIgkoOHO5o=
|
||||
github.com/Intevation/jsonpath v0.2.1 h1:rINNQJ0Pts5XTFEG+zamtdL7l9uuE1z0FBA+r55Sw+A=
|
||||
github.com/Intevation/jsonpath v0.2.1/go.mod h1:WnZ8weMmwAx/fAO3SutjYFU+v7DFreNYnibV7CiaYIw=
|
||||
github.com/ProtonMail/go-crypto v1.1.2 h1:A7JbD57ThNqh7XjmHE+PXpQ3Dqt3BrSAC0AL0Go3KS0=
|
||||
github.com/ProtonMail/go-crypto v1.1.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=
|
||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.8.0 h1:WvMv3CMcFsqKSM4/Qf8sf3tgyQkzDqQmoSE49bnBuP4=
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.8.0/go.mod h1:qb2GUSnmA9ipBW5GVtCtEhkummSlqs2A8Ar3S0HBgSY=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
|
||||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
|
||||
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.9.0 h1:ruLzBmwe4dR1hdnrsEJ/S7psSBmV15gFttFUPP/+/kE=
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.9.0/go.mod h1:IldDyh9Hv1ZCCYatTuuEt1XZJ0OPjxLpTarDfglih7s=
|
||||
github.com/PuerkitoBio/goquery v1.11.0 h1:jZ7pwMQXIITcUXNH83LLk+txlaEy6NVOfTuP43xxfqw=
|
||||
github.com/PuerkitoBio/goquery v1.11.0/go.mod h1:wQHgxUOU3JGuj3oD/QFfxUdlzW6xPHfqyHre6VMY4DQ=
|
||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
|
||||
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
|
||||
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
|
||||
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
|
|
@ -31,67 +33,93 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||
go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
|
||||
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ func TestLoadCertificates(t *testing.T) {
|
|||
passphrase = "qwer"
|
||||
missingCert = "data/testclientcert_missing.crt"
|
||||
missingTestkey = "data/testclientkey_missing.pem"
|
||||
privateKey = "data/privated.pem"
|
||||
privateKey = "data/private.pem"
|
||||
privateCert = "data/cert.crt"
|
||||
)
|
||||
|
||||
// Try to load cert that is not protected, expect success.
|
||||
if cert, err := LoadCertificate(&testCert, &testKey, nil); cert == nil || err != nil {
|
||||
t.Errorf("Failure: Couldn't load supposedly valid certificate.")
|
||||
t.Errorf("Failure: Couldn't load supposedly valid certificate. Got error: %v", err)
|
||||
}
|
||||
// Try to load no cert, expect error.
|
||||
if cert, err := LoadCertificate(nil, &testKey, nil); cert != nil || err == nil {
|
||||
|
|
@ -46,7 +46,7 @@ func TestLoadCertificates(t *testing.T) {
|
|||
}
|
||||
// Try to load encrypted cert, expecting success.
|
||||
if cert, err := LoadCertificate(&privateCert, &privateKey, &passphrase); cert == nil || err != nil {
|
||||
t.Errorf("Failure: Couldn't load supposedly valid encrypted certificate.")
|
||||
t.Errorf("Failure: Couldn't load supposedly valid encrypted certificate. Got error: %v", err)
|
||||
}
|
||||
// Try to load wrong encrypted cert, expecting error.
|
||||
if cert, err := LoadCertificate(&testKey, &privateKey, &passphrase); cert != nil || err == nil {
|
||||
|
|
@ -56,8 +56,8 @@ func TestLoadCertificates(t *testing.T) {
|
|||
if cert, err := LoadCertificate(&missingCert, &privateKey, &passphrase); cert != nil || err == nil {
|
||||
t.Errorf("Failure: No Failure while loading nonexistens certificate.")
|
||||
}
|
||||
// Try to load nonexistent encrypted cert, expecting error.
|
||||
// Try to load nonexistent encrypted cert, expecting success.
|
||||
if cert, err := LoadCertificate(nil, nil, nil); cert != nil || err != nil {
|
||||
t.Errorf("Failure: Expected nil return.")
|
||||
t.Errorf("Failure: Expected nil return. Got error: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
60
internal/certs/createTestCerts.sh
Executable file
60
internal/certs/createTestCerts.sh
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: 2025 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
# Software-Engineering: 2025 Intevation GmbH <https://intevation.de>
|
||||
|
||||
# cab be used to generated the certificates for the go tests
|
||||
# as the resulting files are in the repository, this script does not
|
||||
# need to be run each time, its purpose is to document how the keys and
|
||||
# certs were created
|
||||
|
||||
set -e
|
||||
|
||||
certtool --generate-privkey --outfile testserver-key.pem
|
||||
|
||||
|
||||
echo '
|
||||
organization = "CSAF"
|
||||
unit = "CSAF Distribution"
|
||||
country = "DE"
|
||||
cn = "csaf.test"
|
||||
|
||||
dns_name = "csaf.test"
|
||||
dns_name = "localhost"
|
||||
dns_name = "*.csaf.test"
|
||||
ip_address = "127.0.0.1"
|
||||
ip_address = "::1"
|
||||
|
||||
tls_www_server
|
||||
tls_www_client
|
||||
ocsp_signing_key
|
||||
encryption_key
|
||||
signing_key
|
||||
expiration_days = 36500
|
||||
' > gnutls-certtool.testserver.template
|
||||
|
||||
certtool --generate-self-signed --load-privkey testserver-key.pem --outfile cert.crt --template gnutls-certtool.testserver.template --stdout | head -1
|
||||
|
||||
# for testing legacy code path, we use openssl's traditional mode to
|
||||
# create a password protected variant after RFC 1423 that still can be read
|
||||
# by https://pkg.go.dev/crypto/x509#DecryptPEMBlock. Citation:
|
||||
# Legacy PEM encryption as specified in RFC 1423 is insecure by design.
|
||||
# Since it does not authenticate the ciphertext, it is vulnerable
|
||||
# to padding oracle attacks that can let an attacker recover the plaintext.
|
||||
openssl rsa -in testserver-key.pem -out private.pem -aes256 -passout pass:qwer -traditional
|
||||
|
||||
echo '
|
||||
organization = "CSAF Tools Development (internal)"
|
||||
country = "DE"
|
||||
cn = "Tester"
|
||||
|
||||
tls_www_client
|
||||
encryption_key
|
||||
signing_key
|
||||
|
||||
expiration_days = 36500
|
||||
' > gnutls-certtool.testclientkey.template
|
||||
|
||||
certtool --generate-privkey --bits 3072 --outfile testclientkey.pem
|
||||
certtool --generate-self-signed --load-privkey testclientkey.pem --template gnutls-certtool.testclientkey.template --outfile testclient.crt
|
||||
|
|
@ -1,37 +1,28 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGajCCBNKgAwIBAgIUGNi4GgCUssOOe3k0VuHf3R0+d54wDQYJKoZIhvcNAQEL
|
||||
BQAwgY0xFDASBgNVBAMTC0NvbW1vbiBuYW1lMRMwEQYDVQQLEwppbnRldmF0aW9u
|
||||
MRMwEQYDVQQKEwppbnRldmF0aW9uMRMwEQYDVQQHEwppbnRldmF0aW9uMRUwEwYD
|
||||
VQQIEwxMb3dlciBTYXhvbnkxCzAJBgNVBAYTAkdFMRIwEAYKCZImiZPyLGQBGRYC
|
||||
REMwHhcNMjMwOTE5MDcwMDA1WhcNMjYwNjE0MDcwMDA3WjCB8DEQMA4GA1UEAxMH
|
||||
cmVxdWVzdDETMBEGA1UECxMKaW50ZXZhdGlvbjETMBEGA1UEChMKaW50ZXZhdGlv
|
||||
bjETMBEGA1UEBxMKb3NuYWJydWVjazEVMBMGA1UECBMMbG93ZXIgc2F4b255MQsw
|
||||
CQYDVQQGEwJHRTESMBAGCgmSJomT8ixkARkWAkRDMREwDwYKCZImiZPyLGQBGRYB
|
||||
LjERMA8GCgmSJomT8ixkARkWAS4xETAPBgoJkiaJk/IsZAEZFgEuMRMwEQYKCZIm
|
||||
iZPyLGQBGRYDd3d3MRcwFQYKCZImiZPyLGQBARMHbm8gaWRlYTCCAaIwDQYJKoZI
|
||||
hvcNAQEBBQADggGPADCCAYoCggGBAN0vZbLXtRzd61rR8Hos0BGnqCaJXIwGARwx
|
||||
JojMyxASFT+KeC4QDRkgRrK6OY4k/i7TEHuUGk/Bm754++554wmmhDqv1Q4+VhhR
|
||||
1K/JAz/HVZNTAR1rPKwG82lyEpPxlRNZg/QtF9DqQSoSkL/fJLs+rq4zlKozXzRE
|
||||
auZ5Be8So1dXRZfMVUMDgtk+IX8+iCeZisiWfv62ttQ0EiuiXLagd6ruEuoCSVi2
|
||||
tVswsC/Hp8AI2Ro56mmHiWthuae1H8yDWUFLSe9AQW65qC/xVUgo/nMpK2BYVFKb
|
||||
70TMjl/dZM0Qn1tdiNyqCkbIhXjklZvZYhO+15TPkgDXDsqRUjpTrLZXLGrD6XIx
|
||||
CRLZGY6YrUfsFTjUC6JrUrAR8zY7SLsYN5sUmFUSMpJnI+T/SD4p/0CXrKrbMOjW
|
||||
Qqz6FX/WHPxvswGKHk5zHYGHrzx7OKmfVa6gzUgZSfOHj2xOOR2Un9DwNavIrmSC
|
||||
WYXKZqig5qDyfzBvlXWEio/5GrDwgQIDAQABo4IBWzCCAVcwgcIGA1UdEQSBujCB
|
||||
t4IrYSBkbnNOYW1lIG9mIHRoZSBzdWJqZWN0IG9mIHRoZSBjZXJ0aWZpY2F0ZYI3
|
||||
YW4gYWRkaXRpb25hbCBkbnNOYW1lIG9mIHRoZSBzdWJqZWN0IG9mIHRoZSBjZXJ0
|
||||
aWZpY2F0ZYIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIBLoIP
|
||||
c2Vjb25kIGFkZGl0aW9ugg50aGlyZCBhZGRpdGlvboIHZG5zTmFtZTAMBgNVHRMB
|
||||
Af8EAjAAMDEGA1UdJQQqMCgGCCsGAQUFBwMJBggrBgEFBQcDAgYIKwYBBQUHAwEG
|
||||
CCsGAQUFBwMCMA8GA1UdDwEB/wQFAwMHsAAwHQYDVR0OBBYEFKrFhODjTKCopb+W
|
||||
Qa29PsHR4HXgMB8GA1UdIwQYMBaAFCyZxCa1ZUHVy8LjikE8zumAiEgfMA0GCSqG
|
||||
SIb3DQEBCwUAA4IBgQBTrAgh6d+qiLumEfmkNCmhewxKxDZp+Ni2nz9XRzNO2cQE
|
||||
U0n8MdbnQInW3xJXng2sAcl1fQz0RN1hkyjDwi69mbbPgcTYmxJFvyt+zRYBe/Sq
|
||||
4CGGkxEdPW94tMpQ6SrCn2mAMnvcq9A1pYBVYyPeUsaRHC5OUBFOMCevNy8JwNyY
|
||||
MJ0H5HQCyCysbzA1d521pogGUs/tmbE+ym9zpV8vG0b6De1PexjVeGkTNYz6NCR2
|
||||
VZTQ+OJ5iE5pHPEC1Qif44LrR9Kdn/wu3RjTYyHeBOJFjK+DKgleNF4QVTcZQIPE
|
||||
snN4H+/VSgTZQ3kgWbtpd1m5oRBJovEc2Qe+l+iDFCk8OA4z/x+fkvOeD3NUAl7D
|
||||
9Pt3cP3UtWUJp4NJn2dvUljmQhB02HSqdNBhqKSg4/cf7l8Zo1ejvBUosrlgw3C3
|
||||
apDaC4/xk7woFKVYW25teH2ze+Gpz/YsLDtmL7Bri8CGVsqsN9yqO8SstwKBa3Rt
|
||||
xQ2em6XnnanApT4iFX4=
|
||||
MIIE2DCCA0CgAwIBAgIUT/9u6/HtTciy3NB6UGXu+U+UzT8wDQYJKoZIhvcNAQEL
|
||||
BQAwTDELMAkGA1UEBhMCREUxDTALBgNVBAoTBENTQUYxGjAYBgNVBAsTEUNTQUYg
|
||||
RGlzdHJpYnV0aW9uMRIwEAYDVQQDEwljc2FmLnRlc3QwIBcNMjUxMDE3MTAyMjM1
|
||||
WhgPMjEyNTA5MjMxMDIyMzVaMEwxCzAJBgNVBAYTAkRFMQ0wCwYDVQQKEwRDU0FG
|
||||
MRowGAYDVQQLExFDU0FGIERpc3RyaWJ1dGlvbjESMBAGA1UEAxMJY3NhZi50ZXN0
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwqJ45WlBG5CqW3Meewsf
|
||||
Es1tqQRsHS/L6Hlz/aTZQHte/Co18qklnza0ZvK0mbPsQ8HLKXfU6Am5yw3u6vZj
|
||||
XNfhWDW4QtsSk9f/y/fBADw17qYinoVyLpqZU5Z6kFRY5npY0C9bCtsAZd4qimx5
|
||||
yu/MhM8LHI9K2oKPSkFgRCTRKAo9sZ97o4wZmTxJIasOr0SPpmfMLs2sHSEqcK4d
|
||||
/RxZ+OtYtd3pmE/WjxtSozCkdAccvrH+TSAuF3+/6oBiov8yX0KPNEBiiwuDXMUD
|
||||
QWkjfcrxQZAswMWRo55JJYBbIjrinW8vldLooFo5trNEE2nukgRPhvLhiJdKKAeg
|
||||
+A8jM/Bx7JgjRCPppIEmWdvXg+CS6L0hGj49pg3OcIiNNoufoXPRkFqmRh72n1Oj
|
||||
2RC13W8H3C3SDYz20mqJhkbci+05vO/LgKj9te8xEs/xa4xCtv7ycuB2Etzf1cWS
|
||||
zfz5LGXwwLI0rjpx3OAsr5i8Fukxe5maYLS9AUCTetTnAgMBAAGjga8wgawwDAYD
|
||||
VR0TAQH/BAIwADAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF
|
||||
BwMJMEQGA1UdEQQ9MDuCCWNzYWYudGVzdIIJbG9jYWxob3N0ggsqLmNzYWYudGVz
|
||||
dIcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0O
|
||||
BBYEFN2InaQvsu6hULCYeKc6pdE4VgVHMA0GCSqGSIb3DQEBCwUAA4IBgQBjPdXd
|
||||
2xHzce3mi4RlANT4nOSdpELhl54xeJDgI9Evt70N8B4uTmOI5+F6JVICE25cnDs1
|
||||
c9SoHpWzh1ZuzfiBYa/cdQNUtaTfgHLi5GYtV1DzmKXVRUciBiNBWWxYMbTGvTOO
|
||||
i3r6DEgOYuukeL4qj//EGOcTJEarHVSxPMuXTD/PoP/VpIdqRS9drEpFUC6lecZc
|
||||
UJtUPAcyx0oD2vNmPmulDfYFMLLOPrIeNa0g7os4wgUl7+9wR1cPPRTXY0fW6Hoi
|
||||
j+a8Qn80Q3PrOuEO/SZ4aHHpOk90bRqofyIhFjPwS0YN5w/Sn23uq1u2Dx+Zy+5K
|
||||
6Cs9p5dJWu5/zU4ZdbQlpYIHXQVbido1TY92Z84skEsac2wVh7L2LMB3p3Gu9WYn
|
||||
oKqFYCw5FICvRgyh1KG8QWhW59Em0Jxr8rTw6qyBQACdixKy6/1ok2ArMivTC8Gd
|
||||
rEbefshgc6dnAZCAp1MjCU+tg9iYEymSSLdOtUKvHEIosUGO1p5ol0hReTQ=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
|||
42
internal/certs/data/private.pem
Normal file
42
internal/certs/data/private.pem
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,3ACC7169D177F0159193ACAF3B3997A3
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,054A583F6C90570F
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,27 +1,26 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEkDCCAvigAwIBAgIBFDANBgkqhkiG9w0BAQsFADBKMQ8wDQYDVQQDEwZUZXN0
|
||||
ZXIxKjAoBgNVBAoTIUNTQUYgVG9vbHMgRGV2ZWxvcG1lbnQgKGludGVybmFsKTEL
|
||||
MAkGA1UEBhMCREUwHhcNMjMwOTA0MDcyMjAzWhcNMjMxMDI0MDcyMjAzWjBVMRow
|
||||
GAYDVQQDExFUTFMgVGVzdCBDbGllbnQgMTEqMCgGA1UEChMhQ1NBRiBUb29scyBE
|
||||
ZXZlbG9wbWVudCAoaW50ZXJuYWwpMQswCQYDVQQGEwJERTCCAaIwDQYJKoZIhvcN
|
||||
AQEBBQADggGPADCCAYoCggGBAN0vZbLXtRzd61rR8Hos0BGnqCaJXIwGARwxJojM
|
||||
yxASFT+KeC4QDRkgRrK6OY4k/i7TEHuUGk/Bm754++554wmmhDqv1Q4+VhhR1K/J
|
||||
Az/HVZNTAR1rPKwG82lyEpPxlRNZg/QtF9DqQSoSkL/fJLs+rq4zlKozXzREauZ5
|
||||
Be8So1dXRZfMVUMDgtk+IX8+iCeZisiWfv62ttQ0EiuiXLagd6ruEuoCSVi2tVsw
|
||||
sC/Hp8AI2Ro56mmHiWthuae1H8yDWUFLSe9AQW65qC/xVUgo/nMpK2BYVFKb70TM
|
||||
jl/dZM0Qn1tdiNyqCkbIhXjklZvZYhO+15TPkgDXDsqRUjpTrLZXLGrD6XIxCRLZ
|
||||
GY6YrUfsFTjUC6JrUrAR8zY7SLsYN5sUmFUSMpJnI+T/SD4p/0CXrKrbMOjWQqz6
|
||||
FX/WHPxvswGKHk5zHYGHrzx7OKmfVa6gzUgZSfOHj2xOOR2Un9DwNavIrmSCWYXK
|
||||
Zqig5qDyfzBvlXWEio/5GrDwgQIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1Ud
|
||||
JQQMMAoGCCsGAQUFBwMCMA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFKrFhODj
|
||||
TKCopb+WQa29PsHR4HXgMB8GA1UdIwQYMBaAFI6GhktAq9L2uRChC9LcXeedKiUg
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBgQAbUDaIkmubooDde7BpZQx742BsPg4IN68bIg9A
|
||||
3jI9codx9c8l9ROvZ/7FeRNXzhYrQUwzcKpwtQ1mB7kM85oXaTLxrtnkZAO2fFSb
|
||||
8RA6QjOrnOvewWaO3moCZaPnN1wWtlnUev2tD7D2Tz/f20dE2wbDV0BGb8bU4eGI
|
||||
UVgzYrMh0MHaC8LKoXUWP97jp/p+9CG4D2S1CmpzP2Nm1dS03oj4UHIUtamjivYY
|
||||
vOeoKATXmj59lgYqqoAVbTH6f4mZlZGmzUhRxK6hck7xBdiXAwfta72m4WzE7HRh
|
||||
nHAgO5aVWb6zltvVDJhYumB9Itv+LI7uU8fF9Uyc65SZ2BevxgikoDNxTx0oNr+4
|
||||
hExQhJfKuPFF2NI1N2tPYJT53Cek/ZJfjX3TyBneqehthtRqoAIIEaF/QlXqzJIi
|
||||
G66YFC3xFlLmaQh52DJkF2+hzcPhFTVQv3yCirGLUSS9Nm7vTO2wnnW5arZazSV+
|
||||
enRZb3oiVYFVDh0Hymz9g5VraMw=
|
||||
MIIEeDCCAuCgAwIBAgIUTqTcNqmr8Ou/MpL1AUnM/3gcoUkwDQYJKoZIhvcNAQEL
|
||||
BQAwSjELMAkGA1UEBhMCREUxKjAoBgNVBAoTIUNTQUYgVG9vbHMgRGV2ZWxvcG1l
|
||||
bnQgKGludGVybmFsKTEPMA0GA1UEAxMGVGVzdGVyMCAXDTI1MTAxNzEwMjIzNloY
|
||||
DzIxMjUwOTIzMTAyMjM2WjBKMQswCQYDVQQGEwJERTEqMCgGA1UEChMhQ1NBRiBU
|
||||
b29scyBEZXZlbG9wbWVudCAoaW50ZXJuYWwpMQ8wDQYDVQQDEwZUZXN0ZXIwggGi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDBN4fIBbwuGJXjXoa6F7e4Zzin
|
||||
Yd9EB4nt5TkNoMkRgQe0JIJ+t1/lS/xlI7ATxNjUdybnYwCrEfDvy8XGwN6te+Xh
|
||||
dz6HKDWPijW+ritQW9kouxJJSpna95L8SqU4tjdfyL/2X9E/7j3VYw1//zcmhLJg
|
||||
1Os0+JHPcPuj1vmwLa1v7eGTCNlt0K8DbrlhPlteJB3hWolNIoVDjRemZFmqwUeV
|
||||
GZ/XJos7OTB07p08yCOFhLl9jXCgEDDkKmcnAil3YhjudlEGSjdzFLskVD4xrtQ5
|
||||
GsbdJHyHhcUdgh+vqX2bFSklwdwVil1qIUEHnxpcRMaluZQ4u1tCgNhKNQHrJzVQ
|
||||
n1aRVAYdX1PxfoIb5wt0+25MiVw8y8EcrMH97Ss26eNAtLeHZNrY9alqx/Cs8gOi
|
||||
I8wA2Nga138tZuCJRXsDOnom9RrtdPLajhSb7n33Iq8ZDhYVGEIm2pc5MJxaI53V
|
||||
e2WhmemFPfYwUAtzdGgwrBoY9MechdtNLGZqHxECAwEAAaNUMFIwDAYDVR0TAQH/
|
||||
BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0O
|
||||
BBYEFBVaa/ovyPpbk/8nlmuISWB2/t8xMA0GCSqGSIb3DQEBCwUAA4IBgQC8EeDx
|
||||
qipM7bAFxkAOmvhNAjodKXRCWKhatD8HryeINOPgWajzLlHj/PCnULulhaFO1viA
|
||||
+iBBKbHb+7LImb/owlNVu8iYDh/xBXmLrOHyd12K8dyN471iTBrskQwSCnYd6e/p
|
||||
4i0hhNj5JidOgA6swjt9j4X7/IgsvXexLIAhqgQDSsKQpPK17E9IB+d5p3UHU71w
|
||||
Ob1mGIZ2j/GJnC6YmGFPqIZZ+cy3aVOypWf8RVZYPTFCz43ZuC70cP3kl2io75Rp
|
||||
rWUNKXU+yUdBphHN6KJXUmlH4T9yqXKqnxK+9CnVC/CTlucF9VpktN7wfVxVPsrY
|
||||
L79iys+FLPKrDkqcjpIJ2l/n/ugcUcXvN477qFCGbRY/3tB3Dmf4AvMPpTsStkXw
|
||||
Ld+xAHog8upjVGsmXODX4sKjRMIFLIHbM01Iw0ECdKoKIMwjFGenwGmpBZA/Pfxe
|
||||
AXBejd9KD0stCfHuKqx7Iu5N7Fg8BCLzmcSyoOmwJEo+Z3Z42IfSjOX8rQQ=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
|||
|
|
@ -3,180 +3,180 @@ Public Key Info:
|
|||
Key Security Level: High (3072 bits)
|
||||
|
||||
modulus:
|
||||
00:dd:2f:65:b2:d7:b5:1c:dd:eb:5a:d1:f0:7a:2c:d0
|
||||
11:a7:a8:26:89:5c:8c:06:01:1c:31:26:88:cc:cb:10
|
||||
12:15:3f:8a:78:2e:10:0d:19:20:46:b2:ba:39:8e:24
|
||||
fe:2e:d3:10:7b:94:1a:4f:c1:9b:be:78:fb:ee:79:e3
|
||||
09:a6:84:3a:af:d5:0e:3e:56:18:51:d4:af:c9:03:3f
|
||||
c7:55:93:53:01:1d:6b:3c:ac:06:f3:69:72:12:93:f1
|
||||
95:13:59:83:f4:2d:17:d0:ea:41:2a:12:90:bf:df:24
|
||||
bb:3e:ae:ae:33:94:aa:33:5f:34:44:6a:e6:79:05:ef
|
||||
12:a3:57:57:45:97:cc:55:43:03:82:d9:3e:21:7f:3e
|
||||
88:27:99:8a:c8:96:7e:fe:b6:b6:d4:34:12:2b:a2:5c
|
||||
b6:a0:77:aa:ee:12:ea:02:49:58:b6:b5:5b:30:b0:2f
|
||||
c7:a7:c0:08:d9:1a:39:ea:69:87:89:6b:61:b9:a7:b5
|
||||
1f:cc:83:59:41:4b:49:ef:40:41:6e:b9:a8:2f:f1:55
|
||||
48:28:fe:73:29:2b:60:58:54:52:9b:ef:44:cc:8e:5f
|
||||
dd:64:cd:10:9f:5b:5d:88:dc:aa:0a:46:c8:85:78:e4
|
||||
95:9b:d9:62:13:be:d7:94:cf:92:00:d7:0e:ca:91:52
|
||||
3a:53:ac:b6:57:2c:6a:c3:e9:72:31:09:12:d9:19:8e
|
||||
98:ad:47:ec:15:38:d4:0b:a2:6b:52:b0:11:f3:36:3b
|
||||
48:bb:18:37:9b:14:98:55:12:32:92:67:23:e4:ff:48
|
||||
3e:29:ff:40:97:ac:aa:db:30:e8:d6:42:ac:fa:15:7f
|
||||
d6:1c:fc:6f:b3:01:8a:1e:4e:73:1d:81:87:af:3c:7b
|
||||
38:a9:9f:55:ae:a0:cd:48:19:49:f3:87:8f:6c:4e:39
|
||||
1d:94:9f:d0:f0:35:ab:c8:ae:64:82:59:85:ca:66:a8
|
||||
a0:e6:a0:f2:7f:30:6f:95:75:84:8a:8f:f9:1a:b0:f0
|
||||
81:
|
||||
00:c1:37:87:c8:05:bc:2e:18:95:e3:5e:86:ba:17:b7
|
||||
b8:67:38:a7:61:df:44:07:89:ed:e5:39:0d:a0:c9:11
|
||||
81:07:b4:24:82:7e:b7:5f:e5:4b:fc:65:23:b0:13:c4
|
||||
d8:d4:77:26:e7:63:00:ab:11:f0:ef:cb:c5:c6:c0:de
|
||||
ad:7b:e5:e1:77:3e:87:28:35:8f:8a:35:be:ae:2b:50
|
||||
5b:d9:28:bb:12:49:4a:99:da:f7:92:fc:4a:a5:38:b6
|
||||
37:5f:c8:bf:f6:5f:d1:3f:ee:3d:d5:63:0d:7f:ff:37
|
||||
26:84:b2:60:d4:eb:34:f8:91:cf:70:fb:a3:d6:f9:b0
|
||||
2d:ad:6f:ed:e1:93:08:d9:6d:d0:af:03:6e:b9:61:3e
|
||||
5b:5e:24:1d:e1:5a:89:4d:22:85:43:8d:17:a6:64:59
|
||||
aa:c1:47:95:19:9f:d7:26:8b:3b:39:30:74:ee:9d:3c
|
||||
c8:23:85:84:b9:7d:8d:70:a0:10:30:e4:2a:67:27:02
|
||||
29:77:62:18:ee:76:51:06:4a:37:73:14:bb:24:54:3e
|
||||
31:ae:d4:39:1a:c6:dd:24:7c:87:85:c5:1d:82:1f:af
|
||||
a9:7d:9b:15:29:25:c1:dc:15:8a:5d:6a:21:41:07:9f
|
||||
1a:5c:44:c6:a5:b9:94:38:bb:5b:42:80:d8:4a:35:01
|
||||
eb:27:35:50:9f:56:91:54:06:1d:5f:53:f1:7e:82:1b
|
||||
e7:0b:74:fb:6e:4c:89:5c:3c:cb:c1:1c:ac:c1:fd:ed
|
||||
2b:36:e9:e3:40:b4:b7:87:64:da:d8:f5:a9:6a:c7:f0
|
||||
ac:f2:03:a2:23:cc:00:d8:d8:1a:d7:7f:2d:66:e0:89
|
||||
45:7b:03:3a:7a:26:f5:1a:ed:74:f2:da:8e:14:9b:ee
|
||||
7d:f7:22:af:19:0e:16:15:18:42:26:da:97:39:30:9c
|
||||
5a:23:9d:d5:7b:65:a1:99:e9:85:3d:f6:30:50:0b:73
|
||||
74:68:30:ac:1a:18:f4:c7:9c:85:db:4d:2c:66:6a:1f
|
||||
11:
|
||||
|
||||
public exponent:
|
||||
01:00:01:
|
||||
|
||||
private exponent:
|
||||
14:ff:c0:f9:ff:bc:b4:26:e5:87:53:d3:2e:e6:3e:42
|
||||
ce:d6:0a:02:94:84:be:b5:30:46:02:50:8e:90:e0:cf
|
||||
b6:b0:b7:a6:bd:48:cc:d5:8b:d8:ea:72:ff:af:dd:17
|
||||
3c:be:d1:1b:ca:6d:cd:10:a6:86:a8:d9:d2:44:44:27
|
||||
d0:65:51:65:0c:27:34:07:dc:7b:38:64:10:03:7c:f4
|
||||
a1:cd:40:de:24:3a:e0:21:bc:ef:33:1d:9f:61:e8:57
|
||||
ac:e4:9c:c0:7b:df:7c:f8:20:83:ac:0b:8e:0b:d3:62
|
||||
eb:8a:8e:03:5b:a3:e5:08:ae:df:a7:fe:85:92:e8:a5
|
||||
ae:58:46:72:d6:fc:91:43:b1:7b:a4:c0:5f:51:c3:50
|
||||
0d:e2:67:e8:af:51:13:41:a9:8d:ef:fb:a1:a4:e2:84
|
||||
7c:2b:a0:50:c5:fe:ed:84:a5:25:83:86:4a:d3:0f:56
|
||||
37:38:e6:1e:26:7d:45:22:0b:ba:22:35:be:f8:8b:1b
|
||||
72:90:13:c4:1f:c5:d1:34:b5:0e:b2:ee:f7:e1:b9:5e
|
||||
a2:29:8d:f9:6e:23:4b:50:8f:35:c8:a9:f3:d2:1f:dd
|
||||
ce:a0:96:50:2d:2e:af:cf:b5:e1:20:e7:e9:d2:49:ed
|
||||
b5:0e:5b:3e:d1:4b:f1:fa:c2:73:3a:1b:51:34:7e:75
|
||||
30:06:d2:47:d2:a8:2a:45:be:16:fb:8f:63:84:85:b7
|
||||
bf:f7:c4:c5:3d:95:56:8c:d1:02:7f:58:ac:4d:11:7b
|
||||
c5:55:f3:c8:4e:d7:d9:aa:62:b0:e3:1e:04:5c:97:d1
|
||||
ca:e2:71:aa:8b:33:b4:34:e9:04:d4:70:7c:f4:cb:57
|
||||
19:c1:03:23:f4:bc:4d:91:8f:b2:9a:99:1c:6c:81:2d
|
||||
4d:2d:e9:a1:e3:ce:e3:c9:62:52:89:1f:47:86:61:f1
|
||||
dd:bc:46:8d:79:0a:99:9d:aa:4b:a9:0a:72:54:db:dc
|
||||
ae:48:be:60:4a:73:99:d8:3c:9e:07:78:05:df:87:39
|
||||
70:0e:fd:af:d3:2b:ad:6c:52:d9:f8:43:99:00:12:6c
|
||||
5f:69:2b:22:87:33:54:4f:f9:69:fc:e9:db:7b:61:ac
|
||||
7c:c4:4c:7c:66:73:81:a9:61:a5:73:1e:fc:8a:aa:9a
|
||||
ba:b6:94:18:94:81:99:b5:a1:0f:e2:15:c5:4c:ac:98
|
||||
df:07:96:f8:ea:89:c6:97:31:b5:8d:b0:16:21:46:cc
|
||||
ce:28:62:3e:9b:c5:29:70:26:2f:d8:24:8e:a8:52:7d
|
||||
d1:0e:83:ce:a7:09:9b:d3:57:87:3f:98:5f:c8:ab:ba
|
||||
aa:31:2e:19:ae:84:1d:39:ab:9e:b2:42:f6:75:ff:68
|
||||
ae:73:00:fa:d7:a4:c5:3d:7c:4f:54:65:4e:1c:88:e6
|
||||
c2:b5:9d:a2:ca:38:61:45:09:17:01:68:5a:f7:4e:4d
|
||||
cb:24:f1:e3:57:a1:97:58:1e:b3:ef:57:91:e0:1d:95
|
||||
51:8c:a9:4a:4e:f7:cd:fe:f7:04:f3:ff:67:ad:e7:01
|
||||
14:dc:7e:e4:00:c0:38:51:2f:04:db:39:6c:f1:1b:a4
|
||||
a5:f1:b4:5a:c3:17:d2:41:1a:5a:b5:f3:69:3b:b8:ba
|
||||
7b:59:96:d7:b2:c2:2c:9a:dd:e9:42:ce:fb:c8:22:fc
|
||||
c5:33:97:6d:68:89:cd:e5:bc:2e:cc:9d:23:65:18:04
|
||||
0c:83:b6:35:7e:16:09:96:d1:48:61:31:b1:ce:f8:50
|
||||
f0:14:ba:57:2f:02:1b:61:9c:bc:81:c1:ef:b3:bf:2f
|
||||
fb:36:af:18:8c:90:40:55:5a:fd:a7:d4:ed:3b:94:a6
|
||||
df:ab:eb:6c:d2:bc:e3:80:7e:d5:06:21:28:9b:04:65
|
||||
b5:cc:04:b2:44:e9:2d:3b:7d:de:24:90:8d:fb:90:2d
|
||||
40:17:51:cf:a7:fa:ee:54:89:8f:c0:f4:e4:c2:bd:44
|
||||
94:1d:8d:fc:b7:d7:05:4d:46:dc:63:1f:7f:d8:b4:8b
|
||||
11:db:37:be:4d:e9:2b:33:b9:6b:8c:a7:f0:43:56:c5
|
||||
|
||||
|
||||
prime1:
|
||||
00:e9:63:0f:d7:49:31:27:a8:36:fe:95:bd:8d:05:c1
|
||||
35:48:2e:03:4f:a6:57:54:3a:a4:95:3f:8e:9f:28:7c
|
||||
d2:df:af:54:36:9e:7c:9f:c3:b9:64:8f:c0:b0:96:3c
|
||||
aa:01:f6:9a:be:83:e2:85:20:0d:33:de:88:97:af:6f
|
||||
be:3f:53:5a:a3:77:02:fd:81:17:91:3b:b2:2d:ab:78
|
||||
db:d9:43:db:04:69:82:61:30:e4:96:ac:88:8b:f6:3f
|
||||
56:c4:49:fd:d5:e5:8c:9d:30:ad:cf:d9:8d:5c:87:b5
|
||||
27:4b:09:8e:19:ed:e2:11:3f:69:b2:47:be:70:39:11
|
||||
41:a3:db:bb:b9:0e:e4:7b:50:d0:d2:c2:89:81:36:b9
|
||||
6b:a6:fe:94:5b:06:66:e6:ed:86:52:42:5e:a9:0e:18
|
||||
db:18:f9:14:21:3d:e0:3c:8d:79:c3:f5:d2:cc:51:65
|
||||
fb:1c:49:ed:0a:d5:33:99:34:16:f9:1d:68:4a:78:da
|
||||
5f:
|
||||
00:f0:57:25:fd:aa:7e:98:13:08:28:99:16:eb:af:2e
|
||||
22:f6:e6:d7:bd:df:49:57:17:71:bf:21:ba:bf:75:54
|
||||
5a:38:92:64:8c:4a:10:d4:4f:77:18:44:c2:79:f0:9d
|
||||
72:26:2e:9a:27:5d:e7:41:0b:c6:65:cb:fa:89:6d:9b
|
||||
fb:87:78:e2:87:22:d4:92:21:f5:3a:57:fa:b0:bf:bb
|
||||
66:a2:bf:43:af:e8:58:b4:e2:a1:ed:97:62:09:0d:49
|
||||
ca:4c:99:a2:f4:f3:31:df:80:8e:56:be:64:9d:72:59
|
||||
ef:e9:db:4d:a3:e2:cf:79:1e:99:89:b2:f1:e3:2d:bc
|
||||
8f:a0:2a:2f:a6:f0:21:18:2d:f1:57:20:55:c1:c9:18
|
||||
c1:64:c6:9c:00:df:b2:54:55:8d:fe:d3:46:a0:5c:2e
|
||||
f8:f7:10:b6:27:3a:4a:79:a1:14:b1:0c:c3:72:5b:2b
|
||||
66:d6:85:2c:7e:58:72:eb:33:62:73:34:e5:38:87:2e
|
||||
17:
|
||||
|
||||
prime2:
|
||||
00:f2:9d:ae:5f:bd:b7:a3:87:a7:8d:30:46:06:8b:15
|
||||
a9:e5:a9:58:1c:2b:3a:7e:78:35:36:56:31:42:df:46
|
||||
87:e8:57:0d:6e:99:de:cf:fb:a8:72:16:71:4b:b3:ad
|
||||
ed:74:07:cb:cf:7d:2b:12:89:66:c4:0f:8a:ea:e3:37
|
||||
17:2c:75:92:11:7a:a6:da:29:24:33:9b:69:c2:64:68
|
||||
03:db:31:de:fe:1d:a2:4d:9d:91:9f:f0:50:b8:8f:d0
|
||||
22:11:b9:b0:95:98:5e:65:bf:45:97:9b:35:f2:98:27
|
||||
46:7c:b2:86:eb:7b:8b:57:f2:c3:49:47:7d:01:4a:9a
|
||||
b0:e6:67:05:e5:61:7a:ab:63:c8:cb:d8:44:69:88:72
|
||||
a5:a9:60:89:60:df:e6:d9:4d:16:2b:35:7b:20:00:f3
|
||||
3c:d1:78:f9:22:eb:48:c3:7f:78:63:e6:34:60:48:30
|
||||
66:02:bb:38:c2:94:2e:b9:86:b2:2f:9a:4f:17:7f:e1
|
||||
1f:
|
||||
00:cd:ce:5d:fb:04:16:34:f4:de:02:7d:00:07:3e:b0
|
||||
94:8c:f4:3a:62:05:37:1a:4f:d8:40:2e:31:11:07:77
|
||||
09:8b:bd:76:6e:85:b9:43:df:3f:86:cb:db:6d:fe:c6
|
||||
4c:ca:e1:16:ce:5c:0e:e1:b1:10:0d:8d:48:99:d7:43
|
||||
7f:6c:b6:20:b2:cd:0c:56:26:02:18:81:e1:67:e5:cd
|
||||
b3:66:1e:77:dc:49:6a:5d:8c:9c:0e:24:14:3e:a1:4a
|
||||
7e:cf:72:e6:e4:03:e6:38:41:fa:2b:91:71:6c:33:b0
|
||||
ec:07:3a:be:5b:f8:74:f5:e4:1f:9c:c4:d0:d4:75:a8
|
||||
35:09:05:0f:7f:54:4e:2a:bc:cc:92:de:1e:f4:74:8a
|
||||
56:36:e0:b1:37:cf:b3:9c:57:05:76:59:69:c3:03:de
|
||||
c2:33:0c:c4:a1:4f:2a:b8:3c:20:63:c9:58:96:1a:e2
|
||||
62:ce:bf:fb:a9:51:b0:66:99:35:d6:d2:60:59:72:bd
|
||||
17:
|
||||
|
||||
coefficient:
|
||||
00:93:3e:7c:b9:ea:87:52:37:fa:d5:0a:36:fb:e1:d0
|
||||
fc:62:4d:00:0b:ad:a8:fb:bd:34:53:96:c2:6c:a1:6a
|
||||
49:b7:a0:24:33:16:95:79:14:ac:bb:75:8d:78:e9:10
|
||||
fa:be:44:60:58:94:4a:9c:ba:64:1d:86:27:8b:7f:51
|
||||
4d:80:b0:ff:7a:91:c0:4d:a4:aa:d1:f1:79:7d:8f:71
|
||||
49:12:73:d4:44:5f:0c:2e:55:a6:d9:13:b8:3b:e5:dc
|
||||
e1:14:98:7e:eb:5b:60:ad:d7:4b:da:c0:d8:3f:bf:70
|
||||
92:53:8c:31:6a:8b:61:5e:a3:7d:ff:84:2c:7d:ed:9f
|
||||
74:29:9a:e7:14:fb:c3:ab:8e:9f:60:6a:98:ab:86:0b
|
||||
ea:fb:ff:20:2f:3b:a7:76:03:3a:55:bb:b2:c6:9c:b5
|
||||
66:36:b8:1c:7f:9b:b6:62:89:ff:6a:d6:35:58:0b:f0
|
||||
55:27:01:f0:67:8d:88:3f:74:48:3d:bf:8c:fc:05:62
|
||||
47:
|
||||
33:6a:05:3e:1e:46:46:58:e2:61:38:6a:c2:8f:77:a2
|
||||
27:b7:19:38:75:40:d6:8c:87:bc:65:a6:24:c3:97:e5
|
||||
ef:70:1b:2c:4e:9c:08:ca:1d:eb:97:11:74:14:bb:99
|
||||
de:22:a1:6e:bc:6c:c6:25:98:8a:8e:17:f4:f9:4d:a3
|
||||
1d:01:5e:26:0e:b4:e8:1c:aa:06:7c:66:b1:89:5a:b4
|
||||
82:65:d1:bf:20:cb:b2:57:a8:af:7f:00:07:00:7c:5e
|
||||
d4:09:60:0c:0a:6e:a8:e1:16:1b:04:95:b1:bc:2b:35
|
||||
ad:80:78:0a:0a:1d:5f:c9:cc:24:3a:5e:20:03:50:44
|
||||
b8:b0:f3:f1:17:ff:41:b8:5d:56:9b:1c:f1:e6:2b:c6
|
||||
ba:a2:8c:18:25:8c:d5:90:f1:28:66:29:bb:40:3d:b2
|
||||
f9:65:99:2e:b7:1b:e3:d0:d2:1a:d7:96:70:cc:f6:74
|
||||
c5:2e:bf:f5:c9:60:c0:ff:38:f8:a8:db:1a:7d:6a:4e
|
||||
|
||||
|
||||
exp1:
|
||||
00:99:16:2d:91:dd:a4:ac:8a:9e:68:27:f8:89:c4:38
|
||||
93:a6:a0:e7:f3:1a:fd:35:76:b1:f6:64:16:3d:37:e5
|
||||
88:bc:c8:d8:c8:6a:f4:fc:26:fa:38:88:42:b0:92:1b
|
||||
80:b8:80:f5:c7:f9:e2:5f:c8:42:60:bf:9b:81:43:c6
|
||||
5c:58:55:68:a2:c8:b1:e1:6f:07:f2:6f:e1:d4:2b:21
|
||||
bf:b3:a7:da:c5:ee:1f:63:79:1a:b7:ea:bc:36:72:73
|
||||
e1:8a:27:ae:a4:db:49:7c:e2:2d:60:a5:27:20:86:b3
|
||||
c0:ee:6b:7a:16:6f:ff:55:a8:ee:bf:ce:67:90:5d:1e
|
||||
80:9b:e6:ca:1f:fd:30:c9:e2:9c:d7:62:5b:a7:b2:29
|
||||
b5:ff:78:06:00:1f:16:e8:6a:ed:2c:8f:f4:5f:97:ab
|
||||
9e:2b:a7:56:18:e7:e9:6a:4e:b2:8c:63:76:be:26:b6
|
||||
6a:1c:88:31:40:65:d0:ce:b1:68:50:47:85:dd:33:a0
|
||||
a9:
|
||||
5c:1b:49:f7:f9:0b:23:04:c8:2f:a6:db:dd:de:f8:f3
|
||||
75:63:ea:72:5d:cc:21:90:5e:8b:3d:45:f0:71:ea:ad
|
||||
d8:d8:61:a8:52:0a:39:13:6b:34:e5:c5:12:2e:60:68
|
||||
8a:b1:79:6a:74:d6:57:5b:47:e1:63:56:d4:ac:29:07
|
||||
30:57:e7:98:9a:84:94:ac:66:ea:c1:24:d5:ef:e4:c5
|
||||
e4:c1:20:13:9e:1b:c0:d6:c9:ef:e0:00:36:2f:dd:83
|
||||
a5:ef:8b:40:0c:a3:a4:60:04:2c:c2:32:95:14:69:db
|
||||
43:e8:43:cc:f6:f3:44:1b:b2:03:cf:8c:5b:df:ff:4f
|
||||
9b:b6:0f:25:0f:09:df:d6:5b:93:64:54:f9:3b:34:3d
|
||||
89:7d:83:f3:e1:c6:da:03:1f:b3:f5:0c:30:10:a3:ff
|
||||
cd:cf:9d:bf:52:db:8f:d9:67:b0:a2:8f:94:97:d3:fe
|
||||
49:60:28:39:13:74:97:26:ce:28:10:b1:78:04:76:69
|
||||
|
||||
|
||||
exp2:
|
||||
00:8d:b1:5f:7c:94:ed:62:39:40:b6:a9:a1:cc:02:80
|
||||
c5:77:d6:9e:19:dd:79:4d:11:61:6a:79:8e:4d:92:de
|
||||
bb:53:0b:3c:52:02:d5:69:3c:7d:95:1b:dc:51:2d:00
|
||||
00:35:0a:b4:92:5a:74:c4:5f:b0:c0:02:9f:cc:2c:a5
|
||||
29:08:93:25:9a:c5:ba:1a:a1:7a:7e:15:5e:ff:e3:ea
|
||||
07:8e:85:a2:c9:60:7f:40:bb:2c:a8:6f:0e:85:ab:a0
|
||||
0f:b5:b0:70:1b:fe:1f:eb:66:78:fb:60:ef:71:de:40
|
||||
d9:de:cb:d9:16:40:52:12:2c:3a:b7:5a:63:fc:54:18
|
||||
e2:05:bd:d7:68:ae:b4:98:d2:2f:1c:36:13:46:5b:25
|
||||
31:f1:28:eb:32:c3:b1:2b:e9:e4:6f:99:cd:6d:d4:80
|
||||
3a:5d:d0:3c:18:93:b7:2c:4e:0e:fe:b1:1c:97:ba:b1
|
||||
61:72:68:eb:6e:60:62:a5:81:b0:21:33:0a:cc:1b:a8
|
||||
5b:
|
||||
6e:6d:c5:d5:b3:8a:aa:dd:9c:e6:5e:e6:0d:fd:20:48
|
||||
85:1d:62:da:47:8c:1a:8d:2f:2e:b8:da:51:15:dd:54
|
||||
7c:eb:ab:49:80:6d:39:32:e7:e6:4f:2a:2d:6a:20:43
|
||||
02:35:26:c4:91:76:d6:b8:e8:31:2d:57:00:5d:15:f5
|
||||
a0:82:55:27:3b:88:dc:0c:c6:e1:19:87:b5:f5:03:9b
|
||||
b8:36:ae:ff:bf:50:d8:63:63:34:df:3d:11:a1:ff:d3
|
||||
ed:41:ed:0b:f9:df:a4:de:19:fb:18:ae:70:6d:88:08
|
||||
0d:95:02:a1:5c:be:7d:55:eb:74:75:d2:cb:bd:5a:05
|
||||
23:12:d9:0e:ec:50:88:f4:07:1c:e3:1c:5e:f4:cd:69
|
||||
97:46:97:30:a8:3c:ea:ad:72:db:de:fc:35:cc:b4:d1
|
||||
25:0d:3b:d0:86:27:18:f6:02:37:28:c9:64:b9:86:31
|
||||
98:58:41:13:c8:26:4b:d6:f7:a1:8d:fe:6e:e0:76:ff
|
||||
|
||||
|
||||
|
||||
Public Key PIN:
|
||||
pin-sha256:iFdBnKP/7hZCLdj7qqTtdNPFjpZGka259fSYvv3X02U=
|
||||
pin-sha256:Zv2mSFRUYM7ofg5obMJJxhZpnuvO7gkCOlqfDK1gzks=
|
||||
Public Key ID:
|
||||
sha256:8857419ca3ffee16422dd8fbaaa4ed74d3c58e964691adb9f5f498befdd7d365
|
||||
sha1:aac584e0e34ca0a8a5bf9641adbd3ec1d1e075e0
|
||||
sha256:66fda648545460cee87e0e686cc249c616699eebceee09023a5a9f0cad60ce4b
|
||||
sha1:155a6bfa2fc8fa5b93ff27966b88496076fedf31
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
|||
37
internal/misc/json.go
Normal file
37
internal/misc/json.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// This file is Free Software under the Apache-2.0 License
|
||||
// without warranty, see README.md and LICENSES/Apache-2.0.txt for details.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2025 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2025 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package misc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// StrictJSONParse creates a JSON decoder that decodes an interface
|
||||
// while not allowing trailing data
|
||||
func StrictJSONParse(jsonData io.Reader, target any) error {
|
||||
decoder := json.NewDecoder(jsonData)
|
||||
// Don't allow unknown fields
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
if err := decoder.Decode(target); err != nil {
|
||||
return fmt.Errorf("JSON decoding error: %w", err)
|
||||
}
|
||||
|
||||
// Check for any trailing data after the main JSON structure
|
||||
if _, err := decoder.Token(); err != io.EOF {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading trailing data: %w", err)
|
||||
}
|
||||
return fmt.Errorf("unexpected trailing data after JSON object")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package misc
|
||||
package misc //revive:disable-line:var-naming
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
|
|||
21
internal/misc/url.go
Normal file
21
internal/misc/url.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// This file is Free Software under the Apache-2.0 License
|
||||
// without warranty, see README.md and LICENSES/Apache-2.0.txt for details.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2025 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2025 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package misc
|
||||
|
||||
import "net/url"
|
||||
|
||||
// JoinURL joins the two URLs while preserving the query and fragment part of the latter.
|
||||
func JoinURL(baseURL *url.URL, relativeURL *url.URL) *url.URL {
|
||||
u := baseURL.JoinPath(relativeURL.Path)
|
||||
u.RawQuery = relativeURL.RawQuery
|
||||
u.RawFragment = relativeURL.RawFragment
|
||||
// Enforce https, this is required if the base url was only a domain
|
||||
u.Scheme = "https"
|
||||
return u
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ func TestUnmarshalText(t *testing.T) {
|
|||
byteSlice := []byte{'3', 'h'}
|
||||
var emptySlice []byte
|
||||
if testTimeRange.UnmarshalText(byteSlice) != nil {
|
||||
t.Errorf(testTimeRange.UnmarshalText(byteSlice).Error())
|
||||
t.Error(testTimeRange.UnmarshalText(byteSlice).Error())
|
||||
}
|
||||
if testTimeRange.UnmarshalText(emptySlice) == nil {
|
||||
t.Errorf("Failure: UnmarshalText succeeded on invalid slice of bytes.")
|
||||
|
|
@ -104,10 +104,10 @@ func TestUnmarshalFlag(t *testing.T) {
|
|||
time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC))
|
||||
if err := testTimeRange.UnmarshalFlag("3h"); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := testTimeRange.UnmarshalFlag("2006-01-02T15:04:05"); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := testTimeRange.UnmarshalFlag("2006-01-02T15:04:05a"); err == nil {
|
||||
t.Errorf("Failure: Extracted time from invalid string")
|
||||
|
|
@ -119,7 +119,7 @@ func TestUnmarshalFlag(t *testing.T) {
|
|||
t.Errorf("Failure: Extracted time from invalid string")
|
||||
}
|
||||
if err := testTimeRange.UnmarshalFlag("2006-01-02T15:04:05, 2007-01-02T15:04:05"); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ type Parser[C any] struct {
|
|||
// If a config file was specified it is loaded.
|
||||
// Returns the arguments and the configuration.
|
||||
func (p *Parser[C]) Parse() ([]string, *C, error) {
|
||||
|
||||
var cmdLineOpts C
|
||||
if p.SetDefaults != nil {
|
||||
p.SetDefaults(&cmdLineOpts)
|
||||
|
|
@ -82,6 +81,7 @@ func (p *Parser[C]) Parse() ([]string, *C, error) {
|
|||
|
||||
// No config file -> We are good.
|
||||
if path == "" {
|
||||
slog.Warn("No config file found. Maybe you want to specify one or store it in a respective default location", "locations", p.DefaultConfigLocations)
|
||||
return args, &cmdLineOpts, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ func TestParse(t *testing.T) {
|
|||
cmd.Env = append(os.Environ(), "TEST_HELP=1")
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// test the version flag
|
||||
|
|
@ -104,7 +104,7 @@ func TestParse(t *testing.T) {
|
|||
cmd.Env = append(os.Environ(), "TEST_VERSION=1")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ func TestLoadToml(t *testing.T) {
|
|||
t.Errorf("Failure: Succeeded in parsing nonexistant parameter")
|
||||
}
|
||||
if err := loadTOML(&cfg, "data/config.toml"); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
171
testdata/csaf-documents/trailing-garbage-data/avendor-advisory-0004.json
vendored
Normal file
171
testdata/csaf-documents/trailing-garbage-data/avendor-advisory-0004.json
vendored
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
{
|
||||
"document": {
|
||||
"category": "csaf_vex",
|
||||
"csaf_version": "2.0",
|
||||
"distribution": {
|
||||
"tlp": {
|
||||
"label": "WHITE",
|
||||
"url": "https://www.first.org/tlp/v1/"
|
||||
}
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"category": "summary",
|
||||
"title": "Test document summary",
|
||||
"text": "Auto generated test CSAF document"
|
||||
}
|
||||
],
|
||||
"publisher": {
|
||||
"category": "vendor",
|
||||
"name": "ACME Inc.",
|
||||
"namespace": "https://www.example.com"
|
||||
},
|
||||
"title": "Test CSAF document",
|
||||
"tracking": {
|
||||
"current_release_date": "2020-01-01T00:00:00Z",
|
||||
"generator": {
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"engine": {
|
||||
"name": "csaf-tool",
|
||||
"version": "0.3.2"
|
||||
}
|
||||
},
|
||||
"id": "Avendor-advisory-0004",
|
||||
"initial_release_date": "2020-01-01T00:00:00Z",
|
||||
"revision_history": [
|
||||
{
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"number": "1",
|
||||
"summary": "Initial version"
|
||||
}
|
||||
],
|
||||
"status": "final",
|
||||
"version": "1"
|
||||
}
|
||||
},
|
||||
"product_tree": {
|
||||
"branches": [
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.1",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.1",
|
||||
"product_id": "CSAFPID_0001"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.2",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.2",
|
||||
"product_id": "CSAFPID_0002"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2.0",
|
||||
"product": {
|
||||
"name": "AVendor product_1 2.0",
|
||||
"product_id": "CSAFPID_0003"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_2",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1",
|
||||
"product": {
|
||||
"name": "AVendor1 product_2 1",
|
||||
"product_id": "CSAFPID_0004"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_3",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2022H2",
|
||||
"product": {
|
||||
"name": "AVendor product_3 2022H2",
|
||||
"product_id": "CSAFPID_0005"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"cve": "CVE-2020-1234",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-1234"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Customers should upgrade to the latest version of the product",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cve": "CVE-2020-9876",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-9876"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Still under investigation",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
invalid data
|
||||
169
testdata/csaf-documents/valid/advisory-tracking-generator-no-version.json
vendored
Normal file
169
testdata/csaf-documents/valid/advisory-tracking-generator-no-version.json
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
{
|
||||
"document": {
|
||||
"category": "csaf_vex",
|
||||
"csaf_version": "2.0",
|
||||
"distribution": {
|
||||
"tlp": {
|
||||
"label": "WHITE",
|
||||
"url": "https://www.first.org/tlp/v1/"
|
||||
}
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"category": "summary",
|
||||
"title": "Test document summary",
|
||||
"text": "Auto generated test CSAF document"
|
||||
}
|
||||
],
|
||||
"publisher": {
|
||||
"category": "vendor",
|
||||
"name": "ACME Inc.",
|
||||
"namespace": "https://www.example.com"
|
||||
},
|
||||
"title": "Test CSAF document",
|
||||
"tracking": {
|
||||
"current_release_date": "2020-01-01T00:00:00Z",
|
||||
"generator": {
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"engine": {
|
||||
"name": "csaf-tool"
|
||||
}
|
||||
},
|
||||
"id": "Avendor-advisory-0004",
|
||||
"initial_release_date": "2020-01-01T00:00:00Z",
|
||||
"revision_history": [
|
||||
{
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"number": "1",
|
||||
"summary": "Initial version"
|
||||
}
|
||||
],
|
||||
"status": "final",
|
||||
"version": "1"
|
||||
}
|
||||
},
|
||||
"product_tree": {
|
||||
"branches": [
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.1",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.1",
|
||||
"product_id": "CSAFPID_0001"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.2",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.2",
|
||||
"product_id": "CSAFPID_0002"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2.0",
|
||||
"product": {
|
||||
"name": "AVendor product_1 2.0",
|
||||
"product_id": "CSAFPID_0003"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_2",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1",
|
||||
"product": {
|
||||
"name": "AVendor1 product_2 1",
|
||||
"product_id": "CSAFPID_0004"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_3",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2022H2",
|
||||
"product": {
|
||||
"name": "AVendor product_3 2022H2",
|
||||
"product_id": "CSAFPID_0005"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"cve": "CVE-2020-1234",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-1234"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Customers should upgrade to the latest version of the product",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cve": "CVE-2020-9876",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-9876"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Still under investigation",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
170
testdata/csaf-documents/valid/avendor-advisory-0004.json
vendored
Normal file
170
testdata/csaf-documents/valid/avendor-advisory-0004.json
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"document": {
|
||||
"category": "csaf_vex",
|
||||
"csaf_version": "2.0",
|
||||
"distribution": {
|
||||
"tlp": {
|
||||
"label": "WHITE",
|
||||
"url": "https://www.first.org/tlp/v1/"
|
||||
}
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"category": "summary",
|
||||
"title": "Test document summary",
|
||||
"text": "Auto generated test CSAF document"
|
||||
}
|
||||
],
|
||||
"publisher": {
|
||||
"category": "vendor",
|
||||
"name": "ACME Inc.",
|
||||
"namespace": "https://www.example.com"
|
||||
},
|
||||
"title": "Test CSAF document",
|
||||
"tracking": {
|
||||
"current_release_date": "2020-01-01T00:00:00Z",
|
||||
"generator": {
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"engine": {
|
||||
"name": "csaf-tool",
|
||||
"version": "0.3.2"
|
||||
}
|
||||
},
|
||||
"id": "Avendor-advisory-0004",
|
||||
"initial_release_date": "2020-01-01T00:00:00Z",
|
||||
"revision_history": [
|
||||
{
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"number": "1",
|
||||
"summary": "Initial version"
|
||||
}
|
||||
],
|
||||
"status": "final",
|
||||
"version": "1"
|
||||
}
|
||||
},
|
||||
"product_tree": {
|
||||
"branches": [
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.1",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.1",
|
||||
"product_id": "CSAFPID_0001"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1.2",
|
||||
"product": {
|
||||
"name": "AVendor product_1 1.2",
|
||||
"product_id": "CSAFPID_0002"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2.0",
|
||||
"product": {
|
||||
"name": "AVendor product_1 2.0",
|
||||
"product_id": "CSAFPID_0003"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor1",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_2",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "1",
|
||||
"product": {
|
||||
"name": "AVendor1 product_2 1",
|
||||
"product_id": "CSAFPID_0004"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "vendor",
|
||||
"name": "AVendor",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_name",
|
||||
"name": "product_3",
|
||||
"branches": [
|
||||
{
|
||||
"category": "product_version",
|
||||
"name": "2022H2",
|
||||
"product": {
|
||||
"name": "AVendor product_3 2022H2",
|
||||
"product_id": "CSAFPID_0005"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"cve": "CVE-2020-1234",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-1234"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Customers should upgrade to the latest version of the product",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cve": "CVE-2020-9876",
|
||||
"notes": [
|
||||
{
|
||||
"category": "description",
|
||||
"title": "CVE description",
|
||||
"text": "https://nvd.nist.gov/vuln/detail/CVE-2020-9876"
|
||||
}
|
||||
],
|
||||
"product_status": {
|
||||
"under_investigation": ["CSAFPID_0001"]
|
||||
},
|
||||
"threats": [
|
||||
{
|
||||
"category": "impact",
|
||||
"details": "Still under investigation",
|
||||
"date": "2020-01-01T00:00:00Z",
|
||||
"product_ids": ["CSAFPID_0001"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package util
|
||||
package util //revive:disable-line:var-naming
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package util
|
||||
package util //revive:disable-line:var-naming
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package util
|
||||
package util //revive:disable-line:var-naming
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package util
|
||||
package util //revive:disable-line:var-naming
|
||||
|
||||
// Set is a simple set type.
|
||||
type Set[K comparable] map[K]struct{}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||
// Software-Engineering: 2022 Intevation GmbH <https://intevation.de>
|
||||
|
||||
package util
|
||||
package util //revive:disable-line:var-naming
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue