works now
This commit is contained in:
parent
a866740565
commit
4bc59831da
File diff suppressed because one or more lines are too long
|
@ -5,14 +5,14 @@ import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import me.ayunami2000.ayuncraft.java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import me.ayunami2000.ayuncraft.java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import me.ayunami2000.ayuncraft.java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
@ -21,8 +21,8 @@ import javax.crypto.BadPaddingException;
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.NoSuchPaddingException;
|
||||||
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import me.ayunami2000.ayuncraft.javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.bouncycastle.crypto.BufferedBlockCipher;
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
||||||
import org.bouncycastle.crypto.CipherKeyGenerator;
|
import org.bouncycastle.crypto.CipherKeyGenerator;
|
||||||
import org.bouncycastle.crypto.KeyGenerationParameters;
|
import org.bouncycastle.crypto.KeyGenerationParameters;
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
package net.lax1dude.eaglercraft;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import java.security.Key;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.src.*;
|
||||||
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
public class WebsocketNetworkManager implements INetworkManager {
|
||||||
|
private boolean isInputBeingDecrypted;
|
||||||
|
private boolean isOutputEncrypted;
|
||||||
|
private SecretKey sharedKeyForEncryption;
|
||||||
|
|
||||||
|
private final boolean logpackets=false;
|
||||||
|
|
||||||
|
private BufferedBlockCipher inputBufferedBlockCipher=null;
|
||||||
|
private BufferedBlockCipher outputBufferedBlockCipher=null;
|
||||||
|
|
||||||
|
private NetHandler netHandler;
|
||||||
|
|
||||||
|
public WebsocketNetworkManager(String uri, String eagler, NetHandler netHandler) throws IOException {
|
||||||
|
this.netHandler = netHandler;
|
||||||
|
this.sharedKeyForEncryption = null;
|
||||||
|
this.isInputBeingDecrypted = false;
|
||||||
|
this.isOutputEncrypted = false;
|
||||||
|
if(!EaglerAdapter.startConnection(uri)) {
|
||||||
|
throw new IOException("websocket to "+uri+" failed");
|
||||||
|
}
|
||||||
|
EaglerAdapter.setDebugVar("minecraftServer", uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetHandler(NetHandler netHandler) {
|
||||||
|
this.netHandler = netHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
public void addToSendQueue(Packet var1) {
|
||||||
|
try {
|
||||||
|
sendBuffer.reset();
|
||||||
|
|
||||||
|
DataOutputStream yee;
|
||||||
|
if(this.isOutputEncrypted&&!(var1 instanceof Packet252SharedKey)){
|
||||||
|
yee = this.encryptOuputStream();
|
||||||
|
}else{
|
||||||
|
yee = new DataOutputStream(sendBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && var1 instanceof Packet252SharedKey && !this.isOutputEncrypted)
|
||||||
|
{
|
||||||
|
this.sharedKeyForEncryption = ((Packet252SharedKey)var1).getSharedKey();
|
||||||
|
this.isOutputEncrypted=true;
|
||||||
|
//yee=this.encryptOuputStream(yee);
|
||||||
|
}
|
||||||
|
Packet.writePacket(var1, yee);
|
||||||
|
if(logpackets)System.out.println("SENDING: "+var1);
|
||||||
|
yee.flush();
|
||||||
|
EaglerAdapter.writePacket(sendBuffer.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void wakeThreads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ByteBufferDirectInputStream extends InputStream {
|
||||||
|
private ByteBuffer buf;
|
||||||
|
private ByteBufferDirectInputStream(ByteBuffer b) {
|
||||||
|
this.buf = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
return buf.remaining() > 0 ? ((int)buf.get() & 0xFF) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return buf.remaining();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuffer oldChunkBuffer = null;
|
||||||
|
private LinkedList<ByteBuffer> readChunks = new LinkedList();
|
||||||
|
|
||||||
|
private ByteBuffer oldDecryptedChunkBuffer = null;
|
||||||
|
private LinkedList<ByteBuffer> decryptedReadChunks = new LinkedList();
|
||||||
|
|
||||||
|
public void processReadPackets() {
|
||||||
|
readChunks.clear();
|
||||||
|
|
||||||
|
if(oldChunkBuffer != null) {
|
||||||
|
readChunks.add(oldChunkBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] packet;
|
||||||
|
while((packet = EaglerAdapter.readPacket()) != null) {
|
||||||
|
readChunks.add(ByteBuffer.wrap(packet));
|
||||||
|
}
|
||||||
|
if(!readChunks.isEmpty()) {
|
||||||
|
|
||||||
|
int cap = 0;
|
||||||
|
for(ByteBuffer b : readChunks) {
|
||||||
|
cap += b.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer stream = ByteBuffer.allocate(cap);
|
||||||
|
for(ByteBuffer b : readChunks) {
|
||||||
|
stream.put(b);
|
||||||
|
}
|
||||||
|
stream.flip();
|
||||||
|
|
||||||
|
if(this.isInputBeingDecrypted){
|
||||||
|
decryptedReadChunks.clear();
|
||||||
|
|
||||||
|
if (oldDecryptedChunkBuffer != null) {
|
||||||
|
decryptedReadChunks.add(oldDecryptedChunkBuffer);
|
||||||
|
oldDecryptedChunkBuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] block = new byte[/*2048*/32];
|
||||||
|
byte[] decryp = new byte[this.inputBufferedBlockCipher.getOutputSize(/*2048*/32)];
|
||||||
|
while (stream.remaining() >= /*2048*/32) {
|
||||||
|
stream.get(block);
|
||||||
|
int i = this.inputBufferedBlockCipher.processByte(block, 0, /*2048*/32, decryp, 0);
|
||||||
|
ByteBuffer chunk = ByteBuffer.allocate(i);
|
||||||
|
chunk.put(decryp, 0, i);
|
||||||
|
chunk.flip();
|
||||||
|
decryptedReadChunks.add(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
oldChunkBuffer = stream.remaining() > 0 ? stream.slice() : null;
|
||||||
|
|
||||||
|
int cap2 = 0;
|
||||||
|
for (ByteBuffer b : decryptedReadChunks) {
|
||||||
|
cap2 += b.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer decStream = ByteBuffer.allocate(cap2);
|
||||||
|
for (ByteBuffer b : decryptedReadChunks) {
|
||||||
|
decStream.put(b);
|
||||||
|
}
|
||||||
|
decStream.flip();
|
||||||
|
|
||||||
|
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(decStream));
|
||||||
|
while (decStream.hasRemaining()) {
|
||||||
|
decStream.mark();
|
||||||
|
try {
|
||||||
|
Packet pkt = Packet.readPacket(packetStream, false);
|
||||||
|
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
||||||
|
pkt.processPacket(this.netHandler);
|
||||||
|
} catch (EOFException e) {
|
||||||
|
decStream.reset();
|
||||||
|
break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
continue;
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
e2.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decStream.hasRemaining()) {
|
||||||
|
oldDecryptedChunkBuffer = decStream.slice();
|
||||||
|
} else {
|
||||||
|
oldDecryptedChunkBuffer = null;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(stream));
|
||||||
|
while (stream.hasRemaining()) {
|
||||||
|
stream.mark();
|
||||||
|
try {
|
||||||
|
Packet pkt = Packet.readPacket(packetStream, false);
|
||||||
|
boolean change=false;
|
||||||
|
if (pkt != null) {
|
||||||
|
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && pkt instanceof Packet252SharedKey && !this.isInputBeingDecrypted) {
|
||||||
|
packetStream = this.decryptInputStream(new ByteBufferDirectInputStream(stream));
|
||||||
|
change=true;
|
||||||
|
}
|
||||||
|
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
||||||
|
pkt.processPacket(this.netHandler);
|
||||||
|
if(change){
|
||||||
|
processReadPackets();
|
||||||
|
return;
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (EOFException e) {
|
||||||
|
stream.reset();
|
||||||
|
break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
continue;
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
e2.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream.hasRemaining()) {
|
||||||
|
oldChunkBuffer = stream.slice();
|
||||||
|
} else {
|
||||||
|
oldChunkBuffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void serverShutdown() {
|
||||||
|
if(EaglerAdapter.connectionOpen()) {
|
||||||
|
EaglerAdapter.endConnection();
|
||||||
|
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataInputStream decryptInputStream(ByteBufferDirectInputStream var1) throws IOException
|
||||||
|
{
|
||||||
|
this.isInputBeingDecrypted = true;
|
||||||
|
if(this.inputBufferedBlockCipher==null){
|
||||||
|
this.inputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(false, (Key) this.sharedKeyForEncryption);
|
||||||
|
}
|
||||||
|
return new DataInputStream(CryptManager.decryptInputStream(this.inputBufferedBlockCipher, var1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flushes the stream and replaces it with an encryptedOutputStream
|
||||||
|
*/
|
||||||
|
private DataOutputStream encryptOuputStream(DataOutputStream var0) throws IOException
|
||||||
|
{
|
||||||
|
var0.flush();
|
||||||
|
this.isOutputEncrypted = true;
|
||||||
|
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.sharedKeyForEncryption, var0), 5120);
|
||||||
|
return new DataOutputStream(var1);
|
||||||
|
}
|
||||||
|
private DataOutputStream encryptOuputStream() throws IOException
|
||||||
|
{
|
||||||
|
if(this.outputBufferedBlockCipher==null){
|
||||||
|
this.outputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(true, (Key) this.sharedKeyForEncryption);
|
||||||
|
}
|
||||||
|
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.outputBufferedBlockCipher, sendBuffer), 5120);
|
||||||
|
return new DataOutputStream(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int packetSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void networkShutdown(String var1, Object... var2) {
|
||||||
|
serverShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeConnections() {
|
||||||
|
if(EaglerAdapter.connectionOpen()) {
|
||||||
|
EaglerAdapter.endConnection();
|
||||||
|
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
src/lwjgl/java/net/minecraft/src/Packet252SharedKey.java
Normal file
89
src/lwjgl/java/net/minecraft/src/Packet252SharedKey.java
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
|
||||||
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
public class Packet252SharedKey extends Packet
|
||||||
|
{
|
||||||
|
private byte[] sharedSecret = new byte[0];
|
||||||
|
private byte[] verifyToken = new byte[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Secret AES key decrypted from sharedSecret via the server's private RSA key
|
||||||
|
*/
|
||||||
|
private SecretKey sharedKey;
|
||||||
|
|
||||||
|
public Packet252SharedKey() {}
|
||||||
|
|
||||||
|
public Packet252SharedKey(SecretKey par1SecretKey, PublicKey par2PublicKey, byte[] par3ArrayOfByte)
|
||||||
|
{
|
||||||
|
this.sharedKey = par1SecretKey;
|
||||||
|
this.sharedSecret = CryptManager.encryptData(par2PublicKey, par1SecretKey.getEncoded());
|
||||||
|
this.verifyToken = CryptManager.encryptData(par2PublicKey, par3ArrayOfByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Reads the raw packet data from the data stream.
|
||||||
|
*/
|
||||||
|
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
||||||
|
{
|
||||||
|
this.sharedSecret = readBytesFromStream(par1DataInputStream);
|
||||||
|
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Writes the raw packet data to the data stream.
|
||||||
|
*/
|
||||||
|
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
||||||
|
{
|
||||||
|
writeByteArray(par1DataOutputStream, this.sharedSecret);
|
||||||
|
writeByteArray(par1DataOutputStream, this.verifyToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passes this Packet on to the NetHandler for processing.
|
||||||
|
*/
|
||||||
|
public void processPacket(NetHandler par1NetHandler)
|
||||||
|
{
|
||||||
|
par1NetHandler.handleSharedKey(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Return the size of the packet (not counting the header).
|
||||||
|
*/
|
||||||
|
public int getPacketSize()
|
||||||
|
{
|
||||||
|
return 2 + this.sharedSecret.length + 2 + this.verifyToken.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return secretKey, decrypting it from the sharedSecret byte array if needed
|
||||||
|
*/
|
||||||
|
public SecretKey getSharedKey(PrivateKey par1PrivateKey)
|
||||||
|
{
|
||||||
|
return par1PrivateKey == null ? this.sharedKey : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the secret AES sharedKey (used by client only)
|
||||||
|
*/
|
||||||
|
public SecretKey getSharedKey()
|
||||||
|
{
|
||||||
|
return this.getSharedKey(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return verifyToken
|
||||||
|
*/
|
||||||
|
public byte[] getVerifyToken(PrivateKey par1PrivateKey)
|
||||||
|
{
|
||||||
|
return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData(par1PrivateKey, this.verifyToken);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
|
||||||
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
public class Packet253ServerAuthData extends Packet
|
||||||
|
{
|
||||||
|
private String serverId;
|
||||||
|
private PublicKey publicKey;
|
||||||
|
private byte[] verifyToken = new byte[0];
|
||||||
|
|
||||||
|
public Packet253ServerAuthData() {}
|
||||||
|
|
||||||
|
public Packet253ServerAuthData(String par1Str, PublicKey par2PublicKey, byte[] par3ArrayOfByte)
|
||||||
|
{
|
||||||
|
this.serverId = par1Str;
|
||||||
|
this.publicKey = par2PublicKey;
|
||||||
|
this.verifyToken = par3ArrayOfByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Reads the raw packet data from the data stream.
|
||||||
|
*/
|
||||||
|
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
||||||
|
{
|
||||||
|
this.serverId = readString(par1DataInputStream, 20);
|
||||||
|
this.publicKey = CryptManager.decodePublicKey(readBytesFromStream(par1DataInputStream));
|
||||||
|
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Writes the raw packet data to the data stream.
|
||||||
|
*/
|
||||||
|
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
||||||
|
{
|
||||||
|
writeString(this.serverId, par1DataOutputStream);
|
||||||
|
writeByteArray(par1DataOutputStream, this.publicKey.getEncoded());
|
||||||
|
writeByteArray(par1DataOutputStream, this.verifyToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passes this Packet on to the NetHandler for processing.
|
||||||
|
*/
|
||||||
|
public void processPacket(NetHandler par1NetHandler)
|
||||||
|
{
|
||||||
|
par1NetHandler.handleServerAuthData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Return the size of the packet (not counting the header).
|
||||||
|
*/
|
||||||
|
public int getPacketSize()
|
||||||
|
{
|
||||||
|
return 2 + this.serverId.length() * 2 + 2 + this.publicKey.getEncoded().length + 2 + this.verifyToken.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerId()
|
||||||
|
{
|
||||||
|
return this.serverId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicKey getPublicKey()
|
||||||
|
{
|
||||||
|
return this.publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getVerifyToken()
|
||||||
|
{
|
||||||
|
return this.verifyToken;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,78 +0,0 @@
|
||||||
package net.minecraft.src;
|
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.CryptManager;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.PubKey;
|
|
||||||
import me.ayunami2000.ayuncraft.java.security.PublicKey;
|
|
||||||
|
|
||||||
public class Packet253ServerAuthData extends Packet
|
|
||||||
{
|
|
||||||
private String serverId;
|
|
||||||
private PubKey publicKey;
|
|
||||||
private byte[] verifyToken = new byte[0];
|
|
||||||
|
|
||||||
public Packet253ServerAuthData() {}
|
|
||||||
|
|
||||||
public Packet253ServerAuthData(String par1Str, PubKey par2PublicKey, byte[] par3ArrayOfByte)
|
|
||||||
{
|
|
||||||
this.serverId = par1Str;
|
|
||||||
this.publicKey = par2PublicKey;
|
|
||||||
this.verifyToken = par3ArrayOfByte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract. Reads the raw packet data from the data stream.
|
|
||||||
*/
|
|
||||||
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
|
||||||
{
|
|
||||||
this.serverId = readString(par1DataInputStream, 20);
|
|
||||||
this.publicKey = CryptManager.decodePublicKey(readBytesFromStream(par1DataInputStream));
|
|
||||||
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract. Writes the raw packet data to the data stream.
|
|
||||||
*/
|
|
||||||
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
|
||||||
{
|
|
||||||
writeString(this.serverId, par1DataOutputStream);
|
|
||||||
writeByteArray(par1DataOutputStream, this.publicKey.getEncoded());
|
|
||||||
writeByteArray(par1DataOutputStream, this.verifyToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passes this Packet on to the NetHandler for processing.
|
|
||||||
*/
|
|
||||||
public void processPacket(NetHandler par1NetHandler)
|
|
||||||
{
|
|
||||||
par1NetHandler.handleServerAuthData(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract. Return the size of the packet (not counting the header).
|
|
||||||
*/
|
|
||||||
public int getPacketSize()
|
|
||||||
{
|
|
||||||
return 2 + this.serverId.length() * 2 + 2 + this.publicKey.getEncoded().length + 2 + this.verifyToken.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getServerId()
|
|
||||||
{
|
|
||||||
return this.serverId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PubKey getPublicKey()
|
|
||||||
{
|
|
||||||
return this.publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getVerifyToken()
|
|
||||||
{
|
|
||||||
return this.verifyToken;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.util.HexString;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerLength implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public int val;
|
|
||||||
|
|
||||||
public BerLength() {}
|
|
||||||
|
|
||||||
public static int encodeLength(OutputStream reverseOS, int length) throws IOException {
|
|
||||||
|
|
||||||
if (length <= 127) {
|
|
||||||
// this is the short form
|
|
||||||
reverseOS.write(length);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length <= 255) {
|
|
||||||
reverseOS.write(length);
|
|
||||||
reverseOS.write(0x81);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length <= 65535) {
|
|
||||||
reverseOS.write(length);
|
|
||||||
reverseOS.write(length >> 8);
|
|
||||||
reverseOS.write(0x82);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length <= 16777215) {
|
|
||||||
reverseOS.write(length);
|
|
||||||
reverseOS.write(length >> 8);
|
|
||||||
reverseOS.write(length >> 16);
|
|
||||||
reverseOS.write(0x83);
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int numLengthBytes = 1;
|
|
||||||
while (((int) (Math.pow(2, 8 * numLengthBytes) - 1)) < length) {
|
|
||||||
numLengthBytes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < numLengthBytes; i++) {
|
|
||||||
reverseOS.write(length >> (8 * i));
|
|
||||||
}
|
|
||||||
reverseOS.write(0x80 | numLengthBytes);
|
|
||||||
|
|
||||||
return 1 + numLengthBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int readEocByte(InputStream is) throws IOException {
|
|
||||||
int b = is.read();
|
|
||||||
if (b != 0) {
|
|
||||||
if (b == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
throw new IOException(
|
|
||||||
"Byte " + HexString.fromByte(b) + " does not match end of contents octet of zero.");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int readEocByte(InputStream is, OutputStream os) throws IOException {
|
|
||||||
int b = is.read();
|
|
||||||
if (b != 0) {
|
|
||||||
if (b == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
os.write(b);
|
|
||||||
throw new IOException(
|
|
||||||
"Byte " + HexString.fromByte(b) + " does not match end of contents octet of zero.");
|
|
||||||
}
|
|
||||||
os.write(b);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
|
|
||||||
val = is.read();
|
|
||||||
// check for short form
|
|
||||||
if (val < 128) {
|
|
||||||
if (val == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lengthLength = val & 0x7f;
|
|
||||||
// check for indefinite length
|
|
||||||
if (lengthLength == 0) {
|
|
||||||
val = -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthLength > 4) {
|
|
||||||
throw new IOException("Length is out of bounds: " + lengthLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = 0;
|
|
||||||
for (int i = 0; i < lengthLength; i++) {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
val |= nextByte << (8 * (lengthLength - i - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return lengthLength + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, OutputStream os) throws IOException {
|
|
||||||
|
|
||||||
val = is.read();
|
|
||||||
if (val == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
os.write(val);
|
|
||||||
|
|
||||||
// check for short form
|
|
||||||
if (val < 128) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lengthLength = val & 0x7f;
|
|
||||||
// check for indefinite length
|
|
||||||
if (lengthLength == 0) {
|
|
||||||
val = -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthLength > 4) {
|
|
||||||
throw new IOException("Length is out of bounds: " + lengthLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = 0;
|
|
||||||
for (int i = 0; i < lengthLength; i++) {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
os.write(nextByte);
|
|
||||||
val |= nextByte << (8 * (lengthLength - i - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return lengthLength + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the end of contents octets from the given input stream if this length object has the
|
|
||||||
* indefinite form.
|
|
||||||
*
|
|
||||||
* @param is the input stream
|
|
||||||
* @return the number of bytes read from the input stream
|
|
||||||
* @throws IOException if an error occurs while reading from the input stream
|
|
||||||
*/
|
|
||||||
public int readEocIfIndefinite(InputStream is) throws IOException {
|
|
||||||
if (val >= 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
readEocByte(is);
|
|
||||||
readEocByte(is);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,259 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.util.HexString;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerTag implements Serializable {
|
|
||||||
|
|
||||||
public static final int UNIVERSAL_CLASS = 0x00;
|
|
||||||
public static final int APPLICATION_CLASS = 0x40;
|
|
||||||
public static final int CONTEXT_CLASS = 0x80;
|
|
||||||
public static final int PRIVATE_CLASS = 0xc0;
|
|
||||||
public static final int PRIMITIVE = 0x00;
|
|
||||||
public static final int CONSTRUCTED = 0x20;
|
|
||||||
public static final int BOOLEAN_TAG = 1;
|
|
||||||
public static final int INTEGER_TAG = 2;
|
|
||||||
public static final int BIT_STRING_TAG = 3;
|
|
||||||
public static final int OCTET_STRING_TAG = 4;
|
|
||||||
public static final int NULL_TAG = 5;
|
|
||||||
public static final int OBJECT_IDENTIFIER_TAG = 6;
|
|
||||||
public static final int OBJECT_DESCRIPTOR_TAG = 7;
|
|
||||||
public static final int REAL_TAG = 9;
|
|
||||||
public static final int ENUMERATED_TAG = 10;
|
|
||||||
public static final int UTF8_STRING_TAG = 12;
|
|
||||||
public static final int TIME_TAG = 14;
|
|
||||||
public static final int SEQUENCE_TAG = 16;
|
|
||||||
public static final int SET_TAG = 17;
|
|
||||||
public static final int NUMERIC_STRING_TAG = 18;
|
|
||||||
public static final int PRINTABLE_STRING_TAG = 19;
|
|
||||||
public static final int TELETEX_STRING_TAG = 20;
|
|
||||||
public static final int VIDEOTEX_STRING_TAG = 21;
|
|
||||||
public static final int IA5_STRING_TAG = 22;
|
|
||||||
public static final int UTC_TIME_TAG = 23;
|
|
||||||
public static final int GENERALIZED_TIME_TAG = 24;
|
|
||||||
public static final int GRAPHIC_STRING_TAG = 25;
|
|
||||||
public static final int VISIBLE_STRING_TAG = 26;
|
|
||||||
public static final int GENERAL_STRING_TAG = 27;
|
|
||||||
public static final int UNIVERSAL_STRING_TAG = 28;
|
|
||||||
public static final int BMP_STRING_TAG = 30;
|
|
||||||
public static final int DATE_TAG = 31;
|
|
||||||
public static final int TIME_OF_DAY_TAG = 32;
|
|
||||||
public static final int DATE_TIME_TAG = 33;
|
|
||||||
public static final int DURATION_TAG = 34;
|
|
||||||
public static final BerTag SEQUENCE = new BerTag(UNIVERSAL_CLASS, CONSTRUCTED, SEQUENCE_TAG);
|
|
||||||
public static final BerTag SET = new BerTag(UNIVERSAL_CLASS, CONSTRUCTED, SET_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public byte[] tagBytes = null;
|
|
||||||
public int tagClass;
|
|
||||||
public int primitive;
|
|
||||||
public int tagNumber;
|
|
||||||
|
|
||||||
public BerTag(int identifierClass, int primitive, int tagNumber) {
|
|
||||||
this.tagClass = identifierClass;
|
|
||||||
this.primitive = primitive;
|
|
||||||
this.tagNumber = tagNumber;
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerTag() {}
|
|
||||||
|
|
||||||
private void code() {
|
|
||||||
if (tagNumber < 31) {
|
|
||||||
tagBytes = new byte[1];
|
|
||||||
tagBytes[0] = (byte) (tagClass | primitive | tagNumber);
|
|
||||||
} else {
|
|
||||||
int tagLength = 1;
|
|
||||||
while (tagNumber > (Math.pow(2, (7 * tagLength)) - 1)) {
|
|
||||||
tagLength++;
|
|
||||||
}
|
|
||||||
|
|
||||||
tagBytes = new byte[1 + tagLength];
|
|
||||||
tagBytes[0] = (byte) (tagClass | primitive | 31);
|
|
||||||
|
|
||||||
for (int j = 1; j <= (tagLength - 1); j++) {
|
|
||||||
tagBytes[j] = (byte) (((tagNumber >> (7 * (tagLength - j))) & 0xff) | 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
tagBytes[tagLength] = (byte) (tagNumber & 0x7f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
if (tagBytes == null) {
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
for (int i = (tagBytes.length - 1); i >= 0; i--) {
|
|
||||||
reverseOS.write(tagBytes[i]);
|
|
||||||
}
|
|
||||||
return tagBytes.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encodeForwards(OutputStream os) throws IOException {
|
|
||||||
if (tagBytes == null) {
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < tagBytes.length; i++) {
|
|
||||||
os.write(tagBytes[i]);
|
|
||||||
}
|
|
||||||
return tagBytes.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
|
|
||||||
tagClass = nextByte & 0xC0;
|
|
||||||
primitive = nextByte & 0x20;
|
|
||||||
tagNumber = nextByte & 0x1f;
|
|
||||||
|
|
||||||
int codeLength = 1;
|
|
||||||
|
|
||||||
if (tagNumber == 0x1f) {
|
|
||||||
tagNumber = 0;
|
|
||||||
int numTagBytes = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength++;
|
|
||||||
if (numTagBytes >= 6) {
|
|
||||||
throw new IOException("Tag is too large.");
|
|
||||||
}
|
|
||||||
tagNumber = tagNumber << 7;
|
|
||||||
tagNumber |= (nextByte & 0x7f);
|
|
||||||
numTagBytes++;
|
|
||||||
} while ((nextByte & 0x80) != 0);
|
|
||||||
}
|
|
||||||
tagBytes = null;
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, OutputStream os) throws IOException {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
os.write(nextByte);
|
|
||||||
|
|
||||||
tagClass = nextByte & 0xC0;
|
|
||||||
primitive = nextByte & 0x20;
|
|
||||||
tagNumber = nextByte & 0x1f;
|
|
||||||
|
|
||||||
int codeLength = 1;
|
|
||||||
|
|
||||||
if (tagNumber == 0x1f) {
|
|
||||||
tagNumber = 0;
|
|
||||||
int numTagBytes = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
os.write(nextByte);
|
|
||||||
|
|
||||||
codeLength++;
|
|
||||||
if (numTagBytes >= 6) {
|
|
||||||
throw new IOException("Tag is too large.");
|
|
||||||
}
|
|
||||||
tagNumber = tagNumber << 7;
|
|
||||||
tagNumber |= (nextByte & 0x7f);
|
|
||||||
numTagBytes++;
|
|
||||||
} while ((nextByte & 0x80) != 0);
|
|
||||||
}
|
|
||||||
tagBytes = null;
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes the Identifier from the ByteArrayInputStream and throws an Exception if it is not equal
|
|
||||||
* to itself. Returns the number of bytes read from the InputStream.
|
|
||||||
*
|
|
||||||
* @param is the input stream to read the identifier from.
|
|
||||||
* @return the length of the identifier read.
|
|
||||||
* @throws IOException if an exception occurs reading the identifier from the stream.
|
|
||||||
*/
|
|
||||||
public int decodeAndCheck(InputStream is) throws IOException {
|
|
||||||
if (tagBytes == null) {
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
for (byte identifierByte : tagBytes) {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextByte != (identifierByte & 0xff)) {
|
|
||||||
throw new IOException(
|
|
||||||
"Identifier does not match, expected: 0x"
|
|
||||||
+ HexString.fromByte(identifierByte)
|
|
||||||
+ ", received: 0x"
|
|
||||||
+ HexString.fromByte((byte) nextByte));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tagBytes.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(int identifierClass, int primitive, int tagNumber) {
|
|
||||||
return (this.tagNumber == tagNumber
|
|
||||||
&& this.tagClass == identifierClass
|
|
||||||
&& this.primitive == primitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (!(obj instanceof BerTag)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
BerTag berIdentifier = (BerTag) obj;
|
|
||||||
return (tagNumber == berIdentifier.tagNumber
|
|
||||||
&& tagClass == berIdentifier.tagClass
|
|
||||||
&& primitive == berIdentifier.primitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 17;
|
|
||||||
hash = hash * 31 + tagNumber;
|
|
||||||
hash = hash * 31 + tagClass;
|
|
||||||
hash = hash * 31 + primitive;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "identifier class: "
|
|
||||||
+ tagClass
|
|
||||||
+ ", primitive: "
|
|
||||||
+ primitive
|
|
||||||
+ ", tag number: "
|
|
||||||
+ tagNumber;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class DecodeUtil {
|
|
||||||
|
|
||||||
private DecodeUtil() {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int decodeUnknownComponent(InputStream is) throws IOException {
|
|
||||||
int byteCount = 0;
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
byteCount += length.decode(is);
|
|
||||||
int lengthVal = length.val;
|
|
||||||
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
if (lengthVal < 0) {
|
|
||||||
byteCount += berTag.decode(is);
|
|
||||||
while (!berTag.equals(0, 0, 0)) {
|
|
||||||
byteCount += decodeUnknownComponent(is);
|
|
||||||
byteCount += berTag.decode(is);
|
|
||||||
}
|
|
||||||
byteCount += BerLength.readEocByte(is);
|
|
||||||
return byteCount;
|
|
||||||
} else {
|
|
||||||
Util.readFullyAndDiscard(is, lengthVal);
|
|
||||||
return byteCount + lengthVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int decodeUnknownComponent(InputStream is, OutputStream os) throws IOException {
|
|
||||||
int byteCount = 0;
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
byteCount += length.decode(is, os);
|
|
||||||
int lengthVal = length.val;
|
|
||||||
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
if (lengthVal < 0) {
|
|
||||||
byteCount += berTag.decode(is, os);
|
|
||||||
while (!berTag.equals(0, 0, 0)) {
|
|
||||||
byteCount += decodeUnknownComponent(is, os);
|
|
||||||
byteCount += berTag.decode(is, os);
|
|
||||||
}
|
|
||||||
byteCount += BerLength.readEocByte(is, os);
|
|
||||||
return byteCount;
|
|
||||||
} else {
|
|
||||||
byte[] contentBytes = new byte[lengthVal];
|
|
||||||
Util.readFully(is, contentBytes);
|
|
||||||
os.write(contentBytes);
|
|
||||||
return byteCount + lengthVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber;
|
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public class ReverseByteArrayOutputStream extends OutputStream {
|
|
||||||
|
|
||||||
private final boolean automaticResize;
|
|
||||||
public byte[] buffer;
|
|
||||||
public int index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a <code>ReverseByteArrayOutputStream</code> with a byte array of size <code>bufferSize
|
|
||||||
* </code>. The buffer will not be resized automatically. Use {@link
|
|
||||||
* #ReverseByteArrayOutputStream(int, boolean)} instead if you want the buffer to be dynamically
|
|
||||||
* resized.
|
|
||||||
*
|
|
||||||
* @param bufferSize the size of the underlying buffer
|
|
||||||
*/
|
|
||||||
public ReverseByteArrayOutputStream(int bufferSize) {
|
|
||||||
this(new byte[bufferSize], bufferSize - 1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReverseByteArrayOutputStream(int bufferSize, boolean automaticResize) {
|
|
||||||
this(new byte[bufferSize], bufferSize - 1, automaticResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReverseByteArrayOutputStream(byte[] buffer) {
|
|
||||||
this(buffer, buffer.length - 1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReverseByteArrayOutputStream(byte[] buffer, int startingIndex) {
|
|
||||||
this(buffer, startingIndex, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReverseByteArrayOutputStream(byte[] buffer, int startingIndex, boolean automaticResize) {
|
|
||||||
if (buffer.length <= 0) {
|
|
||||||
throw new IllegalArgumentException("buffer size may not be <= 0");
|
|
||||||
}
|
|
||||||
this.buffer = buffer;
|
|
||||||
index = startingIndex;
|
|
||||||
this.automaticResize = automaticResize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(int arg0) {
|
|
||||||
write((byte) arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(byte arg0) {
|
|
||||||
try {
|
|
||||||
buffer[index] = arg0;
|
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
|
||||||
if (automaticResize) {
|
|
||||||
resize();
|
|
||||||
buffer[index] = arg0;
|
|
||||||
} else {
|
|
||||||
throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resize() {
|
|
||||||
byte[] newBuffer = new byte[buffer.length * 2];
|
|
||||||
System.arraycopy(
|
|
||||||
buffer, index + 1, newBuffer, buffer.length + index + 1, buffer.length - index - 1);
|
|
||||||
index += buffer.length;
|
|
||||||
buffer = newBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte[] byteArray) {
|
|
||||||
// check if there is enough space - resize otherwise
|
|
||||||
while (index + 1 - byteArray.length < 0) {
|
|
||||||
if (automaticResize) {
|
|
||||||
resize();
|
|
||||||
} else {
|
|
||||||
throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.arraycopy(byteArray, 0, buffer, index - byteArray.length + 1, byteArray.length);
|
|
||||||
index -= byteArray.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new array containing the subarray of the stream array that contains the coded
|
|
||||||
* content.
|
|
||||||
*
|
|
||||||
* @return a new array containing the subarray of the stream array
|
|
||||||
*/
|
|
||||||
public byte[] getArray() {
|
|
||||||
if (index == -1) {
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
int subBufferLength = buffer.length - index - 1;
|
|
||||||
byte[] subBuffer = new byte[subBufferLength];
|
|
||||||
System.arraycopy(buffer, index + 1, subBuffer, 0, subBufferLength);
|
|
||||||
return subBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ByteBuffer getByteBuffer() {
|
|
||||||
return ByteBuffer.wrap(buffer, index + 1, buffer.length - (index + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
index = buffer.length - 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.internal;
|
|
||||||
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public class Util {
|
|
||||||
|
|
||||||
public static void readFully(InputStream is, byte[] buffer) throws IOException {
|
|
||||||
readFully(is, buffer, 0, buffer.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void readFully(InputStream is, byte[] buffer, int off, int len) throws IOException {
|
|
||||||
while (len > 0) {
|
|
||||||
int bytesRead = is.read(buffer, off, len);
|
|
||||||
if (bytesRead == -1) {
|
|
||||||
throw new EOFException("End of input stream reached.");
|
|
||||||
}
|
|
||||||
len -= bytesRead;
|
|
||||||
off += bytesRead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void readFullyAndDiscard(InputStream is, int lengthVal) throws IOException {
|
|
||||||
readFully(is, new byte[lengthVal]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.DecodeUtil;
|
|
||||||
import com.beanit.asn1bean.util.HexString;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerAny implements Serializable, BerType {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public byte[] value;
|
|
||||||
|
|
||||||
public BerAny() {}
|
|
||||||
|
|
||||||
public BerAny(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
reverseOS.write(value);
|
|
||||||
return value.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
|
|
||||||
return decode(is, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, BerTag tag) throws IOException {
|
|
||||||
|
|
||||||
int byteCount = 0;
|
|
||||||
|
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
if (tag == null) {
|
|
||||||
tag = new BerTag();
|
|
||||||
byteCount = tag.decode(is, os);
|
|
||||||
} else {
|
|
||||||
tag.encode(os);
|
|
||||||
}
|
|
||||||
byteCount += DecodeUtil.decodeUnknownComponent(is, os);
|
|
||||||
value = os.toByteArray();
|
|
||||||
return byteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return HexString.fromBytes(value);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerBitString implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BIT_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public byte[] value = null;
|
|
||||||
public int numBits;
|
|
||||||
private byte[] code = null;
|
|
||||||
|
|
||||||
public BerBitString() {}
|
|
||||||
|
|
||||||
public BerBitString(byte[] value, int numBits) {
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
throw new NullPointerException("value cannot be null");
|
|
||||||
}
|
|
||||||
if (numBits < 0) {
|
|
||||||
throw new IllegalArgumentException("numBits cannot be negative.");
|
|
||||||
}
|
|
||||||
if (numBits > (value.length * 8)) {
|
|
||||||
throw new IllegalArgumentException("'value' is too short to hold all bits.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.value = value;
|
|
||||||
this.numBits = numBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerBitString(boolean[] value) {
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
throw new NullPointerException("value cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
numBits = value.length;
|
|
||||||
this.value = new byte[(numBits + 7) / 8];
|
|
||||||
for (int i = 0; i < numBits; i++) {
|
|
||||||
if (value[i]) {
|
|
||||||
this.value[i / 8] = (byte) (this.value[i / 8] | (1 << (7 - (i % 8))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerBitString(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean[] getValueAsBooleans() {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean[] booleans = new boolean[numBits];
|
|
||||||
for (int i = 0; i < numBits; i++) {
|
|
||||||
booleans[i] = ((value[i / 8] & (1 << (7 - (i % 8)))) > 0);
|
|
||||||
}
|
|
||||||
return booleans;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = (value.length - 1); i >= 0; i--) {
|
|
||||||
reverseOS.write(value[i]);
|
|
||||||
}
|
|
||||||
reverseOS.write(value.length * 8 - numBits);
|
|
||||||
|
|
||||||
int codeLength = value.length + 1;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
// could be encoded in primitiv and constructed mode
|
|
||||||
// only primitiv mode is implemented
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
value = new byte[length.val - 1];
|
|
||||||
|
|
||||||
int unusedBits = is.read();
|
|
||||||
if (unusedBits == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
if (unusedBits > 7) {
|
|
||||||
throw new IOException(
|
|
||||||
"Number of unused bits in bit string expected to be less than 8 but is: " + unusedBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
numBits = (value.length * 8) - unusedBits;
|
|
||||||
|
|
||||||
if (value.length > 0) {
|
|
||||||
Util.readFully(is, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += value.length + 1;
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (boolean bit : getValueAsBooleans()) {
|
|
||||||
if (bit) {
|
|
||||||
sb.append('1');
|
|
||||||
} else {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerBoolean implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BOOLEAN_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public boolean value;
|
|
||||||
private byte[] code = null;
|
|
||||||
|
|
||||||
public BerBoolean() {}
|
|
||||||
|
|
||||||
public BerBoolean(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerBoolean(boolean value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = 1;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
reverseOS.write(0xff);
|
|
||||||
} else {
|
|
||||||
reverseOS.write(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
if (length.val != 1) {
|
|
||||||
throw new IOException("Decoded length of BerBoolean is not correct");
|
|
||||||
}
|
|
||||||
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength++;
|
|
||||||
value = nextByte != 0;
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(os, false);
|
|
||||||
code = os.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "" + value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerDate extends BerTime {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerDate() {}
|
|
||||||
|
|
||||||
public BerDate(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerDate(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerDateTime extends BerTime {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TIME_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerDateTime() {}
|
|
||||||
|
|
||||||
public BerDateTime(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerDateTime(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerDuration extends BerTime {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DURATION_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerDuration() {}
|
|
||||||
|
|
||||||
public BerDuration(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerDuration(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,780 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
|
|
||||||
import com.beanit.asn1bean.ber.types.string.BerObjectDescriptor;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerEmbeddedPdv implements BerType, Serializable {
|
|
||||||
|
|
||||||
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 11);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private byte[] code = null;
|
|
||||||
private Identification identification = null;
|
|
||||||
private BerObjectDescriptor dataValueDescriptor = null;
|
|
||||||
private BerOctetString dataValue = null;
|
|
||||||
|
|
||||||
public BerEmbeddedPdv() {}
|
|
||||||
|
|
||||||
public BerEmbeddedPdv(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identification getIdentification() {
|
|
||||||
return identification;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdentification(Identification identification) {
|
|
||||||
this.identification = identification;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectDescriptor getDataValueDescriptor() {
|
|
||||||
return dataValueDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataValueDescriptor(BerObjectDescriptor dataValueDescriptor) {
|
|
||||||
this.dataValueDescriptor = dataValueDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerOctetString getDataValue() {
|
|
||||||
return dataValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataValue(BerOctetString dataValue) {
|
|
||||||
this.dataValue = dataValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
int sublength;
|
|
||||||
|
|
||||||
codeLength += dataValue.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 2
|
|
||||||
reverseOS.write(0x82);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
if (dataValueDescriptor != null) {
|
|
||||||
codeLength += dataValueDescriptor.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
|
|
||||||
reverseOS.write(0x81);
|
|
||||||
codeLength += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sublength = identification.encode(reverseOS);
|
|
||||||
codeLength += sublength;
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, sublength);
|
|
||||||
// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
|
|
||||||
reverseOS.write(0xA0);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
int tlByteCount = 0;
|
|
||||||
int vByteCount = 0;
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
tlByteCount += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
tlByteCount += length.decode(is);
|
|
||||||
int lengthVal = length.val;
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
|
|
||||||
vByteCount += length.decode(is);
|
|
||||||
identification = new Identification();
|
|
||||||
vByteCount += identification.decode(is, null);
|
|
||||||
vByteCount += length.readEocIfIndefinite(is);
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
|
|
||||||
dataValueDescriptor = new BerObjectDescriptor();
|
|
||||||
vByteCount += dataValueDescriptor.decode(is, false);
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
|
|
||||||
dataValue = new BerOctetString();
|
|
||||||
vByteCount += dataValue.decode(is, false);
|
|
||||||
if (lengthVal >= 0 && vByteCount == lengthVal) {
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthVal < 0) {
|
|
||||||
if (!berTag.equals(0, 0, 0)) {
|
|
||||||
throw new IOException("Decoded sequence has wrong end of contents octets");
|
|
||||||
}
|
|
||||||
vByteCount += BerLength.readEocByte(is);
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException(
|
|
||||||
"Unexpected end of sequence, length tag: " + lengthVal + ", bytes decoded: " + vByteCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(reverseOS, false);
|
|
||||||
code = reverseOS.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
appendAsString(sb, 0);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendAsString(StringBuilder sb, int indentLevel) {
|
|
||||||
|
|
||||||
sb.append("{");
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (identification != null) {
|
|
||||||
sb.append("identification: ");
|
|
||||||
identification.appendAsString(sb, indentLevel + 1);
|
|
||||||
} else {
|
|
||||||
sb.append("identification: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataValueDescriptor != null) {
|
|
||||||
sb.append(",\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
sb.append("dataValueDescriptor: ").append(dataValueDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(",\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (dataValue != null) {
|
|
||||||
sb.append("dataValue: ").append(dataValue);
|
|
||||||
} else {
|
|
||||||
sb.append("dataValue: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
sb.append("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Identification implements BerType, Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private byte[] code = null;
|
|
||||||
private Syntaxes syntaxes = null;
|
|
||||||
private BerObjectIdentifier syntax = null;
|
|
||||||
private BerInteger presentationContextId = null;
|
|
||||||
private ContextNegotiation contextNegotiation = null;
|
|
||||||
private BerObjectIdentifier transferSyntax = null;
|
|
||||||
private BerNull fixed = null;
|
|
||||||
|
|
||||||
public Identification() {}
|
|
||||||
|
|
||||||
public Identification(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Syntaxes getSyntaxes() {
|
|
||||||
return syntaxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSyntaxes(Syntaxes syntaxes) {
|
|
||||||
this.syntaxes = syntaxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier getSyntax() {
|
|
||||||
return syntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSyntax(BerObjectIdentifier syntax) {
|
|
||||||
this.syntax = syntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerInteger getPresentationContextId() {
|
|
||||||
return presentationContextId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPresentationContextId(BerInteger presentationContextId) {
|
|
||||||
this.presentationContextId = presentationContextId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContextNegotiation getContextNegotiation() {
|
|
||||||
return contextNegotiation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContextNegotiation(ContextNegotiation contextNegotiation) {
|
|
||||||
this.contextNegotiation = contextNegotiation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier getTransferSyntax() {
|
|
||||||
return transferSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
|
|
||||||
this.transferSyntax = transferSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerNull getFixed() {
|
|
||||||
return fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFixed(BerNull fixed) {
|
|
||||||
this.fixed = fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
if (fixed != null) {
|
|
||||||
codeLength += fixed.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 5
|
|
||||||
reverseOS.write(0x85);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transferSyntax != null) {
|
|
||||||
codeLength += transferSyntax.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 4
|
|
||||||
reverseOS.write(0x84);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contextNegotiation != null) {
|
|
||||||
codeLength += contextNegotiation.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
|
|
||||||
reverseOS.write(0xA3);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presentationContextId != null) {
|
|
||||||
codeLength += presentationContextId.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 2
|
|
||||||
reverseOS.write(0x82);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syntax != null) {
|
|
||||||
codeLength += syntax.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
|
|
||||||
reverseOS.write(0x81);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syntaxes != null) {
|
|
||||||
codeLength += syntaxes.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
|
|
||||||
reverseOS.write(0xA0);
|
|
||||||
codeLength += 1;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, BerTag berTag) throws IOException {
|
|
||||||
|
|
||||||
int tlvByteCount = 0;
|
|
||||||
boolean tagWasPassed = (berTag != null);
|
|
||||||
|
|
||||||
if (berTag == null) {
|
|
||||||
berTag = new BerTag();
|
|
||||||
tlvByteCount += berTag.decode(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
|
|
||||||
syntaxes = new Syntaxes();
|
|
||||||
tlvByteCount += syntaxes.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
|
|
||||||
syntax = new BerObjectIdentifier();
|
|
||||||
tlvByteCount += syntax.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
|
|
||||||
presentationContextId = new BerInteger();
|
|
||||||
tlvByteCount += presentationContextId.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
|
|
||||||
contextNegotiation = new ContextNegotiation();
|
|
||||||
tlvByteCount += contextNegotiation.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
|
|
||||||
transferSyntax = new BerObjectIdentifier();
|
|
||||||
tlvByteCount += transferSyntax.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
|
|
||||||
fixed = new BerNull();
|
|
||||||
tlvByteCount += fixed.decode(is, false);
|
|
||||||
return tlvByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tagWasPassed) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(reverseOS);
|
|
||||||
code = reverseOS.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
appendAsString(sb, 0);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendAsString(StringBuilder sb, int indentLevel) {
|
|
||||||
|
|
||||||
if (syntaxes != null) {
|
|
||||||
sb.append("syntaxes: ");
|
|
||||||
syntaxes.appendAsString(sb, indentLevel + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syntax != null) {
|
|
||||||
sb.append("syntax: ").append(syntax);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presentationContextId != null) {
|
|
||||||
sb.append("presentationContextId: ").append(presentationContextId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contextNegotiation != null) {
|
|
||||||
sb.append("contextNegotiation: ");
|
|
||||||
contextNegotiation.appendAsString(sb, indentLevel + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transferSyntax != null) {
|
|
||||||
sb.append("transferSyntax: ").append(transferSyntax);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixed != null) {
|
|
||||||
sb.append("fixed: ").append(fixed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("<none>");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Syntaxes implements BerType, Serializable {
|
|
||||||
|
|
||||||
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private byte[] code = null;
|
|
||||||
private BerObjectIdentifier abstract_ = null;
|
|
||||||
private BerObjectIdentifier transfer = null;
|
|
||||||
|
|
||||||
public Syntaxes() {}
|
|
||||||
|
|
||||||
public Syntaxes(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier getAbstract() {
|
|
||||||
return abstract_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAbstract(BerObjectIdentifier abstract_) {
|
|
||||||
this.abstract_ = abstract_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier getTransfer() {
|
|
||||||
return transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransfer(BerObjectIdentifier transfer) {
|
|
||||||
this.transfer = transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
codeLength += transfer.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
|
|
||||||
reverseOS.write(0x81);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
codeLength += abstract_.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 0
|
|
||||||
reverseOS.write(0x80);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
int tlByteCount = 0;
|
|
||||||
int vByteCount = 0;
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
tlByteCount += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
tlByteCount += length.decode(is);
|
|
||||||
int lengthVal = length.val;
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
|
|
||||||
abstract_ = new BerObjectIdentifier();
|
|
||||||
vByteCount += abstract_.decode(is, false);
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
|
|
||||||
transfer = new BerObjectIdentifier();
|
|
||||||
vByteCount += transfer.decode(is, false);
|
|
||||||
if (lengthVal >= 0 && vByteCount == lengthVal) {
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthVal < 0) {
|
|
||||||
if (!berTag.equals(0, 0, 0)) {
|
|
||||||
throw new IOException("Decoded sequence has wrong end of contents octets");
|
|
||||||
}
|
|
||||||
vByteCount += BerLength.readEocByte(is);
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException(
|
|
||||||
"Unexpected end of sequence, length tag: "
|
|
||||||
+ lengthVal
|
|
||||||
+ ", bytes decoded: "
|
|
||||||
+ vByteCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream reverseOS =
|
|
||||||
new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(reverseOS, false);
|
|
||||||
code = reverseOS.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
appendAsString(sb, 0);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendAsString(StringBuilder sb, int indentLevel) {
|
|
||||||
|
|
||||||
sb.append("{");
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (abstract_ != null) {
|
|
||||||
sb.append("abstract_: ").append(abstract_);
|
|
||||||
} else {
|
|
||||||
sb.append("abstract_: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(",\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (transfer != null) {
|
|
||||||
sb.append("transfer: ").append(transfer);
|
|
||||||
} else {
|
|
||||||
sb.append("transfer: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
sb.append("}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ContextNegotiation implements BerType, Serializable {
|
|
||||||
|
|
||||||
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private byte[] code = null;
|
|
||||||
private BerInteger presentationContextId = null;
|
|
||||||
private BerObjectIdentifier transferSyntax = null;
|
|
||||||
|
|
||||||
public ContextNegotiation() {}
|
|
||||||
|
|
||||||
public ContextNegotiation(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerInteger getPresentationContextId() {
|
|
||||||
return presentationContextId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPresentationContextId(BerInteger presentationContextId) {
|
|
||||||
this.presentationContextId = presentationContextId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier getTransferSyntax() {
|
|
||||||
return transferSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
|
|
||||||
this.transferSyntax = transferSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
codeLength += transferSyntax.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
|
|
||||||
reverseOS.write(0x81);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
codeLength += presentationContextId.encode(reverseOS, false);
|
|
||||||
// write tag: CONTEXT_CLASS, PRIMITIVE, 0
|
|
||||||
reverseOS.write(0x80);
|
|
||||||
codeLength += 1;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
int tlByteCount = 0;
|
|
||||||
int vByteCount = 0;
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
tlByteCount += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
tlByteCount += length.decode(is);
|
|
||||||
int lengthVal = length.val;
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
|
|
||||||
presentationContextId = new BerInteger();
|
|
||||||
vByteCount += presentationContextId.decode(is, false);
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
|
|
||||||
transferSyntax = new BerObjectIdentifier();
|
|
||||||
vByteCount += transferSyntax.decode(is, false);
|
|
||||||
if (lengthVal >= 0 && vByteCount == lengthVal) {
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
vByteCount += berTag.decode(is);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Tag does not match mandatory sequence component.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lengthVal < 0) {
|
|
||||||
if (!berTag.equals(0, 0, 0)) {
|
|
||||||
throw new IOException("Decoded sequence has wrong end of contents octets");
|
|
||||||
}
|
|
||||||
vByteCount += BerLength.readEocByte(is);
|
|
||||||
return tlByteCount + vByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException(
|
|
||||||
"Unexpected end of sequence, length tag: "
|
|
||||||
+ lengthVal
|
|
||||||
+ ", bytes decoded: "
|
|
||||||
+ vByteCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream reverseOS =
|
|
||||||
new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(reverseOS, false);
|
|
||||||
code = reverseOS.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
appendAsString(sb, 0);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendAsString(StringBuilder sb, int indentLevel) {
|
|
||||||
|
|
||||||
sb.append("{");
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (presentationContextId != null) {
|
|
||||||
sb.append("presentationContextId: ").append(presentationContextId);
|
|
||||||
} else {
|
|
||||||
sb.append("presentationContextId: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(",\n");
|
|
||||||
for (int i = 0; i < indentLevel + 1; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
if (transferSyntax != null) {
|
|
||||||
sb.append("transferSyntax: ").append(transferSyntax);
|
|
||||||
} else {
|
|
||||||
sb.append("transferSyntax: <empty-required-field>");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("\n");
|
|
||||||
for (int i = 0; i < indentLevel; i++) {
|
|
||||||
sb.append("\t");
|
|
||||||
}
|
|
||||||
sb.append("}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class BerEnum extends BerInteger {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.ENUMERATED_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerEnum() {}
|
|
||||||
|
|
||||||
public BerEnum(byte[] code) {
|
|
||||||
super(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerEnum(BigInteger val) {
|
|
||||||
this.value = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerEnum(long val) {
|
|
||||||
this.value = BigInteger.valueOf(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class BerGeneralizedTime extends BerVisibleString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERALIZED_TIME_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generalized time is one of the following (ITU-T X.680 08/2015): YYYYMMDDHH[MM[SS]][.fff]
|
|
||||||
* LocalTime YYYYMMDDHH[MM[SS]][.fff]Z UTC YYYYMMDDHH[MM[SS]][.fff]+-HH[MM] local time with time
|
|
||||||
* zone
|
|
||||||
*
|
|
||||||
* <p>Regexp: ^ (?<year>\\d{4}) YYYY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) HH (
|
|
||||||
* [MM[SS]] (?<minute>\\d{2}) MM (?<second>\\d{2})? [SS] )? ([.,](?<frac>\\d+))? [.fff] (or
|
|
||||||
* [,fff]) (?<timezone> "" or "Z" or "+-HH[MM]" Z | ( "+-HH[MM]" [+-] "+-" \\d{2}(?<tzmin>\\d{2})?
|
|
||||||
* HH[MM] ) )? $
|
|
||||||
*/
|
|
||||||
private static final String GENERALIZED_TIME_PATTERN =
|
|
||||||
"^(?<year>\\d{4})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})((?<minute>\\d{2})(?<second>\\d{2})?)?([.,](?<frac>\\d+))?(?<timezone>Z|([+-]\\d{2}(?<tzmin>\\d{2})?))?$";
|
|
||||||
|
|
||||||
private static final Pattern generalizedTimePattern = Pattern.compile(GENERALIZED_TIME_PATTERN);
|
|
||||||
|
|
||||||
public BerGeneralizedTime() {}
|
|
||||||
|
|
||||||
public BerGeneralizedTime(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerGeneralizedTime(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Calendar asCalendar() throws ParseException {
|
|
||||||
|
|
||||||
Matcher matcher = generalizedTimePattern.matcher(toString());
|
|
||||||
|
|
||||||
if (!matcher.find()) {
|
|
||||||
throw new ParseException("", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
String mg, mgf;
|
|
||||||
int year = Integer.parseInt(matcher.group("year"));
|
|
||||||
int month = Integer.parseInt(matcher.group("month"));
|
|
||||||
month -= 1; // java.util.Calendar's month goes from 0 to 11
|
|
||||||
int day = Integer.parseInt(matcher.group("day"));
|
|
||||||
int hour = Integer.parseInt(matcher.group("hour"));
|
|
||||||
|
|
||||||
mg = matcher.group("minute");
|
|
||||||
mgf = matcher.group("frac");
|
|
||||||
int minute = 0, second = 0, millisec = 0;
|
|
||||||
double frac = mgf == null ? 0 : Double.parseDouble("0." + mgf);
|
|
||||||
if (mg == null) {
|
|
||||||
// Missing minutes and seconds
|
|
||||||
if (mgf != null) {
|
|
||||||
// frac is a fraction of a hour
|
|
||||||
millisec = (int) Math.round(1000 * 60 * 60 * frac);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
minute = Integer.parseInt(mg);
|
|
||||||
mg = matcher.group("second");
|
|
||||||
if (mg == null) {
|
|
||||||
// Missing seconds
|
|
||||||
if (mgf != null) {
|
|
||||||
// frac is a fraction of a minute
|
|
||||||
millisec = (int) Math.round(1000 * 60 * frac);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
second = Integer.parseInt(mg);
|
|
||||||
if (mgf != null) {
|
|
||||||
// frac is a fraction of a second
|
|
||||||
millisec = (int) Math.round(1000 * frac);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mg = matcher.group("timezone");
|
|
||||||
String mgt = matcher.group("tzmin");
|
|
||||||
String timeZoneStr =
|
|
||||||
mg == null
|
|
||||||
? TimeZone.getDefault().getID()
|
|
||||||
: (mg.equals("Z") ? "UTC" : (mgt == null ? "GMT" + mg + "00" : "GMT" + mg));
|
|
||||||
TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
|
|
||||||
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.setLenient(true); // accept millisec greater than 999
|
|
||||||
calendar.set(year, month, day, hour, minute, second);
|
|
||||||
calendar.set(Calendar.MILLISECOND, millisec);
|
|
||||||
calendar.setTimeZone(timeZone);
|
|
||||||
|
|
||||||
return calendar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date asDate() throws ParseException {
|
|
||||||
return asCalendar().getTime();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class BerInteger implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.INTEGER_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public BigInteger value;
|
|
||||||
private byte[] code = null;
|
|
||||||
|
|
||||||
public BerInteger() {}
|
|
||||||
|
|
||||||
public BerInteger(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerInteger(BigInteger val) {
|
|
||||||
this.value = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerInteger(long val) {
|
|
||||||
this.value = BigInteger.valueOf(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] encoded = value.toByteArray();
|
|
||||||
int codeLength = encoded.length;
|
|
||||||
reverseOS.write(encoded);
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
if (length.val < 1) {
|
|
||||||
throw new IOException("Decoded length of BerInteger is not correct");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] byteCode = new byte[length.val];
|
|
||||||
Util.readFully(is, byteCode);
|
|
||||||
|
|
||||||
codeLength += length.val;
|
|
||||||
|
|
||||||
value = new BigInteger(byteCode);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(os, false);
|
|
||||||
code = os.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "" + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte byteValue() {
|
|
||||||
return value.byteValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public short shortValue() {
|
|
||||||
return value.shortValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int intValue() {
|
|
||||||
return value.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long longValue() {
|
|
||||||
return value.longValue();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerNull implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NULL_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerNull() {}
|
|
||||||
|
|
||||||
public BerNull(byte[] code) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = BerLength.encodeLength(reverseOS, 0);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
if (length.val != 0) {
|
|
||||||
throw new IOException("Decoded length of BerNull is not correct");
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ASN1_NULL";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class BerObjectIdentifier implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_IDENTIFIER_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public int[] value;
|
|
||||||
private byte[] code = null;
|
|
||||||
|
|
||||||
public BerObjectIdentifier() {}
|
|
||||||
|
|
||||||
public BerObjectIdentifier(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerObjectIdentifier(int[] value) {
|
|
||||||
if ((value.length < 2)
|
|
||||||
|| ((value[0] == 0 || value[0] == 1) && (value[1] > 39))
|
|
||||||
|| value[0] > 2) {
|
|
||||||
throw new IllegalArgumentException("invalid object identifier components");
|
|
||||||
}
|
|
||||||
for (int objectIdentifierComponent : value) {
|
|
||||||
if (objectIdentifierComponent < 0) {
|
|
||||||
throw new IllegalArgumentException("invalid object identifier components");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int firstSubidentifier = 40 * value[0] + value[1];
|
|
||||||
|
|
||||||
int subidentifier;
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
for (int i = (value.length - 1); i > 0; i--) {
|
|
||||||
|
|
||||||
if (i == 1) {
|
|
||||||
subidentifier = firstSubidentifier;
|
|
||||||
} else {
|
|
||||||
subidentifier = value[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get length of subidentifier
|
|
||||||
int subIDLength = 1;
|
|
||||||
while (subidentifier > (Math.pow(2, (7 * subIDLength)) - 1)) {
|
|
||||||
subIDLength++;
|
|
||||||
}
|
|
||||||
|
|
||||||
reverseOS.write(subidentifier & 0x7f);
|
|
||||||
|
|
||||||
for (int j = 1; j <= (subIDLength - 1); j++) {
|
|
||||||
reverseOS.write(((subidentifier >> (7 * j)) & 0xff) | 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += subIDLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
if (length.val == 0) {
|
|
||||||
value = new int[0];
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] byteCode = new byte[length.val];
|
|
||||||
Util.readFully(is, byteCode);
|
|
||||||
|
|
||||||
codeLength += length.val;
|
|
||||||
|
|
||||||
List<Integer> objectIdentifierComponentsList = new ArrayList<>();
|
|
||||||
|
|
||||||
int subIDEndIndex = 0;
|
|
||||||
while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
|
|
||||||
if (subIDEndIndex >= (length.val - 1)) {
|
|
||||||
throw new IOException("Invalid Object Identifier");
|
|
||||||
}
|
|
||||||
subIDEndIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int subidentifier = 0;
|
|
||||||
for (int i = 0; i <= subIDEndIndex; i++) {
|
|
||||||
subidentifier |= ((byteCode[i] & 0x7f) << ((subIDEndIndex - i) * 7));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subidentifier < 40) {
|
|
||||||
objectIdentifierComponentsList.add(0);
|
|
||||||
objectIdentifierComponentsList.add(subidentifier);
|
|
||||||
} else if (subidentifier < 80) {
|
|
||||||
objectIdentifierComponentsList.add(1);
|
|
||||||
objectIdentifierComponentsList.add(subidentifier - 40);
|
|
||||||
} else {
|
|
||||||
objectIdentifierComponentsList.add(2);
|
|
||||||
objectIdentifierComponentsList.add(subidentifier - 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
subIDEndIndex++;
|
|
||||||
|
|
||||||
while (subIDEndIndex < length.val) {
|
|
||||||
int subIDStartIndex = subIDEndIndex;
|
|
||||||
|
|
||||||
while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
|
|
||||||
if (subIDEndIndex == (length.val - 1)) {
|
|
||||||
throw new IOException("Invalid Object Identifier");
|
|
||||||
}
|
|
||||||
subIDEndIndex++;
|
|
||||||
}
|
|
||||||
subidentifier = 0;
|
|
||||||
for (int j = subIDStartIndex; j <= subIDEndIndex; j++) {
|
|
||||||
subidentifier |= ((byteCode[j] & 0x7f) << ((subIDEndIndex - j) * 7));
|
|
||||||
}
|
|
||||||
objectIdentifierComponentsList.add(subidentifier);
|
|
||||||
subIDEndIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = new int[objectIdentifierComponentsList.size()];
|
|
||||||
for (int i = 0; i < objectIdentifierComponentsList.size(); i++) {
|
|
||||||
value[i] = objectIdentifierComponentsList.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (value == null || value.length == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(Integer.toString(value[0]));
|
|
||||||
for (int i = 1; i < value.length; i++) {
|
|
||||||
sb.append(".").append(value[i]);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import com.beanit.asn1bean.util.HexString;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerOctetString implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OCTET_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public byte[] value;
|
|
||||||
|
|
||||||
public BerOctetString() {}
|
|
||||||
|
|
||||||
public BerOctetString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
reverseOS.write(value);
|
|
||||||
int codeLength = value.length;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
int nextByte = is.read();
|
|
||||||
switch (nextByte) {
|
|
||||||
case -1:
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
case 0x04:
|
|
||||||
return 1 + decodePrimitiveOctetString(is);
|
|
||||||
case 0x24:
|
|
||||||
return 1 + decodeConstructedOctetString(is);
|
|
||||||
default:
|
|
||||||
throw new IOException(
|
|
||||||
"Octet String identifier does not match, expected: 0x04 or 0x24, received: 0x"
|
|
||||||
+ HexString.fromByte((byte) nextByte));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return decodePrimitiveOctetString(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decodeConstructedOctetString(InputStream is) throws IOException {
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
int lengthLength = length.decode(is);
|
|
||||||
|
|
||||||
value = new byte[0];
|
|
||||||
int vLength = 0;
|
|
||||||
|
|
||||||
if (length.val < 0) {
|
|
||||||
BerTag berTag = new BerTag();
|
|
||||||
vLength += berTag.decode(is);
|
|
||||||
while (!berTag.equals(0, 0, 0)) {
|
|
||||||
BerOctetString subOctetString = new BerOctetString();
|
|
||||||
vLength += subOctetString.decode(is, false);
|
|
||||||
value = concatenate(value, subOctetString.value);
|
|
||||||
vLength += berTag.decode(is);
|
|
||||||
}
|
|
||||||
vLength += BerLength.readEocByte(is);
|
|
||||||
} else {
|
|
||||||
while (vLength < length.val) {
|
|
||||||
BerOctetString subOctetString = new BerOctetString();
|
|
||||||
vLength += subOctetString.decode(is);
|
|
||||||
value = concatenate(value, subOctetString.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lengthLength + vLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] concatenate(byte[] a, byte[] b) {
|
|
||||||
int aLen = a.length;
|
|
||||||
int bLen = b.length;
|
|
||||||
|
|
||||||
byte[] c = new byte[aLen + bLen];
|
|
||||||
System.arraycopy(a, 0, c, 0, aLen);
|
|
||||||
System.arraycopy(b, 0, c, aLen, bLen);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decodePrimitiveOctetString(InputStream is) throws IOException {
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
value = new byte[length.val];
|
|
||||||
|
|
||||||
if (length.val != 0) {
|
|
||||||
Util.readFully(is, value);
|
|
||||||
codeLength += length.val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return HexString.fromBytes(value);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,240 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class BerReal implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.REAL_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public double value;
|
|
||||||
private byte[] code = null;
|
|
||||||
|
|
||||||
public BerReal() {}
|
|
||||||
|
|
||||||
public BerReal(byte[] code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerReal(double value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
reverseOS.write(code);
|
|
||||||
if (withTag) {
|
|
||||||
return tag.encode(reverseOS) + code.length;
|
|
||||||
}
|
|
||||||
return code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeLength = encodeValue(reverseOS);
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int encodeValue(OutputStream reverseOS) throws IOException {
|
|
||||||
|
|
||||||
// explained in Annex C and Ch. 8.5 of X.690
|
|
||||||
|
|
||||||
// we use binary encoding, with base 2 and F==0
|
|
||||||
// F is only needed when encoding with base 8 or 16
|
|
||||||
|
|
||||||
long longBits = Double.doubleToLongBits(value);
|
|
||||||
|
|
||||||
boolean isNegative = (longBits & 0x8000000000000000L) == 0x8000000000000000L;
|
|
||||||
|
|
||||||
int exponent = ((int) (longBits >> 52)) & 0x7ff;
|
|
||||||
|
|
||||||
long mantissa = (longBits & 0x000fffffffffffffL) | 0x0010000000000000L;
|
|
||||||
|
|
||||||
if (exponent == 0x7ff) {
|
|
||||||
if (mantissa == 0x0010000000000000L) {
|
|
||||||
if (isNegative) {
|
|
||||||
// - infinity
|
|
||||||
reverseOS.write(0x41);
|
|
||||||
} else {
|
|
||||||
// + infinity
|
|
||||||
reverseOS.write(0x40);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
throw new IOException("NAN not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((exponent == 0 && mantissa == 0x0010000000000000L)) {
|
|
||||||
// zero
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// because IEEE double-precision format is (-1)^sign * 1.b51b50..b0 * 2^(e-1023) we need to
|
|
||||||
// subtract 1023 and 52
|
|
||||||
// from the exponent to get an exponent corresponding to an integer matissa as need here.
|
|
||||||
exponent -= 1075; // 1023 + 52 = 1075
|
|
||||||
|
|
||||||
// trailing zeros of the mantissa should be removed. Therefor find out how much the mantissa can
|
|
||||||
// be shifted and
|
|
||||||
// the exponent can be increased
|
|
||||||
int exponentIncr = 0;
|
|
||||||
while (((mantissa >> exponentIncr) & 0xff) == 0x00) {
|
|
||||||
exponentIncr += 8;
|
|
||||||
}
|
|
||||||
while (((mantissa >> exponentIncr) & 0x01) == 0x00) {
|
|
||||||
exponentIncr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
exponent += exponentIncr;
|
|
||||||
mantissa >>= exponentIncr;
|
|
||||||
|
|
||||||
int mantissaLength = (Long.SIZE - Long.numberOfLeadingZeros(mantissa) + 7) / 8;
|
|
||||||
|
|
||||||
for (int i = 0; i < mantissaLength; i++) {
|
|
||||||
reverseOS.write((int) (mantissa >> (8 * i)));
|
|
||||||
}
|
|
||||||
int codeLength = mantissaLength;
|
|
||||||
|
|
||||||
byte[] exponentBytes = BigInteger.valueOf(exponent).toByteArray();
|
|
||||||
reverseOS.write(exponentBytes);
|
|
||||||
codeLength += exponentBytes.length;
|
|
||||||
|
|
||||||
byte exponentFormat;
|
|
||||||
if (exponentBytes.length < 4) {
|
|
||||||
exponentFormat = (byte) (exponentBytes.length - 1);
|
|
||||||
} else {
|
|
||||||
reverseOS.write(exponentBytes.length);
|
|
||||||
codeLength++;
|
|
||||||
exponentFormat = 0x03;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNegative) {
|
|
||||||
reverseOS.write(0x80 | 0x40 | exponentFormat);
|
|
||||||
} else {
|
|
||||||
reverseOS.write(0x80 | exponentFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength++;
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
if (length.val == 0) {
|
|
||||||
value = 0;
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length.val == 1) {
|
|
||||||
int nextByte = is.read();
|
|
||||||
if (nextByte == -1) {
|
|
||||||
throw new EOFException("Unexpected end of input stream.");
|
|
||||||
}
|
|
||||||
if (nextByte == 0x40) {
|
|
||||||
value = Double.POSITIVE_INFINITY;
|
|
||||||
} else if (nextByte == 0x41) {
|
|
||||||
value = Double.NEGATIVE_INFINITY;
|
|
||||||
} else {
|
|
||||||
throw new IOException("invalid real encoding");
|
|
||||||
}
|
|
||||||
return codeLength + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] byteCode = new byte[length.val];
|
|
||||||
Util.readFully(is, byteCode);
|
|
||||||
|
|
||||||
if ((byteCode[0] & 0x80) != 0x80) {
|
|
||||||
throw new IOException("Only binary REAL encoding is supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += length.val;
|
|
||||||
int tempLength = 1;
|
|
||||||
|
|
||||||
int sign = 1;
|
|
||||||
if ((byteCode[0] & 0x40) == 0x40) {
|
|
||||||
sign = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int exponentLength = (byteCode[0] & 0x03) + 1;
|
|
||||||
if (exponentLength == 4) {
|
|
||||||
exponentLength = byteCode[1];
|
|
||||||
tempLength++;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempLength += exponentLength;
|
|
||||||
|
|
||||||
int exponent = 0;
|
|
||||||
for (int i = 0; i < exponentLength; i++) {
|
|
||||||
exponent |= byteCode[1 + i] << (8 * (exponentLength - i - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
long mantissa = 0;
|
|
||||||
for (int i = 0; i < length.val - tempLength; i++) {
|
|
||||||
mantissa |= (byteCode[i + tempLength] & 0xffL) << (8 * (length.val - tempLength - i - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
value = sign * mantissa * Math.pow(2, exponent);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeAndSave(int encodingSizeGuess) throws IOException {
|
|
||||||
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
|
|
||||||
encode(os, false);
|
|
||||||
code = os.getArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "" + value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerTime extends BerVisibleString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerTime() {}
|
|
||||||
|
|
||||||
public BerTime(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerTime(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerTimeOfDay extends BerTime {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_OF_DAY_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerTimeOfDay() {}
|
|
||||||
|
|
||||||
public BerTimeOfDay(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerTimeOfDay(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public interface BerType {
|
|
||||||
|
|
||||||
int encode(OutputStream reverseOS) throws IOException;
|
|
||||||
|
|
||||||
int decode(InputStream is) throws IOException;
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class BerUtcTime extends BerVisibleString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTC_TIME_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTC time is one of the following (ITU-T X.680 08/2015): YYMMDDhhmm[ss]Z YYMMDDhhmm[ss](+|-)hhmm
|
|
||||||
* Regexp: ^ (?<year>\\d{2}) YY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) hh
|
|
||||||
* (?<minute>\\d{2}) mm (?<second>\\d{2})? ss (?<timezone> Z | Z or (+|-)hhmm ( [+-]\\d{4}
|
|
||||||
* (+|-)hhmm ) ) $
|
|
||||||
*/
|
|
||||||
private static final String UTC_TIME_PATTERN =
|
|
||||||
"^(?<year>\\d{2})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})(?<minute>\\d{2})(?<second>\\d{2})?(?<timezone>Z|([+-]\\d{4}))$";
|
|
||||||
|
|
||||||
private static final Pattern utcTimePattern = Pattern.compile(UTC_TIME_PATTERN);
|
|
||||||
|
|
||||||
public BerUtcTime() {}
|
|
||||||
|
|
||||||
public BerUtcTime(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerUtcTime(String valueAsString) {
|
|
||||||
super(valueAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
Calendar asCalendar() throws ParseException {
|
|
||||||
|
|
||||||
Matcher matcher = utcTimePattern.matcher(toString());
|
|
||||||
|
|
||||||
if (!matcher.find()) throw new ParseException("", 0);
|
|
||||||
|
|
||||||
String mg;
|
|
||||||
int year = Integer.parseInt(matcher.group("year"));
|
|
||||||
int month = Integer.parseInt(matcher.group("month"));
|
|
||||||
month -= 1; // java.util.Calendar's month goes from 0 to 11
|
|
||||||
int day = Integer.parseInt(matcher.group("day"));
|
|
||||||
int hour = Integer.parseInt(matcher.group("hour"));
|
|
||||||
int minute = Integer.parseInt(matcher.group("minute"));
|
|
||||||
mg = matcher.group("second");
|
|
||||||
int second = mg == null ? 0 : Integer.parseInt(mg);
|
|
||||||
|
|
||||||
mg = matcher.group("timezone");
|
|
||||||
String timeZoneStr = mg.equals("Z") ? "UTC" : "GMT" + mg;
|
|
||||||
TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
|
|
||||||
|
|
||||||
Calendar calendar = Calendar.getInstance(timeZone);
|
|
||||||
|
|
||||||
// Add 2000 to the year
|
|
||||||
int century = (calendar.get(Calendar.YEAR) / 100) * 100;
|
|
||||||
year += century;
|
|
||||||
|
|
||||||
// noinspection MagicConstant
|
|
||||||
calendar.set(year, month, day, hour, minute, second);
|
|
||||||
calendar.set(Calendar.MILLISECOND, 0);
|
|
||||||
|
|
||||||
return calendar;
|
|
||||||
}
|
|
||||||
|
|
||||||
Date asDate() throws ParseException {
|
|
||||||
return asCalendar().getTime();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerBMPString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BMP_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerBMPString() {}
|
|
||||||
|
|
||||||
public BerBMPString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerGeneralString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERAL_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerGeneralString() {}
|
|
||||||
|
|
||||||
public BerGeneralString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerGraphicString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GRAPHIC_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerGraphicString() {}
|
|
||||||
|
|
||||||
public BerGraphicString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerIA5String extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.IA5_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerIA5String() {}
|
|
||||||
|
|
||||||
public BerIA5String(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerNumericString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NUMERIC_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerNumericString() {}
|
|
||||||
|
|
||||||
public BerNumericString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerObjectDescriptor extends BerGraphicString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_DESCRIPTOR_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerObjectDescriptor() {}
|
|
||||||
|
|
||||||
public BerObjectDescriptor(byte[] value) {
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength;
|
|
||||||
|
|
||||||
codeLength = super.encode(reverseOS, false);
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerPrintableString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.PRINTABLE_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerPrintableString() {}
|
|
||||||
|
|
||||||
public BerPrintableString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerTeletexString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TELETEX_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerTeletexString() {}
|
|
||||||
|
|
||||||
public BerTeletexString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
public class BerUTF8String extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTF8_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerUTF8String() {}
|
|
||||||
|
|
||||||
public BerUTF8String(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerUTF8String(String valueAsString) {
|
|
||||||
value = valueAsString.getBytes(StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerUniversalString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UNIVERSAL_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerUniversalString() {}
|
|
||||||
|
|
||||||
public BerUniversalString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class BerVideotexString extends BerOctetString {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VIDEOTEX_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BerVideotexString() {}
|
|
||||||
|
|
||||||
public BerVideotexString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = super.encode(reverseOS, false);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
codeLength += super.decode(is, false);
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 The ASN1bean Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.ber.types.string;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.beanit.asn1bean.ber.BerLength;
|
|
||||||
import com.beanit.asn1bean.ber.BerTag;
|
|
||||||
import com.beanit.asn1bean.ber.internal.Util;
|
|
||||||
import com.beanit.asn1bean.ber.types.BerType;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class BerVisibleString implements Serializable, BerType {
|
|
||||||
|
|
||||||
public static final BerTag tag =
|
|
||||||
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VISIBLE_STRING_TAG);
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
public byte[] value;
|
|
||||||
|
|
||||||
public BerVisibleString() {}
|
|
||||||
|
|
||||||
public BerVisibleString(byte[] value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BerVisibleString(String valueAsString) {
|
|
||||||
value = valueAsString.getBytes(UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int encode(OutputStream reverseOS) throws IOException {
|
|
||||||
return encode(reverseOS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
reverseOS.write(value);
|
|
||||||
int codeLength = value.length;
|
|
||||||
|
|
||||||
codeLength += BerLength.encodeLength(reverseOS, codeLength);
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.encode(reverseOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int decode(InputStream is) throws IOException {
|
|
||||||
return decode(is, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int decode(InputStream is, boolean withTag) throws IOException {
|
|
||||||
|
|
||||||
int codeLength = 0;
|
|
||||||
|
|
||||||
if (withTag) {
|
|
||||||
codeLength += tag.decodeAndCheck(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
BerLength length = new BerLength();
|
|
||||||
codeLength += length.decode(is);
|
|
||||||
|
|
||||||
value = new byte[length.val];
|
|
||||||
|
|
||||||
if (length.val != 0) {
|
|
||||||
Util.readFully(is, value);
|
|
||||||
codeLength += length.val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(value, UTF_8);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2019 beanit
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.beanit.asn1bean.util;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class HexString {
|
|
||||||
|
|
||||||
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
|
||||||
|
|
||||||
/** Don't let anyone instantiate this class. */
|
|
||||||
private HexString() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the byte as a hex string. If b is less than 16 the hex string returned contains a
|
|
||||||
* leading zero.
|
|
||||||
*
|
|
||||||
* @param b the byte to be converted
|
|
||||||
* @return the hex string.
|
|
||||||
*/
|
|
||||||
public static String fromByte(byte b) {
|
|
||||||
return fromBytes(new byte[] {b});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromByte(int b) {
|
|
||||||
return fromBytes(new byte[] {(byte) b});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the integer value as hex string filled with leading zeros.
|
|
||||||
*
|
|
||||||
* @param i the integer value to be converted
|
|
||||||
* @return the hex string
|
|
||||||
*/
|
|
||||||
public static String fromInt(int i) {
|
|
||||||
byte[] bytes = new byte[] {(byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) i};
|
|
||||||
return fromBytes(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the long value as hex string filled with leading zeros.
|
|
||||||
*
|
|
||||||
* @param l the long value to be converted
|
|
||||||
* @return the hex string
|
|
||||||
*/
|
|
||||||
public static String fromLong(long l) {
|
|
||||||
byte[] bytes =
|
|
||||||
new byte[] {
|
|
||||||
(byte) (l >> 56),
|
|
||||||
(byte) (l >> 48),
|
|
||||||
(byte) (l >> 40),
|
|
||||||
(byte) (l >> 32),
|
|
||||||
(byte) (l >> 24),
|
|
||||||
(byte) (l >> 16),
|
|
||||||
(byte) (l >> 8),
|
|
||||||
(byte) l
|
|
||||||
};
|
|
||||||
return fromBytes(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromBytes(byte[] bytes) {
|
|
||||||
return fromBytes(bytes, 0, bytes.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromBytesFormatted(byte[] bytes) {
|
|
||||||
return fromBytesFormatted(bytes, 0, bytes.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromBytes(byte[] bytes, int offset, int length) {
|
|
||||||
char[] hexChars = new char[length * 2];
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
int v = bytes[j + offset] & 0xff;
|
|
||||||
hexChars[j * 2] = hexArray[v >>> 4];
|
|
||||||
hexChars[j * 2 + 1] = hexArray[v & 0x0f];
|
|
||||||
}
|
|
||||||
return new String(hexChars);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromBytes(ByteBuffer buffer) {
|
|
||||||
return fromBytes(buffer.array(), buffer.arrayOffset(), buffer.arrayOffset() + buffer.limit());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromBytesFormatted(byte[] bytes, int offset, int length) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
int l = 1;
|
|
||||||
for (int i = offset; i < (offset + length); i++) {
|
|
||||||
if ((l != 1) && ((l - 1) % 8 == 0)) {
|
|
||||||
builder.append(' ');
|
|
||||||
}
|
|
||||||
if ((l != 1) && ((l - 1) % 16 == 0)) {
|
|
||||||
builder.append('\n');
|
|
||||||
}
|
|
||||||
l++;
|
|
||||||
appendFromByte(bytes[i], builder);
|
|
||||||
if (i != offset + length - 1) {
|
|
||||||
builder.append(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the given hex string to a byte array.
|
|
||||||
*
|
|
||||||
* @param hexString the hex string
|
|
||||||
* @return the bytes
|
|
||||||
* @throws NumberFormatException if the string is not a valid hex string
|
|
||||||
*/
|
|
||||||
public static byte[] toBytes(String hexString) {
|
|
||||||
|
|
||||||
Objects.requireNonNull(hexString);
|
|
||||||
if ((hexString.length() == 0) || ((hexString.length() % 2) != 0)) {
|
|
||||||
throw new NumberFormatException("argument is not a valid hex string");
|
|
||||||
}
|
|
||||||
|
|
||||||
int length = hexString.length();
|
|
||||||
|
|
||||||
byte[] data = new byte[length / 2];
|
|
||||||
for (int i = 0; i < length; i += 2) {
|
|
||||||
int firstCharacter = Character.digit(hexString.charAt(i), 16);
|
|
||||||
int secondCharacter = Character.digit(hexString.charAt(i + 1), 16);
|
|
||||||
|
|
||||||
if (firstCharacter == -1 || secondCharacter == -1) {
|
|
||||||
throw new NumberFormatException("argument is not a valid hex string");
|
|
||||||
}
|
|
||||||
|
|
||||||
data[i / 2] = (byte) ((firstCharacter << 4) + secondCharacter);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void appendFromByte(byte b, StringBuilder builder) {
|
|
||||||
builder.append(fromByte(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void appendFromBytes(StringBuilder builder, byte[] bytes, int offset, int length) {
|
|
||||||
builder.append(fromBytes(bytes, offset, length));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a description of interface RSABaseInterface here.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 06/01/2010
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface RSABaseInterface
|
|
||||||
{
|
|
||||||
byte PUBLIC_KEY = 1;
|
|
||||||
byte PRIVATE_KEY = 2;
|
|
||||||
byte COMPLETE_KEY = 3;
|
|
||||||
}
|
|
|
@ -1,209 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
/**
|
|
||||||
* Class representing full private and public RSA keys.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 05/31/2010
|
|
||||||
*/
|
|
||||||
public class RSACompleteKey extends RSAPrivateKey
|
|
||||||
{
|
|
||||||
/** The first CRT exponent. */
|
|
||||||
private BigInteger dP;
|
|
||||||
|
|
||||||
/** The second CRT exponent. */
|
|
||||||
private BigInteger dQ;
|
|
||||||
|
|
||||||
/** The public exponent. */
|
|
||||||
private BigInteger e;
|
|
||||||
|
|
||||||
/** The larger prime factor of the modulus. */
|
|
||||||
private BigInteger p;
|
|
||||||
|
|
||||||
/** The LCM of the primes. */
|
|
||||||
private BigInteger phi;
|
|
||||||
|
|
||||||
/** The smaller prime factor of the modulus. */
|
|
||||||
private BigInteger q;
|
|
||||||
|
|
||||||
/** The CRT coefficient. */
|
|
||||||
private BigInteger qInv;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Default constructor. */
|
|
||||||
public RSACompleteKey() {
|
|
||||||
super(null, null);
|
|
||||||
setPubExp(null);
|
|
||||||
setPrimes(null, null);
|
|
||||||
setCRTExpOne(null);
|
|
||||||
setCRTExpTwo(null);
|
|
||||||
setCRTCoeff(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main constructor. */
|
|
||||||
public RSACompleteKey(BigInteger prime1,
|
|
||||||
BigInteger prime2,
|
|
||||||
BigInteger modulus,
|
|
||||||
BigInteger pubExp,
|
|
||||||
BigInteger priExp,
|
|
||||||
BigInteger crtExp1,
|
|
||||||
BigInteger crtExp2,
|
|
||||||
BigInteger crtCoeff) {
|
|
||||||
super(modulus, priExp);
|
|
||||||
setPubExp(pubExp);
|
|
||||||
setPrimes(prime1, prime2);
|
|
||||||
setCRTExpOne(crtExp1);
|
|
||||||
setCRTExpTwo(crtExp2);
|
|
||||||
setCRTCoeff(crtCoeff);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Computes the LCM of the primes. */
|
|
||||||
protected void computePhi() {
|
|
||||||
phi = lcm(pMinusOne(), qMinusOne());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs the classical RSA computation. */
|
|
||||||
protected BigInteger decrypt(BigInteger c) {
|
|
||||||
BigInteger m1, m2, dm, h;
|
|
||||||
m1 = c.modPow(getCRTExpOne(), getPrimeOne());
|
|
||||||
m2 = c.modPow(getCRTExpTwo(), getPrimeTwo());
|
|
||||||
dm = m1.subtract(m2).abs();
|
|
||||||
h = getCRTCoeff().multiply(dm).mod(getPrimeOne());
|
|
||||||
return m2.add(getPrimeTwo().multiply(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the first CRT exponent. */
|
|
||||||
public BigInteger getCRTExpOne() {
|
|
||||||
return dP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the second CRT exponent. */
|
|
||||||
public BigInteger getCRTExpTwo() {
|
|
||||||
return dQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the CRT coefficient. */
|
|
||||||
public BigInteger getCRTCoeff() {
|
|
||||||
return qInv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns phi. */
|
|
||||||
public BigInteger getPhi() {
|
|
||||||
return phi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the larger prime factor. */
|
|
||||||
public BigInteger getPrimeOne() {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the smaller prime factor. */
|
|
||||||
public BigInteger getPrimeTwo() {
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the public exponent. */
|
|
||||||
public BigInteger getPubExp() {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true when key is valid. */
|
|
||||||
public boolean isValid() {
|
|
||||||
if (noValuesNull() && isPrime(p) && isPrime(q)) {
|
|
||||||
computePhi();
|
|
||||||
return p.multiply(q).equals(getModulus()) &&
|
|
||||||
e.compareTo(THREE) >= 0 &&
|
|
||||||
e.compareTo(getModulus()) < 0 &&
|
|
||||||
e.gcd(phi).equals(ONE) &&
|
|
||||||
getPriExp().compareTo(getModulus()) < 0 &&
|
|
||||||
getPriExp().equals(e.modInverse(phi)) &&
|
|
||||||
dP.compareTo(p) < 0 &&
|
|
||||||
dQ.compareTo(q) < 0 &&
|
|
||||||
dP.equals(e.modInverse(pMinusOne())) &&
|
|
||||||
dQ.equals(e.modInverse(qMinusOne())) &&
|
|
||||||
qInv.compareTo(p) < 0 &&
|
|
||||||
qInv.equals(q.modInverse(p));
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true when no fields are null. */
|
|
||||||
private boolean noValuesNull() {
|
|
||||||
return !(isNull(p) || isNull(q) || isNull(getModulus()) ||
|
|
||||||
isNull(e) || isNull(getPriExp()) || isNull(dP) ||
|
|
||||||
isNull(dQ) || isNull(qInv));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns p minus one. */
|
|
||||||
protected BigInteger pMinusOne() {
|
|
||||||
if (isNull(p)) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return p.subtract(ONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns q minus one. */
|
|
||||||
protected BigInteger qMinusOne() {
|
|
||||||
if (isNull(q)) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return q.subtract(ONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** Sets the CRT exponent. */
|
|
||||||
public void setCRTCoeff(BigInteger crtCoeff) {
|
|
||||||
qInv = weedOut(crtCoeff);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the first CRT exponent. */
|
|
||||||
public void setCRTExpOne(BigInteger crtExp1) {
|
|
||||||
dP = weedOut(crtExp1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the second CRT exponent. */
|
|
||||||
public void setCRTExpTwo(BigInteger crtExp2) {
|
|
||||||
dQ = weedOut(crtExp2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets phi. */
|
|
||||||
public void setPhi(BigInteger phi) {
|
|
||||||
this.phi = weedOut(phi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the prime factors. */
|
|
||||||
public void setPrimes(BigInteger prime1, BigInteger prime2) {
|
|
||||||
if (isNull(prime1 = weedOut(prime1)) || isNull(prime2 = weedOut(prime2))) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (isPositive(prime1.subtract(prime2))) {
|
|
||||||
p = prime1;
|
|
||||||
q = prime2;
|
|
||||||
} else if (isPositive(prime2.subtract(prime1))) {
|
|
||||||
p = prime2;
|
|
||||||
q = prime1;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the public exponent. */
|
|
||||||
public void setPubExp(BigInteger pubExp) {
|
|
||||||
e = weedOut(pubExp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
/**
|
|
||||||
* Interface providing often used BigInteger constants.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 05/30/2010
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface RSAConstants
|
|
||||||
{
|
|
||||||
BigInteger ZERO = BigInteger.ZERO;
|
|
||||||
BigInteger ONE = BigInteger.ONE;
|
|
||||||
BigInteger TWO = BigInteger.valueOf(2);
|
|
||||||
BigInteger THREE = BigInteger.valueOf(3);
|
|
||||||
BigInteger TWO_FIFTY_SIX = BigInteger.valueOf(256);
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract class representing common features of RSA keys.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 06/01/2010
|
|
||||||
*/
|
|
||||||
public abstract class RSAKey implements RSAConstants, RSABaseInterface
|
|
||||||
{
|
|
||||||
/** The modulus. */
|
|
||||||
private BigInteger n;
|
|
||||||
|
|
||||||
/** Default constructor. */
|
|
||||||
protected RSAKey() {
|
|
||||||
setModulus(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main constructor. */
|
|
||||||
protected RSAKey(BigInteger modulus) {
|
|
||||||
setModulus(modulus);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the contents of a file as a byte array. */
|
|
||||||
/*
|
|
||||||
protected byte[] getBytes(String fileName) {
|
|
||||||
File fIn = new File(fileName);
|
|
||||||
if (!fIn.canRead()) {
|
|
||||||
System.err.println("Can't read " + fileName);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInputStream in = null;
|
|
||||||
byte[] bytes = null;
|
|
||||||
try {
|
|
||||||
in = new FileInputStream(fIn);
|
|
||||||
|
|
||||||
long fileSize = fIn.length();
|
|
||||||
if (fileSize > Integer.MAX_VALUE) {
|
|
||||||
System.out.println("Sorry, file was too large!");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = new byte[(int) fileSize];
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int numRead = 0;
|
|
||||||
while (offset < bytes.length
|
|
||||||
&& (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) {
|
|
||||||
offset += numRead;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (in != null) in.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Returns the modulus. */
|
|
||||||
public BigInteger getModulus() {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of bytes required to store the modulus. */
|
|
||||||
protected int getModulusByteSize() {
|
|
||||||
return (int) Math.ceil(getModulus().bitLength() / 8.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a portion of the array argument. */
|
|
||||||
protected byte[] getSubArray(byte[] inBytes, int start, int end) {
|
|
||||||
if (start >= inBytes.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (end > inBytes.length) {
|
|
||||||
end = inBytes.length;
|
|
||||||
}
|
|
||||||
int bytesToGet = end - start;
|
|
||||||
if (bytesToGet < 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] outBytes = new byte[bytesToGet];
|
|
||||||
for (int i = start; i < end; i++) {
|
|
||||||
outBytes[i - start] = inBytes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return outBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true when the argument is null. */
|
|
||||||
public final boolean isNull(Object obj) {
|
|
||||||
return !(obj != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true when the argument is greater than zero. */
|
|
||||||
public final boolean isPositive(BigInteger number) {
|
|
||||||
return (number.compareTo(ZERO) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true when the argument is prime. */
|
|
||||||
public boolean isPrime(BigInteger number) {
|
|
||||||
return number.isProbablePrime(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Computes the least common multiple. */
|
|
||||||
public BigInteger lcm(BigInteger a, BigInteger b) {
|
|
||||||
return (a.multiply(b).divide(a.gcd(b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates an array of pseudo-random nonzero bytes. */
|
|
||||||
protected byte[] makePaddingString(int len) {
|
|
||||||
if (len < 8) return null;
|
|
||||||
Random rndm = new Random();
|
|
||||||
|
|
||||||
byte[] PS = new byte[len];
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
PS[i] = (byte)(rndm.nextInt(255) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reshapes a byte array into an array of byte arrays. */
|
|
||||||
protected byte[][] reshape(byte[] inBytes, int colSize) {
|
|
||||||
if (colSize < 1) {
|
|
||||||
colSize = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rowSize = (int) Math.ceil((double)inBytes.length / (double)colSize);
|
|
||||||
|
|
||||||
if (rowSize == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[][] outBytes = new byte[rowSize][];
|
|
||||||
|
|
||||||
for (int i = 0; i < rowSize; i++) {
|
|
||||||
outBytes[i] = getSubArray(inBytes, i * colSize, (i + 1) * colSize);
|
|
||||||
}
|
|
||||||
return outBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the modulus. */
|
|
||||||
public void setModulus(BigInteger modulus) {
|
|
||||||
n = weedOut(modulus);
|
|
||||||
if (isNull(n) || n.bitLength() < 96) {
|
|
||||||
n = null;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Converts a BigInteger into a byte array of the specified length. */
|
|
||||||
protected byte[] toByteArray(BigInteger x, int numBytes) {
|
|
||||||
if (x.compareTo(TWO_FIFTY_SIX.pow(numBytes)) >= 0) {
|
|
||||||
return null; // number is to big to fit in the byte array
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] ba = new byte[numBytes--];
|
|
||||||
BigInteger[] divAndRem = new BigInteger[2];
|
|
||||||
|
|
||||||
for (int power = numBytes; power >= 0; power--) {
|
|
||||||
divAndRem = x.divideAndRemainder(TWO_FIFTY_SIX.pow(power));
|
|
||||||
ba[numBytes - power] = (byte) divAndRem[0].intValue();
|
|
||||||
x = divAndRem[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ba;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Converts a byte array into a BigInteger. */
|
|
||||||
protected BigInteger toInteger(byte[] X) {
|
|
||||||
BigInteger x = ZERO;
|
|
||||||
|
|
||||||
for (int i = 0; i < X.length; i++) {
|
|
||||||
x = x.add(BigInteger.valueOf(X[i]).multiply(TWO_FIFTY_SIX.pow(X.length - 1 - i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Uses the key and returns true if use was successful. */
|
|
||||||
//public abstract boolean use(String source, String destination);
|
|
||||||
public abstract boolean use(byte[] sourceBytes, ByteArrayOutputStream baos);
|
|
||||||
|
|
||||||
/** Weeds out bad inputs. */
|
|
||||||
public final BigInteger weedOut(BigInteger arg) {
|
|
||||||
if (!isNull(arg) && isPositive(arg)) {
|
|
||||||
return arg;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class representing private and public keys with the ability to generate new keys.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 05/31/2010
|
|
||||||
*/
|
|
||||||
public class RSAKeyGenerator extends RSACompleteKey
|
|
||||||
{
|
|
||||||
/** Minimum number of bits in the modulus allowed. */
|
|
||||||
private static final int MIN_BIT_LENGTH = 1024;
|
|
||||||
|
|
||||||
/** Source of securely (pseudo-) random bits. */
|
|
||||||
Random rand = new Random();
|
|
||||||
|
|
||||||
/** The number of bits required in the modulus. */
|
|
||||||
private int bitLength;
|
|
||||||
|
|
||||||
/** Default constructor. */
|
|
||||||
public RSAKeyGenerator() {
|
|
||||||
super();
|
|
||||||
setBitLength(MIN_BIT_LENGTH);
|
|
||||||
generateNewKeys();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main constructor. */
|
|
||||||
public RSAKeyGenerator(int bitLength) {
|
|
||||||
super();
|
|
||||||
setBitLength(bitLength);
|
|
||||||
generateNewKeys();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates new private and public keys. */
|
|
||||||
public void generateNewKeys() {
|
|
||||||
setPrimes(BigInteger.probablePrime(75 * bitLength / 100, rand),
|
|
||||||
BigInteger.probablePrime(25 * bitLength / 100, rand));
|
|
||||||
setModulus(getPrimeOne().multiply(getPrimeTwo()));
|
|
||||||
computePhi();
|
|
||||||
|
|
||||||
BigInteger i;
|
|
||||||
for (i = BigInteger.probablePrime((bitLength / 10), rand);
|
|
||||||
i.compareTo(getModulus()) < 0;
|
|
||||||
i = i.nextProbablePrime()) {
|
|
||||||
if (i.gcd(getPhi()).equals(ONE)) {
|
|
||||||
setPubExp(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setPriExp(getPubExp().modInverse(getPhi()));
|
|
||||||
setCRTExpOne(getPubExp().modInverse(pMinusOne()));
|
|
||||||
setCRTExpTwo(getPubExp().modInverse(qMinusOne()));
|
|
||||||
setCRTCoeff(getPrimeTwo().modInverse(getPrimeOne()));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes a new RSA key. */
|
|
||||||
public RSAKey makeKey(byte whichKey) {
|
|
||||||
switch (whichKey) {
|
|
||||||
case PUBLIC_KEY:
|
|
||||||
return makePublicKey();
|
|
||||||
case PRIVATE_KEY:
|
|
||||||
return makePrivateKey();
|
|
||||||
case COMPLETE_KEY:
|
|
||||||
return makeCompleteKey();
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes complete RSA key objects. */
|
|
||||||
private RSACompleteKey makeCompleteKey() {
|
|
||||||
return new RSACompleteKey(getPrimeOne(),
|
|
||||||
getPrimeTwo(),
|
|
||||||
getModulus(),
|
|
||||||
getPubExp(),
|
|
||||||
getPriExp(),
|
|
||||||
getCRTExpOne(),
|
|
||||||
getCRTExpTwo(),
|
|
||||||
getCRTCoeff());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes private RSA key objects. */
|
|
||||||
private RSAPrivateKey makePrivateKey() {
|
|
||||||
return new RSAPrivateKey(getModulus(), getPriExp());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes public RSA key objects. */
|
|
||||||
private RSAPublicKey makePublicKey() {
|
|
||||||
return new RSAPublicKey(getModulus(), getPubExp());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the number of bits in the modulus. */
|
|
||||||
public void setBitLength(int bitLength) {
|
|
||||||
this.bitLength = (bitLength >= MIN_BIT_LENGTH ? bitLength : MIN_BIT_LENGTH);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class representing a private RSA key.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 05/31/2010
|
|
||||||
*/
|
|
||||||
public class RSAPrivateKey extends RSAKey
|
|
||||||
{
|
|
||||||
/** The private exponent. */
|
|
||||||
private BigInteger d;
|
|
||||||
|
|
||||||
/** Default constructor. */
|
|
||||||
public RSAPrivateKey() {
|
|
||||||
super();
|
|
||||||
setPriExp(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main constructor. */
|
|
||||||
public RSAPrivateKey(BigInteger modulus, BigInteger priExp) {
|
|
||||||
super(modulus);
|
|
||||||
setPriExp(priExp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs the classical RSA computation. */
|
|
||||||
protected BigInteger decrypt(BigInteger c) {
|
|
||||||
return c.modPow(getPriExp(), getModulus());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Extracts the data portion of the byte array. */
|
|
||||||
protected byte[] extractData(byte[] EB) {
|
|
||||||
if (EB.length < 12 || EB[0] != 0x00 || EB[1] != 0x02) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int index = 2;
|
|
||||||
do {} while (EB[index++] != 0x00);
|
|
||||||
|
|
||||||
return getSubArray(EB, index, EB.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the private exponent. */
|
|
||||||
public BigInteger getPriExp() {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the private exponent. */
|
|
||||||
public void setPriExp(BigInteger priExp)
|
|
||||||
{
|
|
||||||
d = weedOut(priExp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Uses key and returns true if decryption was successful. */
|
|
||||||
/*
|
|
||||||
public boolean use(String source, String destination) {
|
|
||||||
byte[] sourceBytes = getBytes(source);
|
|
||||||
if (isNull(sourceBytes)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int k = getModulusByteSize();
|
|
||||||
BigInteger c, m;
|
|
||||||
byte[] EB, M;
|
|
||||||
byte[][] C = reshape(sourceBytes, k);
|
|
||||||
BufferedOutputStream out = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
out = new BufferedOutputStream(new FileOutputStream(destination));
|
|
||||||
for (int i = 0; i < C.length; i++) {
|
|
||||||
if (C[i].length != k) return false;
|
|
||||||
c = new BigInteger(C[i]);
|
|
||||||
m = decrypt(c);
|
|
||||||
EB = toByteArray(m, k);
|
|
||||||
M = extractData(EB);
|
|
||||||
out.write(M);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (isNull(out)) out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean use(byte[] sourceBytes, ByteArrayOutputStream out) {
|
|
||||||
System.out.println(1);
|
|
||||||
int k = getModulusByteSize();
|
|
||||||
System.out.println(2);
|
|
||||||
BigInteger c, m;
|
|
||||||
byte[] EB, M;
|
|
||||||
byte[][] C = reshape(sourceBytes, k);
|
|
||||||
System.out.println(3);
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < C.length; i++) {
|
|
||||||
System.out.println(4);
|
|
||||||
if (C[i].length != k) return false;
|
|
||||||
c = new BigInteger(C[i]);
|
|
||||||
System.out.println(5);
|
|
||||||
m = decrypt(c);
|
|
||||||
System.out.println(6);
|
|
||||||
EB = toByteArray(m, k);
|
|
||||||
System.out.println(7);
|
|
||||||
M = extractData(EB);
|
|
||||||
System.out.println(8);
|
|
||||||
out.write(M);
|
|
||||||
System.out.println("FARD: "+Arrays.toString(M));
|
|
||||||
}
|
|
||||||
System.out.println(9);
|
|
||||||
out.flush();
|
|
||||||
//out.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
/*
|
|
||||||
String errMsg = "An exception occured!%n%s%n%s%n%s";
|
|
||||||
System.err.println(String.format(errMsg, e.getClass(), e.getMessage(), Arrays.toString(e.getStackTrace())));
|
|
||||||
*/
|
|
||||||
System.err.println(e.getClass().getName()+"\n"+e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
package com.rhg.rsa;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class representing a public RSA key.
|
|
||||||
*
|
|
||||||
* @author Rob
|
|
||||||
* @version 05/30/2010
|
|
||||||
*/
|
|
||||||
public class RSAPublicKey extends RSAKey
|
|
||||||
{
|
|
||||||
/** The public exponent. */
|
|
||||||
private BigInteger e;
|
|
||||||
|
|
||||||
/** Default constructor. */
|
|
||||||
public RSAPublicKey() {
|
|
||||||
super(null);
|
|
||||||
setPubExp(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main constructor. */
|
|
||||||
public RSAPublicKey(BigInteger modulus, BigInteger pubExp)
|
|
||||||
{
|
|
||||||
super(modulus);
|
|
||||||
setPubExp(pubExp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs the classical RSA computation. */
|
|
||||||
protected BigInteger encrypt(BigInteger m) {
|
|
||||||
return m.modPow(getPubExp(), getModulus());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the public exponent. */
|
|
||||||
public BigInteger getPubExp() {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the public exponent. */
|
|
||||||
public void setPubExp(BigInteger pubExp)
|
|
||||||
{
|
|
||||||
e = weedOut(pubExp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Uses the key and returns true if encryption was successful. */
|
|
||||||
/*
|
|
||||||
public boolean use(String source, String destination) {
|
|
||||||
byte[] sourceBytes = getBytes(source);
|
|
||||||
if (isNull(sourceBytes)) {
|
|
||||||
System.err.println(String.format("%s contained nothing.", source));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int k = getModulusByteSize();
|
|
||||||
byte BT = 0x02;
|
|
||||||
byte[] C, M;
|
|
||||||
byte[][] D = reshape(sourceBytes, k - 11);
|
|
||||||
ByteArrayOutputStream EB = new ByteArrayOutputStream(k);
|
|
||||||
FileOutputStream out = null;
|
|
||||||
BigInteger m, c;
|
|
||||||
|
|
||||||
try {
|
|
||||||
out = new FileOutputStream(destination);
|
|
||||||
for (int i = 0; i < D.length; i++) {
|
|
||||||
EB.reset();
|
|
||||||
EB.write(0x00); EB.write(BT); EB.write(makePaddingString(k - D[i].length - 3));
|
|
||||||
EB.write(0x00); EB.write(D[i]);
|
|
||||||
M = EB.toByteArray();
|
|
||||||
m = new BigInteger(M);
|
|
||||||
c = encrypt(m);
|
|
||||||
C = toByteArray(c, k);
|
|
||||||
out.write(C);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
String errMsg = "An exception occured!%n%s%n%s%n%s";
|
|
||||||
System.err.println(String.format(errMsg, e.getClass(), e.getMessage(), e.getStackTrace()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean use(byte[] sourceBytes, ByteArrayOutputStream out) {
|
|
||||||
System.out.println(1);
|
|
||||||
int k = getModulusByteSize();
|
|
||||||
System.out.println(2);
|
|
||||||
byte BT = 0x02;
|
|
||||||
byte[] C, M;
|
|
||||||
byte[][] D = reshape(sourceBytes, k - 11);
|
|
||||||
System.out.println(3);
|
|
||||||
ByteArrayOutputStream EB = new ByteArrayOutputStream(k);
|
|
||||||
System.out.println(4);
|
|
||||||
BigInteger m, c;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < D.length; i++) {
|
|
||||||
System.out.println(5);
|
|
||||||
EB.reset();
|
|
||||||
System.out.println(6);
|
|
||||||
EB.write(0x00); EB.write(BT); EB.write(makePaddingString(k - D[i].length - 3));
|
|
||||||
System.out.println(7);
|
|
||||||
EB.write(0x00); EB.write(D[i]);
|
|
||||||
System.out.println(8);
|
|
||||||
M = EB.toByteArray();
|
|
||||||
System.out.println(9);
|
|
||||||
m = new BigInteger(M);
|
|
||||||
System.out.println(10);
|
|
||||||
c = encrypt(m);
|
|
||||||
System.out.println(11);
|
|
||||||
C = toByteArray(c, k);
|
|
||||||
System.out.println(12);
|
|
||||||
out.write(C);
|
|
||||||
System.out.println("FARD: "+Arrays.toString(C));
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
//out.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
/*
|
|
||||||
String errMsg = "An exception occured!%n%s%n%s%n%s";
|
|
||||||
System.err.println(String.format(errMsg, e.getClass(), e.getMessage(), Arrays.toString(e.getStackTrace())));
|
|
||||||
*/
|
|
||||||
System.err.println(e.getClass().getName()+"\n"+e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package me.ayunami2000.ayuncraft;
|
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.java.security.PublicKey;
|
|
||||||
|
|
||||||
public class ModifiablePublicKey implements PublicKey {
|
|
||||||
private String algorithm;
|
|
||||||
private String format;
|
|
||||||
private byte[] encoded;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAlgorithm() {
|
|
||||||
return algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFormat() {
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getEncoded() {
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModifiablePublicKey(String algo,String form,byte[] data){
|
|
||||||
algorithm=algo;
|
|
||||||
format=form;
|
|
||||||
encoded=data;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
package me.ayunami2000.ayuncraft;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public class ParseRSAPublicKey {
|
|
||||||
private static final int SEQUENCE = 0x30;
|
|
||||||
private static final int INTEGER = 0x02;
|
|
||||||
private final ByteBuffer derBuf;
|
|
||||||
|
|
||||||
private static byte[] derDat;
|
|
||||||
|
|
||||||
public ParseRSAPublicKey(byte[] der) {
|
|
||||||
derDat=der;
|
|
||||||
derBuf = ByteBuffer.wrap(der);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte get() {
|
|
||||||
return derBuf.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the next byte of the buffer as an int
|
|
||||||
*/
|
|
||||||
public int getAsInt() {
|
|
||||||
return get() & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getArray(int len) {
|
|
||||||
byte [] arr = new byte[len];
|
|
||||||
derBuf.get(arr);
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int parseId() {
|
|
||||||
// Only the low-tag form is legal.
|
|
||||||
int idOctect = getAsInt();
|
|
||||||
if (idOctect >= 0x31) {
|
|
||||||
throw new RuntimeException("Invalid identifier octets");
|
|
||||||
}
|
|
||||||
return idOctect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long parseLength() {
|
|
||||||
int octet1 = getAsInt();
|
|
||||||
if (octet1 < 128) {
|
|
||||||
// short form of length
|
|
||||||
return octet1;
|
|
||||||
} else {
|
|
||||||
// long form of length
|
|
||||||
int lengthOfLength = octet1 & 0x7f;
|
|
||||||
BigInteger bigLen = new BigInteger(1, getArray(lengthOfLength));
|
|
||||||
|
|
||||||
if (bigLen.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0){
|
|
||||||
throw new RuntimeException("Length is too long");
|
|
||||||
}
|
|
||||||
return bigLen.longValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigInteger parseInteger() {
|
|
||||||
if (parseId() != INTEGER) {
|
|
||||||
throw new RuntimeException("expected SEQUENCE tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
long length = parseLength();
|
|
||||||
if (length > Integer.MAX_VALUE){
|
|
||||||
throw new RuntimeException("Length is too long");
|
|
||||||
}
|
|
||||||
return new BigInteger(1, getArray((int) length));
|
|
||||||
}
|
|
||||||
public PubKey parse() {
|
|
||||||
// Parse SEQUENCE header
|
|
||||||
if (parseId() != SEQUENCE) {
|
|
||||||
throw new RuntimeException("expected SEQUENCE tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
long seqLength = parseLength(); // We ignore this
|
|
||||||
|
|
||||||
// Parse INTEGER modulus
|
|
||||||
BigInteger n = parseInteger();
|
|
||||||
BigInteger e = parseInteger();
|
|
||||||
return new PubKey(derDat, n, e);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
package me.ayunami2000.ayuncraft;
|
|
||||||
/******************************************************************************
|
|
||||||
* Compilation: javac RSA.java
|
|
||||||
* Execution: java RSA N
|
|
||||||
*
|
|
||||||
* Generate an N-bit public and private RSA key and use to encrypt
|
|
||||||
* and decrypt a random message.
|
|
||||||
*
|
|
||||||
* % java RSA 50
|
|
||||||
* public = 65537
|
|
||||||
* private = 553699199426609
|
|
||||||
* modulus = 825641896390631
|
|
||||||
* message = 48194775244950
|
|
||||||
* encrpyted = 321340212160104
|
|
||||||
* decrypted = 48194775244950
|
|
||||||
*
|
|
||||||
* Known bugs (not addressed for simplicity)
|
|
||||||
* -----------------------------------------
|
|
||||||
* - It could be the case that the message >= modulus. To avoid, use
|
|
||||||
* a do-while loop to generate key until modulus happen to be exactly N bits.
|
|
||||||
*
|
|
||||||
* - It's possible that gcd(phi, publicKey) != 1 in which case
|
|
||||||
* the key generation fails. This will only happen if phi is a
|
|
||||||
* multiple of 65537. To avoid, use a do-while loop to generate
|
|
||||||
* keys until the gcd is 1.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
public class RSA {
|
|
||||||
private final static BigInteger one = new BigInteger("1");
|
|
||||||
private final static Random random = new Random();
|
|
||||||
|
|
||||||
private BigInteger privateKey;
|
|
||||||
private BigInteger publicKey;
|
|
||||||
private BigInteger modulus;
|
|
||||||
|
|
||||||
// generate an N-bit (roughly) public and private key
|
|
||||||
RSA(int N) {
|
|
||||||
BigInteger p = BigInteger.probablePrime(N/2, random);
|
|
||||||
BigInteger q = BigInteger.probablePrime(N/2, random);
|
|
||||||
BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));
|
|
||||||
|
|
||||||
modulus = p.multiply(q);
|
|
||||||
publicKey = new BigInteger("65537"); // common value in practice = 2^16 + 1
|
|
||||||
privateKey = publicKey.modInverse(phi);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BigInteger encrypt(BigInteger message) {
|
|
||||||
return message.modPow(publicKey, modulus);
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger decrypt(BigInteger encrypted) {
|
|
||||||
return encrypted.modPow(privateKey, modulus);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void setPublicKey(BigInteger k) {
|
|
||||||
publicKey=k;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPrivateKey(BigInteger k) {
|
|
||||||
privateKey=k;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setModulus(BigInteger k) {
|
|
||||||
modulus=k;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setModulus() {
|
|
||||||
modulus=one;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BigInteger getPublicKey() {
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger getPrivateKey() {
|
|
||||||
return privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger getModulus() {
|
|
||||||
return modulus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
String s = "";
|
|
||||||
s += "public = " + publicKey + "\n";
|
|
||||||
s += "private = " + privateKey + "\n";
|
|
||||||
s += "modulus = " + modulus;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,263 +1,263 @@
|
||||||
package net.lax1dude.eaglercraft;
|
package net.lax1dude.eaglercraft;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.java.security.Key;
|
import me.ayunami2000.ayuncraft.java.security.Key;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.src.*;
|
import net.minecraft.src.*;
|
||||||
import me.ayunami2000.ayuncraft.CryptManager;
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
import org.bouncycastle.crypto.BufferedBlockCipher;
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
|
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
|
||||||
|
|
||||||
public class WebsocketNetworkManager implements INetworkManager {
|
public class WebsocketNetworkManager implements INetworkManager {
|
||||||
private boolean isInputBeingDecrypted;
|
private boolean isInputBeingDecrypted;
|
||||||
private boolean isOutputEncrypted;
|
private boolean isOutputEncrypted;
|
||||||
private SecretKey sharedKeyForEncryption;
|
private SecretKey sharedKeyForEncryption;
|
||||||
|
|
||||||
private final boolean logpackets=false;
|
private final boolean logpackets=false;
|
||||||
|
|
||||||
private BufferedBlockCipher inputBufferedBlockCipher=null;
|
private BufferedBlockCipher inputBufferedBlockCipher=null;
|
||||||
private BufferedBlockCipher outputBufferedBlockCipher=null;
|
private BufferedBlockCipher outputBufferedBlockCipher=null;
|
||||||
|
|
||||||
private NetHandler netHandler;
|
private NetHandler netHandler;
|
||||||
|
|
||||||
public WebsocketNetworkManager(String uri, String eagler, NetHandler netHandler) throws IOException {
|
public WebsocketNetworkManager(String uri, String eagler, NetHandler netHandler) throws IOException {
|
||||||
this.netHandler = netHandler;
|
this.netHandler = netHandler;
|
||||||
this.sharedKeyForEncryption = null;
|
this.sharedKeyForEncryption = null;
|
||||||
this.isInputBeingDecrypted = false;
|
this.isInputBeingDecrypted = false;
|
||||||
this.isOutputEncrypted = false;
|
this.isOutputEncrypted = false;
|
||||||
if(!EaglerAdapter.startConnection(uri)) {
|
if(!EaglerAdapter.startConnection(uri)) {
|
||||||
throw new IOException("websocket to "+uri+" failed");
|
throw new IOException("websocket to "+uri+" failed");
|
||||||
}
|
}
|
||||||
EaglerAdapter.setDebugVar("minecraftServer", uri);
|
EaglerAdapter.setDebugVar("minecraftServer", uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNetHandler(NetHandler netHandler) {
|
public void setNetHandler(NetHandler netHandler) {
|
||||||
this.netHandler = netHandler;
|
this.netHandler = netHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream();
|
private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
public void addToSendQueue(Packet var1) {
|
public void addToSendQueue(Packet var1) {
|
||||||
try {
|
try {
|
||||||
sendBuffer.reset();
|
sendBuffer.reset();
|
||||||
|
|
||||||
DataOutputStream yee;
|
DataOutputStream yee;
|
||||||
if(this.isOutputEncrypted&&!(var1 instanceof Packet252SharedKey)){
|
if(this.isOutputEncrypted&&!(var1 instanceof Packet252SharedKey)){
|
||||||
yee = this.encryptOuputStream();
|
yee = this.encryptOuputStream();
|
||||||
}else{
|
}else{
|
||||||
yee = new DataOutputStream(sendBuffer);
|
yee = new DataOutputStream(sendBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && var1 instanceof Packet252SharedKey && !this.isOutputEncrypted)
|
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && var1 instanceof Packet252SharedKey && !this.isOutputEncrypted)
|
||||||
{
|
{
|
||||||
this.sharedKeyForEncryption = ((Packet252SharedKey)var1).getSharedKey();
|
this.sharedKeyForEncryption = ((Packet252SharedKey)var1).getSharedKey();
|
||||||
this.isOutputEncrypted=true;
|
this.isOutputEncrypted=true;
|
||||||
//yee=this.encryptOuputStream(yee);
|
//yee=this.encryptOuputStream(yee);
|
||||||
}
|
}
|
||||||
Packet.writePacket(var1, yee);
|
Packet.writePacket(var1, yee);
|
||||||
if(logpackets)System.out.println("SENDING: "+var1);
|
if(logpackets)System.out.println("SENDING: "+var1);
|
||||||
yee.flush();
|
yee.flush();
|
||||||
EaglerAdapter.writePacket(sendBuffer.toByteArray());
|
EaglerAdapter.writePacket(sendBuffer.toByteArray());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void wakeThreads() {
|
public void wakeThreads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ByteBufferDirectInputStream extends InputStream {
|
private static class ByteBufferDirectInputStream extends InputStream {
|
||||||
private ByteBuffer buf;
|
private ByteBuffer buf;
|
||||||
private ByteBufferDirectInputStream(ByteBuffer b) {
|
private ByteBufferDirectInputStream(ByteBuffer b) {
|
||||||
this.buf = b;
|
this.buf = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
return buf.remaining() > 0 ? ((int)buf.get() & 0xFF) : -1;
|
return buf.remaining() > 0 ? ((int)buf.get() & 0xFF) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int available() {
|
public int available() {
|
||||||
return buf.remaining();
|
return buf.remaining();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuffer oldChunkBuffer = null;
|
private ByteBuffer oldChunkBuffer = null;
|
||||||
private LinkedList<ByteBuffer> readChunks = new LinkedList();
|
private LinkedList<ByteBuffer> readChunks = new LinkedList();
|
||||||
|
|
||||||
private ByteBuffer oldDecryptedChunkBuffer = null;
|
private ByteBuffer oldDecryptedChunkBuffer = null;
|
||||||
private LinkedList<ByteBuffer> decryptedReadChunks = new LinkedList();
|
private LinkedList<ByteBuffer> decryptedReadChunks = new LinkedList();
|
||||||
|
|
||||||
public void processReadPackets() {
|
public void processReadPackets() {
|
||||||
readChunks.clear();
|
readChunks.clear();
|
||||||
|
|
||||||
if(oldChunkBuffer != null) {
|
if(oldChunkBuffer != null) {
|
||||||
readChunks.add(oldChunkBuffer);
|
readChunks.add(oldChunkBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] packet;
|
byte[] packet;
|
||||||
while((packet = EaglerAdapter.readPacket()) != null) {
|
while((packet = EaglerAdapter.readPacket()) != null) {
|
||||||
readChunks.add(ByteBuffer.wrap(packet));
|
readChunks.add(ByteBuffer.wrap(packet));
|
||||||
}
|
}
|
||||||
if(!readChunks.isEmpty()) {
|
if(!readChunks.isEmpty()) {
|
||||||
|
|
||||||
int cap = 0;
|
int cap = 0;
|
||||||
for(ByteBuffer b : readChunks) {
|
for(ByteBuffer b : readChunks) {
|
||||||
cap += b.limit();
|
cap += b.limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer stream = ByteBuffer.allocate(cap);
|
ByteBuffer stream = ByteBuffer.allocate(cap);
|
||||||
for(ByteBuffer b : readChunks) {
|
for(ByteBuffer b : readChunks) {
|
||||||
stream.put(b);
|
stream.put(b);
|
||||||
}
|
}
|
||||||
stream.flip();
|
stream.flip();
|
||||||
|
|
||||||
if(this.isInputBeingDecrypted){
|
if(this.isInputBeingDecrypted){
|
||||||
decryptedReadChunks.clear();
|
decryptedReadChunks.clear();
|
||||||
|
|
||||||
if (oldDecryptedChunkBuffer != null) {
|
if (oldDecryptedChunkBuffer != null) {
|
||||||
decryptedReadChunks.add(oldDecryptedChunkBuffer);
|
decryptedReadChunks.add(oldDecryptedChunkBuffer);
|
||||||
oldDecryptedChunkBuffer = null;
|
oldDecryptedChunkBuffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] block = new byte[/*2048*/32];
|
byte[] block = new byte[/*2048*/32];
|
||||||
byte[] decryp = new byte[this.inputBufferedBlockCipher.getOutputSize(/*2048*/32)];
|
byte[] decryp = new byte[this.inputBufferedBlockCipher.getOutputSize(/*2048*/32)];
|
||||||
while (stream.remaining() >= /*2048*/32) {
|
while (stream.remaining() >= /*2048*/32) {
|
||||||
stream.get(block);
|
stream.get(block);
|
||||||
int i = this.inputBufferedBlockCipher.processByte(block, 0, /*2048*/32, decryp, 0);
|
int i = this.inputBufferedBlockCipher.processByte(block, 0, /*2048*/32, decryp, 0);
|
||||||
ByteBuffer chunk = ByteBuffer.allocate(i);
|
ByteBuffer chunk = ByteBuffer.allocate(i);
|
||||||
chunk.put(decryp, 0, i);
|
chunk.put(decryp, 0, i);
|
||||||
chunk.flip();
|
chunk.flip();
|
||||||
decryptedReadChunks.add(chunk);
|
decryptedReadChunks.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
oldChunkBuffer = stream.remaining() > 0 ? stream.slice() : null;
|
oldChunkBuffer = stream.remaining() > 0 ? stream.slice() : null;
|
||||||
|
|
||||||
int cap2 = 0;
|
int cap2 = 0;
|
||||||
for (ByteBuffer b : decryptedReadChunks) {
|
for (ByteBuffer b : decryptedReadChunks) {
|
||||||
cap2 += b.limit();
|
cap2 += b.limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer decStream = ByteBuffer.allocate(cap2);
|
ByteBuffer decStream = ByteBuffer.allocate(cap2);
|
||||||
for (ByteBuffer b : decryptedReadChunks) {
|
for (ByteBuffer b : decryptedReadChunks) {
|
||||||
decStream.put(b);
|
decStream.put(b);
|
||||||
}
|
}
|
||||||
decStream.flip();
|
decStream.flip();
|
||||||
|
|
||||||
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(decStream));
|
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(decStream));
|
||||||
while (decStream.hasRemaining()) {
|
while (decStream.hasRemaining()) {
|
||||||
decStream.mark();
|
decStream.mark();
|
||||||
try {
|
try {
|
||||||
Packet pkt = Packet.readPacket(packetStream, false);
|
Packet pkt = Packet.readPacket(packetStream, false);
|
||||||
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
||||||
pkt.processPacket(this.netHandler);
|
pkt.processPacket(this.netHandler);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
decStream.reset();
|
decStream.reset();
|
||||||
break;
|
break;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
continue;
|
continue;
|
||||||
} catch (Throwable e2) {
|
} catch (Throwable e2) {
|
||||||
e2.printStackTrace();
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decStream.hasRemaining()) {
|
if (decStream.hasRemaining()) {
|
||||||
oldDecryptedChunkBuffer = decStream.slice();
|
oldDecryptedChunkBuffer = decStream.slice();
|
||||||
} else {
|
} else {
|
||||||
oldDecryptedChunkBuffer = null;
|
oldDecryptedChunkBuffer = null;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(stream));
|
DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(stream));
|
||||||
while (stream.hasRemaining()) {
|
while (stream.hasRemaining()) {
|
||||||
stream.mark();
|
stream.mark();
|
||||||
try {
|
try {
|
||||||
Packet pkt = Packet.readPacket(packetStream, false);
|
Packet pkt = Packet.readPacket(packetStream, false);
|
||||||
boolean change=false;
|
boolean change=false;
|
||||||
if (pkt != null) {
|
if (pkt != null) {
|
||||||
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && pkt instanceof Packet252SharedKey && !this.isInputBeingDecrypted) {
|
if (Minecraft.getMinecraft().gameSettings.useDefaultProtocol && pkt instanceof Packet252SharedKey && !this.isInputBeingDecrypted) {
|
||||||
packetStream = this.decryptInputStream(new ByteBufferDirectInputStream(stream));
|
packetStream = this.decryptInputStream(new ByteBufferDirectInputStream(stream));
|
||||||
change=true;
|
change=true;
|
||||||
}
|
}
|
||||||
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
if(logpackets)System.out.println("RECEIVING: " + pkt);
|
||||||
pkt.processPacket(this.netHandler);
|
pkt.processPacket(this.netHandler);
|
||||||
if(change){
|
if(change){
|
||||||
processReadPackets();
|
processReadPackets();
|
||||||
return;
|
return;
|
||||||
//break;
|
//break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
stream.reset();
|
stream.reset();
|
||||||
break;
|
break;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
continue;
|
continue;
|
||||||
} catch (Throwable e2) {
|
} catch (Throwable e2) {
|
||||||
e2.printStackTrace();
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream.hasRemaining()) {
|
if (stream.hasRemaining()) {
|
||||||
oldChunkBuffer = stream.slice();
|
oldChunkBuffer = stream.slice();
|
||||||
} else {
|
} else {
|
||||||
oldChunkBuffer = null;
|
oldChunkBuffer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serverShutdown() {
|
public void serverShutdown() {
|
||||||
if(EaglerAdapter.connectionOpen()) {
|
if(EaglerAdapter.connectionOpen()) {
|
||||||
EaglerAdapter.endConnection();
|
EaglerAdapter.endConnection();
|
||||||
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataInputStream decryptInputStream(ByteBufferDirectInputStream var1) throws IOException
|
private DataInputStream decryptInputStream(ByteBufferDirectInputStream var1) throws IOException
|
||||||
{
|
{
|
||||||
this.isInputBeingDecrypted = true;
|
this.isInputBeingDecrypted = true;
|
||||||
if(this.inputBufferedBlockCipher==null){
|
if(this.inputBufferedBlockCipher==null){
|
||||||
this.inputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(false, (Key) this.sharedKeyForEncryption);
|
this.inputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(false, (Key) this.sharedKeyForEncryption);
|
||||||
}
|
}
|
||||||
return new DataInputStream(CryptManager.decryptInputStream(this.inputBufferedBlockCipher, var1));
|
return new DataInputStream(CryptManager.decryptInputStream(this.inputBufferedBlockCipher, var1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* flushes the stream and replaces it with an encryptedOutputStream
|
* flushes the stream and replaces it with an encryptedOutputStream
|
||||||
*/
|
*/
|
||||||
private DataOutputStream encryptOuputStream(DataOutputStream var0) throws IOException
|
private DataOutputStream encryptOuputStream(DataOutputStream var0) throws IOException
|
||||||
{
|
{
|
||||||
var0.flush();
|
var0.flush();
|
||||||
this.isOutputEncrypted = true;
|
this.isOutputEncrypted = true;
|
||||||
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.sharedKeyForEncryption, var0), 5120);
|
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.sharedKeyForEncryption, var0), 5120);
|
||||||
return new DataOutputStream(var1);
|
return new DataOutputStream(var1);
|
||||||
}
|
}
|
||||||
private DataOutputStream encryptOuputStream() throws IOException
|
private DataOutputStream encryptOuputStream() throws IOException
|
||||||
{
|
{
|
||||||
if(this.outputBufferedBlockCipher==null){
|
if(this.outputBufferedBlockCipher==null){
|
||||||
this.outputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(true, (Key) this.sharedKeyForEncryption);
|
this.outputBufferedBlockCipher = CryptManager.createBufferedBlockCipher(true, (Key) this.sharedKeyForEncryption);
|
||||||
}
|
}
|
||||||
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.outputBufferedBlockCipher, sendBuffer), 5120);
|
BufferedOutputStream var1 = new BufferedOutputStream(CryptManager.encryptOuputStream(this.outputBufferedBlockCipher, sendBuffer), 5120);
|
||||||
return new DataOutputStream(var1);
|
return new DataOutputStream(var1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int packetSize() {
|
public int packetSize() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void networkShutdown(String var1, Object... var2) {
|
public void networkShutdown(String var1, Object... var2) {
|
||||||
serverShutdown();
|
serverShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeConnections() {
|
public void closeConnections() {
|
||||||
if(EaglerAdapter.connectionOpen()) {
|
if(EaglerAdapter.connectionOpen()) {
|
||||||
EaglerAdapter.endConnection();
|
EaglerAdapter.endConnection();
|
||||||
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
EaglerAdapter.setDebugVar("minecraftServer", "null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,91 +1,88 @@
|
||||||
package net.minecraft.src;
|
package net.minecraft.src;
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.CryptManager;
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import me.ayunami2000.ayuncraft.PubKey;
|
import me.ayunami2000.ayuncraft.PubKey;
|
||||||
import me.ayunami2000.ayuncraft.java.security.Key;
|
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
|
||||||
import me.ayunami2000.ayuncraft.java.security.PrivateKey;
|
|
||||||
import me.ayunami2000.ayuncraft.java.security.PublicKey;
|
public class Packet252SharedKey extends Packet
|
||||||
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
|
{
|
||||||
|
private byte[] sharedSecret = new byte[0];
|
||||||
public class Packet252SharedKey extends Packet
|
private byte[] verifyToken = new byte[0];
|
||||||
{
|
|
||||||
private byte[] sharedSecret = new byte[0];
|
/**
|
||||||
private byte[] verifyToken = new byte[0];
|
* Secret AES key decrypted from sharedSecret via the server's private RSA key
|
||||||
|
*/
|
||||||
/**
|
private SecretKey sharedKey;
|
||||||
* Secret AES key decrypted from sharedSecret via the server's private RSA key
|
|
||||||
*/
|
public Packet252SharedKey() {}
|
||||||
private SecretKey sharedKey;
|
|
||||||
|
public Packet252SharedKey(SecretKey par1SecretKey, PubKey par2PublicKey, byte[] par3ArrayOfByte)
|
||||||
public Packet252SharedKey() {}
|
{
|
||||||
|
this.sharedKey = par1SecretKey;
|
||||||
public Packet252SharedKey(SecretKey par1SecretKey, PubKey par2PublicKey, byte[] par3ArrayOfByte)
|
this.sharedSecret = CryptManager.encryptData(par2PublicKey, par1SecretKey.getEncoded());
|
||||||
{
|
this.verifyToken = CryptManager.encryptData(par2PublicKey, par3ArrayOfByte);
|
||||||
this.sharedKey = par1SecretKey;
|
}
|
||||||
this.sharedSecret = CryptManager.encryptData(par2PublicKey, par1SecretKey.getEncoded());
|
|
||||||
this.verifyToken = CryptManager.encryptData(par2PublicKey, par3ArrayOfByte);
|
/**
|
||||||
}
|
* Abstract. Reads the raw packet data from the data stream.
|
||||||
|
*/
|
||||||
/**
|
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
||||||
* Abstract. Reads the raw packet data from the data stream.
|
{
|
||||||
*/
|
this.sharedSecret = readBytesFromStream(par1DataInputStream);
|
||||||
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
||||||
{
|
}
|
||||||
this.sharedSecret = readBytesFromStream(par1DataInputStream);
|
|
||||||
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
/**
|
||||||
}
|
* Abstract. Writes the raw packet data to the data stream.
|
||||||
|
*/
|
||||||
/**
|
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
||||||
* Abstract. Writes the raw packet data to the data stream.
|
{
|
||||||
*/
|
writeByteArray(par1DataOutputStream, this.sharedSecret);
|
||||||
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
writeByteArray(par1DataOutputStream, this.verifyToken);
|
||||||
{
|
}
|
||||||
writeByteArray(par1DataOutputStream, this.sharedSecret);
|
|
||||||
writeByteArray(par1DataOutputStream, this.verifyToken);
|
/**
|
||||||
}
|
* Passes this Packet on to the NetHandler for processing.
|
||||||
|
*/
|
||||||
/**
|
public void processPacket(NetHandler par1NetHandler)
|
||||||
* Passes this Packet on to the NetHandler for processing.
|
{
|
||||||
*/
|
par1NetHandler.handleSharedKey(this);
|
||||||
public void processPacket(NetHandler par1NetHandler)
|
}
|
||||||
{
|
|
||||||
par1NetHandler.handleSharedKey(this);
|
/**
|
||||||
}
|
* Abstract. Return the size of the packet (not counting the header).
|
||||||
|
*/
|
||||||
/**
|
public int getPacketSize()
|
||||||
* Abstract. Return the size of the packet (not counting the header).
|
{
|
||||||
*/
|
return 2 + this.sharedSecret.length + 2 + this.verifyToken.length;
|
||||||
public int getPacketSize()
|
}
|
||||||
{
|
|
||||||
return 2 + this.sharedSecret.length + 2 + this.verifyToken.length;
|
/**
|
||||||
}
|
* Return secretKey, decrypting it from the sharedSecret byte array if needed
|
||||||
|
*/
|
||||||
/**
|
public SecretKey getSharedKey(PubKey par1PrivateKey)
|
||||||
* Return secretKey, decrypting it from the sharedSecret byte array if needed
|
{
|
||||||
*/
|
return par1PrivateKey == null ? this.sharedKey : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret));
|
||||||
public SecretKey getSharedKey(PubKey par1PrivateKey)
|
}
|
||||||
{
|
|
||||||
return par1PrivateKey == null ? this.sharedKey : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret));
|
/**
|
||||||
}
|
* Return the secret AES sharedKey (used by client only)
|
||||||
|
*/
|
||||||
/**
|
public SecretKey getSharedKey()
|
||||||
* Return the secret AES sharedKey (used by client only)
|
{
|
||||||
*/
|
return this.getSharedKey(null);
|
||||||
public SecretKey getSharedKey()
|
}
|
||||||
{
|
|
||||||
return this.getSharedKey(null);
|
/**
|
||||||
}
|
* Return verifyToken
|
||||||
|
*/
|
||||||
/**
|
public byte[] getVerifyToken(PubKey par1PrivateKey)
|
||||||
* Return verifyToken
|
{
|
||||||
*/
|
return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData(par1PrivateKey, this.verifyToken);
|
||||||
public byte[] getVerifyToken(PubKey par1PrivateKey)
|
}
|
||||||
{
|
|
||||||
return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData(par1PrivateKey, this.verifyToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
|
||||||
|
import me.ayunami2000.ayuncraft.CryptManager;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import me.ayunami2000.ayuncraft.PubKey;
|
||||||
|
|
||||||
|
public class Packet253ServerAuthData extends Packet
|
||||||
|
{
|
||||||
|
private String serverId;
|
||||||
|
private PubKey publicKey;
|
||||||
|
private byte[] verifyToken = new byte[0];
|
||||||
|
|
||||||
|
public Packet253ServerAuthData() {}
|
||||||
|
|
||||||
|
public Packet253ServerAuthData(String par1Str, PubKey par2PublicKey, byte[] par3ArrayOfByte)
|
||||||
|
{
|
||||||
|
this.serverId = par1Str;
|
||||||
|
this.publicKey = par2PublicKey;
|
||||||
|
this.verifyToken = par3ArrayOfByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Reads the raw packet data from the data stream.
|
||||||
|
*/
|
||||||
|
public void readPacketData(DataInputStream par1DataInputStream) throws IOException
|
||||||
|
{
|
||||||
|
this.serverId = readString(par1DataInputStream, 20);
|
||||||
|
this.publicKey = CryptManager.decodePublicKey(readBytesFromStream(par1DataInputStream));
|
||||||
|
this.verifyToken = readBytesFromStream(par1DataInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Writes the raw packet data to the data stream.
|
||||||
|
*/
|
||||||
|
public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
|
||||||
|
{
|
||||||
|
writeString(this.serverId, par1DataOutputStream);
|
||||||
|
writeByteArray(par1DataOutputStream, this.publicKey.getEncoded());
|
||||||
|
writeByteArray(par1DataOutputStream, this.verifyToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passes this Packet on to the NetHandler for processing.
|
||||||
|
*/
|
||||||
|
public void processPacket(NetHandler par1NetHandler)
|
||||||
|
{
|
||||||
|
par1NetHandler.handleServerAuthData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract. Return the size of the packet (not counting the header).
|
||||||
|
*/
|
||||||
|
public int getPacketSize()
|
||||||
|
{
|
||||||
|
return 2 + this.serverId.length() * 2 + 2 + this.publicKey.getEncoded().length + 2 + this.verifyToken.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerId()
|
||||||
|
{
|
||||||
|
return this.serverId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PubKey getPublicKey()
|
||||||
|
{
|
||||||
|
return this.publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getVerifyToken()
|
||||||
|
{
|
||||||
|
return this.verifyToken;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user