Skip to content

Commit 83a09d9

Browse files
committed
Merge origin/master into maven-deploy
2 parents 3379266 + 119af05 commit 83a09d9

File tree

519 files changed

+6849
-2549
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

519 files changed

+6849
-2549
lines changed

.gitignore

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ pom.xml.releaseBackup
44
pom.xml.versionsBackup
55
pom.xml.next
66
release.properties
7-
/TLS-Core/nbproject/
8-
/Attacks/nbproject/
97
/apps/
10-
nbactions.xml
11-
TLS-Client/nbactions.xml
12-
TLS-Server/nbactions.xml
13-
Attacks/nbactions.xml
8+
nbproject/
9+
nbactions.xml

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/impl/EarlyCCSAttacker.java

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99
package de.rub.nds.tlsattacker.attacks.impl;
1010

1111
import de.rub.nds.tlsattacker.attacks.config.EarlyCCSCommandConfig;
12-
import de.rub.nds.modifiablevariable.bytearray.ByteArrayModificationFactory;
13-
import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray;
14-
import de.rub.nds.tlsattacker.core.constants.HandshakeMessageType;
12+
import de.rub.nds.tlsattacker.core.constants.ProtocolMessageType;
1513
import de.rub.nds.tlsattacker.core.protocol.message.CertificateMessage;
1614
import de.rub.nds.tlsattacker.core.protocol.message.ChangeCipherSpecMessage;
17-
import de.rub.nds.tlsattacker.core.protocol.message.FinishedMessage;
15+
import de.rub.nds.tlsattacker.core.protocol.message.ClientHelloMessage;
1816
import de.rub.nds.tlsattacker.core.protocol.message.ProtocolMessage;
19-
import de.rub.nds.tlsattacker.core.protocol.message.RSAClientKeyExchangeMessage;
2017
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloDoneMessage;
2118
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloMessage;
2219
import de.rub.nds.tlsattacker.core.util.LogLevel;
@@ -25,10 +22,8 @@
2522
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
2623
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutorFactory;
2724
import de.rub.nds.tlsattacker.core.workflow.WorkflowTrace;
28-
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowTraceType;
2925
import de.rub.nds.tlsattacker.core.workflow.action.ReceiveAction;
3026
import de.rub.nds.tlsattacker.core.workflow.action.SendAction;
31-
import de.rub.nds.tlsattacker.transport.TransportHandler;
3227
import java.util.LinkedList;
3328
import java.util.List;
3429
import org.apache.logging.log4j.LogManager;
@@ -50,71 +45,42 @@ public EarlyCCSAttacker(EarlyCCSCommandConfig config) {
5045

5146
@Override
5247
public void executeAttack() {
48+
// byte[] ms = new byte[48];
49+
// byte[] pms = new byte[48];
50+
// pms[0] = 3;
51+
// pms[1] = 3;
52+
// workflowTrace.add(new ChangePreMasterSecretAction(pms));
53+
// workflowTrace.add(new ChangeMasterSecretAction(ms));
5354
throw new UnsupportedOperationException("Not implemented yet");
5455
}
5556

5657
@Override
5758
public Boolean isVulnerable() {
5859
TlsConfig tlsConfig = config.createConfig();
59-
tlsConfig.setWorkflowTraceType(WorkflowTraceType.HELLO);
60+
tlsConfig.setTlsTimeout(1000);
61+
tlsConfig.setTimeout(1000);
6062
TlsContext tlsContext = new TlsContext(tlsConfig);
61-
WorkflowExecutor workflowExecutor = WorkflowExecutorFactory.createWorkflowExecutor(tlsConfig.getExecutorType(),
62-
tlsContext);
63-
64-
byte[] ms = new byte[48];
65-
byte[] pms = new byte[48];
66-
pms[0] = 3;
67-
pms[1] = 3;
68-
69-
WorkflowTrace workflowTrace = tlsContext.getWorkflowTrace();
63+
WorkflowTrace workflowTrace = new WorkflowTrace();
64+
workflowTrace.add(new SendAction(new ClientHelloMessage(tlsConfig)));
7065
List<ProtocolMessage> messageList = new LinkedList<>();
7166
messageList.add(new ServerHelloMessage(tlsConfig));
7267
messageList.add(new CertificateMessage(tlsConfig));
7368
messageList.add(new ServerHelloDoneMessage(tlsConfig));
74-
ReceiveAction receiveAction = new ReceiveAction(messageList);
75-
workflowTrace.add(receiveAction);
69+
workflowTrace.add(new ReceiveAction(messageList));
7670
messageList = new LinkedList<>();
77-
RSAClientKeyExchangeMessage clientKeyExchange1 = new RSAClientKeyExchangeMessage(tlsConfig);
78-
messageList.add(clientKeyExchange1);
79-
ModifiableByteArray modpms = new ModifiableByteArray();
80-
modpms.setModification(ByteArrayModificationFactory.explicitValue(pms));
81-
clientKeyExchange1.getComputations().setPlainPaddedPremasterSecret(modpms);
82-
ModifiableByteArray modms = new ModifiableByteArray();
83-
modms.setModification(ByteArrayModificationFactory.explicitValue(ms));
84-
clientKeyExchange1.getComputations().setMasterSecret(modms);
85-
clientKeyExchange1.setGoingToBeSent(false);
86-
ChangeCipherSpecMessage changeCipherSpec1 = new ChangeCipherSpecMessage(tlsConfig);
87-
messageList.add(changeCipherSpec1);
88-
changeCipherSpec1.setGoingToBeSent(false);
89-
FinishedMessage fin1 = new FinishedMessage(tlsConfig);
90-
fin1.setGoingToBeSent(false);
91-
92-
messageList.add(new ChangeCipherSpecMessage(tlsConfig));
93-
94-
RSAClientKeyExchangeMessage clientKeyExchange2 = new RSAClientKeyExchangeMessage(tlsConfig);
95-
messageList.add(clientKeyExchange2);
96-
modpms = new ModifiableByteArray();
97-
modpms.setModification(ByteArrayModificationFactory.explicitValue(pms));
98-
clientKeyExchange2.getComputations().setPlainPaddedPremasterSecret(modpms);
99-
modms = new ModifiableByteArray();
100-
modms.setModification(ByteArrayModificationFactory.explicitValue(ms));
101-
clientKeyExchange2.getComputations().setMasterSecret(modms);
102-
messageList.add(new FinishedMessage(tlsConfig));
103-
SendAction sendAction = new SendAction(messageList);
104-
workflowTrace.add(sendAction);
71+
messageList.add(new ChangeCipherSpecMessage());
72+
workflowTrace.add(new SendAction(messageList));
10573
messageList = new LinkedList<>();
106-
107-
messageList.add(new ChangeCipherSpecMessage(tlsConfig));
108-
messageList.add(new FinishedMessage(tlsConfig));
109-
receiveAction = new ReceiveAction(messageList);
110-
workflowTrace.add(receiveAction);
74+
workflowTrace.add(new ReceiveAction(messageList));
75+
tlsConfig.setWorkflowTrace(workflowTrace);
76+
WorkflowExecutor workflowExecutor = WorkflowExecutorFactory.createWorkflowExecutor(tlsConfig.getExecutorType(),
77+
tlsContext);
11178
workflowExecutor.executeWorkflow();
112-
113-
if (workflowTrace.getActuallyRecievedHandshakeMessagesOfType(HandshakeMessageType.FINISHED).isEmpty()) {
114-
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Not vulnerable (probably), no Server Finished message found");
79+
if (!workflowTrace.getActualReceivedProtocolMessagesOfType(ProtocolMessageType.ALERT).isEmpty()) {
80+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Not vulnerable (probably), no Alert message found");
11581
return false;
11682
} else {
117-
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Vulnerable (probably), Server Finished message found");
83+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Vulnerable (probably), Alert message found");
11884
return true;
11985
}
12086
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/impl/Lucky13Attacker.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
*/
99
package de.rub.nds.tlsattacker.attacks.impl;
1010

11+
import java.io.FileWriter;
12+
import java.io.IOException;
13+
import java.util.Collections;
14+
import java.util.HashMap;
15+
import java.util.LinkedList;
16+
import java.util.List;
17+
import java.util.Map;
18+
import org.apache.logging.log4j.LogManager;
19+
import org.apache.logging.log4j.Logger;
20+
1121
import de.rub.nds.tlsattacker.attacks.config.Lucky13CommandConfig;
1222
import de.rub.nds.modifiablevariable.VariableModification;
1323
import de.rub.nds.modifiablevariable.bytearray.ByteArrayModificationFactory;
@@ -17,27 +27,14 @@
1727
import de.rub.nds.tlsattacker.core.protocol.message.AlertMessage;
1828
import de.rub.nds.tlsattacker.core.protocol.message.ApplicationMessage;
1929
import de.rub.nds.tlsattacker.core.record.Record;
20-
import de.rub.nds.tlsattacker.core.util.LogLevel;
2130
import de.rub.nds.tlsattacker.core.workflow.TlsConfig;
2231
import de.rub.nds.tlsattacker.core.workflow.TlsContext;
2332
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
2433
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutorFactory;
2534
import de.rub.nds.tlsattacker.core.workflow.WorkflowTrace;
26-
import de.rub.nds.tlsattacker.core.workflow.action.MessageActionFactory;
2735
import de.rub.nds.tlsattacker.core.workflow.action.ReceiveAction;
2836
import de.rub.nds.tlsattacker.core.workflow.action.SendAction;
29-
import de.rub.nds.tlsattacker.transport.ConnectionEnd;
30-
import de.rub.nds.tlsattacker.transport.TransportHandler;
3137
import de.rub.nds.modifiablevariable.util.ArrayConverter;
32-
import java.io.FileWriter;
33-
import java.io.IOException;
34-
import java.util.Collections;
35-
import java.util.HashMap;
36-
import java.util.LinkedList;
37-
import java.util.List;
38-
import java.util.Map;
39-
import org.apache.logging.log4j.LogManager;
40-
import org.apache.logging.log4j.Logger;
4138

4239
/**
4340
* Executes the Lucky13 attack test

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/impl/SniAttacker.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,6 @@ public void executeAttack() {
5151

5252
@Override
5353
public Boolean isVulnerable() {
54-
TlsConfig tlsConfig = config.createConfig();
55-
TlsContext tlsContext = new TlsContext(tlsConfig);
56-
WorkflowExecutor workflowExecutor = WorkflowExecutorFactory.createWorkflowExecutor(tlsConfig.getExecutorType(),
57-
tlsContext);
58-
WorkflowTrace trace = tlsContext.getWorkflowTrace();
59-
List<TLSAction> actions = trace.getTLSActions();
60-
ServerNameIndicationExtensionMessage sni = new ServerNameIndicationExtensionMessage();
61-
ServerNamePair pair = new ServerNamePair();
62-
pair.setServerNameConfig(config.getServerName2().getBytes());
63-
pair.setServerNameTypeConfig(NameType.HOST_NAME.getValue());
64-
sni.getServerNameList().add(pair);
6554
throw new UnsupportedOperationException("Work in progress");
6655
}
6756

TLS-Client/src/main/java/de/rub/nds/tlsattacker/client/main/TLSClient.java renamed to TLS-Client/src/main/java/de/rub/nds/tlsattacker/client/main/TlsClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
* @author Robert Merget - robert.merget@rub.de
2828
*/
29-
public class TLSClient {
29+
public class TlsClient {
3030

3131
private static final Logger LOGGER = LogManager.getLogger("Client");
3232

@@ -44,7 +44,7 @@ public static void main(String args[]) {
4444
TlsConfig tlsConfig = null;
4545
try {
4646
tlsConfig = config.createConfig();
47-
TLSClient client = new TLSClient();
47+
TlsClient client = new TlsClient();
4848
client.startTlsClient(tlsConfig);
4949
} catch (ConfigurationException E) {
5050
LOGGER.info("Encountered a ConfigurationException aborting.");

TLS-Client/src/test/java/de/rub/nds/tlsattacker/client/TlsClientTest.java renamed to TLS-Client/src/test/java/de/rub/nds/tlsattacker/client/main/TlsClientTest.java

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,8 @@
66
* Licensed under Apache License 2.0
77
* http://www.apache.org/licenses/LICENSE-2.0
88
*/
9-
package de.rub.nds.tlsattacker.client;
9+
package de.rub.nds.tlsattacker.client.main;
1010

11-
import de.rub.nds.tlsattacker.client.config.ClientCommandConfig;
12-
import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate;
13-
import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver;
14-
import de.rub.nds.tlsattacker.core.constants.CipherSuite;
15-
import de.rub.nds.tlsattacker.core.constants.ProtocolVersion;
16-
import de.rub.nds.tlsattacker.core.constants.PublicKeyAlgorithm;
17-
import de.rub.nds.tlsattacker.core.exceptions.WorkflowExecutionException;
18-
import de.rub.nds.tlsattacker.core.protocol.message.CertificateMessage;
19-
import de.rub.nds.tlsattacker.core.protocol.message.ChangeCipherSpecMessage;
20-
import de.rub.nds.tlsattacker.core.protocol.message.ClientHelloMessage;
21-
import de.rub.nds.tlsattacker.core.protocol.message.FinishedMessage;
22-
import de.rub.nds.tlsattacker.core.protocol.message.RSAClientKeyExchangeMessage;
23-
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloDoneMessage;
24-
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloMessage;
25-
import de.rub.nds.tlsattacker.core.util.KeyStoreGenerator;
26-
import de.rub.nds.tlsattacker.core.workflow.TlsConfig;
27-
import de.rub.nds.tlsattacker.core.workflow.TlsContext;
28-
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
29-
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutorFactory;
30-
import de.rub.nds.tlsattacker.core.workflow.WorkflowTrace;
31-
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowTraceType;
32-
import de.rub.nds.tlsattacker.core.workflow.action.MessageActionFactory;
33-
import de.rub.nds.tlsattacker.transport.ConnectionEnd;
34-
import de.rub.nds.tlsattacker.util.FixedTimeProvider;
35-
import de.rub.nds.tlsattacker.util.TimeHelper;
36-
import de.rub.nds.tlsattacker.util.TimeProvider;
37-
import de.rub.nds.tlsattacker.util.tests.IntegrationTests;
3811
import java.io.IOException;
3912
import java.security.InvalidKeyException;
4013
import java.security.KeyManagementException;
@@ -63,6 +36,34 @@
6336
import org.junit.experimental.categories.Category;
6437
import org.junit.rules.ErrorCollector;
6538

39+
import de.rub.nds.tlsattacker.client.config.ClientCommandConfig;
40+
import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate;
41+
import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver;
42+
import de.rub.nds.tlsattacker.core.constants.CipherSuite;
43+
import de.rub.nds.tlsattacker.core.constants.ProtocolVersion;
44+
import de.rub.nds.tlsattacker.core.constants.PublicKeyAlgorithm;
45+
import de.rub.nds.tlsattacker.core.exceptions.WorkflowExecutionException;
46+
import de.rub.nds.tlsattacker.core.protocol.message.CertificateMessage;
47+
import de.rub.nds.tlsattacker.core.protocol.message.ChangeCipherSpecMessage;
48+
import de.rub.nds.tlsattacker.core.protocol.message.ClientHelloMessage;
49+
import de.rub.nds.tlsattacker.core.protocol.message.FinishedMessage;
50+
import de.rub.nds.tlsattacker.core.protocol.message.RSAClientKeyExchangeMessage;
51+
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloDoneMessage;
52+
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloMessage;
53+
import de.rub.nds.tlsattacker.core.util.BasicTlsServer;
54+
import de.rub.nds.tlsattacker.core.util.KeyStoreGenerator;
55+
import de.rub.nds.tlsattacker.core.workflow.TlsConfig;
56+
import de.rub.nds.tlsattacker.core.workflow.TlsContext;
57+
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
58+
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutorFactory;
59+
import de.rub.nds.tlsattacker.core.workflow.WorkflowTrace;
60+
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowTraceType;
61+
import de.rub.nds.tlsattacker.core.workflow.action.MessageActionFactory;
62+
import de.rub.nds.tlsattacker.transport.ConnectionEndType;
63+
import de.rub.nds.tlsattacker.util.FixedTimeProvider;
64+
import de.rub.nds.tlsattacker.util.TimeHelper;
65+
import de.rub.nds.tlsattacker.util.tests.IntegrationTests;
66+
6667
/**
6768
*
6869
* @author Juraj Somorovsky - juraj.somorovsky@rub.de
@@ -78,7 +79,7 @@ public class TlsClientTest {
7879
@Rule
7980
public ErrorCollector collector = new ErrorCollector();
8081

81-
private TLSServer tlsServer;
82+
private BasicTlsServer tlsServer;
8283

8384
public TlsClientTest() {
8485
Security.addProvider(new BouncyCastleProvider());
@@ -91,7 +92,7 @@ public void testRSAWorkflows() throws OperatorCreationException {
9192
TimeHelper.setProvider(new FixedTimeProvider(0));
9293
KeyPair k = KeyStoreGenerator.createRSAKeyPair(1024);
9394
KeyStore ks = KeyStoreGenerator.createKeyStore(k);
94-
tlsServer = new TLSServer(ks, KeyStoreGenerator.PASSWORD, "TLS", PORT);
95+
tlsServer = new BasicTlsServer(ks, KeyStoreGenerator.PASSWORD, "TLS", PORT);
9596
new Thread(tlsServer).start();
9697
while (!tlsServer.isInitialized())
9798
;
@@ -112,7 +113,7 @@ public void testECWorkflows() throws OperatorCreationException {
112113
try {
113114
KeyPair k = KeyStoreGenerator.createECKeyPair(256);
114115
KeyStore ks = KeyStoreGenerator.createKeyStore(k);
115-
tlsServer = new TLSServer(ks, KeyStoreGenerator.PASSWORD, "TLS", PORT + 1);
116+
tlsServer = new BasicTlsServer(ks, KeyStoreGenerator.PASSWORD, "TLS", PORT + 1);
116117
new Thread(tlsServer).start();
117118
while (!tlsServer.isInitialized())
118119
;
@@ -137,7 +138,8 @@ public void testExecuteWorkflows(PublicKeyAlgorithm algorithm, int port) {
137138
ClientCommandConfig clientCommandConfig = new ClientCommandConfig(new GeneralDelegate());
138139
clientCommandConfig.getGeneralDelegate().setLogLevel(Level.INFO);
139140
TlsConfig config = clientCommandConfig.createConfig();
140-
config.setHost("localhost:" + port);
141+
config.setHost("localhost");
142+
config.setPort(port);
141143
config.setTlsTimeout(TIMEOUT);
142144
List<String> serverList = Arrays.asList(tlsServer.getCipherSuites());
143145
config.setHighestProtocolVersion(ProtocolVersion.TLS10);
@@ -198,23 +200,24 @@ private boolean testCustomWorkflow(int port) {
198200
ClientCommandConfig clientCommandConfig = new ClientCommandConfig(new GeneralDelegate());
199201
clientCommandConfig.getGeneralDelegate().setLogLevel(Level.INFO);
200202
TlsConfig config = clientCommandConfig.createConfig();
201-
config.setHost("localhost:" + port);
203+
config.setHost("localhost");
204+
config.setPort(port);
202205
config.setTlsTimeout(TIMEOUT);
203206
config.setWorkflowTraceType(WorkflowTraceType.HELLO);
204207

205208
TlsContext tlsContext = new TlsContext(config);
206209
config.setWorkflowTrace(new WorkflowTrace());
207210

208211
WorkflowTrace trace = config.getWorkflowTrace();
209-
trace.add(MessageActionFactory.createAction(ConnectionEnd.CLIENT, ConnectionEnd.CLIENT, new ClientHelloMessage(
210-
config)));
211-
trace.add(MessageActionFactory.createAction(ConnectionEnd.CLIENT, ConnectionEnd.SERVER, new ServerHelloMessage(
212-
config), new CertificateMessage(config), new ServerHelloDoneMessage(config)));
212+
trace.add(MessageActionFactory.createAction(ConnectionEndType.CLIENT, ConnectionEndType.CLIENT,
213+
new ClientHelloMessage(config)));
214+
trace.add(MessageActionFactory.createAction(ConnectionEndType.CLIENT, ConnectionEndType.SERVER,
215+
new ServerHelloMessage(config), new CertificateMessage(config), new ServerHelloDoneMessage(config)));
213216

214-
trace.add(MessageActionFactory.createAction(ConnectionEnd.CLIENT, ConnectionEnd.CLIENT,
217+
trace.add(MessageActionFactory.createAction(ConnectionEndType.CLIENT, ConnectionEndType.CLIENT,
215218
new RSAClientKeyExchangeMessage(config), new ChangeCipherSpecMessage(config), new FinishedMessage(
216219
config)));
217-
trace.add(MessageActionFactory.createAction(ConnectionEnd.CLIENT, ConnectionEnd.SERVER,
220+
trace.add(MessageActionFactory.createAction(ConnectionEndType.CLIENT, ConnectionEndType.SERVER,
218221
new ChangeCipherSpecMessage(config), new FinishedMessage(config)));
219222
WorkflowExecutor workflowExecutor = WorkflowExecutorFactory.createWorkflowExecutor(config.getExecutorType(),
220223
tlsContext);

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/config/TLSDelegateConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
import java.util.List;
1919
import org.apache.logging.log4j.LogManager;
2020
import org.apache.logging.log4j.Logger;
21+
import org.bouncycastle.math.ec.ECCurve;
2122

2223
/**
2324
*
2425
* @author Robert Merget - robert.merget@rub.de
2526
*/
2627
public abstract class TLSDelegateConfig {
2728

28-
protected static final Logger LOGGER = LogManager.getLogger("Config");
29+
protected static final Logger LOGGER = LogManager.getLogger(TLSDelegateConfig.class.getName());
2930

3031
private final List<Delegate> delegateList;
3132
private final GeneralDelegate generalDelegate;

0 commit comments

Comments
 (0)