Skip to content

Commit 0451352

Browse files
authored
Merge pull request #361 from RUB-NDS/fixAlpn
fix: Add missing length field to ALPN extension, see #360
2 parents 2112d1f + ce070b1 commit 0451352

File tree

13 files changed

+254
-25
lines changed

13 files changed

+254
-25
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ public static Config mergeWithDefaultValues(Config c) {
290290
private byte[] certificateStatusRequestExtensionRequestExtension = new byte[0];
291291

292292
/**
293-
* Default ALPN announced protocols It's HTTP/2 0x68 0x32 as of RFC7540
293+
* Default ALPN announced protocols
294294
*/
295-
private String applicationLayerProtocolNegotiationAnnouncedProtocols = "h2";
295+
private String[] alpnAnnouncedProtocols = new String[] { "h2" };
296296

297297
@XmlJavaTypeAdapter(ByteArrayAdapter.class)
298298
private byte[] sessionId = new byte[0];
@@ -2055,13 +2055,12 @@ public void setCertificateStatusRequestExtensionRequestExtension(
20552055
this.certificateStatusRequestExtensionRequestExtension = certificateStatusRequestExtensionRequestExtension;
20562056
}
20572057

2058-
public String getApplicationLayerProtocolNegotiationAnnouncedProtocols() {
2059-
return applicationLayerProtocolNegotiationAnnouncedProtocols;
2058+
public String[] getAlpnAnnouncedProtocols() {
2059+
return alpnAnnouncedProtocols;
20602060
}
20612061

2062-
public void setApplicationLayerProtocolNegotiationAnnouncedProtocols(
2063-
String applicationLayerProtocolNegotiationAnnouncedProtocols) {
2064-
this.applicationLayerProtocolNegotiationAnnouncedProtocols = applicationLayerProtocolNegotiationAnnouncedProtocols;
2062+
public void setAlpnAnnouncedProtocols(String[] alpnAnnouncedProtocols) {
2063+
this.alpnAnnouncedProtocols = alpnAnnouncedProtocols;
20652064
}
20662065

20672066
public byte[] getSessionId() {

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/constants/ExtensionByteLength.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ public class ExtensionByteLength {
113113
*/
114114
public static final int ALPN_EXTENSION_LENGTH = 2;
115115

116+
public static final int ALPN_ENTRY_LENGTH = 1;
117+
116118
/**
117119
* Length of the SRP extension identifier length field
118120
*/

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/message/ClientHelloMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public ClientHelloMessage(Config tlsConfig) {
155155
addExtension(new CertificateStatusRequestExtensionMessage());
156156
}
157157
if (tlsConfig.isAddAlpnExtension()) {
158-
addExtension(new AlpnExtensionMessage());
158+
addExtension(new AlpnExtensionMessage(tlsConfig));
159159
}
160160
if (tlsConfig.isAddSRPExtension()) {
161161
addExtension(new SRPExtensionMessage());

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/message/ServerHelloMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public ServerHelloMessage(Config tlsConfig) {
112112
addExtension(new CertificateStatusRequestExtensionMessage());
113113
}
114114
if (tlsConfig.isAddAlpnExtension()) {
115-
addExtension(new AlpnExtensionMessage());
115+
addExtension(new AlpnExtensionMessage(tlsConfig));
116116
}
117117
if (tlsConfig.isAddSRPExtension()) {
118118
addExtension(new SRPExtensionMessage());
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* TLS-Attacker - A Modular Penetration Testing Framework for TLS
3+
*
4+
* Copyright 2014-2017 Ruhr University Bochum / Hackmanit GmbH
5+
*
6+
* Licensed under Apache License 2.0
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
package de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn;
10+
11+
import de.rub.nds.modifiablevariable.ModifiableVariableFactory;
12+
import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray;
13+
import de.rub.nds.modifiablevariable.integer.ModifiableInteger;
14+
import de.rub.nds.tlsattacker.core.protocol.ModifiableVariableHolder;
15+
import java.io.Serializable;
16+
17+
/**
18+
*
19+
* @author Robert Merget <robert.merget@rub.de>
20+
*/
21+
public class AlpnEntry extends ModifiableVariableHolder implements Serializable {
22+
23+
private ModifiableInteger alpnEntryLength;
24+
25+
private ModifiableByteArray alpnEntryBytes;
26+
27+
private byte[] alpnEntryConfig;
28+
29+
public AlpnEntry() {
30+
}
31+
32+
public AlpnEntry(byte[] alpnEntryConfig) {
33+
this.alpnEntryConfig = alpnEntryConfig;
34+
}
35+
36+
public ModifiableInteger getAlpnEntryLength() {
37+
return alpnEntryLength;
38+
}
39+
40+
public void setAlpnEntryLength(ModifiableInteger alpnEntryLength) {
41+
this.alpnEntryLength = alpnEntryLength;
42+
}
43+
44+
public void setAlpnEntryLength(int alpnEntryLength) {
45+
this.alpnEntryLength = ModifiableVariableFactory.safelySetValue(this.alpnEntryLength, alpnEntryLength);
46+
}
47+
48+
public ModifiableByteArray getAlpnEntryBytes() {
49+
return alpnEntryBytes;
50+
}
51+
52+
public void setAlpnEntryBytes(ModifiableByteArray alpnEntryBytes) {
53+
this.alpnEntryBytes = alpnEntryBytes;
54+
}
55+
56+
public void setAlpnEntryBytes(byte[] alpnEntryBytes) {
57+
this.alpnEntryBytes = ModifiableVariableFactory.safelySetValue(this.alpnEntryBytes, alpnEntryBytes);
58+
}
59+
60+
public byte[] getAlpnEntryConfig() {
61+
return alpnEntryConfig;
62+
}
63+
64+
public void setAlpnEntryConfig(byte[] alpnEntryConfig) {
65+
this.alpnEntryConfig = alpnEntryConfig;
66+
}
67+
}

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/message/extension/AlpnExtensionMessage.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@
88
*/
99
package de.rub.nds.tlsattacker.core.protocol.message.extension;
1010

11+
import de.rub.nds.modifiablevariable.HoldsModifiableVariable;
1112
import de.rub.nds.modifiablevariable.ModifiableVariableFactory;
1213
import de.rub.nds.modifiablevariable.ModifiableVariableProperty;
1314
import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray;
1415
import de.rub.nds.modifiablevariable.integer.ModifiableInteger;
16+
import de.rub.nds.tlsattacker.core.config.Config;
1517
import de.rub.nds.tlsattacker.core.constants.ExtensionType;
18+
import de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn.AlpnEntry;
19+
import java.util.LinkedList;
20+
import java.util.List;
1621

1722
/**
1823
* This extension is defined in RFC7301
19-
*
24+
*
2025
* @author Matthias Terlinde <matthias.terlinde@rub.de>
2126
*/
2227
public class AlpnExtensionMessage extends ExtensionMessage {
@@ -26,8 +31,28 @@ public class AlpnExtensionMessage extends ExtensionMessage {
2631
@ModifiableVariableProperty
2732
private ModifiableByteArray alpnAnnouncedProtocols;
2833

34+
@HoldsModifiableVariable
35+
private List<AlpnEntry> alpnEntryList;
36+
2937
public AlpnExtensionMessage() {
3038
super(ExtensionType.ALPN);
39+
alpnEntryList = new LinkedList<>();
40+
}
41+
42+
public AlpnExtensionMessage(Config config) {
43+
super(ExtensionType.ALPN);
44+
alpnEntryList = new LinkedList<>();
45+
for (String string : config.getAlpnAnnouncedProtocols()) {
46+
alpnEntryList.add(new AlpnEntry(string.getBytes()));
47+
}
48+
}
49+
50+
public List<AlpnEntry> getAlpnEntryList() {
51+
return alpnEntryList;
52+
}
53+
54+
public void setAlpnEntryList(List<AlpnEntry> alpnEntryList) {
55+
this.alpnEntryList = alpnEntryList;
3156
}
3257

3358
public ModifiableInteger getAlpnExtensionLength() {

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/parser/extension/AlpnExtensionParser.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
package de.rub.nds.tlsattacker.core.protocol.parser.extension;
1010

1111
import de.rub.nds.tlsattacker.core.constants.ExtensionByteLength;
12+
import de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn.AlpnEntry;
1213
import de.rub.nds.tlsattacker.core.protocol.message.extension.AlpnExtensionMessage;
14+
import de.rub.nds.tlsattacker.core.protocol.parser.extension.alpn.AlpnEntryParser;
15+
import java.util.LinkedList;
16+
import java.util.List;
1317

1418
/**
1519
*
@@ -24,7 +28,16 @@ public AlpnExtensionParser(int startposition, byte[] array) {
2428
@Override
2529
public void parseExtensionMessageContent(AlpnExtensionMessage msg) {
2630
msg.setAlpnExtensionLength(parseIntField(ExtensionByteLength.ALPN_EXTENSION_LENGTH));
27-
msg.setAlpnAnnouncedProtocols(parseByteArrayField(msg.getAlpnExtensionLength().getValue()));
31+
byte[] anouncedProtocols = parseByteArrayField(msg.getAlpnExtensionLength().getValue());
32+
msg.setAlpnAnnouncedProtocols(anouncedProtocols);
33+
List<AlpnEntry> entryList = new LinkedList<>();
34+
int pointer = 0;
35+
while (pointer < anouncedProtocols.length) {
36+
AlpnEntryParser parser = new AlpnEntryParser(pointer, anouncedProtocols);
37+
entryList.add(parser.parse());
38+
pointer = parser.getPointer();
39+
}
40+
msg.setAlpnEntryList(entryList);
2841
}
2942

3043
@Override
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* TLS-Attacker - A Modular Penetration Testing Framework for TLS
3+
*
4+
* Copyright 2014-2017 Ruhr University Bochum / Hackmanit GmbH
5+
*
6+
* Licensed under Apache License 2.0
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
package de.rub.nds.tlsattacker.core.protocol.parser.extension.alpn;
10+
11+
import de.rub.nds.tlsattacker.core.constants.ExtensionByteLength;
12+
import de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn.AlpnEntry;
13+
import de.rub.nds.tlsattacker.core.protocol.parser.Parser;
14+
15+
/**
16+
*
17+
* @author Robert Merget <robert.merget@rub.de>
18+
*/
19+
public class AlpnEntryParser extends Parser<AlpnEntry> {
20+
21+
public AlpnEntryParser(int startposition, byte[] array) {
22+
super(startposition, array);
23+
}
24+
25+
@Override
26+
public AlpnEntry parse() {
27+
AlpnEntry entry = new AlpnEntry();
28+
entry.setAlpnEntryLength(parseIntField(ExtensionByteLength.ALPN_ENTRY_LENGTH));
29+
entry.setAlpnEntryBytes(parseByteArrayField(entry.getAlpnEntryLength().getValue()));
30+
return entry;
31+
}
32+
33+
}

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/preparator/extension/AlpnExtensionPreparator.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
package de.rub.nds.tlsattacker.core.protocol.preparator.extension;
1010

1111
import de.rub.nds.modifiablevariable.util.ArrayConverter;
12+
import de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn.AlpnEntry;
1213
import de.rub.nds.tlsattacker.core.protocol.message.extension.AlpnExtensionMessage;
14+
import de.rub.nds.tlsattacker.core.protocol.preparator.extension.alpn.AlpnEntryPreparator;
1315
import de.rub.nds.tlsattacker.core.protocol.serializer.extension.ExtensionSerializer;
16+
import de.rub.nds.tlsattacker.core.protocol.serializer.extension.alpn.AlpnEntrySerializer;
1417
import de.rub.nds.tlsattacker.core.workflow.chooser.Chooser;
18+
import java.io.ByteArrayOutputStream;
19+
import java.io.IOException;
1520

1621
/**
1722
*
@@ -29,8 +34,18 @@ public AlpnExtensionPreparator(Chooser chooser, AlpnExtensionMessage message,
2934

3035
@Override
3136
public void prepareExtensionContent() {
32-
msg.setAlpnAnnouncedProtocols(chooser.getConfig().getApplicationLayerProtocolNegotiationAnnouncedProtocols()
33-
.getBytes());
37+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
38+
for (AlpnEntry entry : msg.getAlpnEntryList()) {
39+
AlpnEntryPreparator preparator = new AlpnEntryPreparator(chooser, entry);
40+
preparator.prepare();
41+
AlpnEntrySerializer serializer = new AlpnEntrySerializer(entry);
42+
try {
43+
stream.write(serializer.serialize());
44+
} catch (IOException ex) {
45+
LOGGER.warn("Could not serialize AlpnEntry");
46+
}
47+
}
48+
msg.setAlpnAnnouncedProtocols(stream.toByteArray());
3449
LOGGER.debug("Prepared the ALPN Extension with announced protocols "
3550
+ ArrayConverter.bytesToHexString(msg.getAlpnAnnouncedProtocols()));
3651
msg.setAlpnExtensionLength(msg.getAlpnAnnouncedProtocols().getValue().length);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* TLS-Attacker - A Modular Penetration Testing Framework for TLS
3+
*
4+
* Copyright 2014-2017 Ruhr University Bochum / Hackmanit GmbH
5+
*
6+
* Licensed under Apache License 2.0
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
package de.rub.nds.tlsattacker.core.protocol.preparator.extension.alpn;
10+
11+
import de.rub.nds.tlsattacker.core.protocol.message.extension.Alpn.AlpnEntry;
12+
import de.rub.nds.tlsattacker.core.protocol.preparator.Preparator;
13+
import de.rub.nds.tlsattacker.core.workflow.chooser.Chooser;
14+
15+
/**
16+
*
17+
* @author Robert Merget <robert.merget@rub.de>
18+
*/
19+
public class AlpnEntryPreparator extends Preparator<AlpnEntry> {
20+
21+
private final AlpnEntry entry;
22+
23+
public AlpnEntryPreparator(Chooser chooser, AlpnEntry entry) {
24+
super(chooser, entry);
25+
this.entry = entry;
26+
}
27+
28+
@Override
29+
public void prepare() {
30+
entry.setAlpnEntryBytes(entry.getAlpnEntryConfig());
31+
entry.setAlpnEntryLength(entry.getAlpnEntryBytes().getValue().length);
32+
}
33+
34+
}

0 commit comments

Comments
 (0)