You will be provided with a partial code base and an issue statement explaining a problem to resolve.
<issue>
SSL: Set a profile to willingly decrease security
Currently, we have the profiles `ssl-server`, `ssl-client-verification` and `ssl-client-postgres` which will enable `ssl` for certain situations. 

In context of secure-by-default, we should have it in the opposite way - you can set a profile to willingly decrease security.

</issue>

<code>
[start of README.md]
1 <!-- markdownlint-disable MD041 -->
2 <h1 align="center">
3     Corona-Warn-App Server
4 </h1>
5 
6 <p align="center">
7     <a href="https://github.com/corona-warn-app/cwa-server/commits/" title="Last Commit"><img src="https://img.shields.io/github/last-commit/corona-warn-app/cwa-server?style=flat"></a>
8     <a href="https://github.com/corona-warn-app/cwa-server/issues" title="Open Issues"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-server?style=flat"></a>
9     <a href="https://circleci.com/gh/corona-warn-app/cwa-server" title="Build Status"><img src="https://circleci.com/gh/corona-warn-app/cwa-server.svg?style=shield&circle-token=4ab059989d10709df19eb4b98ab7c121a25e981a"></a>
10         <a href="https://sonarcloud.io/dashboard?id=corona-warn-app_cwa-server" title="Quality Gate"><img src="https://sonarcloud.io/api/project_badges/measure?project=corona-warn-app_cwa-server&metric=alert_status"></a>
11         <a href="https://sonarcloud.io/component_measures?id=corona-warn-app_cwa-server&metric=Coverage&view=list" title="Coverage"><img src="https://sonarcloud.io/api/project_badges/measure?project=corona-warn-app_cwa-server&metric=coverage"></a>
12     <a href="https://github.com/corona-warn-app/cwa-server/blob/master/LICENSE" title="License"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg?style=flat"></a>
13 </p>
14 
15 <p align="center">
16   <a href="#development">Development</a> •
17   <a href="#service-apis">Service APIs</a> •
18   <a href="#documentation">Documentation</a> •
19   <a href="#support-and-feedback">Support</a> •
20   <a href="#how-to-contribute">Contribute</a> •
21   <a href="#contributors">Contributors</a> •
22   <a href="#repositories">Repositories</a> •
23   <a href="#licensing">Licensing</a>
24 </p>
25 
26 The goal of this project is to develop the official Corona-Warn-App for Germany based on the exposure notification API from [Apple](https://www.apple.com/covid19/contacttracing/) and [Google](https://www.google.com/covid19/exposurenotifications/). 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.
27 
28 In this documentation, Corona-Warn-App services are also referred to as CWA services.
29 
30 ## Architecture Overview
31 
32 You can find the architecture overview [here](/docs/ARCHITECTURE.md), which will give you
33 a good starting point in how the backend services interact with other services, and what purpose
34 they serve.
35 
36 ## Development
37 
38 After you've checked out this repository, you can run the application in one of the following ways:
39 
40 * As a [Docker](https://www.docker.com/)-based deployment on your local machine. You can run either:
41   * Single components using the respective Dockerfile or
42   * The full backend using the Docker Compose (which is considered the most convenient way)
43 * As a [Maven](https://maven.apache.org)-based build on your local machine.
44   If you want to develop something in a single component, this approach is preferable.
45 
46 ### Docker-Based Deployment
47 
48 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](https://docs.docker.com/get-docker/).
49 
50 #### Running the Full CWA Backend Using Docker Compose
51 
52 For your convenience, a full setup including the generation of test data has been prepared using [Docker Compose](https://docs.docker.com/compose/reference/overview/). 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. The default values for the local Postgres and Zenko Cloudserver should be changed in this file before docker-compose is run.
53 
54 Once the services are built, you can start the whole backend using ```docker-compose up```.
55 The distribution service runs once and then finishes. If you want to trigger additional distribution runs, run ```docker-compose run distribution```.
56 
57 The docker-compose contains the following services:
58 
59 Service           | Description | Endpoint and Default Credentials
60 ------------------|-------------|-----------
61 submission        | The Corona-Warn-App submission service                                                      | `http://localhost:8000` <br> `http://localhost:8006` (for actuator endpoint)
62 distribution      | The Corona-Warn-App distribution service                                                    | NO ENDPOINT
63 postgres          | A [postgres] database installation                                                          | `localhost:8001` <br> `postgres:5432` (from containerized pgadmin) <br> Username: postgres <br> Password: postgres
64 pgadmin           | A [pgadmin](https://www.pgadmin.org/) installation for the postgres database                | `http://localhost:8002` <br> Username: user@domain.com <br> Password: password
65 cloudserver       | [Zenko CloudServer] is a S3-compliant object store  | `http://localhost:8003/` <br> Access key: accessKey1 <br> Secret key: verySecretKey1
66 verification-fake | A very simple fake implementation for the tan verification.                                 | `http://localhost:8004/version/v1/tan/verify` <br> The only valid tan is `edc07f08-a1aa-11ea-bb37-0242ac130002`.
67 
68 ##### Known Limitation
69 
70 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.
71 
72 #### Running Single CWA Services Using Docker
73 
74 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.
75 
76 To build and run the distribution service, run the following command:
77 
78 ```bash
79 ./services/distribution/build_and_run.sh
80 ```
81 
82 To build and run the submission service, run the following command:
83 
84 ```bash
85 ./services/submission/build_and_run.sh
86 ```
87 
88 The submission service is available on [localhost:8080](http://localhost:8080 ).
89 
90 ### Maven-Based Build
91 
92 If you want to actively develop in one of the CWA services, the Maven-based runtime is most suitable.
93 To prepare your machine to run the CWA project locally, we recommend that you first ensure that you've installed the following:
94 
95 * Minimum JDK Version 11: [OpenJDK](https://openjdk.java.net/) / [SapMachine](https://sap.github.io/SapMachine/)
96 * [Maven 3.6](https://maven.apache.org/)
97 * [Postgres]
98 * [Zenko CloudServer]
99 
100 If you are already running a local Postgres, you need to create a database `cwa` and run the following setup scripts:
101 
102 * Create the different CWA roles first by executing [create-roles.sql](setup/create-roles.sql).
103 * Create local database users for the specific roles by running [create-users.sql](./local-setup/create-users.sql).
104 * It is recommended to also run [enable-test-data-docker-compose.sql](./local-setup/enable-test-data-docker-compose.sql)
105 , which enables the test data generation profile. If you already had CWA running before and an existing `diagnosis-key`
106 table on your database, you need to run [enable-test-data.sql](./local-setup/enable-test-data.sql) instead.
107 
108 You can also use `docker-compose` to start Postgres and Zenko. If you do that, you have to
109 set the following environment-variables when running the Spring project:
110 
111 For the distribution module:
112 
113 ```bash
114 POSTGRESQL_SERVICE_PORT=8001
115 VAULT_FILESIGNING_SECRET=</path/to/your/private_key>
116 ```
117 
118 For the submission module:
119 
120 ```bash
121 POSTGRESQL_SERVICE_PORT=8001
122 ```
123 
124 #### Configure
125 
126 After you made sure that the specified dependencies are running, configure them in the respective configuration files.
127 
128 * Configure the Postgres connection in the [submission config](./services/submission/src/main/resources/application.yaml) and in the [distribution config](./services/distribution/src/main/resources/application.yaml)
129 * Configure the S3 compatible object storage in the [distribution config](./services/distribution/src/main/resources/application.yaml)
130 * Configure the private key for the distribution service, the path need to be prefixed with `file:`
131   * `VAULT_FILESIGNING_SECRET` should be the path to the private key, example available in `<repo-root>/docker-compose-test-secrets/private.pem`
132 
133 #### Build
134 
135 After you've checked out the repository, to build the project, run ```mvn install``` in your base directory.
136 
137 #### Run
138 
139 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.
140 
141 If you want to start the submission service, for example, you start it as follows:
142 
143 ```bash
144   cd services/submission/
145   mvn spring-boot:run
146 ```
147 
148 #### Debugging
149 
150 To enable the `DEBUG` log level, you can run the application using the Spring `dev` profile.
151 
152 ```bash
153 mvn spring-boot:run -Dspring.profiles.active=dev
154 ```
155 
156 To be able to set breakpoints (e.g. in IntelliJ), it may be necessary to use the ```-Dspring-boot.run.fork=false``` parameter.
157 
158 ## Service APIs
159 
160 The API that is being exposed by the backend services is documented in an [OpenAPI](https://www.openapis.org/) specification. The specification files are available at the following locations:
161 
162 Service      | OpenAPI Specification
163 -------------|-------------
164 Submission Service        | [services/submission/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/submission/api_v1.json)
165 Distribution Service      | [services/distribution/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/distribution/api_v1.json)
166 
167 ## Spring Profiles
168 
169 ### Distribution
170 
171 Profile               | Effect
172 ----------------------|-------------
173 `dev`                 | Turns the log level to `DEBUG`.
174 `cloud`               | Removes default values for the `datasource` and `objectstore` configurations.
175 `demo`                | Includes incomplete days and hours into the distribution run, thus creating aggregates for the current day and the current hour (and including both in the respective indices). When running multiple distributions in one hour with this profile, the date aggregate for today and the hours aggregate for the current hour will be updated and overwritten. This profile also turns off the expiry policy (Keys must be expired for at least 2 hours before distribution) and the shifting policy (there must be at least 140 keys in a distribution).
176 `testdata`            | Causes test data to be inserted into the database before each distribution run. By default, around 1000 random diagnosis keys will be generated per hour. If there are no diagnosis keys in the database yet, random keys will be generated for every hour from the beginning of the retention period (14 days ago at 00:00 UTC) until one hour before the present hour. If there are already keys in the database, the random keys will be generated for every hour from the latest diagnosis key in the database (by submission timestamp) until one hour before the present hour (or none at all, if the latest diagnosis key in the database was submitted one hour ago or later).
177 `signature-dev`       | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp-dev` so that the non-productive/test public key will be used for client-side validation.
178 `signature-prod`      | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp` so that the productive public key will be used for client-side validation.
179 `ssl-client-postgres` | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/distribution/src/main/resources/application-ssl-client-postgres.yaml)).
180 
181 ### Submission
182 
183 Profile                   | Effect
184 --------------------------|-------------
185 `dev`                     | Turns the log level to `DEBUG`.
186 `cloud`                   | Removes default values for the `datasource` configuration.
187 `ssl-server`              | Enables SSL for the submission endpoint (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-server.yaml)).
188 `ssl-client-postgres`     | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-postgres.yaml)).
189 `ssl-client-verification` | Enforces SSL with a pinned certificate for the connection to the verification server (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-verification.yaml)).
190 
191 ## Documentation
192 
193 The full documentation for the Corona-Warn-App can be found in the [cwa-documentation](https://github.com/corona-warn-app/cwa-documentation) repository. The documentation repository contains technical documents, architecture information, and whitepapers related to this implementation.
194 
195 ## Support and Feedback
196 
197 The following channels are available for discussions, feedback, and support requests:
198 
199 | Type                     | Channel                                                |
200 | ------------------------ | ------------------------------------------------------ |
201 | **General Discussion**   | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="General Discussion"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/question.svg?style=flat-square"></a> </a>   |
202 | **Concept Feedback**    | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="Open Concept Feedback"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/architecture.svg?style=flat-square"></a>  |
203 | **Backend Issue**    | <a href="https://github.com/corona-warn-app/cwa-server/issues/new/choose" title="Open Backend Issue"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-server?style=flat-square"></a>  |
204 | **Other Requests**    | <a href="mailto:corona-warn-app.opensource@sap.com" title="Email CWA Team"><img src="https://img.shields.io/badge/email-CWA%20team-green?logo=mail.ru&style=flat-square&logoColor=white"></a>   |
205 
206 ## How to Contribute
207 
208 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](./CONTRIBUTING.md). By participating in this project, you agree to abide by its [Code of Conduct](./CODE_OF_CONDUCT.md) at all times.
209 
210 ## Contributors
211 
212 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.
213 
214 ## Repositories
215 
216 The following public repositories are currently available for the Corona-Warn-App:
217 
218 | Repository          | Description                                                           |
219 | ------------------- | --------------------------------------------------------------------- |
220 | [cwa-documentation] | Project overview, general documentation, and white papers            |
221 | [cwa-server]        | Backend implementation for the Apple/Google exposure notification API|
222 | [cwa-verification-server] | Backend implementation of the verification process|
223 
224 [cwa-documentation]: https://github.com/corona-warn-app/cwa-documentation
225 [cwa-server]: https://github.com/corona-warn-app/cwa-server
226 [cwa-verification-server]: https://github.com/corona-warn-app/cwa-verification-server
227 [Postgres]: https://www.postgresql.org/
228 [HSQLDB]: http://hsqldb.org/
229 [Zenko CloudServer]: https://github.com/scality/cloudserver
230 
231 ## Licensing
232 
233 Copyright (c) 2020 SAP SE or an SAP affiliate company.
234 
235 Licensed under the **Apache License, Version 2.0** (the "License"); you may not use this file except in compliance with the License.
236 
237 You may obtain a copy of the License at <https://www.apache.org/licenses/LICENSE-2.0>.
238 
239 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](./LICENSE) for the specific language governing permissions and limitations under the License.
240 
[end of README.md]
[start of /dev/null]
1 
[end of /dev/null]
[start of README.md]
1 <!-- markdownlint-disable MD041 -->
2 <h1 align="center">
3     Corona-Warn-App Server
4 </h1>
5 
6 <p align="center">
7     <a href="https://github.com/corona-warn-app/cwa-server/commits/" title="Last Commit"><img src="https://img.shields.io/github/last-commit/corona-warn-app/cwa-server?style=flat"></a>
8     <a href="https://github.com/corona-warn-app/cwa-server/issues" title="Open Issues"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-server?style=flat"></a>
9     <a href="https://circleci.com/gh/corona-warn-app/cwa-server" title="Build Status"><img src="https://circleci.com/gh/corona-warn-app/cwa-server.svg?style=shield&circle-token=4ab059989d10709df19eb4b98ab7c121a25e981a"></a>
10         <a href="https://sonarcloud.io/dashboard?id=corona-warn-app_cwa-server" title="Quality Gate"><img src="https://sonarcloud.io/api/project_badges/measure?project=corona-warn-app_cwa-server&metric=alert_status"></a>
11         <a href="https://sonarcloud.io/component_measures?id=corona-warn-app_cwa-server&metric=Coverage&view=list" title="Coverage"><img src="https://sonarcloud.io/api/project_badges/measure?project=corona-warn-app_cwa-server&metric=coverage"></a>
12     <a href="https://github.com/corona-warn-app/cwa-server/blob/master/LICENSE" title="License"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg?style=flat"></a>
13 </p>
14 
15 <p align="center">
16   <a href="#development">Development</a> •
17   <a href="#service-apis">Service APIs</a> •
18   <a href="#documentation">Documentation</a> •
19   <a href="#support-and-feedback">Support</a> •
20   <a href="#how-to-contribute">Contribute</a> •
21   <a href="#contributors">Contributors</a> •
22   <a href="#repositories">Repositories</a> •
23   <a href="#licensing">Licensing</a>
24 </p>
25 
26 The goal of this project is to develop the official Corona-Warn-App for Germany based on the exposure notification API from [Apple](https://www.apple.com/covid19/contacttracing/) and [Google](https://www.google.com/covid19/exposurenotifications/). 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.
27 
28 In this documentation, Corona-Warn-App services are also referred to as CWA services.
29 
30 ## Architecture Overview
31 
32 You can find the architecture overview [here](/docs/ARCHITECTURE.md), which will give you
33 a good starting point in how the backend services interact with other services, and what purpose
34 they serve.
35 
36 ## Development
37 
38 After you've checked out this repository, you can run the application in one of the following ways:
39 
40 * As a [Docker](https://www.docker.com/)-based deployment on your local machine. You can run either:
41   * Single components using the respective Dockerfile or
42   * The full backend using the Docker Compose (which is considered the most convenient way)
43 * As a [Maven](https://maven.apache.org)-based build on your local machine.
44   If you want to develop something in a single component, this approach is preferable.
45 
46 ### Docker-Based Deployment
47 
48 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](https://docs.docker.com/get-docker/).
49 
50 #### Running the Full CWA Backend Using Docker Compose
51 
52 For your convenience, a full setup including the generation of test data has been prepared using [Docker Compose](https://docs.docker.com/compose/reference/overview/). 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. The default values for the local Postgres and Zenko Cloudserver should be changed in this file before docker-compose is run.
53 
54 Once the services are built, you can start the whole backend using ```docker-compose up```.
55 The distribution service runs once and then finishes. If you want to trigger additional distribution runs, run ```docker-compose run distribution```.
56 
57 The docker-compose contains the following services:
58 
59 Service           | Description | Endpoint and Default Credentials
60 ------------------|-------------|-----------
61 submission        | The Corona-Warn-App submission service                                                      | `http://localhost:8000` <br> `http://localhost:8006` (for actuator endpoint)
62 distribution      | The Corona-Warn-App distribution service                                                    | NO ENDPOINT
63 postgres          | A [postgres] database installation                                                          | `localhost:8001` <br> `postgres:5432` (from containerized pgadmin) <br> Username: postgres <br> Password: postgres
64 pgadmin           | A [pgadmin](https://www.pgadmin.org/) installation for the postgres database                | `http://localhost:8002` <br> Username: user@domain.com <br> Password: password
65 cloudserver       | [Zenko CloudServer] is a S3-compliant object store  | `http://localhost:8003/` <br> Access key: accessKey1 <br> Secret key: verySecretKey1
66 verification-fake | A very simple fake implementation for the tan verification.                                 | `http://localhost:8004/version/v1/tan/verify` <br> The only valid tan is `edc07f08-a1aa-11ea-bb37-0242ac130002`.
67 
68 ##### Known Limitation
69 
70 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.
71 
72 #### Running Single CWA Services Using Docker
73 
74 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.
75 
76 To build and run the distribution service, run the following command:
77 
78 ```bash
79 ./services/distribution/build_and_run.sh
80 ```
81 
82 To build and run the submission service, run the following command:
83 
84 ```bash
85 ./services/submission/build_and_run.sh
86 ```
87 
88 The submission service is available on [localhost:8080](http://localhost:8080 ).
89 
90 ### Maven-Based Build
91 
92 If you want to actively develop in one of the CWA services, the Maven-based runtime is most suitable.
93 To prepare your machine to run the CWA project locally, we recommend that you first ensure that you've installed the following:
94 
95 * Minimum JDK Version 11: [OpenJDK](https://openjdk.java.net/) / [SapMachine](https://sap.github.io/SapMachine/)
96 * [Maven 3.6](https://maven.apache.org/)
97 * [Postgres]
98 * [Zenko CloudServer]
99 
100 If you are already running a local Postgres, you need to create a database `cwa` and run the following setup scripts:
101 
102 * Create the different CWA roles first by executing [create-roles.sql](setup/create-roles.sql).
103 * Create local database users for the specific roles by running [create-users.sql](./local-setup/create-users.sql).
104 * It is recommended to also run [enable-test-data-docker-compose.sql](./local-setup/enable-test-data-docker-compose.sql)
105 , which enables the test data generation profile. If you already had CWA running before and an existing `diagnosis-key`
106 table on your database, you need to run [enable-test-data.sql](./local-setup/enable-test-data.sql) instead.
107 
108 You can also use `docker-compose` to start Postgres and Zenko. If you do that, you have to
109 set the following environment-variables when running the Spring project:
110 
111 For the distribution module:
112 
113 ```bash
114 POSTGRESQL_SERVICE_PORT=8001
115 VAULT_FILESIGNING_SECRET=</path/to/your/private_key>
116 ```
117 
118 For the submission module:
119 
120 ```bash
121 POSTGRESQL_SERVICE_PORT=8001
122 ```
123 
124 #### Configure
125 
126 After you made sure that the specified dependencies are running, configure them in the respective configuration files.
127 
128 * Configure the Postgres connection in the [submission config](./services/submission/src/main/resources/application.yaml) and in the [distribution config](./services/distribution/src/main/resources/application.yaml)
129 * Configure the S3 compatible object storage in the [distribution config](./services/distribution/src/main/resources/application.yaml)
130 * Configure the private key for the distribution service, the path need to be prefixed with `file:`
131   * `VAULT_FILESIGNING_SECRET` should be the path to the private key, example available in `<repo-root>/docker-compose-test-secrets/private.pem`
132 
133 #### Build
134 
135 After you've checked out the repository, to build the project, run ```mvn install``` in your base directory.
136 
137 #### Run
138 
139 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.
140 
141 If you want to start the submission service, for example, you start it as follows:
142 
143 ```bash
144   cd services/submission/
145   mvn spring-boot:run
146 ```
147 
148 #### Debugging
149 
150 To enable the `DEBUG` log level, you can run the application using the Spring `dev` profile.
151 
152 ```bash
153 mvn spring-boot:run -Dspring.profiles.active=dev
154 ```
155 
156 To be able to set breakpoints (e.g. in IntelliJ), it may be necessary to use the ```-Dspring-boot.run.fork=false``` parameter.
157 
158 ## Service APIs
159 
160 The API that is being exposed by the backend services is documented in an [OpenAPI](https://www.openapis.org/) specification. The specification files are available at the following locations:
161 
162 Service      | OpenAPI Specification
163 -------------|-------------
164 Submission Service        | [services/submission/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/submission/api_v1.json)
165 Distribution Service      | [services/distribution/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/distribution/api_v1.json)
166 
167 ## Spring Profiles
168 
169 ### Distribution
170 
171 Profile               | Effect
172 ----------------------|-------------
173 `dev`                 | Turns the log level to `DEBUG`.
174 `cloud`               | Removes default values for the `datasource` and `objectstore` configurations.
175 `demo`                | Includes incomplete days and hours into the distribution run, thus creating aggregates for the current day and the current hour (and including both in the respective indices). When running multiple distributions in one hour with this profile, the date aggregate for today and the hours aggregate for the current hour will be updated and overwritten. This profile also turns off the expiry policy (Keys must be expired for at least 2 hours before distribution) and the shifting policy (there must be at least 140 keys in a distribution).
176 `testdata`            | Causes test data to be inserted into the database before each distribution run. By default, around 1000 random diagnosis keys will be generated per hour. If there are no diagnosis keys in the database yet, random keys will be generated for every hour from the beginning of the retention period (14 days ago at 00:00 UTC) until one hour before the present hour. If there are already keys in the database, the random keys will be generated for every hour from the latest diagnosis key in the database (by submission timestamp) until one hour before the present hour (or none at all, if the latest diagnosis key in the database was submitted one hour ago or later).
177 `signature-dev`       | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp-dev` so that the non-productive/test public key will be used for client-side validation.
178 `signature-prod`      | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp` so that the productive public key will be used for client-side validation.
179 `ssl-client-postgres` | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/distribution/src/main/resources/application-ssl-client-postgres.yaml)).
180 
181 ### Submission
182 
183 Profile                   | Effect
184 --------------------------|-------------
185 `dev`                     | Turns the log level to `DEBUG`.
186 `cloud`                   | Removes default values for the `datasource` configuration.
187 `ssl-server`              | Enables SSL for the submission endpoint (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-server.yaml)).
188 `ssl-client-postgres`     | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-postgres.yaml)).
189 `ssl-client-verification` | Enforces SSL with a pinned certificate for the connection to the verification server (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-verification.yaml)).
190 
191 ## Documentation
192 
193 The full documentation for the Corona-Warn-App can be found in the [cwa-documentation](https://github.com/corona-warn-app/cwa-documentation) repository. The documentation repository contains technical documents, architecture information, and whitepapers related to this implementation.
194 
195 ## Support and Feedback
196 
197 The following channels are available for discussions, feedback, and support requests:
198 
199 | Type                     | Channel                                                |
200 | ------------------------ | ------------------------------------------------------ |
201 | **General Discussion**   | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="General Discussion"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/question.svg?style=flat-square"></a> </a>   |
202 | **Concept Feedback**    | <a href="https://github.com/corona-warn-app/cwa-documentation/issues/new/choose" title="Open Concept Feedback"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-documentation/architecture.svg?style=flat-square"></a>  |
203 | **Backend Issue**    | <a href="https://github.com/corona-warn-app/cwa-server/issues/new/choose" title="Open Backend Issue"><img src="https://img.shields.io/github/issues/corona-warn-app/cwa-server?style=flat-square"></a>  |
204 | **Other Requests**    | <a href="mailto:corona-warn-app.opensource@sap.com" title="Email CWA Team"><img src="https://img.shields.io/badge/email-CWA%20team-green?logo=mail.ru&style=flat-square&logoColor=white"></a>   |
205 
206 ## How to Contribute
207 
208 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](./CONTRIBUTING.md). By participating in this project, you agree to abide by its [Code of Conduct](./CODE_OF_CONDUCT.md) at all times.
209 
210 ## Contributors
211 
212 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.
213 
214 ## Repositories
215 
216 The following public repositories are currently available for the Corona-Warn-App:
217 
218 | Repository          | Description                                                           |
219 | ------------------- | --------------------------------------------------------------------- |
220 | [cwa-documentation] | Project overview, general documentation, and white papers            |
221 | [cwa-server]        | Backend implementation for the Apple/Google exposure notification API|
222 | [cwa-verification-server] | Backend implementation of the verification process|
223 
224 [cwa-documentation]: https://github.com/corona-warn-app/cwa-documentation
225 [cwa-server]: https://github.com/corona-warn-app/cwa-server
226 [cwa-verification-server]: https://github.com/corona-warn-app/cwa-verification-server
227 [Postgres]: https://www.postgresql.org/
228 [HSQLDB]: http://hsqldb.org/
229 [Zenko CloudServer]: https://github.com/scality/cloudserver
230 
231 ## Licensing
232 
233 Copyright (c) 2020 SAP SE or an SAP affiliate company.
234 
235 Licensed under the **Apache License, Version 2.0** (the "License"); you may not use this file except in compliance with the License.
236 
237 You may obtain a copy of the License at <https://www.apache.org/licenses/LICENSE-2.0>.
238 
239 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](./LICENSE) for the specific language governing permissions and limitations under the License.
240 
[end of README.md]
[start of docker-compose.yml]
1 version: '3'
2 services:
3   submission:
4     build:
5       context: ./
6       dockerfile: ./services/submission/Dockerfile
7     depends_on:
8       - postgres
9       - verification-fake
10     ports:
11       - "8000:8080"
12       - "8006:8081"
13     environment:
14       SPRING_PROFILES_ACTIVE: dev
15       POSTGRESQL_SERVICE_PORT: '5432'
16       POSTGRESQL_SERVICE_HOST: postgres
17       POSTGRESQL_DATABASE: ${POSTGRES_DB}
18       POSTGRESQL_PASSWORD_SUBMISION: ${POSTGRES_SUBMISSION_PASSWORD}
19       POSTGRESQL_USER_SUBMISION: ${POSTGRES_SUBMISSION_USER}
20       POSTGRESQL_PASSWORD_FLYWAY: ${POSTGRES_FLYWAY_PASSWORD}
21       POSTGRESQL_USER_FLYWAY: ${POSTGRES_FLYWAY_USER}
22       VERIFICATION_BASE_URL: http://verification-fake:8004
23   distribution:
24     build:
25       context: ./
26       dockerfile: ./services/distribution/Dockerfile
27     depends_on:
28      - postgres
29      - objectstore
30      - create-bucket
31     environment:
32       SPRING_PROFILES_ACTIVE: dev,signature-dev,testdata
33       POSTGRESQL_SERVICE_PORT: '5432'
34       POSTGRESQL_SERVICE_HOST: postgres
35       POSTGRESQL_DATABASE: ${POSTGRES_DB}
36       POSTGRESQL_PASSWORD_DISTRIBUTION: ${POSTGRES_DISTRIBUTION_PASSWORD}
37       POSTGRESQL_USER_DISTRIBUTION: ${POSTGRES_DISTRIBUTION_USER}
38       POSTGRESQL_PASSWORD_FLYWAY: ${POSTGRES_FLYWAY_PASSWORD}
39       POSTGRESQL_USER_FLYWAY: ${POSTGRES_FLYWAY_USER}
40       # Settings for the S3 compatible objectstore
41       CWA_OBJECTSTORE_ACCESSKEY: ${OBJECTSTORE_ACCESSKEY}
42       CWA_OBJECTSTORE_SECRETKEY: ${OBJECTSTORE_SECRETKEY}
43       CWA_OBJECTSTORE_ENDPOINT: http://objectstore
44       CWA_OBJECTSTORE_BUCKET: cwa
45       CWA_OBJECTSTORE_PORT: 8000
46       services.distribution.paths.output: /tmp/distribution
47       # Settings for cryptographic artifacts
48       VAULT_FILESIGNING_SECRET: ${SECRET_PRIVATE}
49     volumes:
50       - ./docker-compose-test-secrets:/secrets
51   postgres:
52     image: postgres:11.8
53     restart: always
54     ports:
55       - "8001:5432"
56     environment:
57       PGDATA: /data/postgres
58       POSTGRES_DB: ${POSTGRES_DB}
59       POSTGRES_USER: ${POSTGRES_USER}
60       POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
61     volumes:
62        - postgres_volume:/data/postgres
63        - ./setup/setup-roles.sql:/docker-entrypoint-initdb.d/1-roles.sql
64        - ./local-setup/create-users.sql:/docker-entrypoint-initdb.d/2-users.sql
65        - ./local-setup/enable-test-data-docker-compose.sql:/docker-entrypoint-initdb.d/3-enable-testdata.sql
66   pgadmin:
67     container_name: pgadmin_container
68     image: dpage/pgadmin4
69     volumes:
70        - pgadmin_volume:/root/.pgadmin
71     ports:
72       - "8002:80"
73     restart: unless-stopped
74     depends_on:
75       - postgres
76     environment:
77       PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
78       PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
79   objectstore:
80     image: "zenko/cloudserver"
81     volumes:
82       - objectstore_volume:/data
83     ports:
84       - "8003:8000"
85     environment:
86       ENDPOINT: objectstore
87       REMOTE_MANAGEMENT_DISABLE: 1
88       SCALITY_ACCESS_KEY_ID: ${OBJECTSTORE_ACCESSKEY}
89       SCALITY_SECRET_ACCESS_KEY: ${OBJECTSTORE_SECRETKEY}
90   create-bucket:
91     image: amazon/aws-cli
92     environment:
93       - AWS_ACCESS_KEY_ID=${OBJECTSTORE_ACCESSKEY}
94       - AWS_SECRET_ACCESS_KEY=${OBJECTSTORE_SECRETKEY}
95     entrypoint: ["/root/scripts/wait-for-it/wait-for-it.sh", "objectstore:8000", "-t", "30", "--"]
96     volumes:
97       - ./scripts/wait-for-it:/root/scripts/wait-for-it
98     command: aws s3api create-bucket --bucket cwa --endpoint-url http://objectstore:8000 --acl public-read
99     depends_on:
100       - objectstore
101   verification-fake:
102     image: lilienthal/cwa-verification-fake:0.0.3
103     restart: always
104     ports:
105       - "8004:8004"
106 volumes:
107   postgres_volume:
108   pgadmin_volume:
109   objectstore_volume:
110 
[end of docker-compose.yml]
[start of services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java]
1 /*-
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.distribution;
22 
23 import app.coronawarn.server.services.distribution.config.DistributionServiceConfig;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.springframework.boot.SpringApplication;
27 import org.springframework.boot.autoconfigure.SpringBootApplication;
28 import org.springframework.boot.autoconfigure.domain.EntityScan;
29 import org.springframework.boot.context.properties.EnableConfigurationProperties;
30 import org.springframework.context.ApplicationContext;
31 import org.springframework.context.annotation.ComponentScan;
32 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
33 
34 /**
35  * The retrieval, assembly and distribution of configuration and diagnosis key data is handled by a chain of {@link
36  * org.springframework.boot.ApplicationRunner} instances. An unrecoverable failure in either one of them is terminating
37  * the chain execution.
38  */
39 @SpringBootApplication
40 @EnableJpaRepositories(basePackages = "app.coronawarn.server.common.persistence")
41 @EntityScan(basePackages = "app.coronawarn.server.common.persistence")
42 @ComponentScan({"app.coronawarn.server.common.persistence",
43     "app.coronawarn.server.services.distribution"})
44 @EnableConfigurationProperties({DistributionServiceConfig.class})
45 public class Application {
46 
47   private static final Logger logger = LoggerFactory.getLogger(Application.class);
48 
49   public static void main(String[] args) {
50     SpringApplication.run(Application.class);
51   }
52 
53   /**
54    * Terminates this application with exit code 1 (general error).
55    */
56   public static void killApplication(ApplicationContext appContext) {
57     SpringApplication.exit(appContext);
58     logger.error("Application terminated abnormally.");
59     System.exit(1);
60   }
61 }
62 
[end of services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java]
[start of services/distribution/src/main/resources/application-cloud.yaml]
1 ---
2 spring:
3   flyway:
4     password: ${POSTGRESQL_PASSWORD_FLYWAY}
5     user: ${POSTGRESQL_USER_FLYWAY}
6   datasource:
7     driver-class-name: org.postgresql.Driver
8     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}
9     username: ${POSTGRESQL_USER_DISTRIBUTION}
10     password: ${POSTGRESQL_PASSWORD_DISTRIBUTION}
11 
12 services:
13   distribution:
14     paths:
15       output: /tmp/distribution
16     objectstore:
17       access-key: ${CWA_OBJECTSTORE_ACCESSKEY}
18       secret-key: ${CWA_OBJECTSTORE_SECRETKEY}
19       endpoint: ${CWA_OBJECTSTORE_ENDPOINT}
20       bucket: ${CWA_OBJECTSTORE_BUCKET}
21       port: ${CWA_OBJECTSTORE_PORT}
22       set-public-read-acl-on-put-object: false
23 
[end of services/distribution/src/main/resources/application-cloud.yaml]
[start of services/distribution/src/main/resources/application-ssl-client-postgres.yaml]
1 ---
2 spring:
3   datasource:
4     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_SUBMISSION_CERTIFICATE_PATH}&sslkey=${SSL_SUBMISSION_PRIVATE_KEY_PATH}
5 
[end of services/distribution/src/main/resources/application-ssl-client-postgres.yaml]
[start of services/distribution/src/main/resources/application.yaml]
1 ---
2 logging:
3   level:
4     org:
5       springframework:
6         web: INFO
7     app:
8       coronawarn: INFO
9 
10 services:
11   distribution:
12     output-file-name: index
13     retention-days: 14
14     expiry-policy-minutes: 120
15     shifting-policy-threshold: 140
16     maximum-number-of-keys-per-bundle: 600000
17     include-incomplete-days: false
18     include-incomplete-hours: false
19     paths:
20       output: out
21       privatekey: ${VAULT_FILESIGNING_SECRET}
22     tek-export:
23       file-name: export.bin
24       file-header: EK Export v1
25       file-header-width: 16
26     api:
27       version-path: version
28       version-v1: v1
29       country-path: country
30       country-germany: DE
31       date-path: date
32       hour-path: hour
33       diagnosis-keys-path: diagnosis-keys
34       parameters-path: configuration
35       app-config-file-name: app_config
36     signature:
37       verification-key-id: 262
38       verification-key-version: v1
39       algorithm-oid: 1.2.840.10045.4.3.2
40       algorithm-name: SHA256withECDSA
41       file-name: export.sig
42       security-provider: BC
43     # Configuration for the S3 compatible object storage hosted by Telekom in Germany
44     objectstore:
45       access-key: ${CWA_OBJECTSTORE_ACCESSKEY:accessKey1}
46       secret-key: ${CWA_OBJECTSTORE_SECRETKEY:verySecretKey1}
47       endpoint: ${CWA_OBJECTSTORE_ENDPOINT:http://localhost}
48       bucket: ${CWA_OBJECTSTORE_BUCKET:cwa}
49       port: ${CWA_OBJECTSTORE_PORT:8003}
50       set-public-read-acl-on-put-object: true
51       retry-attempts: 3
52       retry-backoff: 2000
53       max-number-of-failed-operations: 5
54       max-number-of-s3-threads: 4
55 
56 spring:
57   main:
58     web-application-type: NONE
59 # Postgres configuration
60   jpa:
61     hibernate:
62       ddl-auto: validate
63   flyway:
64     enabled: true
65     locations: classpath:/db/migration, classpath:/db/specific/{vendor}
66     password: ${POSTGRESQL_PASSWORD_FLYWAY:local_setup_flyway}
67     user: ${POSTGRESQL_USER_FLYWAY:local_setup_flyway}
68 
69   datasource:
70     driver-class-name: org.postgresql.Driver
71     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
72     username: ${POSTGRESQL_USER_DISTRIBUTION:local_setup_distribution}
73     password: ${POSTGRESQL_PASSWORD_DISTRIBUTION:local_setup_distribution}
74 
[end of services/distribution/src/main/resources/application.yaml]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java]
1 /*-
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission;
22 
23 import io.micrometer.core.aop.TimedAspect;
24 import io.micrometer.core.instrument.MeterRegistry;
25 import org.springframework.boot.SpringApplication;
26 import org.springframework.boot.autoconfigure.SpringBootApplication;
27 import org.springframework.boot.autoconfigure.domain.EntityScan;
28 import org.springframework.boot.context.properties.EnableConfigurationProperties;
29 import org.springframework.cloud.openfeign.EnableFeignClients;
30 import org.springframework.context.annotation.Bean;
31 import org.springframework.context.annotation.ComponentScan;
32 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
33 import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
34 
35 @SpringBootApplication
36 @EnableJpaRepositories(basePackages = "app.coronawarn.server.common.persistence")
37 @EntityScan(basePackages = "app.coronawarn.server.common.persistence")
38 @ComponentScan({"app.coronawarn.server.common.persistence",
39     "app.coronawarn.server.services.submission"})
40 @EnableConfigurationProperties
41 @EnableFeignClients
42 public class ServerApplication {
43 
44   @Bean
45   TimedAspect timedAspect(MeterRegistry registry) {
46     return new TimedAspect(registry);
47   }
48 
49   @Bean
50   ProtobufHttpMessageConverter protobufHttpMessageConverter() {
51     return new ProtobufHttpMessageConverter();
52   }
53 
54   public static void main(String[] args) {
55     SpringApplication.run(ServerApplication.class);
56   }
57 }
58 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java]
1 /*-
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission.config;
22 
23 import org.springframework.boot.context.properties.ConfigurationProperties;
24 import org.springframework.stereotype.Component;
25 
26 @Component
27 @ConfigurationProperties(prefix = "services.submission")
28 public class SubmissionServiceConfig {
29 
30   // Exponential moving average of the last N real request durations (in ms), where
31   // N = fakeDelayMovingAverageSamples.
32   private Double initialFakeDelayMilliseconds;
33   private Double fakeDelayMovingAverageSamples;
34   private Integer retentionDays;
35   private Payload payload;
36   private Verification verification;
37   private Monitoring monitoring;
38 
39   public Double getInitialFakeDelayMilliseconds() {
40     return initialFakeDelayMilliseconds;
41   }
42 
43   public void setInitialFakeDelayMilliseconds(Double initialFakeDelayMilliseconds) {
44     this.initialFakeDelayMilliseconds = initialFakeDelayMilliseconds;
45   }
46 
47   public Double getFakeDelayMovingAverageSamples() {
48     return fakeDelayMovingAverageSamples;
49   }
50 
51   public void setFakeDelayMovingAverageSamples(Double fakeDelayMovingAverageSamples) {
52     this.fakeDelayMovingAverageSamples = fakeDelayMovingAverageSamples;
53   }
54 
55   public Integer getRetentionDays() {
56     return retentionDays;
57   }
58 
59   public void setRetentionDays(Integer retentionDays) {
60     this.retentionDays = retentionDays;
61   }
62 
63   public Integer getMaxNumberOfKeys() {
64     return payload.getMaxNumberOfKeys();
65   }
66 
67   public void setPayload(Payload payload) {
68     this.payload = payload;
69   }
70 
71   private static class Payload {
72 
73     private Integer maxNumberOfKeys;
74 
75     public Integer getMaxNumberOfKeys() {
76       return maxNumberOfKeys;
77     }
78 
79     public void setMaxNumberOfKeys(Integer maxNumberOfKeys) {
80       this.maxNumberOfKeys = maxNumberOfKeys;
81     }
82   }
83 
84   public String getVerificationBaseUrl() {
85     return verification.getBaseUrl();
86   }
87 
88   public void setVerification(Verification verification) {
89     this.verification = verification;
90   }
91 
92   public String getVerificationPath() {
93     return verification.getPath();
94   }
95 
96   private static class Verification {
97     private String baseUrl;
98 
99     private String path;
100 
101     public String getBaseUrl() {
102       return baseUrl;
103     }
104 
105     public String getPath() {
106       return path;
107     }
108 
109     public void setBaseUrl(String baseUrl) {
110       this.baseUrl = baseUrl;
111     }
112 
113     public void setPath(String path) {
114       this.path = path;
115     }
116   }
117 
118   private static class Monitoring {
119     private Long batchSize;
120 
121     public Long getBatchSize() {
122       return batchSize;
123     }
124 
125     public void setBatchSize(Long batchSize) {
126       this.batchSize = batchSize;
127     }
128   }
129 
130   public Monitoring getMonitoring() {
131     return monitoring;
132   }
133 
134   public void setMonitoring(Monitoring monitoring) {
135     this.monitoring = monitoring;
136   }
137 
138   public Long getMonitoringBatchSize() {
139     return this.monitoring.getBatchSize();
140   }
141 
142   public void setMonitoringBatchSize(Long batchSize) {
143     this.monitoring.setBatchSize(batchSize);
144   }
145 }
146 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java]
1 /*
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission.verification;
22 
23 import feign.Client;
24 import feign.httpclient.ApacheHttpClient;
25 import java.io.IOException;
26 import java.security.GeneralSecurityException;
27 import javax.net.ssl.SSLContext;
28 import org.apache.http.impl.client.HttpClientBuilder;
29 import org.apache.http.ssl.SSLContextBuilder;
30 import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
31 import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
32 import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory;
33 import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory;
34 import org.springframework.context.annotation.Bean;
35 import org.springframework.context.annotation.Profile;
36 import org.springframework.core.env.Environment;
37 import org.springframework.stereotype.Component;
38 import org.springframework.util.ResourceUtils;
39 
40 @Component
41 @Profile("ssl-client-verification")
42 public class CloudFeignClientProvider implements FeignClientProvider {
43 
44   private final Environment environment;
45   private final HostnameVerifierProvider hostnameVerifierProvider;
46 
47   public CloudFeignClientProvider(Environment environment, HostnameVerifierProvider hostnameVerifierProvider) {
48     this.environment = environment;
49     this.hostnameVerifierProvider = hostnameVerifierProvider;
50   }
51 
52   @Override
53   public Client createFeignClient() {
54     return new ApacheHttpClient(createHttpClientFactory().createBuilder().build());
55   }
56 
57   private SSLContext getSslContext() {
58     try {
59       String keyStorePath = environment.getProperty("client.ssl.key-store");
60       String keyStorePassword = environment.getProperty("client.ssl.key-store-password");
61       String keyPassword = environment.getProperty("client.ssl.key-password");
62 
63       String trustStorePath = environment.getProperty("client.ssl.verification.trust-store");
64       String trustStorePassword = environment.getProperty("client.ssl.verification.trust-store-password");
65 
66       return SSLContextBuilder
67           .create()
68           .loadKeyMaterial(ResourceUtils.getFile(keyStorePath), keyStorePassword.toCharArray(),
69               keyPassword.toCharArray())
70           .loadTrustMaterial(ResourceUtils.getFile(trustStorePath), trustStorePassword.toCharArray())
71           .build();
72     } catch (IOException | GeneralSecurityException e) {
73       throw new RuntimeException(e);
74     }
75   }
76 
77   /**
78    * Creates an {@link ApacheHttpClientFactory} that validates SSL certificates and host names.
79    */
80   @Bean
81   public ApacheHttpClientFactory createHttpClientFactory() {
82     return new DefaultApacheHttpClientFactory(HttpClientBuilder.create()
83         .setSSLContext(getSslContext())
84         .setSSLHostnameVerifier(this.hostnameVerifierProvider.createHostnameVerifier()));
85   }
86 
87   @Bean
88   public ApacheHttpClientConnectionManagerFactory createConnectionManager() {
89     return new DefaultApacheHttpClientConnectionManagerFactory();
90   }
91 }
92 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java]
1 /*
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission.verification;
22 
23 import javax.net.ssl.HostnameVerifier;
24 import org.apache.http.conn.ssl.DefaultHostnameVerifier;
25 import org.springframework.context.annotation.Profile;
26 import org.springframework.stereotype.Component;
27 
28 @Component
29 @Profile("ssl-client-verification-verify-hostname")
30 public class DefaultHostnameVerifierProvider implements HostnameVerifierProvider {
31 
32   @Override
33   public HostnameVerifier createHostnameVerifier() {
34     return new DefaultHostnameVerifier();
35   }
36 }
37 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java]
1 /*
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission.verification;
22 
23 import feign.Client;
24 import feign.httpclient.ApacheHttpClient;
25 import org.apache.http.impl.client.HttpClientBuilder;
26 import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
27 import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
28 import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory;
29 import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory;
30 import org.springframework.context.annotation.Bean;
31 import org.springframework.context.annotation.Profile;
32 import org.springframework.stereotype.Component;
33 
34 @Component
35 @Profile("!ssl-client-verification")
36 public class DevelopmentFeignClientProvider implements FeignClientProvider {
37 
38   @Override
39   public Client createFeignClient() {
40     return new ApacheHttpClient(createHttpClientFactory().createBuilder().build());
41   }
42 
43   /**
44    * Creates an {@link ApacheHttpClientFactory} that neither validates SSL certificates nor host names.
45    */
46   @Bean
47   public ApacheHttpClientFactory createHttpClientFactory() {
48     return new DefaultApacheHttpClientFactory(HttpClientBuilder.create());
49   }
50 
51   @Bean
52   public ApacheHttpClientConnectionManagerFactory createConnectionManager() {
53     return new DefaultApacheHttpClientConnectionManagerFactory();
54   }
55 }
56 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java]
[start of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java]
1 /*
2  * ---license-start
3  * Corona-Warn-App
4  * ---
5  * Copyright (C) 2020 SAP SE and all other contributors
6  * ---
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ---license-end
19  */
20 
21 package app.coronawarn.server.services.submission.verification;
22 
23 import javax.net.ssl.HostnameVerifier;
24 import org.apache.http.conn.ssl.NoopHostnameVerifier;
25 import org.springframework.context.annotation.Profile;
26 import org.springframework.stereotype.Component;
27 
28 @Component
29 @Profile("!ssl-client-verification-verify-hostname")
30 public class NoopHostnameVerifierProvider implements HostnameVerifierProvider {
31 
32   @Override
33   public HostnameVerifier createHostnameVerifier() {
34     return new NoopHostnameVerifier();
35   }
36 }
37 
[end of services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java]
[start of services/submission/src/main/resources/application-cloud.yaml]
1 ---
2 spring:
3   flyway:
4     password: ${POSTGRESQL_PASSWORD_FLYWAY}
5     user: ${POSTGRESQL_USER_FLYWAY}
6   datasource:
7     driver-class-name: org.postgresql.Driver
8     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}
9     username: ${POSTGRESQL_USER_SUBMISSION}
10     password: ${POSTGRESQL_PASSWORD_SUBMISSION}
11 
12 services:
13   submission:
14     verification:
15       base-url: ${VERIFICATION_BASE_URL}
16 
[end of services/submission/src/main/resources/application-cloud.yaml]
[start of services/submission/src/main/resources/application-ssl-client-postgres.yaml]
1 ---
2 spring:
3   datasource:
4     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_SUBMISSION_CERTIFICATE_PATH}&sslkey=${SSL_SUBMISSION_PRIVATE_KEY_PATH}
5 
[end of services/submission/src/main/resources/application-ssl-client-postgres.yaml]
[start of services/submission/src/main/resources/application-ssl-client-verification.yaml]
1 ---
2 client:
3   ssl:
4     key-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
5     key-store: ${SSL_SUBMISSION_KEYSTORE_PATH}
6     key-store-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
7     verification:
8       trust-store: ${SSL_VERIFICATION_TRUSTSTORE_PATH}
9       trust-store-password: ${SSL_VERIFICATION_TRUSTSTORE_PASSWORD}
10 
[end of services/submission/src/main/resources/application-ssl-client-verification.yaml]
[start of services/submission/src/main/resources/application-ssl-server.yaml]
1 ---
2 server:
3   ssl:
4     enabled: true
5     enabled-protocols: TLSv1.2,TLSv1.3
6     protocol: TLS
7     ciphers: >-
8       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
9       TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
10       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
11       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
12       TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
13       TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
14       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
15       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
16       TLS_AES_128_GCM_SHA256
17       TLS_AES_256_GCM_SHA384
18       TLS_AES_128_CCM_SHA256
19     key-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
20     key-store: ${SSL_SUBMISSION_KEYSTORE_PATH}
21     key-store-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
22     key-store-provider: SUN
23     key-store-type: JKS
24 
[end of services/submission/src/main/resources/application-ssl-server.yaml]
[start of services/submission/src/main/resources/application.yaml]
1 ---
2 logging:
3   level:
4     org:
5       springframework:
6         web: INFO
7 
8 services:
9   submission:
10     # The initial value of the moving average for fake request delays.
11     initial-fake-delay-milliseconds: 10
12     # The number of samples for the calculation of the moving average for fake request delays.
13     fake-delay-moving-average-samples: 10
14     retention-days: 14
15     payload:
16       max-number-of-keys: 14
17     verification:
18       base-url: ${VERIFICATION_BASE_URL:http://localhost:8004}
19       path: /version/v1/tan/verify
20     monitoring:
21       batch-size: 5
22 
23 spring:
24   jpa:
25     hibernate:
26       ddl-auto: validate
27   flyway:
28     enabled: true
29     locations: classpath:/db/migration, classpath:/db/specific/{vendor}
30     password: ${POSTGRESQL_PASSWORD_FLYWAY:local_setup_flyway}
31     user: ${POSTGRESQL_USER_FLYWAY:local_setup_flyway}
32 # Postgres configuration
33   datasource:
34     driver-class-name: org.postgresql.Driver
35     url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
36     username: ${POSTGRESQL_USER_SUBMISSION:local_setup_submission}
37     password: ${POSTGRESQL_PASSWORD_SUBMISSION:local_setup_submission}
38 
39 management:
40   server:
41     port: 8081
42   endpoint:
43     metrics:
44       enabled: true
45     prometheus:
46       enabled: true
47     health:
48       group:
49         readiness:
50           include: db, verificationService
51           show-details: always
52   endpoints:
53     web:
54       exposure:
55         include: 'health, prometheus'
56   metrics:
57     export:
58       prometheus:
59         enabled: true
60   health:
61     probes:
62       enabled: true
63 
64 feign:
65   httpclient:
66     maxConnections: 200
67     maxConnectionsPerRoute: 200
68 
[end of services/submission/src/main/resources/application.yaml]
</code>

Here is an example of a patch file. It consists of changes to the code base. It specifies the file names, the line numbers of each change, and the removed and added lines. A single patch file can contain changes to multiple files.
<patch>
--- a/file.py
+++ b/file.py
@@ -1,27 +1,35 @@
 def euclidean(a, b):
-    while b:
-        a, b = b, a % b
-    return a
+    if b == 0:
+        return a
+    return euclidean(b, a % b)
 
 
 def bresenham(x0, y0, x1, y1):
     points = []
     dx = abs(x1 - x0)
     dy = abs(y1 - y0)
-    sx = 1 if x0 < x1 else -1
-    sy = 1 if y0 < y1 else -1
-    err = dx - dy
+    x, y = x0, y0
+    sx = -1 if x0 > x1 else 1
+    sy = -1 if y0 > y1 else 1
 
-    while True:
-        points.append((x0, y0))
-        if x0 == x1 and y0 == y1:
-            break
-        e2 = 2 * err
-        if e2 > -dy:
+    if dx > dy:
+        err = dx / 2.0
+        while x != x1:
+            points.append((x, y))
             err -= dy
-            x0 += sx
-        if e2 < dx:
-            err += dx
-            y0 += sy
+            if err < 0:
+                y += sy
+                err += dx
+            x += sx
+    else:
+        err = dy / 2.0
+        while y != y1:
+            points.append((x, y))
+            err -= dx
+            if err < 0:
+                x += sx
+                err += dy
+            y += sy
 
+    points.append((x, y))
     return points
</patch>

I need you to solve the provded issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the format shown above.
Respond below:


SSL: Set a profile to willingly decrease security
Currently, we have the profiles `ssl-server`, `ssl-client-verification` and `ssl-client-postgres` which will enable `ssl` for certain situations. 

In context of secure-by-default, we should have it in the opposite way - you can set a profile to willingly decrease security.

<patch>
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -113,12 +113,14 @@ For the distribution module:
 ```bash
 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:
 
 ```bash
 POSTGRESQL_SERVICE_PORT=8001
+SPRING_PROFILES_ACTIVE=disable-ssl-server,disable-ssl-client-postgres,disable-ssl-client-verification,disable-ssl-client-verification-verify-hostname
 ```
 
 #### Configure
@@ -159,8 +161,8 @@ To be able to set breakpoints (e.g. in IntelliJ), it may be necessary to use the
 
 The API that is being exposed by the backend services is documented in an [OpenAPI](https://www.openapis.org/) specification. The specification files are available at the following locations:
 
-Service      | OpenAPI Specification
--------------|-------------
+Service                   | OpenAPI Specification
+--------------------------|-------------
 Submission Service        | [services/submission/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/submission/api_v1.json)
 Distribution Service      | [services/distribution/api_v1.json](https://github.com/corona-warn-app/cwa-server/raw/master/services/distribution/api_v1.json)
 
@@ -168,25 +170,26 @@ Distribution Service      | [services/distribution/api_v1.json](https://github.c
 
 ### Distribution
 
-Profile               | Effect
-----------------------|-------------
-`dev`                 | Turns the log level to `DEBUG`.
-`cloud`               | Removes default values for the `datasource` and `objectstore` configurations.
-`demo`                | Includes incomplete days and hours into the distribution run, thus creating aggregates for the current day and the current hour (and including both in the respective indices). When running multiple distributions in one hour with this profile, the date aggregate for today and the hours aggregate for the current hour will be updated and overwritten. This profile also turns off the expiry policy (Keys must be expired for at least 2 hours before distribution) and the shifting policy (there must be at least 140 keys in a distribution).
-`testdata`            | Causes test data to be inserted into the database before each distribution run. By default, around 1000 random diagnosis keys will be generated per hour. If there are no diagnosis keys in the database yet, random keys will be generated for every hour from the beginning of the retention period (14 days ago at 00:00 UTC) until one hour before the present hour. If there are already keys in the database, the random keys will be generated for every hour from the latest diagnosis key in the database (by submission timestamp) until one hour before the present hour (or none at all, if the latest diagnosis key in the database was submitted one hour ago or later).
-`signature-dev`       | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp-dev` so that the non-productive/test public key will be used for client-side validation.
-`signature-prod`      | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp` so that the productive public key will be used for client-side validation.
-`ssl-client-postgres` | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/distribution/src/main/resources/application-ssl-client-postgres.yaml)).
+Profile                       | Effect
+------------------------------|-------------
+`dev`                         | Turns the log level to `DEBUG`.
+`cloud`                       | Removes default values for the `datasource` and `objectstore` configurations.
+`demo`                        | Includes incomplete days and hours into the distribution run, thus creating aggregates for the current day and the current hour (and including both in the respective indices). When running multiple distributions in one hour with this profile, the date aggregate for today and the hours aggregate for the current hour will be updated and overwritten. This profile also turns off the expiry policy (Keys must be expired for at least 2 hours before distribution) and the shifting policy (there must be at least 140 keys in a distribution).
+`testdata`                    | Causes test data to be inserted into the database before each distribution run. By default, around 1000 random diagnosis keys will be generated per hour. If there are no diagnosis keys in the database yet, random keys will be generated for every hour from the beginning of the retention period (14 days ago at 00:00 UTC) until one hour before the present hour. If there are already keys in the database, the random keys will be generated for every hour from the latest diagnosis key in the database (by submission timestamp) until one hour before the present hour (or none at all, if the latest diagnosis key in the database was submitted one hour ago or later).
+`signature-dev`               | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp-dev` so that the non-productive/test public key will be used for client-side validation.
+`signature-prod`              | Sets the app package ID in the export packages' signature info to `de.rki.coronawarnapp` so that the productive public key will be used for client-side validation.
+`disable-ssl-client-postgres` | Disables SSL for the connection to the postgres database.
 
 ### Submission
 
-Profile                   | Effect
---------------------------|-------------
-`dev`                     | Turns the log level to `DEBUG`.
-`cloud`                   | Removes default values for the `datasource` configuration.
-`ssl-server`              | Enables SSL for the submission endpoint (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-server.yaml)).
-`ssl-client-postgres`     | Enforces SSL with a pinned certificate for the connection to the postgres (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-postgres.yaml)).
-`ssl-client-verification` | Enforces SSL with a pinned certificate for the connection to the verification server (see [here](https://github.com/corona-warn-app/cwa-server/blob/master/services/submission/src/main/resources/application-ssl-client-verification.yaml)).
+Profile                                           | Effect
+--------------------------------------------------|-------------
+`dev`                                             | Turns the log level to `DEBUG`.
+`cloud`                                           | Removes default values for the `datasource` configuration.
+`disable-ssl-server`                              | Disables SSL for the submission endpoint.
+`disable-ssl-client-postgres`                     | Disables SSL with a pinned certificate for the connection to the postgres database.
+`disable-ssl-client-verification`                 | Disables SSL with a pinned certificate for the connection to the verification server.
+`disable-ssl-client-verification-verify-hostname` | Disables the verification of the SSL hostname for the connection to the verification server.
 
 ## Documentation
 
diff --git a/docker-compose.yml b/docker-compose.yml
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,7 +11,7 @@ services:
       - "8000:8080"
       - "8006:8081"
     environment:
-      SPRING_PROFILES_ACTIVE: dev
+      SPRING_PROFILES_ACTIVE: dev,disable-ssl-server,disable-ssl-client-postgres,disable-ssl-client-verification,disable-ssl-client-verification-verify-hostname
       POSTGRESQL_SERVICE_PORT: '5432'
       POSTGRESQL_SERVICE_HOST: postgres
       POSTGRESQL_DATABASE: ${POSTGRES_DB}
@@ -29,7 +29,7 @@ services:
      - objectstore
      - create-bucket
     environment:
-      SPRING_PROFILES_ACTIVE: dev,signature-dev,testdata
+      SPRING_PROFILES_ACTIVE: dev,signature-dev,testdata,disable-ssl-client-postgres
       POSTGRESQL_SERVICE_PORT: '5432'
       POSTGRESQL_SERVICE_HOST: postgres
       POSTGRESQL_DATABASE: ${POSTGRES_DB}
diff --git a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java
--- a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java
+++ b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/Application.java
@@ -21,6 +21,8 @@
 package app.coronawarn.server.services.distribution;
 
 import app.coronawarn.server.services.distribution.config.DistributionServiceConfig;
+import java.util.Arrays;
+import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
@@ -28,7 +30,9 @@
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.EnvironmentAware;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 
 /**
@@ -42,7 +46,7 @@
 @ComponentScan({"app.coronawarn.server.common.persistence",
     "app.coronawarn.server.services.distribution"})
 @EnableConfigurationProperties({DistributionServiceConfig.class})
-public class Application {
+public class Application implements EnvironmentAware {
 
   private static final Logger logger = LoggerFactory.getLogger(Application.class);
 
@@ -58,4 +62,13 @@ public static void killApplication(ApplicationContext appContext) {
     logger.error("Application terminated abnormally.");
     System.exit(1);
   }
+
+  @Override
+  public void setEnvironment(Environment environment) {
+    List<String> profiles = Arrays.asList(environment.getActiveProfiles());
+    if (profiles.contains("disable-ssl-client-postgres")) {
+      logger.warn("The distribution runner is started with postgres connection TLS disabled. "
+          + "This should never be used in PRODUCTION!");
+    }
+  }
 }
diff --git a/services/distribution/src/main/resources/application-cloud.yaml b/services/distribution/src/main/resources/application-cloud.yaml
--- a/services/distribution/src/main/resources/application-cloud.yaml
+++ b/services/distribution/src/main/resources/application-cloud.yaml
@@ -5,7 +5,6 @@ spring:
     user: ${POSTGRESQL_USER_FLYWAY}
   datasource:
     driver-class-name: org.postgresql.Driver
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}
     username: ${POSTGRESQL_USER_DISTRIBUTION}
     password: ${POSTGRESQL_PASSWORD_DISTRIBUTION}
 
diff --git a/services/distribution/src/main/resources/application-disable-ssl-client-postgres.yaml b/services/distribution/src/main/resources/application-disable-ssl-client-postgres.yaml
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/main/resources/application-disable-ssl-client-postgres.yaml
@@ -0,0 +1,4 @@
+---
+spring:
+  datasource:
+    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
diff --git a/services/distribution/src/main/resources/application-ssl-client-postgres.yaml b/services/distribution/src/main/resources/application-ssl-client-postgres.yaml
deleted file mode 100644
--- a/services/distribution/src/main/resources/application-ssl-client-postgres.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-spring:
-  datasource:
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_SUBMISSION_CERTIFICATE_PATH}&sslkey=${SSL_SUBMISSION_PRIVATE_KEY_PATH}
diff --git a/services/distribution/src/main/resources/application.yaml b/services/distribution/src/main/resources/application.yaml
--- a/services/distribution/src/main/resources/application.yaml
+++ b/services/distribution/src/main/resources/application.yaml
@@ -68,6 +68,6 @@ spring:
 
   datasource:
     driver-class-name: org.postgresql.Driver
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
+    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_DISTRIBUTION_CERTIFICATE_PATH}&sslkey=${SSL_DISTRIBUTION_PRIVATE_KEY_PATH}
     username: ${POSTGRESQL_USER_DISTRIBUTION:local_setup_distribution}
     password: ${POSTGRESQL_PASSWORD_DISTRIBUTION:local_setup_distribution}
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/ServerApplication.java
@@ -22,13 +22,19 @@
 
 import io.micrometer.core.aop.TimedAspect;
 import io.micrometer.core.instrument.MeterRegistry;
+import java.util.Arrays;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.EnvironmentAware;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
 
@@ -39,7 +45,13 @@
     "app.coronawarn.server.services.submission"})
 @EnableConfigurationProperties
 @EnableFeignClients
-public class ServerApplication {
+public class ServerApplication implements EnvironmentAware {
+
+  private static final Logger logger = LoggerFactory.getLogger(ServerApplication.class);
+
+  public static void main(String[] args) {
+    SpringApplication.run(ServerApplication.class);
+  }
 
   @Bean
   TimedAspect timedAspect(MeterRegistry registry) {
@@ -51,7 +63,27 @@ ProtobufHttpMessageConverter protobufHttpMessageConverter() {
     return new ProtobufHttpMessageConverter();
   }
 
-  public static void main(String[] args) {
-    SpringApplication.run(ServerApplication.class);
+  @Override
+  public void setEnvironment(Environment environment) {
+    List<String> profiles = Arrays.asList(environment.getActiveProfiles());
+    if (profiles.contains("disable-ssl-server")) {
+      logger.warn(
+          "The submission service is started with endpoint TLS disabled. This should never be used in PRODUCTION!");
+    }
+    if (profiles.contains("disable-ssl-client-postgres")) {
+      logger.warn(
+          "The submission service is started with postgres connection TLS disabled. This should never be used in"
+              + "PRODUCTION!");
+    }
+    if (profiles.contains("disable-ssl-client-verification")) {
+      logger.warn(
+          "The submission service is started with verification service connection TLS disabled. This should never be"
+              + "used in PRODUCTION!");
+    }
+    if (profiles.contains("disable-ssl-client-verification-verify-hostname")) {
+      logger.warn(
+          "The submission service is started with verification service TLS hostname validation disabled. This should"
+              + "never be used in PRODUCTION!");
+    }
   }
 }
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/config/SubmissionServiceConfig.java
@@ -20,6 +20,7 @@
 
 package app.coronawarn.server.services.submission.config;
 
+import java.io.File;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 
@@ -35,6 +36,7 @@ public class SubmissionServiceConfig {
   private Payload payload;
   private Verification verification;
   private Monitoring monitoring;
+  private Client client;
 
   public Double getInitialFakeDelayMilliseconds() {
     return initialFakeDelayMilliseconds;
@@ -142,4 +144,74 @@ public Long getMonitoringBatchSize() {
   public void setMonitoringBatchSize(Long batchSize) {
     this.monitoring.setBatchSize(batchSize);
   }
+
+  public Client getClient() {
+    return client;
+  }
+
+  public void setClient(Client client) {
+    this.client = client;
+  }
+
+  public static class Client {
+
+    private Ssl ssl;
+
+    public Ssl getSsl() {
+      return ssl;
+    }
+
+    public void setSsl(Ssl ssl) {
+      this.ssl = ssl;
+    }
+
+    public static class Ssl {
+
+      private File keyStore;
+      private String keyStorePassword;
+      private String keyPassword;
+      private File trustStore;
+      private String trustStorePassword;
+
+      public File getKeyStore() {
+        return keyStore;
+      }
+
+      public void setKeyStore(File keyStore) {
+        this.keyStore = keyStore;
+      }
+
+      public String getKeyStorePassword() {
+        return keyStorePassword;
+      }
+
+      public void setKeyStorePassword(String keyStorePassword) {
+        this.keyStorePassword = keyStorePassword;
+      }
+
+      public String getKeyPassword() {
+        return keyPassword;
+      }
+
+      public void setKeyPassword(String keyPassword) {
+        this.keyPassword = keyPassword;
+      }
+
+      public File getTrustStore() {
+        return trustStore;
+      }
+
+      public void setTrustStore(File trustStore) {
+        this.trustStore = trustStore;
+      }
+
+      public String getTrustStorePassword() {
+        return trustStorePassword;
+      }
+
+      public void setTrustStorePassword(String trustStorePassword) {
+        this.trustStorePassword = trustStorePassword;
+      }
+    }
+  }
 }
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/CloudFeignClientProvider.java
@@ -20,8 +20,11 @@
 
 package app.coronawarn.server.services.submission.verification;
 
+import app.coronawarn.server.services.submission.config.SubmissionServiceConfig;
+import app.coronawarn.server.services.submission.config.SubmissionServiceConfig.Client.Ssl;
 import feign.Client;
 import feign.httpclient.ApacheHttpClient;
+import java.io.File;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import javax.net.ssl.SSLContext;
@@ -33,19 +36,29 @@
 import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Profile;
-import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
-import org.springframework.util.ResourceUtils;
 
 @Component
-@Profile("ssl-client-verification")
+@Profile("!disable-ssl-client-verification")
 public class CloudFeignClientProvider implements FeignClientProvider {
 
-  private final Environment environment;
   private final HostnameVerifierProvider hostnameVerifierProvider;
+  private final File keyStore;
+  private final String keyStorePassword;
+  private final String keyPassword;
+  private final File trustStore;
+  private final String trustStorePassword;
 
-  public CloudFeignClientProvider(Environment environment, HostnameVerifierProvider hostnameVerifierProvider) {
-    this.environment = environment;
+  /**
+   * Creates a {@link CloudFeignClientProvider} that provides feign clients with fixed key and trust material.
+   */
+  public CloudFeignClientProvider(SubmissionServiceConfig config, HostnameVerifierProvider hostnameVerifierProvider) {
+    Ssl sslConfig = config.getClient().getSsl();
+    this.keyStore = sslConfig.getKeyStore();
+    this.keyStorePassword = sslConfig.getKeyStorePassword();
+    this.keyPassword = sslConfig.getKeyPassword();
+    this.trustStore = sslConfig.getTrustStore();
+    this.trustStorePassword = sslConfig.getTrustStorePassword();
     this.hostnameVerifierProvider = hostnameVerifierProvider;
   }
 
@@ -56,18 +69,10 @@ public Client createFeignClient() {
 
   private SSLContext getSslContext() {
     try {
-      String keyStorePath = environment.getProperty("client.ssl.key-store");
-      String keyStorePassword = environment.getProperty("client.ssl.key-store-password");
-      String keyPassword = environment.getProperty("client.ssl.key-password");
-
-      String trustStorePath = environment.getProperty("client.ssl.verification.trust-store");
-      String trustStorePassword = environment.getProperty("client.ssl.verification.trust-store-password");
-
       return SSLContextBuilder
           .create()
-          .loadKeyMaterial(ResourceUtils.getFile(keyStorePath), keyStorePassword.toCharArray(),
-              keyPassword.toCharArray())
-          .loadTrustMaterial(ResourceUtils.getFile(trustStorePath), trustStorePassword.toCharArray())
+          .loadKeyMaterial(this.keyStore, this.keyStorePassword.toCharArray(), this.keyPassword.toCharArray())
+          .loadTrustMaterial(this.trustStore, this.trustStorePassword.toCharArray())
           .build();
     } catch (IOException | GeneralSecurityException e) {
       throw new RuntimeException(e);
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DefaultHostnameVerifierProvider.java
@@ -26,7 +26,7 @@
 import org.springframework.stereotype.Component;
 
 @Component
-@Profile("ssl-client-verification-verify-hostname")
+@Profile("!disable-ssl-client-verification-verify-hostname")
 public class DefaultHostnameVerifierProvider implements HostnameVerifierProvider {
 
   @Override
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/DevelopmentFeignClientProvider.java
@@ -32,9 +32,15 @@
 import org.springframework.stereotype.Component;
 
 @Component
-@Profile("!ssl-client-verification")
+@Profile("disable-ssl-client-verification")
 public class DevelopmentFeignClientProvider implements FeignClientProvider {
 
+  private final HostnameVerifierProvider hostnameVerifierProvider;
+
+  public DevelopmentFeignClientProvider(HostnameVerifierProvider hostnameVerifierProvider) {
+    this.hostnameVerifierProvider = hostnameVerifierProvider;
+  }
+
   @Override
   public Client createFeignClient() {
     return new ApacheHttpClient(createHttpClientFactory().createBuilder().build());
@@ -45,7 +51,8 @@ public Client createFeignClient() {
    */
   @Bean
   public ApacheHttpClientFactory createHttpClientFactory() {
-    return new DefaultApacheHttpClientFactory(HttpClientBuilder.create());
+    return new DefaultApacheHttpClientFactory(HttpClientBuilder.create()
+        .setSSLHostnameVerifier(this.hostnameVerifierProvider.createHostnameVerifier()));
   }
 
   @Bean
diff --git a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java
--- a/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java
+++ b/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/NoopHostnameVerifierProvider.java
@@ -26,7 +26,7 @@
 import org.springframework.stereotype.Component;
 
 @Component
-@Profile("!ssl-client-verification-verify-hostname")
+@Profile("disable-ssl-client-verification-verify-hostname")
 public class NoopHostnameVerifierProvider implements HostnameVerifierProvider {
 
   @Override
diff --git a/services/submission/src/main/resources/application-cloud.yaml b/services/submission/src/main/resources/application-cloud.yaml
--- a/services/submission/src/main/resources/application-cloud.yaml
+++ b/services/submission/src/main/resources/application-cloud.yaml
@@ -5,7 +5,6 @@ spring:
     user: ${POSTGRESQL_USER_FLYWAY}
   datasource:
     driver-class-name: org.postgresql.Driver
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}
     username: ${POSTGRESQL_USER_SUBMISSION}
     password: ${POSTGRESQL_PASSWORD_SUBMISSION}
 
diff --git a/services/submission/src/main/resources/application-disable-ssl-client-postgres.yaml b/services/submission/src/main/resources/application-disable-ssl-client-postgres.yaml
new file mode 100644
--- /dev/null
+++ b/services/submission/src/main/resources/application-disable-ssl-client-postgres.yaml
@@ -0,0 +1,4 @@
+---
+spring:
+  datasource:
+    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
diff --git a/services/submission/src/main/resources/application-disable-ssl-server.yaml b/services/submission/src/main/resources/application-disable-ssl-server.yaml
new file mode 100644
--- /dev/null
+++ b/services/submission/src/main/resources/application-disable-ssl-server.yaml
@@ -0,0 +1,4 @@
+---
+server:
+  ssl:
+    enabled: false
diff --git a/services/submission/src/main/resources/application-ssl-client-postgres.yaml b/services/submission/src/main/resources/application-ssl-client-postgres.yaml
deleted file mode 100644
--- a/services/submission/src/main/resources/application-ssl-client-postgres.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-spring:
-  datasource:
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_SUBMISSION_CERTIFICATE_PATH}&sslkey=${SSL_SUBMISSION_PRIVATE_KEY_PATH}
diff --git a/services/submission/src/main/resources/application-ssl-client-verification.yaml b/services/submission/src/main/resources/application-ssl-client-verification.yaml
deleted file mode 100644
--- a/services/submission/src/main/resources/application-ssl-client-verification.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-client:
-  ssl:
-    key-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
-    key-store: ${SSL_SUBMISSION_KEYSTORE_PATH}
-    key-store-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
-    verification:
-      trust-store: ${SSL_VERIFICATION_TRUSTSTORE_PATH}
-      trust-store-password: ${SSL_VERIFICATION_TRUSTSTORE_PASSWORD}
diff --git a/services/submission/src/main/resources/application-ssl-server.yaml b/services/submission/src/main/resources/application-ssl-server.yaml
deleted file mode 100644
--- a/services/submission/src/main/resources/application-ssl-server.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-server:
-  ssl:
-    enabled: true
-    enabled-protocols: TLSv1.2,TLSv1.3
-    protocol: TLS
-    ciphers: >-
-      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
-      TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
-      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
-      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-      TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
-      TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
-      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
-      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
-      TLS_AES_128_GCM_SHA256
-      TLS_AES_256_GCM_SHA384
-      TLS_AES_128_CCM_SHA256
-    key-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
-    key-store: ${SSL_SUBMISSION_KEYSTORE_PATH}
-    key-store-password: ${SSL_SUBMISSION_KEYSTORE_PASSWORD}
-    key-store-provider: SUN
-    key-store-type: JKS
diff --git a/services/submission/src/main/resources/application.yaml b/services/submission/src/main/resources/application.yaml
--- a/services/submission/src/main/resources/application.yaml
+++ b/services/submission/src/main/resources/application.yaml
@@ -32,7 +32,7 @@ spring:
 # Postgres configuration
   datasource:
     driver-class-name: org.postgresql.Driver
-    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST:localhost}:${POSTGRESQL_SERVICE_PORT:5432}/${POSTGRESQL_DATABASE:cwa}
+    url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE}?ssl=true&sslmode=verify-full&sslrootcert=${SSL_POSTGRES_CERTIFICATE_PATH}&sslcert=${SSL_SUBMISSION_CERTIFICATE_PATH}&sslkey=${SSL_SUBMISSION_PRIVATE_KEY_PATH}
     username: ${POSTGRESQL_USER_SUBMISSION:local_setup_submission}
     password: ${POSTGRESQL_PASSWORD_SUBMISSION:local_setup_submission}
 
@@ -64,4 +64,4 @@ management:
 feign:
   httpclient:
     maxConnections: 200
-    maxConnectionsPerRoute: 200
+    maxConnectionsPerRoute: 200
\ No newline at end of file

</patch>
diff --git a/services/submission/src/test/java/app/coronawarn/server/services/submission/ServerApplicationTests.java b/services/submission/src/test/java/app/coronawarn/server/services/submission/ServerApplicationTests.java
--- a/services/submission/src/test/java/app/coronawarn/server/services/submission/ServerApplicationTests.java
+++ b/services/submission/src/test/java/app/coronawarn/server/services/submission/ServerApplicationTests.java
@@ -28,8 +28,10 @@
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.test.context.ActiveProfiles;
 
 @SpringBootTest
+@ActiveProfiles({ "disable-ssl-client-verification", "disable-ssl-client-verification-verify-hostname" })
 class ServerApplicationTests {
 
   @Autowired
diff --git a/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/PayloadValidationTest.java b/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/PayloadValidationTest.java
--- a/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/PayloadValidationTest.java
+++ b/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/PayloadValidationTest.java
@@ -44,8 +44,10 @@
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
 
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles({"disable-ssl-client-verification", "disable-ssl-client-verification-verify-hostname"})
 class PayloadValidationTest {
 
   @MockBean
diff --git a/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/SubmissionControllerTest.java b/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/SubmissionControllerTest.java
--- a/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/SubmissionControllerTest.java
+++ b/services/submission/src/test/java/app/coronawarn/server/services/submission/controller/SubmissionControllerTest.java
@@ -73,8 +73,10 @@
 import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
 
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles({ "disable-ssl-client-verification", "disable-ssl-client-verification-verify-hostname" })
 class SubmissionControllerTest {
 
   private static final URI SUBMISSION_URL = URI.create("/version/v1/diagnosis-keys");
diff --git a/services/submission/src/test/java/app/coronawarn/server/services/submission/monitoring/VerificationServiceHealthIndicatorTest.java b/services/submission/src/test/java/app/coronawarn/server/services/submission/monitoring/VerificationServiceHealthIndicatorTest.java
--- a/services/submission/src/test/java/app/coronawarn/server/services/submission/monitoring/VerificationServiceHealthIndicatorTest.java
+++ b/services/submission/src/test/java/app/coronawarn/server/services/submission/monitoring/VerificationServiceHealthIndicatorTest.java
@@ -32,14 +32,15 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 import org.springframework.web.context.WebApplicationContext;
 
-
 @TestPropertySource(properties = {"management.port="})
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles({ "disable-ssl-client-verification", "disable-ssl-client-verification-verify-hostname" })
 class VerificationServiceHealthIndicatorTest {
 
   @MockBean
diff --git a/services/submission/src/test/java/app/coronawarn/server/services/submission/verification/TanVerifierTest.java b/services/submission/src/test/java/app/coronawarn/server/services/submission/verification/TanVerifierTest.java
--- a/services/submission/src/test/java/app/coronawarn/server/services/submission/verification/TanVerifierTest.java
+++ b/services/submission/src/test/java/app/coronawarn/server/services/submission/verification/TanVerifierTest.java
@@ -20,7 +20,6 @@
 
 package app.coronawarn.server.services.submission.verification;
 
-
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
 import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
@@ -49,11 +48,11 @@
 import org.springframework.http.MediaType;
 import org.springframework.test.context.ActiveProfiles;
 
-@SpringBootTest(classes = {TanVerifier.class, DevelopmentFeignClientProvider.class})
+@SpringBootTest(classes = {TanVerifier.class, DevelopmentFeignClientProvider.class, NoopHostnameVerifierProvider.class})
 @ImportAutoConfiguration({FeignAutoConfiguration.class, FeignTestConfiguration.class})
 @EnableConfigurationProperties(value = SubmissionServiceConfig.class)
 @EnableFeignClients
-@ActiveProfiles("feign")
+@ActiveProfiles({ "feign", "disable-ssl-client-verification", "disable-ssl-client-verification-verify-hostname" })
 class TanVerifierTest {
 
   @Autowired
