Skip to content

Commit fcec2ed

Browse files
authored
Merge pull request #325 from tls-attacker/integrationTestsProbes
Integration Tests (server probes)
2 parents feba378 + d4fe900 commit fcec2ed

34 files changed

+1573
-34
lines changed

Jenkinsfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pipeline {
5454
}
5555
}
5656
options {
57-
timeout(activity: true, time: 120, unit: 'SECONDS')
57+
timeout(activity: true, time: 240, unit: 'SECONDS')
5858
}
5959
steps {
6060
withMaven(jdk: env.JDK_TOOL_NAME, maven: env.MAVEN_TOOL_NAME) {
@@ -77,7 +77,7 @@ pipeline {
7777
}
7878
}
7979
options {
80-
timeout(activity: true, time: 120, unit: 'SECONDS')
80+
timeout(activity: true, time: 180, unit: 'SECONDS')
8181
}
8282
steps {
8383
withMaven(jdk: env.JDK_TOOL_NAME, maven: env.MAVEN_TOOL_NAME) {
@@ -99,7 +99,7 @@ pipeline {
9999
}
100100
}
101101
options {
102-
timeout(activity: true, time: 120, unit: 'SECONDS')
102+
timeout(activity: true, time: 600, unit: 'SECONDS')
103103
}
104104
steps {
105105
withMaven(jdk: env.JDK_TOOL_NAME, maven: env.MAVEN_TOOL_NAME) {
@@ -135,4 +135,4 @@ pipeline {
135135
recordIssues enabledForFailure: true, tools: [mavenConsole(), java(), javaDoc()]
136136
}
137137
}
138-
}
138+
}

Scanner-Core/src/main/java/de/rub/nds/scanner/core/config/ExecutorConfig.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import de.rub.nds.scanner.core.constants.ProbeType;
1313
import de.rub.nds.scanner.core.constants.ScannerDetail;
1414
import java.util.Arrays;
15+
import java.util.LinkedList;
1516
import java.util.List;
1617

1718
public final class ExecutorConfig {
@@ -98,6 +99,20 @@ public void setProbes(ProbeType... probes) {
9899
this.probes = Arrays.asList(probes);
99100
}
100101

102+
public void addProbes(List<ProbeType> probes) {
103+
if (this.probes == null) {
104+
this.probes = new LinkedList<>();
105+
}
106+
this.probes.addAll(probes);
107+
}
108+
109+
public void addProbes(ProbeType... probes) {
110+
if (this.probes == null) {
111+
this.probes = new LinkedList<>();
112+
}
113+
this.probes.addAll(Arrays.asList(probes));
114+
}
115+
101116
public int getProbeTimeout() {
102117
return probeTimeout;
103118
}

Scanner-Core/src/main/java/de/rub/nds/scanner/core/report/ScanReport.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ public synchronized void putResult(AnalyzedProperty property, Boolean result) {
139139
: TestResults.UNCERTAIN);
140140
}
141141

142+
public synchronized void putResult(AnalyzedProperty property, List<?> result) {
143+
this.putResult(property, new ListResult<>((List<?>) result, property.getName()));
144+
}
145+
146+
public synchronized void putResult(AnalyzedProperty property, Set<?> result) {
147+
this.putResult(property, new SetResult<>((Set<?>) result, property.getName()));
148+
}
149+
150+
public synchronized void putResult(AnalyzedProperty property, Map<?, ?> result) {
151+
this.putResult(property, new MapResult<>((Map<?, ?>) result, property.getName()));
152+
}
153+
142154
public synchronized void markAsChangedAndNotify() {
143155
this.hasChanged();
144156
this.notifyObservers();

TLS-Scanner-Core/src/main/java/de/rub/nds/tlsscanner/core/report/TlsScanReport.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ public abstract class TlsScanReport extends ScanReport {
4242

4343
private KnownPaddingOracleVulnerability knownPaddingOracleVulnerability = null;
4444

45-
// Extensions
46-
private List<String> supportedAlpns = null;
47-
4845
// DTLS
4946
private Integer totalReceivedRetransmissions = 0;
5047

@@ -73,14 +70,6 @@ public synchronized void setKnownPaddingOracleVulnerability(
7370
this.knownPaddingOracleVulnerability = knownPaddingOracleVulnerability;
7471
}
7572

76-
public synchronized List<String> getSupportedAlpns() {
77-
return supportedAlpns;
78-
}
79-
80-
public synchronized void setSupportedAlpns(List<String> supportedAlpns) {
81-
this.supportedAlpns = supportedAlpns;
82-
}
83-
8473
public synchronized Integer getTotalReceivedRetransmissions() {
8574
return totalReceivedRetransmissions;
8675
}
@@ -239,6 +228,13 @@ public synchronized List<NamedGroup> getSupportedNamedGroups() {
239228
return listResult == null ? null : listResult.getList();
240229
}
241230

231+
public synchronized List<NamedGroup> getStaticEcdsaPkgGroups() {
232+
@SuppressWarnings("unchecked")
233+
ListResult<NamedGroup> listResult =
234+
(ListResult<NamedGroup>) getListResult(TlsAnalyzedProperty.STATIC_ECDSA_PK_GROUPS);
235+
return listResult == null ? null : listResult.getList();
236+
}
237+
242238
public synchronized List<NamedGroup> getEphemeralEcdsaPkgGroups() {
243239
@SuppressWarnings("unchecked")
244240
ListResult<NamedGroup> listResult =
@@ -298,4 +294,11 @@ public synchronized List<TokenBindingKeyParameters> getSupportedTokenbindingKeyP
298294
getListResult(TlsAnalyzedProperty.SUPPORTED_TOKENBINDING_KEY_PARAMETERS);
299295
return listResult == null ? null : listResult.getList();
300296
}
297+
298+
public synchronized List<String> getSupportedAlpnConstans() {
299+
@SuppressWarnings("unchecked")
300+
ListResult<String> listResult =
301+
(ListResult<String>) getListResult(TlsAnalyzedProperty.SUPPORTED_ALPN_CONSTANTS);
302+
return listResult == null ? null : listResult.getList();
303+
}
301304
}

TLS-Server-Scanner/src/main/java/de/rub/nds/tlsscanner/serverscanner/report/ServerContainerReportCreator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,15 +442,15 @@ private ReportContainer createAttackVulnerabilitiesContainer(ServerReport report
442442

443443
private ReportContainer createAlpnContainer(ServerReport report) {
444444
ListContainer container = new ListContainer();
445-
if (report.getSupportedAlpns() == null) {
445+
if (report.getSupportedAlpnConstans() == null) {
446446
return container;
447447
}
448448
container.add(new HeadlineContainer("ALPN"));
449449
for (AlpnProtocol alpnProtocol : AlpnProtocol.values()) {
450450
if (alpnProtocol.isGrease()) {
451451
continue;
452452
}
453-
if (report.getSupportedAlpns().contains(alpnProtocol.getConstant())) {
453+
if (report.getSupportedAlpnConstans().contains(alpnProtocol.getConstant())) {
454454
container.add(
455455
new KeyValueContainer(
456456
alpnProtocol.getPrintableName(),

TLS-Server-Scanner/src/main/java/de/rub/nds/tlsscanner/serverscanner/report/ServerReportPrinter.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,23 +2159,18 @@ public StringBuilder appendAlpacaAttack(StringBuilder builder) {
21592159

21602160
public StringBuilder appendAlpn(StringBuilder builder) {
21612161
@SuppressWarnings("unchecked")
2162-
ListResult<String> alpnResult =
2163-
(ListResult<String>)
2164-
report.getListResult(TlsAnalyzedProperty.SUPPORTED_ALPN_CONSTANTS);
2165-
if (alpnResult != null) {
2166-
List<String> alpns = alpnResult.getList();
2167-
if (alpns != null) {
2168-
prettyAppendHeading(builder, "ALPN");
2169-
for (AlpnProtocol alpnProtocol : AlpnProtocol.values()) {
2170-
if (alpnProtocol.isGrease()) {
2171-
continue;
2172-
}
2173-
if (alpns.contains(alpnProtocol.getConstant())) {
2174-
prettyAppend(builder, alpnProtocol.getPrintableName(), true);
2175-
} else {
2176-
if (detail.isGreaterEqualTo(ScannerDetail.DETAILED)) {
2177-
prettyAppend(builder, alpnProtocol.getPrintableName(), false);
2178-
}
2162+
List<String> alpns = report.getSupportedAlpnConstans();
2163+
if (alpns != null) {
2164+
prettyAppendHeading(builder, "ALPN");
2165+
for (AlpnProtocol alpnProtocol : AlpnProtocol.values()) {
2166+
if (alpnProtocol.isGrease()) {
2167+
continue;
2168+
}
2169+
if (alpns.contains(alpnProtocol.getConstant())) {
2170+
prettyAppend(builder, alpnProtocol.getPrintableName(), true);
2171+
} else {
2172+
if (detail.isGreaterEqualTo(ScannerDetail.DETAILED)) {
2173+
prettyAppend(builder, alpnProtocol.getPrintableName(), false);
21792174
}
21802175
}
21812176
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* TLS-Scanner - A TLS configuration and analysis tool based on TLS-Attacker
3+
*
4+
* Copyright 2017-2023 Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH
5+
*
6+
* Licensed under Apache License, Version 2.0
7+
* http://www.apache.org/licenses/LICENSE-2.0.txt
8+
*/
9+
package de.rub.nds.tlsscanner.serverscanner.probe;
10+
11+
import static org.junit.Assume.assumeNotNull;
12+
13+
import com.github.dockerjava.api.exception.DockerException;
14+
import com.github.dockerjava.api.model.Image;
15+
import de.rub.nds.scanner.core.constants.TestResult;
16+
import de.rub.nds.tls.subject.ConnectionRole;
17+
import de.rub.nds.tls.subject.TlsImplementationType;
18+
import de.rub.nds.tls.subject.constants.TransportType;
19+
import de.rub.nds.tls.subject.docker.DockerClientManager;
20+
import de.rub.nds.tls.subject.docker.DockerTlsInstance;
21+
import de.rub.nds.tls.subject.docker.DockerTlsManagerFactory;
22+
import de.rub.nds.tls.subject.docker.DockerTlsServerInstance;
23+
import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate;
24+
import de.rub.nds.tlsattacker.core.workflow.ParallelExecutor;
25+
import de.rub.nds.tlsscanner.core.constants.TlsAnalyzedProperty;
26+
import de.rub.nds.tlsscanner.serverscanner.config.ServerScannerConfig;
27+
import de.rub.nds.tlsscanner.serverscanner.report.ServerReport;
28+
import de.rub.nds.tlsscanner.serverscanner.selector.ConfigSelector;
29+
import java.security.Security;
30+
import java.util.List;
31+
import java.util.UUID;
32+
import org.apache.logging.log4j.LogManager;
33+
import org.apache.logging.log4j.Logger;
34+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
35+
import org.junit.Assume;
36+
import org.junit.jupiter.api.AfterEach;
37+
import org.junit.jupiter.api.BeforeAll;
38+
import org.junit.jupiter.api.BeforeEach;
39+
import org.junit.jupiter.api.Test;
40+
import org.junit.jupiter.api.TestInstance;
41+
42+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
43+
public abstract class AbstractProbeIT {
44+
45+
private static final Logger LOGGER = LogManager.getLogger();
46+
private static final int MAX_ATTEMPTS = 3;
47+
private static List<Image> localImages;
48+
49+
private final TlsImplementationType implementation;
50+
private final String version;
51+
private final String additionalParameters;
52+
private final TransportType transportType;
53+
54+
private DockerTlsInstance dockerInstance;
55+
protected ServerReport report;
56+
protected ParallelExecutor parallelExecutor;
57+
protected ConfigSelector configSelector;
58+
private ServerScannerConfig config;
59+
60+
public AbstractProbeIT(
61+
TlsImplementationType implementation, String version, String additionalParameters) {
62+
this.implementation = implementation;
63+
this.version = version;
64+
this.additionalParameters = additionalParameters;
65+
this.transportType = TransportType.TCP;
66+
}
67+
68+
public AbstractProbeIT(
69+
TlsImplementationType implementation,
70+
String version,
71+
String additionalParameters,
72+
TransportType transportType) {
73+
this.implementation = implementation;
74+
this.version = version;
75+
this.additionalParameters = additionalParameters;
76+
this.transportType = transportType;
77+
}
78+
79+
@BeforeAll
80+
public void loadList() {
81+
try {
82+
DockerClientManager.getDockerClient().listContainersCmd().exec();
83+
} catch (Exception ex) {
84+
Assume.assumeNoException(ex);
85+
}
86+
localImages = DockerTlsManagerFactory.getAllImages();
87+
}
88+
89+
@BeforeEach
90+
public void setUp() throws InterruptedException {
91+
Security.addProvider(new BouncyCastleProvider());
92+
DockerClientManager.setDockerServerUsername(System.getenv("DOCKER_USERNAME"));
93+
DockerClientManager.setDockerServerPassword(System.getenv("DOCKER_PASSWORD"));
94+
prepareContainer();
95+
}
96+
97+
private void prepareContainer() throws DockerException, InterruptedException {
98+
Image image =
99+
DockerTlsManagerFactory.getMatchingImage(
100+
localImages, implementation, version, ConnectionRole.SERVER);
101+
getDockerInstance(image);
102+
}
103+
104+
private void getDockerInstance(Image image) throws DockerException, InterruptedException {
105+
DockerTlsManagerFactory.TlsServerInstanceBuilder serverInstanceBuilder;
106+
if (image != null) {
107+
serverInstanceBuilder =
108+
new DockerTlsManagerFactory.TlsServerInstanceBuilder(image, transportType);
109+
} else {
110+
serverInstanceBuilder =
111+
new DockerTlsManagerFactory.TlsServerInstanceBuilder(
112+
implementation, version, transportType)
113+
.pull();
114+
localImages = DockerTlsManagerFactory.getAllImages();
115+
assumeNotNull(
116+
image,
117+
String.format(
118+
"TLS implementation %s %s not available",
119+
implementation.name(), version));
120+
}
121+
serverInstanceBuilder
122+
.containerName("server-scanner-test-server-" + UUID.randomUUID())
123+
.additionalParameters(additionalParameters);
124+
dockerInstance = serverInstanceBuilder.build();
125+
dockerInstance.start();
126+
}
127+
128+
@AfterEach
129+
public void tearDown() {
130+
killContainer();
131+
}
132+
133+
private void killContainer() {
134+
if (dockerInstance != null && dockerInstance.getId() != null) {
135+
dockerInstance.kill();
136+
}
137+
}
138+
139+
@Test
140+
public void testProbe() throws InterruptedException {
141+
LOGGER.info("Testing: " + getProbe().getProbeName());
142+
for (int i = 0; i < MAX_ATTEMPTS; i++) {
143+
try {
144+
executeProbe();
145+
} catch (Exception ignored) {
146+
LOGGER.info(
147+
"Encountered exception during scanner execution ("
148+
+ ignored.getMessage()
149+
+ ")");
150+
}
151+
if (!executedAsPlanned()) {
152+
LOGGER.info("Failed to complete scan, reexecuting...");
153+
killContainer();
154+
prepareContainer();
155+
} else {
156+
return;
157+
}
158+
}
159+
LOGGER.error("Failed");
160+
}
161+
162+
private void executeProbe() {
163+
// Preparing config, executor, config selector, and report
164+
config = new ServerScannerConfig(new GeneralDelegate());
165+
config.getClientDelegate()
166+
.setHost("localhost:" + ((DockerTlsServerInstance) dockerInstance).getPort());
167+
parallelExecutor = new ParallelExecutor(1, 3);
168+
configSelector = new ConfigSelector(config, parallelExecutor);
169+
configSelector.findWorkingConfigs();
170+
report = new ServerReport();
171+
prepareReport();
172+
// Executing probe
173+
TlsServerProbe probe = getProbe();
174+
probe.adjustConfig(report);
175+
probe.executeTest();
176+
probe.merge(report);
177+
}
178+
179+
protected abstract TlsServerProbe getProbe();
180+
181+
protected abstract void prepareReport();
182+
183+
protected abstract boolean executedAsPlanned();
184+
185+
protected boolean verifyProperty(TlsAnalyzedProperty property, TestResult result) {
186+
return report.getResult(property) == result;
187+
}
188+
}

0 commit comments

Comments
 (0)