diff --git a/.github/workflows/generate-markdown.yml b/.github/workflows/generate-markdown.yml new file mode 100644 index 0000000..de3559a --- /dev/null +++ b/.github/workflows/generate-markdown.yml @@ -0,0 +1,19 @@ +name: generate-markdown + +on: + push: + branches: + - "main" + - "build-scripts" + pull_request: + branches: + - "main" +jobs: + auto-update-readme: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Markdown autodocs + uses: dineshsonachalam/markdown-autodocs@v1.0.4 + with: + output_file_paths: '[./README.md, ./docs/*.md]' diff --git a/Makefile b/Makefile index c761729..112598d 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,22 @@ tag_checked_out: git checkout -q tags/${BUILDTAG} @echo Don\'t forget that we are in checked out tag $(BUILDTAG) now. +# use bash shell arithmetic and sed to turn a `git describe` version +# into a semver version. For this we increase the PATCH number, so that +# any commit after a tag is considered newer than the semver from the tag +# without an optional 'v' +GITDESC := $(shell git describe) +GITDESCPATCH := $(shell echo '$(GITDESC)' | sed -E 's/v?[0-9]+\.[0-9]+\.([0-9]+)[-+]?.*/\1/') +SEMVERPATCH := $(shell echo $$(( $(GITDESCPATCH) + 1 ))) +# Hint: The regexp in the next line only matches if there is a hyphen (`-`) +# and we can assume that git describe has added a string after the tag +SEMVER := $(shell echo '$(GITDESC)' | sed -E 's/v?([0-9]+\.[0-9]+\.)([0-9]+)(-.*)/\1$(SEMVERPATCH)\3/' ) +testsemver: + @echo from \'$(GITDESC)\' transformed to \'$(SEMVER)\' + + +# Set -ldflags parameter to pass the semversion. +LDFLAGS = -ldflags "-X github.com/csaf-poc/csaf_distribution/util.SemVersion=$(SEMVER)" # Build binaries and place them under bin-$(GOOS)-$(GOARCH) # Using 'Target-specific Variable Values' to specify the build target system @@ -48,7 +64,7 @@ build_win: GOOS = windows build_linux build_win: $(eval BINDIR = bin-$(GOOS)-$(GOARCH)/ ) $(MKDIR) $(BINDIR) - env GOARCH=$(GOARCH) GOOS=$(GOOS) $(BUILD) -o $(BINDIR) -v ./cmd/... + env GOARCH=$(GOARCH) GOOS=$(GOOS) $(BUILD) -o $(BINDIR) $(LDFLAGS) -v ./cmd/... # Remove bin-*-* directories diff --git a/cmd/csaf_checker/main.go b/cmd/csaf_checker/main.go index 661e33f..3482c01 100644 --- a/cmd/csaf_checker/main.go +++ b/cmd/csaf_checker/main.go @@ -3,8 +3,8 @@ // // SPDX-License-Identifier: MIT // -// SPDX-FileCopyrightText: 2021 German Federal Office for Information Security (BSI) -// Software-Engineering: 2021 Intevation GmbH +// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +// Software-Engineering: 2022 Intevation GmbH package main @@ -12,11 +12,13 @@ import ( "bufio" _ "embed" // Used for embedding. "encoding/json" + "fmt" "html/template" "io" "log" "os" + "github.com/csaf-poc/csaf_distribution/util" "github.com/jessevdk/go-flags" ) @@ -29,6 +31,7 @@ type options struct { Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"` ClientCert *string `long:"client-cert" description:"TLS client certificate file (PEM encoded data)" value-name:"CERT-FILE"` ClientKey *string `long:"client-key" description:"TLS client private key file (PEM encoded data)" value-name:"KEY-FILE"` + Version bool `long:"version" description:"Display version of the binary"` } func errCheck(err error) { @@ -132,6 +135,11 @@ func realMain(args []string) { domains, err := flags.ParseArgs(opts, args) errCheck(err) + if opts.Version { + fmt.Println(util.SemVersion) + return + } + if len(domains) == 0 { log.Println("No domains given.") return diff --git a/cmd/csaf_provider/controller.go b/cmd/csaf_provider/controller.go index 54be92f..3ce1005 100644 --- a/cmd/csaf_provider/controller.go +++ b/cmd/csaf_provider/controller.go @@ -82,7 +82,13 @@ func (c *controller) auth( verify := os.Getenv("SSL_CLIENT_VERIFY") log.Printf("SSL_CLIENT_VERIFY: %s\n", verify) - log.Printf("ca: %s\n", os.Getenv("SSL_CLIENT_I_DN")) + if verify == "SUCCESS" || strings.HasPrefix(verify, "FAILED") { + // potentially we want to see the Issuer when there is a problem + // but it is not clear if we get this far in case of "FAILED". + // docs (accessed 2022-03-31 when 1.20.2 was current stable): + // https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify + log.Printf("SSL_CLIENT_I_DN: %s\n", os.Getenv("SSL_CLIENT_I_DN")) + } switch { case verify == "SUCCESS" && (c.cfg.Issuer == nil || *c.cfg.Issuer == os.Getenv("SSL_CLIENT_I_DN")): diff --git a/cmd/csaf_provider/main.go b/cmd/csaf_provider/main.go index 29a64ec..daaefb3 100644 --- a/cmd/csaf_provider/main.go +++ b/cmd/csaf_provider/main.go @@ -9,16 +9,32 @@ package main import ( + "fmt" "log" "net/http/cgi" + + "github.com/csaf-poc/csaf_distribution/util" + "github.com/jessevdk/go-flags" ) +type options struct { + Version bool `long:"version" description:"Display version of the binary"` +} + func main() { cfg, err := loadConfig() if err != nil { log.Fatalf("error: %v\n", err) } + var opts options + parser := flags.NewParser(&opts, flags.Default) + parser.Parse() + if opts.Version { + fmt.Println(util.SemVersion) + return + } + c, err := newController(cfg) if err != nil { log.Fatalf("error: %v\n", err) diff --git a/cmd/csaf_uploader/main.go b/cmd/csaf_uploader/main.go index 7b4c49e..dcee311 100644 --- a/cmd/csaf_uploader/main.go +++ b/cmd/csaf_uploader/main.go @@ -23,6 +23,7 @@ import ( "github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/csaf-poc/csaf_distribution/csaf" + "github.com/csaf-poc/csaf_distribution/util" "github.com/jessevdk/go-flags" "github.com/mitchellh/go-homedir" "golang.org/x/crypto/bcrypt" @@ -48,7 +49,8 @@ type options struct { Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"` - Config *string `short:"c" long:"config" description:"Path to config ini file" value-name:"INI-FILE" no-ini:"true"` + Config *string `short:"c" long:"config" description:"Path to config ini file" value-name:"INI-FILE" no-ini:"true"` + Version bool `long:"version" description:"Display version of the binary"` } type processor struct { @@ -359,6 +361,11 @@ func main() { args, err := parser.Parse() check(err) + if opts.Version { + fmt.Println(util.SemVersion) + return + } + if opts.Config != nil { iniParser := flags.NewIniParser(parser) iniParser.ParseAsDefaults = true diff --git a/docs/client-certificate-setup.md b/docs/client-certificate-setup.md index a1c425f..ab397ce 100644 --- a/docs/client-certificate-setup.md +++ b/docs/client-certificate-setup.md @@ -5,29 +5,29 @@ a web browser. ### Configure nginx Assuming the relevant server block is in `/etc/nginx/sites-enabled/default` and the CA used to verify the client certificates is under `/etc/ssl/`, -adjust it like shown in the following example: +adjust the content of the `server{}` block like shown in the following example: + + +```sh + ssl_client_certificate '${SSL_CLIENT_CERTIFICATE}'; # e.g. ssl_client_certificate /etc/ssl/rootca-cert.pem; + ssl_verify_client optional; + ssl_verify_depth 2; + # This example allows access to all three TLP locations for all certs. + location ~ /.well-known/csaf/(red|green|amber)/{ + # For atomic directory switches + disable_symlinks off; + autoindex on; + # in this location access is only allowed with client certs + if ($ssl_client_verify != SUCCESS){ + # we use status code 404 == "Not Found", because we do not + # want to reveal if this location exists or not. + return 404; + } + } ``` -server { - # Other Config - # ... + - ssl_client_certificate /etc/ssl/rootca-cert.pem; - ssl_verify_client optional; - ssl_verify_depth 2; - - # This example allows access to all three TLP locations for all certs. - location ~ /.well-known/csaf/(red|green|amber)/{ - autoindex on; - # in this location access is only allowed with client certs - if ($ssl_client_verify != SUCCESS){ - # we use status code 404 == "Not Found", because we do not - # want to reveal if this location exists or not. - return 404; - } - } -} -``` This will restrict the access to the defined paths in the ```location``` directive to only authenticated client certificates issued by the CAs which are configured with `ssl_client_certificate`. @@ -37,8 +37,15 @@ differently, you could use several location blocks each which a single `if` that matches the `$ssl_client_i_dn` variable to CAs that you would want to allow for that location. -If you want to restrict the writing permission and the accessing to the web-interface of the `csaf_provider` to only some TLS client certificates, the CA issuer of these certificates should be assigned to the `issuer` config option in the `/user/lib/csaf/config.toml` file e.g. `issuer = "C=DE,O=CSAF Tools Development (internal),CN=Tester" `. -To inspect the accepted format for this field you can check the value of the `ca:` in the nginx log file `/var/log/nginx/error.log`. +If you want to restrict the writing permission and access to the web-interface +of the `csaf_provider` to only some TLS client certificates, +the CA issuer of these certificates should be assigned to the `issuer` +config option in the `/user/lib/csaf/config.toml` file +e.g. `issuer = "C=DE,O=CSAF Tools Development (internal),CN=Tester" `. +The value will be checked against the `$ssl_client_i_dn` variable +within the `csaf_provider`. +To inspect the precise string of certain certificate, try it and +check the logged value in the nginx log file, e.g. `/var/log/nginx/error.log`. Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx` on Debian or Ubuntu.) @@ -47,6 +54,6 @@ To test this see [development-client-certs.md](development-client-certs.md) and * From the browser after importing the `testclient1.p12`: nagivate to the protected directories. * With curl: `curl https://{serverURL}/.well-known/csaf/red/ --cert-type p12 --cert testclient1.p12`. -(If the server uses self-signed certifcate one of the following options should be added to the `curl` command: -`--insecure` to disable the verification, -`--cacert {CA-Certificate-File}` to pass the CA-Certificate that verifies the server). \ No newline at end of file +(If the server uses a root certifcate that is not in the default certificate store one of the following options should be added to the `curl` command: + * `--insecure` to disable the verification, + * `--cacert {CA-Certificate-File}` to pass the CA-Certificate that verifies the server). diff --git a/docs/development-ca.md b/docs/development-ca.md index 81ca4d7..20f4b35 100644 --- a/docs/development-ca.md +++ b/docs/development-ca.md @@ -11,14 +11,16 @@ which is suitable for testing in development setups. ## create root CA -```bash -mkdir devca1 -cd devca1 + + +```sh +mkdir -p ~/${FOLDERNAME} +cd ~/${FOLDERNAME} certtool --generate-privkey --outfile rootca-key.pem echo ' -organization = "CSAF Tools Development (internal)" +organization = "'${ORGANAME}'" country = DE cn = "Tester" @@ -30,19 +32,21 @@ serial = 001 expiration_days = 100 ' >gnutls-certtool.rootca.template -certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template +certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template --stdout | head -1 ``` - + ## create webserver cert -```bash -#being in devca1/ + + +```sh +cd ~/${FOLDERNAME} certtool --generate-privkey --outfile testserver-key.pem echo ' -organization = "CSAF Tools Development (internal)" +organization = "'${ORGANAME}'" country = DE cn = "Service Testing" @@ -58,14 +62,20 @@ serial = 010 expiration_days = 50 ' > gnutls-certtool.testserver.template -certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template +certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template --stdout | head -1 cat testserver.crt rootca-cert.pem >bundle.crt -echo Full path config options for nginx: -echo " ssl_certificate \"$PWD/bundle.crt\";" -echo " ssl_certificate_key \"$PWD/testserver-key.pem\";" -``` +SSL_CERTIFICATE=$( +echo "$PWD/bundle.crt" +) +SSL_CERTIFICATE_KEY=$( +echo "$PWD/testserver-key.pem" +) +``` + + +Replace `{FOLDERNAME}` with the folder name you want to save the keys into it and `{ORGANAME}` with the organisation name that should be used by creating the Certificate. ## Considerations and References diff --git a/docs/development-client-certs.md b/docs/development-client-certs.md index 66108db..25b2915 100644 --- a/docs/development-client-certs.md +++ b/docs/development-client-certs.md @@ -10,13 +10,15 @@ would used for server and for client certificates.) The following lines directly create the client certificate. (As opposed to first creating a certificate signing request and then signing it.) + + +```sh +cd ~/${FOLDERNAME} -```bash -# being in devca1/ certtool --generate-privkey --outfile testclient1-key.pem echo ' -organization = "CSAF Tools Development (internal)" +organization = "'${ORGANAME}'" country = DE cn = "TLS Test Client 1" @@ -28,18 +30,23 @@ serial = 020 expiration_days = 50 ' > gnutls-certtool.testclient1.template -certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template +certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template --stdout | head -1 certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12 ``` + and we do a second one with shorter expiration day: -```bash + + +```sh +certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12 + certtool --generate-privkey --outfile testclient2-key.pem echo ' -organization = "CSAF Tools Development (internal)" +organization = "'${ORGANAME}'" country = DE cn = "TLS Test Client 2" @@ -51,13 +58,12 @@ serial = 021 expiration_days = 1 ' > gnutls-certtool.testclient2.template -certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template +certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template --stdout | head -1 certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient2.crt --load-privkey testclient2-key.pem --to-p12 --p12-name "Test Client 2" --null-password --outder --outfile testclient2.p12 ``` + In case of many CAs are used to verify the client certificates these should be included in the list of the allowed CA certificates in the `ssl_client_certificate` bundle of nginx. E.g. `cat rootca-cert-1.pem rootca-cert-2.pem >> allowedCAs.pem`. Nginx config: `ssl_client_certificate allowedCAs.pem;` - - diff --git a/docs/install-server-certificate.md b/docs/install-server-certificate.md index eb2c092..56b4da9 100644 --- a/docs/install-server-certificate.md +++ b/docs/install-server-certificate.md @@ -44,25 +44,21 @@ We recommend to ### Example configuration Assuming the relevant server block is in `/etc/nginx/sites-enabled/default`, -change the `listen` configuration and add options so nginx +change the `listen` configuration in the `server {}` block and add options so nginx finds your your private key and the certificate chain. -```nginx -server { - listen 443 ssl http2 default_server; # ipv4 - listen [::]:443 ssl http2 default_server; # ipv6 - server_name www.example.com + + +```sh + listen 443 ssl default_server; # ipv4 + listen [::]:443 ssl http2 default_server; # ipv6 - ssl_certificate /etc/ssl/{domainName}.pem; # or bundle.crt - ssl_certificate_key /etc/ssl/{domainName}.key"; + ssl_certificate '${SSL_CERTIFICATE}'; # e.g. ssl_certificate /etc/ssl/csaf/bundle.crt + ssl_certificate_key '${SSL_CERTIFICATE_KEY}'; # e.g. ssl_certificate_key /etc/ssl/csaf/testserver-key.pem; - ssl_protocols TLSv1.2 TLSv1.3; - # Other Config - # ... -} + ssl_protocols TLSv1.2 TLSv1.3; ``` - -Replace `{domainName}` with the name for your certificate in the example. + Reload or restart nginx to apply the changes (e.g. `systemctl reload nginx` on Debian or Ubuntu.) diff --git a/docs/provider-setup.md b/docs/provider-setup.md index 929e9ba..2508f33 100644 --- a/docs/provider-setup.md +++ b/docs/provider-setup.md @@ -24,7 +24,9 @@ chmod -R g+w . Modify the content of `/etc/nginx/fcgiwrap.conf` like following: -``` + + +```sh # Include this file on your nginx.conf to support debian cgi-bin scripts using # fcgiwrap location /cgi-bin/ { @@ -55,7 +57,7 @@ location /cgi-bin/ { fastcgi_param SSL_CLIENT_I_DN $ssl_client_i_dn; } ``` - + Add to `/etc/nginx/sites-enabled/default`: ``` @@ -89,28 +91,32 @@ Rename and place the `csaf_provider` binary file under `/usr/lib/cgi-bin/csaf_pr Create configuration file under `/usr/lib/csaf/config.toml`: -``` + + +```sh # upload_signature = true # key = "/usr/lib/csaf/public.asc" key = "/usr/lib/csaf/private.asc" #tlps = ["green", "red"] -canonical_url_prefix = "http://192.168.56.102" +canonical_url_prefix = "https://localhost:8443" #no_passphrase = true ``` -with suitable replacements -(This configurations-example assumes that the private/public keys are available under `/usr/lib/csaf/`). + +with suitable [replacements](#provider-options) +(This configuration examples assumes that the private/public keys are available under `/usr/lib/csaf/`). -with suitable [replacements](#provider-options). - Create the folders: ```(shell) -curl http://192.168.56.102/cgi-bin/csaf_provider.go/create +curl https://192.168.56.102/cgi-bin/csaf_provider.go/create --cert-type p12 --cert {clientCertificatfile} ``` +Replace {clientCertificate} with the client certificate file. Or using the uploader: ```(shell) -./csaf_uploader -a create -u http://192.168.56.102/cgi-bin/csaf_provider.go +./csaf_uploader -a create -u http://192.168.56.102/cgi-bin/csaf_provider.go -p {password} ``` +Replace {password} with the password used for the authentication with csaf_provider. +This needs to set the `password` option in `config.toml`. ## Provider options Provider has many config options described as following: @@ -119,9 +125,9 @@ Provider has many config options described as following: - key: The private OpenPGP key. - folder: Specify the root folder. Default: `/var/www/`. - web: Specify the web folder. Default: `/var/www/html`. - - tlps: Set the allowed TLP comming with the upload request (one or more of "csaf", "white", "amber", "green", "red"). - The "csaf" selection lets the provider takes the value from the CSAF document. - These affects the list items in the web interface. + - tlps: Set the allowed TLP comming with the upload request (one or more of "csaf", "white", "amber", "green", "red"). + The "csaf" selection lets the provider takes the value from the CSAF document. + These affects the list items in the web interface. Default: `["csaf", "white", "amber", "green", "red"]`. - upload_signature: Send signature with the request, an additional input-field in the web interface will be shown to let user enter an ascii armored signature. Default: `false`. - openpgp_url: URL to OpenPGP key-server. Default: `https://openpgp.circl.lu`. diff --git a/docs/scripts/Readme.md b/docs/scripts/Readme.md new file mode 100644 index 0000000..d5aeccd --- /dev/null +++ b/docs/scripts/Readme.md @@ -0,0 +1,25 @@ +Scripts for assisting the Integration tests. They are written on Ubuntu 20.04 TLS amd64. + +- `prepareUbunutForITest.sh` installs the required packages for the csaf_distribution integration tests on a naked ubuntu 20.04 LTS amd64. + +- `TLSConfigsForITest.sh` generates a root CA and webserver cert by running `createRootCAForITest.sh` and `createWebserverCertForITest.sh` +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. + +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 root): +``` bash + curl --fail -O https://raw.githubusercontent.com/csaf-poc/csaf_distribution/main/docs/scripts/prepareUbuntuInstanceForITests.sh + bash prepareUbuntuInstanceForITests.sh + + git clone https://github.com/csaf-poc/csaf_distribution.git + pushd csaf_distribution/docs/scripts/ + + env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSConfigsForITest.sh + env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSClientConfigsForITest.sh + ./setupProviderForITest.sh +``` diff --git a/docs/scripts/TLSClientConfigsForITest.sh b/docs/scripts/TLSClientConfigsForITest.sh new file mode 100755 index 0000000..791af5d --- /dev/null +++ b/docs/scripts/TLSClientConfigsForITest.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +# It sets the right nginx configurations for enabling client certificate authentication. +# FOLDERNAME and ORGANAME variables must be set. +# FOLDERNAME: Where to store the CAs and keys. +# ORGANAME: The organization name used in the CA template. +# Usage Example: env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSClientConfigsForITest.sh + +set -e + +NGINX_CONFIG_PATH=/etc/nginx/sites-available/default + +cd ~/csaf_distribution/docs/scripts/ +source ./createCCForITest.sh + +echo ' + ssl_client_certificate '${SSL_CLIENT_CERTIFICATE}'; # e.g. ssl_client_certificate /etc/ssl/rootca-cert.pem; + ssl_verify_client optional; + ssl_verify_depth 2; + + # This example allows access to all three TLP locations for all certs. + location ~ /.well-known/csaf/(red|green|amber)/{ + # For atomic directory switches + disable_symlinks off; + autoindex on; + # in this location access is only allowed with client certs + if ($ssl_client_verify != SUCCESS){ + # we use status code 404 == "Not Found", because we do not + # want to reveal if this location exists or not. + return 404; + } + } +'> clientCertificateConfigs.txt + +sed -i "/^server {/r ${HOME}/${FOLDERNAME}/clientCertificateConfigs.txt" $NGINX_CONFIG_PATH + +systemctl reload nginx diff --git a/docs/scripts/TLSConfigsForITest.sh b/docs/scripts/TLSConfigsForITest.sh new file mode 100755 index 0000000..2d0a946 --- /dev/null +++ b/docs/scripts/TLSConfigsForITest.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +# This script generates webserver cert that is signed with the generated root CA. +# It sets the right nginx configurations for serving TLS connections. +# FOLDERNAME and ORGANAME variables must be set. +# FOLDERNAME: Where to store the CAs and keys. +# ORGANAME: The organization name used in the CA template. +# Usage Example: env FOLDERNAME=devca1 ORGANAME="CSAF Tools Development (internal)" ./TLSConfigsForITest.sh + +set -e + +NGINX_CONFIG_PATH=/etc/nginx/sites-available/default + +cd ~/csaf_distribution/docs/scripts/ +## Create Root CA +./createRootCAForITest.sh + +## Create webserver cert +source ./createWebserverCertForITest.sh + +# Configure nginx +echo ' + listen 443 ssl default_server; # ipv4 + listen [::]:443 ssl http2 default_server; # ipv6 + + ssl_certificate '${SSL_CERTIFICATE}'; # e.g. ssl_certificate /etc/ssl/csaf/bundle.crt + ssl_certificate_key '${SSL_CERTIFICATE_KEY}'; # e.g. ssl_certificate_key /etc/ssl/csaf/testserver-key.pem; + + ssl_protocols TLSv1.2 TLSv1.3; +' > TLSConfigs.txt + +# a second listener port for testing setup where someone wants to tunnel access +# to an unpriviledged port and still have the same access url +echo ' + listen 8443 ssl default_server; # ipv4 + listen [::]:8443 ssl http2 default_server; # ipv6 +' > TLS8443Configs.txt + +cp $NGINX_CONFIG_PATH $NGINX_CONFIG_PATH.org +sed -i "/^server {/r ${HOME}/${FOLDERNAME}/TLSConfigs.txt" $NGINX_CONFIG_PATH +sed -i "/^server {/r ${HOME}/${FOLDERNAME}/TLS8443Configs.txt" $NGINX_CONFIG_PATH +sed -i "/^\s*listen.*80/d" $NGINX_CONFIG_PATH # Remove configs for listinig on port 80 +systemctl reload nginx + diff --git a/docs/scripts/createCCForITest.sh b/docs/scripts/createCCForITest.sh new file mode 100644 index 0000000..091dad7 --- /dev/null +++ b/docs/scripts/createCCForITest.sh @@ -0,0 +1,57 @@ +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +# This scripts creates two client certificates. It uses for signing the root certifcate +# created with `createRootCAForITest.sh` that must be run earlier. + +set -e + +mkdir -p ~/${FOLDERNAME} +cd ~/${FOLDERNAME} + +certtool --generate-privkey --outfile testclient1-key.pem + +echo ' +organization = "'${ORGANAME}'" +country = DE +cn = "TLS Test Client 1" + +tls_www_client +signing_key +encryption_key + +serial = 020 +expiration_days = 50 +' > gnutls-certtool.testclient1.template + +certtool --generate-certificate --load-privkey testclient1-key.pem --outfile testclient1.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient1.template --stdout | head -1 + +certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient1.crt --load-privkey testclient1-key.pem --to-p12 --p12-name "Test Client 1" --null-password --outder --outfile testclient1.p12 + +certtool --generate-privkey --outfile testclient2-key.pem + +echo ' +organization = "'${ORGANAME}'" +country = DE +cn = "TLS Test Client 2" + +tls_www_client +signing_key +encryption_key + +serial = 021 +expiration_days = 1 +' > gnutls-certtool.testclient2.template + +certtool --generate-certificate --load-privkey testclient2-key.pem --outfile testclient2.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testclient2.template --stdout | head -1 + +certtool --load-ca-certificate rootca-cert.pem --load-certificate testclient2.crt --load-privkey testclient2-key.pem --to-p12 --p12-name "Test Client 2" --null-password --outder --outfile testclient2.p12 + +SSL_CLIENT_CERTIFICATE=$( +echo "$PWD/rootca-cert.pem" +) diff --git a/docs/scripts/createRootCAForITest.sh b/docs/scripts/createRootCAForITest.sh new file mode 100755 index 0000000..cf7cd15 --- /dev/null +++ b/docs/scripts/createRootCAForITest.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +set -e + +mkdir -p ~/${FOLDERNAME} +cd ~/${FOLDERNAME} + +certtool --generate-privkey --outfile rootca-key.pem + +echo ' +organization = "'${ORGANAME}'" +country = DE +cn = "Tester" + +ca +cert_signing_key +crl_signing_key + +serial = 001 +expiration_days = 100 +' >gnutls-certtool.rootca.template + +certtool --generate-self-signed --load-privkey rootca-key.pem --outfile rootca-cert.pem --template gnutls-certtool.rootca.template --stdout | head -1 diff --git a/docs/scripts/createWebserverCertForITest.sh b/docs/scripts/createWebserverCertForITest.sh new file mode 100644 index 0000000..01e927c --- /dev/null +++ b/docs/scripts/createWebserverCertForITest.sh @@ -0,0 +1,41 @@ +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +set -e + +cd ~/${FOLDERNAME} + +certtool --generate-privkey --outfile testserver-key.pem + +echo ' +organization = "'${ORGANAME}'" +country = DE +cn = "Service Testing" + +tls_www_server +signing_key +encryption_key +non_repudiation + +dns_name = "*.local" +dns_name = "localhost" + +serial = 010 +expiration_days = 50 +' > gnutls-certtool.testserver.template + +certtool --generate-certificate --load-privkey testserver-key.pem --outfile testserver.crt --load-ca-certificate rootca-cert.pem --load-ca-privkey rootca-key.pem --template gnutls-certtool.testserver.template --stdout | head -1 + +cat testserver.crt rootca-cert.pem >bundle.crt + +SSL_CERTIFICATE=$( +echo "$PWD/bundle.crt" +) +SSL_CERTIFICATE_KEY=$( +echo "$PWD/testserver-key.pem" +) diff --git a/docs/scripts/downloadExamples.sh b/docs/scripts/downloadExamples.sh new file mode 100755 index 0000000..e8b3ac0 --- /dev/null +++ b/docs/scripts/downloadExamples.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# Desc: Tries getting csaf 2.0 examples from api.github. Do not run too often! +# +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +set -e + +# using an extended regular expression to whitelist only CSAF 2.0 filenames +# with a sane path + +CSAFPATHregexp='^ *"path": "(csaf_2.0/examples/csaf/[a-z0-9+-_]+.json)",' + +curl --silent --show-error -H 'Accept: application/vnd.github.v3.raw' \ + https://api.github.com/repos/oasis-tcs/csaf/contents/csaf_2.0/examples/csaf \ + | grep -E "$CSAFPATHregexp" \ + | sed -E -e "s;${CSAFPATHregexp};\1;" \ + > csaf_examples_pathnames.txt + +mkdir csaf_examples +cd csaf_examples + +cat ../csaf_examples_pathnames.txt | \ + xargs -I {} \ + curl --silent --show-error -H 'Accept: application/vnd.github.v3.raw' \ + https://api.github.com/repos/oasis-tcs/csaf/contents/{} -O diff --git a/docs/scripts/prepareUbuntuInstanceForITests.sh b/docs/scripts/prepareUbuntuInstanceForITests.sh new file mode 100755 index 0000000..22bd00f --- /dev/null +++ b/docs/scripts/prepareUbuntuInstanceForITests.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -e + +# This script prepares a naked Ubuntu 20.04 LTS amd64 +# for the csaf_distribution integration tests +# by installing the required packages. + + +apt install -y make git nginx fcgiwrap gnutls-bin + +# Install Go from binary distribution +curl -O https://storage.googleapis.com/golang/go1.18.linux-amd64.tar.gz +tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz diff --git a/docs/scripts/setupProviderForITest.sh b/docs/scripts/setupProviderForITest.sh new file mode 100755 index 0000000..7002770 --- /dev/null +++ b/docs/scripts/setupProviderForITest.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +# This script sets up the csaf_provider and writes the required nginx configurations. +# It creates the initial folders and uploads some example files to the csaf_provider with the help of `uploadToProvider.sh` + +set -e + +chgrp -R www-data /var/www +chmod -R g+w /var/www + +NGINX_CONFIG_PATH=/etc/nginx/sites-available/default + +cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf + +echo ' +# Include this file on your nginx.conf to support debian cgi-bin scripts using +# fcgiwrap +location /cgi-bin/ { + # Disable gzip (it makes scripts feel slower since they have to complete + # before getting gzipped) + gzip off; + + # Set the root to /usr/lib (inside this location this means that we are + # giving access to the files under /usr/lib/cgi-bin) + root /usr/lib; + + # Fastcgi socket + fastcgi_pass unix:/var/run/fcgiwrap.socket; + + # Fastcgi parameters, include the standard ones + include /etc/nginx/fastcgi_params; + + fastcgi_split_path_info ^(.+\.go)(.*)$; + + # Adjust non standard parameters (SCRIPT_FILENAME) + fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name; + + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param CSAF_CONFIG /usr/lib/csaf/config.toml; + + fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify; + fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn; + fastcgi_param SSL_CLIENT_I_DN $ssl_client_i_dn; +} +' > /etc/nginx/fcgiwrap.conf + +sed -i "/^server {/a include fcgiwrap.conf;" $NGINX_CONFIG_PATH + +echo " + # For atomic directory switches + disable_symlinks off; + + # directory listings + autoindex on; +" > locationConfig.txt +sed -i "/^\s*location \/ {/r locationConfig.txt" $NGINX_CONFIG_PATH # Insert config inside location{} + +systemctl reload nginx + +# assuming that we are in a checked out version in the docs/scripts directory +# and we want to build the version that is currently checked out +pushd ../.. + +export PATH=$PATH:/usr/local/go/bin +make build_linux +# Place the binary under the corresponding path. +mkdir -p /usr/lib/cgi-bin/ +cp bin-linux-amd64/csaf_provider /usr/lib/cgi-bin/csaf_provider.go + +mkdir -p /usr/lib/csaf/ +cp docs/test-keys/*.asc /usr/lib/csaf/ +# Configuration file +echo ' +# upload_signature = true +# key = "/usr/lib/csaf/public.asc" +key = "/usr/lib/csaf/private.asc" +#tlps = ["green", "red"] +canonical_url_prefix = "https://localhost:8443" +#no_passphrase = true +' > /usr/lib/csaf/config.toml + +# Create the Folders +curl https://localhost:8443/cgi-bin/csaf_provider.go/create --cert-type p12 --cert ~/devca1/testclient1.p12 --insecure + +popd + +# Upload files +./uploadToProvider.sh diff --git a/docs/scripts/uploadToProvider.sh b/docs/scripts/uploadToProvider.sh new file mode 100755 index 0000000..c5e30cc --- /dev/null +++ b/docs/scripts/uploadToProvider.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# Desc: Call ./downloadExamples.sh and then try csaf_uploader. +# +# This file is Free Software under the MIT License +# without warranty, see README.md and LICENSES/MIT.txt for details. +# +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +# Software-Engineering: 2022 Intevation GmbH + +set -e + + +# assumes that the following script only downloads file with filenames +# following https://docs.oasis-open.org/csaf/csaf/v2.0/cs01/csaf-v2.0-cs01.html#51-filename +# which are save to process further +./downloadExamples.sh + +TLPs=("white" "green" "amber" "red") +COUNTER=0 +for f in $(ls csaf_examples); + do + ../../bin-linux-amd64/csaf_uploader -a upload -t ${TLPs[$COUNTER]} \ + -u https://localhost:8443/cgi-bin/csaf_provider.go --insecure -P security123 \ + --client-cert ~/devca1/testclient1.crt --client-key ~/devca1/testclient1-key.pem \ + ./csaf_examples/"$f"; + let COUNTER++ + done; diff --git a/docs/test-keys/Readme.md b/docs/test-keys/Readme.md new file mode 100644 index 0000000..70c2b93 --- /dev/null +++ b/docs/test-keys/Readme.md @@ -0,0 +1,23 @@ +OpenPGP key-pair for testing. + +This has been created with: +* gpg (GnuPG) 2.2.19 +* (linked with) libgcrypt 1.8.5 + +### `test1@example.com` + +```bash +gpg --full-gen-key +RSA (sign only) +Requested keysize is 4096 bits +key does not expire at all +Real name: test1 +Email address: test1@example.com +comment: +``` + +```bash +gpg --export-secret-key --armor test1 > private.asc +gpg --export --armor test1 > public.asc +``` +The passphrase for this test OpenPGP key-pair is: `security123` diff --git a/docs/test-keys/private.asc b/docs/test-keys/private.asc new file mode 100644 index 0000000..f5590c5 --- /dev/null +++ b/docs/test-keys/private.asc @@ -0,0 +1,56 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +=ssfC +-----END PGP PRIVATE KEY BLOCK----- diff --git a/docs/test-keys/public.asc b/docs/test-keys/public.asc new file mode 100644 index 0000000..7e28124 --- /dev/null +++ b/docs/test-keys/public.asc @@ -0,0 +1,28 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGI8XxwBEACaVzxyaHp6+D+cO6bNkIQlnX3gmQn5fXeaLF7nwmtYr1c2bAsn +x2SNwrqKIWb80VqPbqO3L+i742IIYF5yS5W/UDaKOFSDqjZsSIleb/gH83Wcnahm +UWxi7ENiHQTSGMG7MWb+uU11TUBhxHsW01oGID06dCz/0PmkkuuggSli3sulM9B7 +UKAqZO2uvGEb3/n2rrEfc8Nh5XgrfbV4f1Gqfxsn1kFr8hIdbfoRuJ98jJ771a4M +eOYurY5EyT/IhFPN+f4sGeztcPtENJIww5wJCzmw5KEPtyTBH97QSUjSsmqGhojk +YpL5yAHId4xGGU717pgxLONS1yjW4r5ydjcUN4xRJLJVb6LB3/3YXcaVhVPXaDM7 +uC97O7CWzlrppACAXMLvsR/flvCskRWAnZ2PKP899Yq3FYZggKC5uvOQbdL3Ya3R +JjI0hRcVRG3by6flRzyfHkz68bsDX5vCCA1NA56JSquCgWDhaORVCE9gVy1KE8ap +h2rgsHwjtde+1wuRDY0FhqFAraWpyxJRT+xCSFozRZxCtBdhAgLnK07ovIUU3aOv +xRpKyUSjw+zVx437S3U8al/hjttgK1KtCt9F5i4nhyXTM+K6FnIHzQsl1OdRNbqA +cmxW1hDmedVOrJwq5VWqquxlf430HrRU9UQGGn1YcGg3rtyLqut63hZvQQARAQAB +tBl0ZXN0MSA8dGVzdDFAZXhhbXBsZS5jb20+iQJOBBMBCgA4FiEEOVOfoEE9nJwJ +7hauNkDK3qAbSi8FAmI8XxwCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ +NkDK3qAbSi8GCQ//SdBBEq7uGHFb5YrNKB9cfGTWgM5cUJRz2I9OaXnDAJDleDED +c/bB3rubSJTAaCj8O0obC9kvKWGzQ89TG064pAC+sQWfnwTvNR3uQyR6050xA1cW +SsWloBICNpwN/oRk4QtUyvy0HIDV/UCe5AgJsR/Y/FnpFv/VJDVfQeckDYdAljqW +b5IQsu1PGTXNzJi1/boMX4NqK/vkSMujIOqXONz7fRhl+Kht8aum1MYZZD2snHG1 +qXoqlUZkDEsbrDPvOds7Pu0DTNpTvBcEFh5apvZW8EtgTBom3/0n4dGxetvXzqVM +sZcToFWEeieYCkXlFOICQT7HSXo06z9pbVncg5IH3ytVaINGxve9ACpwOeIXClur +8U5eRBd3m8KEi/jHYGBQHOO4yUgUDX9YhoabLOvPTD4AsV7FlisqS8GW2YAa+nGK +qyDDIIZtMiG2r1Gd/zdKrjAJZZu1Z1Zt5tphwbxWFRkxFDB8pszo/JXeuyLevBUK +JrsfXjPJLtpTvIrxnUogJvVdF0fmlLJu2FI/71oPrEiyVytH4JpQv44r5jJ6NDH+ +/KSqoF/dzuZIHI7CTTYUNZTDWJryjfc3dZ4pzgloWvotVfZUBwyrLwko+uOblb84 +kSxNqYxdYAjkVFBpr2xEdjhtQg/44MQpImvoWLyXVUt3hFtSOdWZEURcMOk= +=4s3V +-----END PGP PUBLIC KEY BLOCK----- diff --git a/util/file.go b/util/file.go index 66b7240..8e71851 100644 --- a/util/file.go +++ b/util/file.go @@ -3,8 +3,8 @@ // // SPDX-License-Identifier: MIT // -// SPDX-FileCopyrightText: 2021 German Federal Office for Information Security (BSI) -// Software-Engineering: 2021 Intevation GmbH +// SPDX-FileCopyrightText: 2022 German Federal Office for Information Security (BSI) +// Software-Engineering: 2022 Intevation GmbH package util @@ -17,6 +17,10 @@ import ( "time" ) +// SemVersion the version in semver.org format, MUST be overwritten during +// the linking stage of the build process +var SemVersion = "0.0.0" + // NWriter is an io.Writer counting the bytes copied through it. type NWriter struct { io.Writer