Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
RC Patch 1.0.2 (#523)
Browse files Browse the repository at this point in the history
* Add hostname verification (#473)
* Add CSP header (#492)
* Remove use of ForkJoinPool in SubmissionController (#399) (#518)
* Fix http client connection pool size (#519)
* Update android app versions (#520)
* Add "ssl-client-verification-verify-hostname" profile (#521)
* Introduce new version 1.0.2

Co-authored-by: Pit Humke <[email protected]>
Co-authored-by: MKusber <[email protected]>
Co-authored-by: Michael Burwig <[email protected]>
  • Loading branch information
4 people authored Jun 10, 2020
1 parent 445f273 commit b5a83c4
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-Drevision=1.0.1
-Drevision=1.0.2
-Dlicense.projectName=Corona-Warn-App
-Dlicense.inceptionYear=2020
-Dlicense.licenseName=apache_v2
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ ios:
android:
latest:
major: 0
minor: 8
patch: 3
minor: 9
patch: 1
min:
major: 0
minor: 8
minor: 9
patch: 0
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ protected void configure(HttpSecurity http) throws Exception {
.mvcMatchers(HttpMethod.POST, SUBMISSION_ROUTE).permitAll()
.anyRequest().denyAll()
.and().csrf().disable();
http.headers().contentSecurityPolicy("default-src 'self'");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.commons.math3.distribution.PoissonDistribution;
Expand Down Expand Up @@ -62,7 +61,6 @@ public class SubmissionController {

private final SubmissionControllerMonitor submissionControllerMonitor;
private final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
private final ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
private final DiagnosisKeyService diagnosisKeyService;
private final TanVerifier tanVerifier;
private final Double fakeDelayMovingAverageSamples;
Expand Down Expand Up @@ -115,23 +113,21 @@ private DeferredResult<ResponseEntity<Void>> buildFakeDeferredResult() {
private DeferredResult<ResponseEntity<Void>> buildRealDeferredResult(SubmissionPayload exposureKeys, String tan) {
DeferredResult<ResponseEntity<Void>> deferredResult = new DeferredResult<>();

forkJoinPool.submit(() -> {
try {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
if (!this.tanVerifier.verifyTan(tan)) {
submissionControllerMonitor.incrementInvalidTanRequestCounter();
deferredResult.setResult(buildTanInvalidResponseEntity());
} else {
persistDiagnosisKeysPayload(exposureKeys);
deferredResult.setResult(buildSuccessResponseEntity());
stopWatch.stop();
updateFakeDelay(stopWatch.getTotalTimeMillis());
}
} catch (Exception e) {
deferredResult.setErrorResult(e);
try {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
if (!this.tanVerifier.verifyTan(tan)) {
submissionControllerMonitor.incrementInvalidTanRequestCounter();
deferredResult.setResult(buildTanInvalidResponseEntity());
} else {
persistDiagnosisKeysPayload(exposureKeys);
deferredResult.setResult(buildSuccessResponseEntity());
stopWatch.stop();
updateFakeDelay(stopWatch.getTotalTimeMillis());
}
});
} catch (Exception e) {
deferredResult.setErrorResult(e);
}

return deferredResult;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@
package app.coronawarn.server.services.submission.verification;

import feign.Client;
import feign.httpclient.ApacheHttpClient;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory;
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;
Expand All @@ -36,18 +42,20 @@
@Profile("ssl-client-verification")
public class CloudFeignClientProvider implements FeignClientProvider {

Environment environment;
private final Environment environment;
private final HostnameVerifierProvider hostnameVerifierProvider;

public CloudFeignClientProvider(Environment environment) {
public CloudFeignClientProvider(Environment environment, HostnameVerifierProvider hostnameVerifierProvider) {
this.environment = environment;
this.hostnameVerifierProvider = hostnameVerifierProvider;
}

@Override
public Client createFeignClient() {
return new Client.Default(getSslSocketFactory(), new NoopHostnameVerifier());
return new ApacheHttpClient(createHttpClientFactory().createBuilder().build());
}

private SSLSocketFactory getSslSocketFactory() {
private SSLContext getSslContext() {
try {
String keyStorePath = environment.getProperty("client.ssl.key-store");
String keyStorePassword = environment.getProperty("client.ssl.key-store-password");
Expand All @@ -56,15 +64,29 @@ private SSLSocketFactory getSslSocketFactory() {
String trustStorePath = environment.getProperty("client.ssl.verification.trust-store");
String trustStorePassword = environment.getProperty("client.ssl.verification.trust-store-password");

SSLContext sslContext = SSLContextBuilder
return SSLContextBuilder
.create()
.loadKeyMaterial(ResourceUtils.getFile(keyStorePath), keyStorePassword.toCharArray(),
keyPassword.toCharArray())
.loadTrustMaterial(ResourceUtils.getFile(trustStorePath), trustStorePassword.toCharArray())
.build();
return sslContext.getSocketFactory();
} catch (IOException | GeneralSecurityException e) {
throw new RuntimeException(e);
}
}

/**
* Creates an {@link ApacheHttpClientFactory} that validates SSL certificates and host names.
*/
@Bean
public ApacheHttpClientFactory createHttpClientFactory() {
return new DefaultApacheHttpClientFactory(HttpClientBuilder.create()
.setSSLContext(getSslContext())
.setSSLHostnameVerifier(this.hostnameVerifierProvider.createHostnameVerifier()));
}

@Bean
public ApacheHttpClientConnectionManagerFactory createConnectionManager() {
return new DefaultApacheHttpClientConnectionManagerFactory();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* ---license-start
* Corona-Warn-App
* ---
* Copyright (C) 2020 SAP SE and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/

package app.coronawarn.server.services.submission.verification;

import javax.net.ssl.HostnameVerifier;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("ssl-client-verification-verify-hostname")
public class DefaultHostnameVerifierProvider implements HostnameVerifierProvider {

@Override
public HostnameVerifier createHostnameVerifier() {
return new DefaultHostnameVerifier();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ public class DevelopmentFeignClientProvider implements FeignClientProvider {

@Override
public Client createFeignClient() {
return new ApacheHttpClient();
return new ApacheHttpClient(createHttpClientFactory().createBuilder().build());
}

/**
* Creates an {@link ApacheHttpClientFactory} that neither validates SSL certificates nor host names.
*/
@Bean
public ApacheHttpClientFactory createHttpClientFactory() {
return new DefaultApacheHttpClientFactory(HttpClientBuilder.create());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* ---license-start
* Corona-Warn-App
* ---
* Copyright (C) 2020 SAP SE and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/

package app.coronawarn.server.services.submission.verification;

import javax.net.ssl.HostnameVerifier;

public interface HostnameVerifierProvider {

HostnameVerifier createHostnameVerifier();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* ---license-start
* Corona-Warn-App
* ---
* Copyright (C) 2020 SAP SE and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/

package app.coronawarn.server.services.submission.verification;

import javax.net.ssl.HostnameVerifier;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("!ssl-client-verification-verify-hostname")
public class NoopHostnameVerifierProvider implements HostnameVerifierProvider {

@Override
public HostnameVerifier createHostnameVerifier() {
return new NoopHostnameVerifier();
}
}
5 changes: 5 additions & 0 deletions services/submission/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ management:
health:
probes:
enabled: true

feign:
httpclient:
maxConnections: 200
maxConnectionsPerRoute: 200

0 comments on commit b5a83c4

Please sign in to comment.