Code Monkey home page Code Monkey logo

cwa-server's Introduction

Corona-Warn-App Server

DevelopmentService APIsDocumentationSupportContributeContributorsRepositoriesLicensing

The goal of this project is to develop the official Corona-Warn-App for Germany based on the exposure notification API from Apple and Google. The apps (for both iOS and Android) use Bluetooth technology to exchange anonymous encrypted data with other mobile phones (on which the app is also installed) in the vicinity of an app user's phone. The data is stored locally on each user's device, preventing authorities or other parties from accessing or controlling the data. This repository contains the implementation of the server for encryption keys for the Corona-Warn-App.

In this documentation, Corona-Warn-App services are also referred to as CWA services.

Architecture Overview

You can find the architecture overview here, which will give you a good starting point in how the backend services interact with other services, and what purpose they serve.

Development

After you've checked out this repository, you can run the application in one of the following ways:

  • As a Docker-based deployment on your local machine. You can run either:
    • Single components using the respective Dockerfile or
    • The full backend using the Docker Compose (which is considered the most convenient way)
  • As a Maven-based build on your local machine. If you want to develop something in a single component, this approach is preferable.

Docker-Based Deployment

If you want to use Docker-based deployment, you need to install Docker on your local machine. For more information about downloading and installing Docker, see the official Docker documentation.

Running the Full CWA Backend Using Docker Compose

For your convenience, a full setup for local development and testing purposes, including the generation of test data has been prepared using Docker Compose. To build the backend services, run docker-compose build in the repository's root directory. A default configuration file can be found under .env in the root folder of the repository. If the endpoints are to be exposed to the network the default values in this file should be changed before docker-compose is run.

Once the services are built, you can start the whole backend using docker-compose up. The distribution service runs once and then finishes. If you want to trigger additional distribution runs, run docker-compose run distribution.

The docker-compose contains the following services:

Service Description Endpoint and Default Credentials
submission The Corona-Warn-App submission service http://localhost:8000
http://localhost:8006 (for actuator endpoint)
distribution The Corona-Warn-App distribution service NO ENDPOINT
postgres A postgres database installation localhost:8001
postgres:5432 (from containerized pgadmin)
Username: postgres
Password: postgres
pgadmin A pgadmin installation for the postgres database http://localhost:8002
Username: [email protected]
Password: password
cloudserver Zenko CloudServer is a S3-compliant object store http://localhost:8003/
Access key: accessKey1
Secret key: verySecretKey1
verification-fake A very simple fake implementation for the tan verification. http://localhost:8004/version/v1/tan/verify
The only valid tan is edc07f08-a1aa-11ea-bb37-0242ac130002.
Known Limitation

In rare cases the docker-compose runs into a timing issue if the distribution service starts before the bucket of the objectstore was created. This is not a big issue as you can simply run docker-compose run distribution to trigger additional distribution runs after the objectstore was initialized.

Running Single CWA Services Using Docker

If you would like to build and run a single CWA service, it's considered easiest to run them in a Docker environment. You can do this using the script provided in the respective CWA service directory. The Docker script first builds the CWA service and then creates an image for the runtime, which means that there are no additional dependencies for you to install.

To build and run the distribution service, run the following command:

./services/distribution/build_and_run.sh

To build and run the submission service, run the following command:

./services/submission/build_and_run.sh

The submission service is available on localhost:8080.

Maven-Based Build

If you want to actively develop in one of the CWA services, the Maven-based runtime is most suitable. To prepare your machine to run the CWA project locally, we recommend that you first ensure that you've installed the following:

If you are already running a local Postgres, you need to create a database cwa and run the following setup scripts:

You can also use docker-compose to start Postgres and Zenko. If you do that, you have to set the following environment-variables when running the Spring project:

For the distribution module:

POSTGRESQL_SERVICE_PORT=8001
VAULT_FILESIGNING_SECRET=</path/to/your/private_key>
SPRING_PROFILES_ACTIVE=signature-dev,disable-ssl-client-postgres

For the submission module:

POSTGRESQL_SERVICE_PORT=8001
SPRING_PROFILES_ACTIVE=disable-ssl-client-postgres

Configure

After you made sure that the specified dependencies are running, configure them in the respective configuration files.

  • Configure the Postgres connection in the submission config and in the distribution config
  • Configure the S3 compatible object storage in the distribution config
  • Configure the private key for the distribution service, the path need to be prefixed with file:
    • VAULT_FILESIGNING_SECRET should be the path to the private key, example available in <repo-root>/docker-compose-test-secrets/private.pem

Build

After you've checked out the repository, to build the project, run mvn install in your base directory.

Run

Navigate to the service you want to start and run the spring-boot:run target. The configured Postgres and the configured S3 compliant object storage are used as default. When you start the submission service, the endpoint is available on your local port 8080.

If you want to start the submission service, for example, you start it as follows:

  cd services/submission/
  mvn spring-boot:run

Debugging

To enable the DEBUG log level, you can run the application using the Spring debug profile.

mvn spring-boot:run -Dspring.profiles.active=debug

To be able to set breakpoints (e.g. in IntelliJ), it may be necessary to use the -Dspring-boot.run.fork=false parameter.

Service APIs

The API that is being exposed by the backend services is documented in an OpenAPI specification. The specification files are available at the following locations:

Service OpenAPI Specification
Submission Service services/submission/api_v1.json
Distribution Service services/distribution/api_v1.json

Spring Profiles

Distribution

See Distribution Service - Spring Profiles.

Submission

See Submission Service - Spring Profiles.

Documentation

The full documentation for the Corona-Warn-App can be found in the cwa-documentation repository. The documentation repository contains technical documents, architecture information, and whitepapers related to this implementation.

The documentation for cwa-server can be found under the /docs folder.

The JavaDoc documentation for cwa-server is hosted by Github Pages at https://corona-warn-app.github.io/cwa-server.

Support and Feedback

The following channels are available for discussions, feedback, and support requests:

Type Channel
General Discussion
Concept Feedback
Backend Issue
Other Requests

How to Contribute

Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines. By participating in this project, you agree to abide by its Code of Conduct at all times.

Contributors

The German government has asked SAP and Deutsche Telekom to develop the Corona-Warn-App for Germany as open source software. Deutsche Telekom is providing the network and mobile technology and will operate and run the backend for the app in a safe, scalable and stable manner. SAP is responsible for the app development, its framework and the underlying platform. Therefore, development teams of SAP and Deutsche Telekom are contributing to this project. At the same time our commitment to open source means that we are enabling -in fact encouraging- all interested parties to contribute and become part of its developer community.

Repositories

A list of all public repositories from the Corona-Warn-App can be found here.

Licensing

Copyright (c) 2020-2023 SAP SE or an SAP affiliate company and Corona-Warn-App contributors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.

You may obtain a copy of the License from here.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the LICENSE for the specific language governing permissions and limitations under the License.

Please see the detailed licensing information via the REUSE Tool for more details.

cwa-server's People

Contributors

alexmoroianu avatar alicebilc avatar ccfenner avatar christian-kirschnick avatar corona-warn-app-technical-user avatar dependabot-preview[bot] avatar dependabot[bot] avatar ein-tim avatar eugenm-sap avatar evgeniiskrebtcov avatar felixrottler avatar fredrb avatar hilmarf avatar ioangut avatar johanneseschrig avatar jonaszeitzem-sap avatar jsievers avatar kevponsap avatar kilbphilippsap avatar mfromme avatar mibrasap avatar michael-burwig avatar mkusber avatar mlenkeit avatar ole-lilienthal avatar pithumke avatar roesslerj avatar stevesap avatar tkowark avatar unchartedbull avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cwa-server's Issues

Enable HTTPS for dev deployments

Current Implementation

DEV deployments currently use HTTP.

Suggested Enhancement

Enable HTTPS for dev deployments.

Expected Benefits

Mobile clients can remove "whitelisting" for dev endpoints. Also more S is more better.

Generate Key Bundles in 1hr Slices

Each key bundle that is delivered through the CDN shall represent a 1-hour slice. Therefore, there can be a maximum of 24 of these slices per day, each beginning at the full hour.

Newly submitted diagnosis keys shall be made available through the CDN at every full hour. If there are no new diagnosis keys (db connection error, or there are just none, etc.), a new "empty" file shall still be published.

In addition, each day at 0:00 UTC, a file shall be published that contains all the diagnosis keys that were published through the CDN within the previous 24 hrs.

Hard coded credentials in docker-compose.yml

Describe the bug

There are several hard coded credentials for POSTGRESQL_PASSWORD in the docker-compose.yml file.

Expected behaviour

Hard coded credentials shouldn't be part of source code or config files.

Technical details

https://github.com/corona-warn-app/cwa-server/blob/master/docker-compose.yml

Possible Fix

In docker-compose.yml you can specify a file that contains the env variables for the container:

env_file:
- .env

You can set the credentials in the .env file like this:

POSTGRESQL_PASSWORD=xyz

Don't forget to add .env to .gitignore.

The .env file should be placed somewhere local and securely

Additional context

https://cwe.mitre.org/data/definitions/798.html

Set up Fortify scans

We need to enforce static code scans to help us find security related issues early.

Adjust Distribution Strategy

(on hold due to waiting for Google/Apple spec)

Adjust the current distribution strategy to the following:

Server checks hourly whether new keys need to be published.

  • If there are more than N keys available, a new Export should be created.
  • Otherwise, no file will be generated
  • N must be defined as a parameter (properties file)

The app will use the defined API to check what packages exist for each day. Those packages are not assigned to an hour anymore, but rather just “batchfiles”, e.g. bachfile 1, 2, and 3 for day X. A batch file may or may not be part of a bigger batch.

When an export is generated, it needs to know the exact start timestamp. Since this is now dependent on the creation of the previous export, we need to store this time somewhere. Since we are still using two different time intervals for triggering the export (hourly/daily), we need to store both time indicators.

Add mobile configuration

Mobile needs to be able to fetch additional configuration/settings from the server. The process should be similar to the exposure configuration.

Therefore, add a new app-config.yaml to the codebase. The app-config should contain

risk_classes: 
  - 
    class: LOW
    max: 3
    min: 1
    uri: "https://www..."
  - 
    class: MID
    max: 5
    min: 3
    uri: "https://www..."
  - 
    class: HIGH
    max: 8
    min: 5
    uri: "https://www..."

We need validations & tests (also similar to exposure config). The YAML needs to be parsed to the proto message, so it can used in the distribution service for pushing to CDN.

S3Publisher should set Cache Control Headers

The S3Publisher is currently not setting Cache Control Headers. We should cache-control: public, maxage=N

N depends on the type of file:

  • for hours index files, it should be rather low (5 minutes)
  • for days index files, it should be higher (2 hours)
  • for all generated aggregate files, it should be 24 hours

E-Tag should already been set, but should also be verified.

Consider signing index files

Current Implementation

Date, hour, country and version index files are plain, unsigned JSON arrays.

Suggested Enhancement

Wrap index files in SignedPayloads.

Expected Benefits

Attestation that there were no submissions during a time frame etc., basically because of the same reasons for which we sign the diagnosis keys themselves (proof of authenticity and validity, "undeniability").

Set Retention Days to 14

Any key data that is associated to a point in time older than 14 days shall be removed from the database and will also be removed from the CDN and therefore the index file.

Setup Wiki

  • Setup central platform for sharing findings/documentation (GitHub, or Jam)

Save distribution timestamp for diagnosis keys

DiagnosisKey shall be extended by a nullable timestamp field that stores the time at which the respective key was first distributed by the distribution service.
This field is required for partitioning the distribution packages.

Add Parameter file to code base

We need to be able to allow the mobile clients to fetch the parameter file, so they can compute the risk scores accordingly. Therefore, add the file to the repo and the distribution service shall take care of mapping it to the right output file (similar to the aggregate files).

Need to append "/index" to all GET requests.

Describe the bug

Need to append /index to all requests to the Object Store. Example: /version/v1/index

Expected behaviour

Appending /index should not be necessary. Example: /version/v1

Possible Fix

Rename files on upload to the object store.

Update README.md

Update README.md to reflect the apha release scope and status ...be creative.

Submission Service: Enable waiting for Fake Requests

When fake requests are send to the submission service, ensure that the duration of the fake requests take as long as normal requests, so attackers sniffing the traffic are unable to distinguish between fake/normal requests.

ObjectStore POC

Check up on the ObjectStore on the OTC platform & work on connecting it to our service.

  • Add object store
  • Connect the OS to our service
  • Trigger upload of a file and deletion
  • Check whether bundle uploads are possible (zip like)

Logging Handling

We need to be able to monitor our application. This is about monitoring the logs.

From the looks of it, there is no default support for logging tools like Kibana/Splunk built into OC. However, we need to be able to search the logs in a convenient way.

Find out how we can make tools like Kibana/Splunk work with our current deployment.

Generated files for same chunk differ in binary

After running the testdata profile twice, I noticed that the same file for the same chunk differs on byte level, although the file size is identical. This should not happen, as it will cause problems on CDN.

For the index file, it looks like missing sorting is causing the problem, one example:

[23,18,21,22,19,20]

Switch to Postgres/Flyway on Production

All CWA backend in this repo are currently using HSQLDB regardless of their runtime profile.

  • Configure production profile to use Postgres instead of HSQLDB
  • Ensure code compatibility
  • Re-enable flyway (see application.properties) and create required migration scripts
  • Test on OpenShift deployment

Consider adding "/country/{{country}}" to submission endpoint

Current Implementation

Submission endpoint is /version/{{version}}/diagnosis-keys

Suggested Enhancement

Change submission endpoint to /version/{{version}}/diagnosis-keys/country/{{country}}.

Expected Benefits

At the moment we can not be 100% certain that we will never have to submit diagnosis keys to other countries. However, if we ever get that requirement, and needed to introduce a country differentiating parameter, this would be a breaking change and would force us to bump the overall API version. With the proposed change (and an initial implementation for only /version/v1/diagnosis-keys/country/DE), this issue can already be avoided. Also, the proposed change would align the submission and distribution APIs.

Index File Generation

We shall generate an index file that is intended to be accessible through the CDN informs (the frontend app) about which key bundles are available on the CDN at the time of the call.

  • basically a list of time stamps (also see Exposure-Notification-App/ena-backend#15 and #5)

  • the index file shall be digitally signed

  • only key bundles of size > 0 shall be listed in the index file

  • index file must be delivered with an ETag header (CDN side)

  • specify protocol buffers schema for index file

  • implement end point

Submission: Validate request payload

Validate the submitted temporary exposure keys wrt the latest specification, eg. expected value ranges and things like maximum number of keys per submission. Any violations shall result in an error response, HTTP 400.

Exposure Configuration Distribution

The distribution runner shall:

  1. Read configuration parameters file (part of this repository).
  2. Validate the configuration parameters.
  3. Format the configuration parameters according to the current specification.
  4. Push the configuration parameters to the CDN.

Set up Pipeline

We need to have a Pipeline in place. @johanneseschrig & @MKusber please work on this and come up with a solution. Ideally, it would include the static code scan tools (fortify&sonar)

Remove "empty" dates/hours from index files

Current Implementation

All dates/hours between the first submission and now (last full hour) are included in the index files, even if there were no submissions.

Suggested Enhancement

Only list dates/hours for which there were submissions in the index files. The "empty" date/hour files should, however, still be generated, even if they are not in the index.

Expected Benefits

Mobile clients need to do fewer requests (they can simply skip empty dates/hours).

TAN verification handling

  • Implement the TanVerifier that calls the verification server.
  • Return an appropriate response to the caller in case of an invalid TAN

Audit Logging

We would like to store audit events in a separate audit log (similar to what Cloud Platform) provides.

  • Adding of DK: When a DK is uploaded. Also involve verification call / result
  • Creation of aggregate files (daily/hourly) & push result to CDN

@MKusber

Adjust Service/Persistence Code to latest ProtoSpec

message File {
  Header header = 1;
  repeated Key keys = 2;
}

message Header {
  int64 startTimestamp = 1; // Time window of keys in this file based on arrival to server, in UTC.
  int64 endTimestamp = 2;
  string region = 3; // Region for which these keys came from (e.g., country)
  int32 batchNum = 4; // E.g., Batch 2 of 10
  int32 batchSize = 5;
}

message Key {
  bytes keyData = 1; // Key of infected user
  uint32 rollingStartNumber = 2; // Interval number when the key's EKRollingPeriod started.
  uint32 rollingPeriod = 3; // Number of 10-minute windows between key rolling.
  int32 transmissionRiskLevel = 4; // Risk of transmission associated with the person this key came from.

Device Attestation

(onhold due to waiting for Google/Apple spec)

When the user sends the diagnosis keys, we need to verify whether the request came from a legitimate source.

  • Accept the "platform" attribute in the incoming request. Must either be "ios" or "android". Needed for the device verification payload below:
  • Device Verification Payload: This is either Android SafetyNet device attestation or iOS DeviceCheck attestation.

Problem: This highly depends whether data privacy team is OK with this. I will sync with them.

LICENSE missing

Please add a license.
If possible Apache v2.
If you are going to reuse code under MPL license, like DP3T, you can also use MPL, but preference would be Apache.

Exposure configuration parameters not validated

The exposure configuration parameters are currently not validated after being read from the respective yml file. The validation code in ExposureConfigurationValidator is currently used in tests only.

However, the expected behavior shall be the following:

  • The RiskScoreParameters object is constructed based on yml file. (✅)
  • ExposureConfigurationValidator performs validation of the parameters.
  • In case of a failed validation, do not publish the exposure configuration parameters, but do generate and publish the diagnosis key bundles.
  • Clarify whether to keep any previously present (valid) configuration parameters on the object store if a validation error occurs.
  • Any validation errors shall be logged appropriately.

Sign Packages

Exposure bundles that are published through the CDN shall contain an Ed25519 signature and the respective public key certificate.
(see latest protobuf spec)

Signing Approach

Align on the final signing approach (onhold due to waiting for Google/Apple spec)

Define and implement desired behavior for fake request processing

Randomly sent "fake" diagnosis key submission requests are a privacy preserving measure. They are identified by a non-zero value for the cwa-fake HTTP header.

Currently, this results in the "fake" payload to be discarded and an immediate HTTP 200response.
It shall be evaluated whether a delay should be introduced to ensure a constant processing time, regardless of whether dealing with a "fake" or "real" request.

Reject OPTIONS requests

Applies to all submission and distribution endpoints:
Remove OPTIONS from the allowed response header and reject respective requests with status HTTP 405 Method Not Allowed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.