Compare commits
No commits in common. "b0bb4057f67ce470fb557276eead34dd4863c33b" and "dfa921fa4104abcdd2221eda7e351f40b19ab364" have entirely different histories.
b0bb4057f6
...
dfa921fa41
@ -1,23 +0,0 @@
|
|||||||
package com.captainalm.lib.calmnet.packet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface allows getting and setting if the
|
|
||||||
* internal cache should be used within a class instance.
|
|
||||||
*
|
|
||||||
* @author Captain ALM
|
|
||||||
*/
|
|
||||||
public interface IInternalCache {
|
|
||||||
/**
|
|
||||||
* Gets if the internal cache is used.
|
|
||||||
*
|
|
||||||
* @return If the internal cache is used.
|
|
||||||
*/
|
|
||||||
boolean isCacheUsed();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets if the internal cache is used.
|
|
||||||
*
|
|
||||||
* @param used If the internal cache is used.
|
|
||||||
*/
|
|
||||||
void setCacheUsed(boolean used);
|
|
||||||
}
|
|
@ -23,7 +23,7 @@ import static com.captainalm.lib.calmnet.packet.PacketLoader.readByteFromInputSt
|
|||||||
*
|
*
|
||||||
* @author Captain ALM
|
* @author Captain ALM
|
||||||
*/
|
*/
|
||||||
public class EncryptedPacket implements IStreamedPacket, IInternalCache {
|
public class EncryptedPacket implements IStreamedPacket {
|
||||||
/*
|
/*
|
||||||
* Packet Format:
|
* Packet Format:
|
||||||
*
|
*
|
||||||
@ -356,7 +356,10 @@ public class EncryptedPacket implements IStreamedPacket, IInternalCache {
|
|||||||
int flag = readByteFromInputStream(inputStream) & 0xff;
|
int flag = readByteFromInputStream(inputStream) & 0xff;
|
||||||
|
|
||||||
if (size < 5) throw new IOException("inputStream end of stream");
|
if (size < 5) throw new IOException("inputStream end of stream");
|
||||||
int cipherLenCache = PacketLoader.readInteger(inputStream);
|
int cipherLenCache = (readByteFromInputStream(inputStream) & 0xff) * 16777216;
|
||||||
|
cipherLenCache += (readByteFromInputStream(inputStream) & 0xff) * 65536;
|
||||||
|
cipherLenCache += (readByteFromInputStream(inputStream) & 0xff) * 256;
|
||||||
|
cipherLenCache += (readByteFromInputStream(inputStream) & 0xff);
|
||||||
if (cipherLenCache < 1) throw new PacketException("cipher length less than 1");
|
if (cipherLenCache < 1) throw new PacketException("cipher length less than 1");
|
||||||
|
|
||||||
if (size < 5 + cipherLenCache) throw new IOException("inputStream end of stream");
|
if (size < 5 + cipherLenCache) throw new IOException("inputStream end of stream");
|
||||||
@ -375,7 +378,10 @@ public class EncryptedPacket implements IStreamedPacket, IInternalCache {
|
|||||||
trailingArrayLengthCache = 0;
|
trailingArrayLengthCache = 0;
|
||||||
if ((flag & 1) == 1) {
|
if ((flag & 1) == 1) {
|
||||||
if (size < 9 + cipherLenCache) throw new IOException("inputStream end of stream");
|
if (size < 9 + cipherLenCache) throw new IOException("inputStream end of stream");
|
||||||
trailingArrayLengthCache = PacketLoader.readByteFromInputStream(inputStream);
|
trailingArrayLengthCache = (readByteFromInputStream(inputStream) & 0xff) * 16777216;
|
||||||
|
trailingArrayLengthCache += (readByteFromInputStream(inputStream) & 0xff) * 65536;
|
||||||
|
trailingArrayLengthCache += (readByteFromInputStream(inputStream) & 0xff) * 256;
|
||||||
|
trailingArrayLengthCache += (readByteFromInputStream(inputStream) & 0xff);
|
||||||
if (trailingArrayLengthCache < 1) throw new PacketException("trailer length less than 1");
|
if (trailingArrayLengthCache < 1) throw new PacketException("trailer length less than 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +538,6 @@ public class EncryptedPacket implements IStreamedPacket, IInternalCache {
|
|||||||
*
|
*
|
||||||
* @return If the encrypted data is cached.
|
* @return If the encrypted data is cached.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean isCacheUsed() {
|
public boolean isCacheUsed() {
|
||||||
return useCache;
|
return useCache;
|
||||||
}
|
}
|
||||||
@ -542,7 +547,6 @@ public class EncryptedPacket implements IStreamedPacket, IInternalCache {
|
|||||||
*
|
*
|
||||||
* @param used If the encrypted data should be cached.
|
* @param used If the encrypted data should be cached.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void setCacheUsed(boolean used) {
|
public void setCacheUsed(boolean used) {
|
||||||
synchronized (slock) {
|
synchronized (slock) {
|
||||||
useCache = used;
|
useCache = used;
|
||||||
|
@ -1,315 +0,0 @@
|
|||||||
package com.captainalm.lib.calmnet.packet.core;
|
|
||||||
|
|
||||||
import com.captainalm.lib.calmnet.packet.*;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides the ability for supporting streams to negotiate a cipher.
|
|
||||||
* <p>
|
|
||||||
* Major ID: 255
|
|
||||||
* Minor ID: 250
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Captain ALM
|
|
||||||
*/
|
|
||||||
public class NetworkEncryptionCipherPacket implements IStreamedPacket, IAcknowledgement, IInternalCache {
|
|
||||||
private static final PacketProtocolInformation protocol = new PacketProtocolInformation((byte) 255, (byte) 250);
|
|
||||||
|
|
||||||
protected Boolean acknowledgement;
|
|
||||||
protected String[] ciphers;
|
|
||||||
|
|
||||||
protected byte[] cipherData;
|
|
||||||
protected boolean useCache;
|
|
||||||
|
|
||||||
protected final Object slock = new Object();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance of NetworkEncryptionCipherPacket with the specified acknowledgement value and the specified ciphers.
|
|
||||||
*
|
|
||||||
* @param acknowledgement The acknowledgement value to use (Can be null).
|
|
||||||
* @param cipherNames The cipher names.
|
|
||||||
* @throws NullPointerException cipherNames is null.
|
|
||||||
*/
|
|
||||||
public NetworkEncryptionCipherPacket(Boolean acknowledgement, String[] cipherNames) {
|
|
||||||
if (cipherNames == null) throw new NullPointerException("cipherNames is null");
|
|
||||||
this.acknowledgement = acknowledgement;
|
|
||||||
this.ciphers = cipherNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if the class instance is an Acknowledgement.
|
|
||||||
*
|
|
||||||
* @return If the class instance is an Acknowledgement.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isAcknowledgement() {
|
|
||||||
return (acknowledgement != null && acknowledgement);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if the packet is valid.
|
|
||||||
*
|
|
||||||
* @return Is the packet valid?
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isValid() {
|
|
||||||
return (acknowledgement != null && ciphers != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the protocol information.
|
|
||||||
*
|
|
||||||
* @return The protocol information.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public PacketProtocolInformation getProtocol() {
|
|
||||||
return protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the protocol information statically.
|
|
||||||
*
|
|
||||||
* @return The protocol information.
|
|
||||||
*/
|
|
||||||
public static PacketProtocolInformation getTheProtocol() {
|
|
||||||
return protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void processCache() throws PacketException {
|
|
||||||
if (cipherData == null) {
|
|
||||||
if (acknowledgement == null || ciphers == null) throw new PacketException("no data");
|
|
||||||
|
|
||||||
ByteArrayOutputStream arrayData = new ByteArrayOutputStream();
|
|
||||||
arrayData.write((acknowledgement) ? (byte) 1 : (byte) 0);
|
|
||||||
try {
|
|
||||||
PacketLoader.writeInteger(arrayData, ciphers.length);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PacketException(e);
|
|
||||||
}
|
|
||||||
for (String c : ciphers) {
|
|
||||||
if (c == null) throw new PacketException("no data in entry");
|
|
||||||
try {
|
|
||||||
if (c.length() < 1) {
|
|
||||||
PacketLoader.writeInteger(arrayData, 0);
|
|
||||||
} else {
|
|
||||||
byte[] d = c.getBytes(StandardCharsets.UTF_8);
|
|
||||||
PacketLoader.writeInteger(arrayData, d.length);
|
|
||||||
arrayData.write(d);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PacketException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cipherData = arrayData.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the packet payload to a byte array.
|
|
||||||
*
|
|
||||||
* @return The packet payload data.
|
|
||||||
* @throws PacketException An Exception has occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public byte[] savePayload() throws PacketException {
|
|
||||||
synchronized (slock) {
|
|
||||||
processCache();
|
|
||||||
if (useCache) return cipherData; else {
|
|
||||||
byte[] toret = cipherData;
|
|
||||||
cipherData = null;
|
|
||||||
return toret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the packet payload from save data.
|
|
||||||
*
|
|
||||||
* @param packetData The packet payload data.
|
|
||||||
* @throws NullPointerException The new store data is null.
|
|
||||||
* @throws PacketException An Exception has occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void loadPayload(byte[] packetData) throws PacketException {
|
|
||||||
if (packetData == null) throw new NullPointerException("packetData is null");
|
|
||||||
if (packetData.length < 5) throw new PacketException("no data");
|
|
||||||
synchronized (slock) {
|
|
||||||
acknowledgement = (packetData[0] == 1);
|
|
||||||
if (!acknowledgement && packetData[0] != 0) acknowledgement = null;
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
int recordCount = (packetData[index++] & 0xff) * 16777216;
|
|
||||||
recordCount += (packetData[index++] & 0xff) * 65536;
|
|
||||||
recordCount += (packetData[index++] & 0xff) * 256;
|
|
||||||
recordCount += (packetData[index++] & 0xff);
|
|
||||||
if (recordCount < 0) throw new PacketException("record count less than 0");
|
|
||||||
|
|
||||||
if (useCache) cipherData = packetData;
|
|
||||||
ciphers = new String[recordCount];
|
|
||||||
for (int i = 0; i < recordCount; i++) {
|
|
||||||
int recordLength = (packetData[index++] & 0xff) * 16777216;
|
|
||||||
recordLength += (packetData[index++] & 0xff) * 65536;
|
|
||||||
recordLength += (packetData[index++] & 0xff) * 256;
|
|
||||||
recordLength += (packetData[index++] & 0xff);
|
|
||||||
if (recordLength < 0) throw new PacketException("record length less than 0");
|
|
||||||
byte[] currentRecord = new byte[recordLength];
|
|
||||||
if (recordLength > 0) {
|
|
||||||
System.arraycopy(packetData, index, currentRecord, 0, recordLength);
|
|
||||||
index += recordLength;
|
|
||||||
ciphers[i] = new String(currentRecord, StandardCharsets.UTF_8);
|
|
||||||
} else {
|
|
||||||
ciphers[i] = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads payload data to an {@link OutputStream}.
|
|
||||||
*
|
|
||||||
* @param outputStream The output stream to read data to.
|
|
||||||
* @throws NullPointerException outputStream is null.
|
|
||||||
* @throws IOException An IO Exception has occurred.
|
|
||||||
* @throws PacketException An Exception has occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void readData(OutputStream outputStream) throws IOException, PacketException {
|
|
||||||
if (outputStream == null) throw new NullPointerException("outputStream is null");
|
|
||||||
synchronized (slock) {
|
|
||||||
if (useCache) {
|
|
||||||
processCache();
|
|
||||||
outputStream.write(cipherData);
|
|
||||||
} else {
|
|
||||||
outputStream.write((acknowledgement) ? (byte) 1 : (byte) 0);
|
|
||||||
try {
|
|
||||||
PacketLoader.writeInteger(outputStream, ciphers.length);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PacketException(e);
|
|
||||||
}
|
|
||||||
for (String c : ciphers) {
|
|
||||||
if (c == null) throw new PacketException("no data in entry");
|
|
||||||
try {
|
|
||||||
if (c.length() < 1) {
|
|
||||||
PacketLoader.writeInteger(outputStream, 0);
|
|
||||||
} else {
|
|
||||||
byte[] d = c.getBytes(StandardCharsets.UTF_8);
|
|
||||||
PacketLoader.writeInteger(outputStream, d.length);
|
|
||||||
outputStream.write(d);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PacketException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes payload data from an {@link InputStream}.
|
|
||||||
*
|
|
||||||
* @param inputStream The input stream to write data from.
|
|
||||||
* @param size The size of the input payload in bytes.
|
|
||||||
* @throws NullPointerException inputStream is null.
|
|
||||||
* @throws IllegalArgumentException size is less than 0.
|
|
||||||
* @throws IOException An IO Exception has occurred.
|
|
||||||
* @throws PacketException An Exception has occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void writeData(InputStream inputStream, int size) throws IOException, PacketException {
|
|
||||||
if (inputStream == null) throw new NullPointerException("inputStream is null");
|
|
||||||
if (size < 0) throw new IllegalArgumentException("size is less than 0");
|
|
||||||
synchronized (slock) {
|
|
||||||
if (size < 1) throw new IOException("inputStream end of stream");
|
|
||||||
byte aknByte = PacketLoader.readByteFromInputStream(inputStream);
|
|
||||||
acknowledgement = (aknByte == 1);
|
|
||||||
if (!acknowledgement && aknByte != 0) acknowledgement = null;
|
|
||||||
if (size < 5) throw new IOException("inputStream end of stream");
|
|
||||||
|
|
||||||
int recordCount = PacketLoader.readInteger(inputStream);
|
|
||||||
if (recordCount < 0) throw new PacketException("record count less than 0");
|
|
||||||
|
|
||||||
cipherData = null;
|
|
||||||
ciphers = new String[recordCount];
|
|
||||||
for (int i = 0; i < recordCount; i++) {
|
|
||||||
int recordLength = PacketLoader.readInteger(inputStream);
|
|
||||||
if (recordLength < 0) throw new PacketException("record length less than 0");
|
|
||||||
if (recordLength > 0) {
|
|
||||||
byte[] currentRecord = PacketLoader.readArrayFromInputStream(inputStream, recordLength);
|
|
||||||
ciphers[i] = new String(currentRecord, StandardCharsets.UTF_8);
|
|
||||||
} else {
|
|
||||||
ciphers[i] = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the size of the output data.
|
|
||||||
*
|
|
||||||
* @return The size of the output data in bytes.
|
|
||||||
* @throws PacketException An Exception has occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getSize() throws PacketException {
|
|
||||||
synchronized (slock) {
|
|
||||||
processCache();
|
|
||||||
if (useCache) return cipherData.length; else {
|
|
||||||
int toret = cipherData.length;
|
|
||||||
cipherData = null;
|
|
||||||
return toret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the cipher names this packet contains.
|
|
||||||
*
|
|
||||||
* @return An array of cipher names.
|
|
||||||
*/
|
|
||||||
public String[] getCiphers() {
|
|
||||||
return ciphers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the cipher names this packet contains.
|
|
||||||
*
|
|
||||||
* @param cipherNames The array of cipher names.
|
|
||||||
* @throws NullPointerException cipherNames is null.
|
|
||||||
*/
|
|
||||||
public void setCiphers(String[] cipherNames) {
|
|
||||||
if (cipherNames == null) throw new NullPointerException("cipherNames is null");
|
|
||||||
synchronized (slock) {
|
|
||||||
ciphers = cipherNames;
|
|
||||||
cipherData = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if the cipher information is cached.
|
|
||||||
*
|
|
||||||
* @return If the cipher information is cached.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isCacheUsed() {
|
|
||||||
return useCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets if the cipher information is cached.
|
|
||||||
*
|
|
||||||
* @param used If the cipher information is cached.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setCacheUsed(boolean used) {
|
|
||||||
synchronized (slock) {
|
|
||||||
useCache = used;
|
|
||||||
if (!useCache)
|
|
||||||
cipherData = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,6 @@ public class NetworkEncryptionUpgradePacket implements IPacket, IAcknowledgement
|
|||||||
protected boolean upgrade;
|
protected boolean upgrade;
|
||||||
protected boolean base64ed;
|
protected boolean base64ed;
|
||||||
protected ICipherFactory cipherFactory;
|
protected ICipherFactory cipherFactory;
|
||||||
protected boolean sendSecrets;
|
|
||||||
|
|
||||||
protected final Object slock = new Object();
|
protected final Object slock = new Object();
|
||||||
|
|
||||||
@ -83,7 +82,7 @@ public class NetworkEncryptionUpgradePacket implements IPacket, IAcknowledgement
|
|||||||
synchronized (slock) {
|
synchronized (slock) {
|
||||||
if (acknowledgement == null) throw new PacketException("no data");
|
if (acknowledgement == null) throw new PacketException("no data");
|
||||||
|
|
||||||
byte[] cipherBytes = (cipherFactory == null) ? null : (sendSecrets) ? cipherFactory.getSettings() : cipherFactory.getSettingsNoSecrets();
|
byte[] cipherBytes = (cipherFactory == null) ? null : cipherFactory.getSettings();
|
||||||
byte[] toret = new byte[2 + ((cipherBytes == null) ? 0 : cipherBytes.length)];
|
byte[] toret = new byte[2 + ((cipherBytes == null) ? 0 : cipherBytes.length)];
|
||||||
toret[0] = (acknowledgement) ? (byte) 1 : (byte) 0;
|
toret[0] = (acknowledgement) ? (byte) 1 : (byte) 0;
|
||||||
toret[1] = (byte) (((upgrade) ? 1 : 0) + ((base64ed) ? 2 : 0));
|
toret[1] = (byte) (((upgrade) ? 1 : 0) + ((base64ed) ? 2 : 0));
|
||||||
@ -197,24 +196,4 @@ public class NetworkEncryptionUpgradePacket implements IPacket, IAcknowledgement
|
|||||||
public boolean isAcknowledgement() {
|
public boolean isAcknowledgement() {
|
||||||
return (acknowledgement != null && acknowledgement);
|
return (acknowledgement != null && acknowledgement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if secrets are sent as part of cipher settings.
|
|
||||||
*
|
|
||||||
* @return If the secrets are part of the cipher settings.
|
|
||||||
*/
|
|
||||||
public boolean areSecretsSent() {
|
|
||||||
return sendSecrets;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets if secrets should be sent as part of cipher settings.
|
|
||||||
*
|
|
||||||
* @param sendSecrets If secrets are part of the cipher settings.
|
|
||||||
*/
|
|
||||||
public void setIfSecretsSent(boolean sendSecrets) {
|
|
||||||
synchronized (slock) {
|
|
||||||
this.sendSecrets = sendSecrets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,6 @@ public class CALMNETPacketFactory implements IPacketFactory {
|
|||||||
public IPacket getPacket(PacketProtocolInformation information) {
|
public IPacket getPacket(PacketProtocolInformation information) {
|
||||||
if (information == null) throw new NullPointerException("information is null");
|
if (information == null) throw new NullPointerException("information is null");
|
||||||
|
|
||||||
if (information.equals(NetworkEncryptionCipherPacket.getTheProtocol())) return new NetworkEncryptionCipherPacket(null, new String[0]);
|
|
||||||
if (information.equals(Base64Packet.getTheProtocol())) return new Base64Packet(factoryToUse, loaderToUse);
|
if (information.equals(Base64Packet.getTheProtocol())) return new Base64Packet(factoryToUse, loaderToUse);
|
||||||
if (information.equals(EncryptedPacket.getTheProtocol()) && cipherToUse != null) return new EncryptedPacket(factoryToUse, loaderToUse, cipherToUse);
|
if (information.equals(EncryptedPacket.getTheProtocol()) && cipherToUse != null) return new EncryptedPacket(factoryToUse, loaderToUse, cipherToUse);
|
||||||
if (information.equals(NetworkEncryptionUpgradePacket.getTheProtocol())) return new NetworkEncryptionUpgradePacket(null, false, false, cipherToUse);
|
if (information.equals(NetworkEncryptionUpgradePacket.getTheProtocol())) return new NetworkEncryptionUpgradePacket(null, false, false, cipherToUse);
|
||||||
|
Loading…
Reference in New Issue
Block a user