You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2020/05/30 06:18:55 UTC
[incubator-tuweni] 01/07: Fix RLPx connection with pad
This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
commit a8854bcb2ddca31bc3034a761a8184f556d30ef4
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Fri May 29 22:48:19 2020 -0700
Fix RLPx connection with pad
---
.../org/apache/tuweni/rlpx/RLPxConnection.java | 86 ++++++++++++----------
1 file changed, 49 insertions(+), 37 deletions(-)
diff --git a/rlpx/src/main/java/org/apache/tuweni/rlpx/RLPxConnection.java b/rlpx/src/main/java/org/apache/tuweni/rlpx/RLPxConnection.java
index 94b88d6..6594966 100644
--- a/rlpx/src/main/java/org/apache/tuweni/rlpx/RLPxConnection.java
+++ b/rlpx/src/main/java/org/apache/tuweni/rlpx/RLPxConnection.java
@@ -29,6 +29,8 @@ import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.SICBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xerial.snappy.Snappy;
/**
@@ -41,11 +43,13 @@ import org.xerial.snappy.Snappy;
*/
public final class RLPxConnection {
+ private final static Logger logger = LoggerFactory.getLogger(RLPxConnection.class);
+
/**
* Checks if two RLPx connections represent both ends of a connection.
* <p>
* Used for testing.
- *
+ *
* @param one one RLPx connection
* @param other an other RLPx connection
* @return true if both connections refer to the same peers, on each side of the connection
@@ -72,9 +76,12 @@ public final class RLPxConnection {
private final SECP256K1.PublicKey publicKey;
private final SECP256K1.PublicKey peerPublicKey;
private final AESEngine macEncryptionEngine;
+ private final SICBlockCipher decryptionCipher;
+ private final SICBlockCipher encryptionCipher;
private boolean applySnappyCompression = false;
private Bytes buffer = Bytes.EMPTY;
+ private Integer lastFrameSize;
RLPxConnection(
Bytes32 aesSecret,
@@ -96,6 +103,17 @@ public final class RLPxConnection {
updateIngress(ingressMac);
this.publicKey = publicKey;
this.peerPublicKey = peerPublicKey;
+
+ KeyParameter aesKey = new KeyParameter(aesSecret.toArrayUnsafe());
+
+ byte[] IV = new byte[16];
+ Arrays.fill(IV, (byte) 0);
+
+ decryptionCipher = new SICBlockCipher(new AESEngine());
+ decryptionCipher.init(false, new ParametersWithIV(aesKey, IV));
+
+ encryptionCipher = new SICBlockCipher(new AESEngine());
+ encryptionCipher.init(true, new ParametersWithIV(aesKey, IV));
}
/**
@@ -119,12 +137,14 @@ public final class RLPxConnection {
}
public synchronized void stream(Bytes newBytes, Consumer<RLPxMessage> messageConsumer) {
+ logger.debug("Adding new bytes to buffer {}", newBytes);
buffer = Bytes.concatenate(buffer, newBytes);
RLPxMessage message = null;
do {
message = readFrame(buffer);
if (message != null) {
buffer = buffer.slice(message.bytesLength());
+ logger.debug("Read message of type {}", message.messageId());
messageConsumer.accept(message);
}
} while (buffer.size() != 0 && message != null);
@@ -134,41 +154,40 @@ public final class RLPxConnection {
if (messageFrame.size() < 32) {
return null;
}
-
- KeyParameter aesKey = new KeyParameter(aesSecret.toArrayUnsafe());
-
- byte[] IV = new byte[16];
- Arrays.fill(IV, (byte) 0);
-
- SICBlockCipher decryptionCipher = new SICBlockCipher(new AESEngine());
- decryptionCipher.init(false, new ParametersWithIV(aesKey, IV));
-
- Bytes macBytes = messageFrame.slice(16, 16);
- Bytes headerBytes = messageFrame.slice(0, 16);
-
- Bytes decryptedHeader = Bytes.wrap(new byte[16]);
- decryptionCipher.processBytes(headerBytes.toArrayUnsafe(), 0, 16, decryptedHeader.toArrayUnsafe(), 0);
- int frameSize = decryptedHeader.get(0) & 0xff;
- frameSize = (frameSize << 8) + (decryptedHeader.get(1) & 0xff);
- frameSize = (frameSize << 8) + (decryptedHeader.get(2) & 0xff);
+ Integer frameSize = lastFrameSize;
+ if (frameSize == null) {
+
+ Bytes macBytes = messageFrame.slice(16, 16);
+ Bytes headerBytes = messageFrame.slice(0, 16);
+
+ Bytes decryptedHeader = Bytes.wrap(new byte[16]);
+ decryptionCipher.processBytes(headerBytes.toArrayUnsafe(), 0, 16, decryptedHeader.toArrayUnsafe(), 0);
+ frameSize = decryptedHeader.get(0) & 0xff;
+ frameSize = (frameSize << 8) + (decryptedHeader.get(1) & 0xff);
+ frameSize = (frameSize << 8) + (decryptedHeader.get(2) & 0xff);
+
+ Bytes expectedMac = calculateMac(headerBytes, true);
+
+ if (!macBytes.equals(expectedMac)) {
+ throw new InvalidMACException(
+ String
+ .format(
+ "Header MAC did not match expected MAC; expected: %s, received: %s",
+ expectedMac.toHexString(),
+ macBytes.toHexString()));
+ }
+ }
int pad = frameSize % 16 == 0 ? 0 : 16 - frameSize % 16;
-
if (messageFrame.size() < 32 + frameSize + pad + 16) {
+ lastFrameSize = frameSize;
return null;
+ } else {
+ lastFrameSize = null;
}
- Bytes expectedMac = calculateMac(headerBytes, true);
- if (!macBytes.equals(expectedMac)) {
- throw new InvalidMACException(
- String
- .format(
- "Header MAC did not match expected MAC; expected: %s, received: %s",
- expectedMac.toHexString(),
- macBytes.toHexString()));
- }
- Bytes frameData = messageFrame.slice(32, frameSize);
+ Bytes frameData = messageFrame.slice(32, frameSize + pad);
Bytes frameMac = messageFrame.slice(32 + frameSize + pad, 16);
Bytes newFrameMac = Bytes.wrap(new byte[16]);
@@ -190,7 +209,7 @@ public final class RLPxConnection {
int messageType = RLP.decodeInt(decryptedFrameData.slice(0, 1));
- Bytes messageData = decryptedFrameData.slice(1);
+ Bytes messageData = decryptedFrameData.slice(1, decryptedFrameData.size() - 1 - pad);
if (applySnappyCompression) {
try {
messageData = Bytes.wrap(Snappy.uncompress(messageData.toArrayUnsafe()));
@@ -209,13 +228,6 @@ public final class RLPxConnection {
* @return The framed message, as byte buffer.
*/
public Bytes write(RLPxMessage message) {
- KeyParameter aesKey = new KeyParameter(aesSecret.toArrayUnsafe());
-
- byte[] IV = new byte[16];
- Arrays.fill(IV, (byte) 0);
-
- SICBlockCipher encryptionCipher = new SICBlockCipher(new AESEngine());
- encryptionCipher.init(true, new ParametersWithIV(aesKey, IV));
// Compress message
Bytes messageData = message.content();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org