add pubkey auth
This commit is contained in:
parent
bdf67a89f7
commit
5a394749bf
24 changed files with 822 additions and 107 deletions
|
@ -333,6 +333,16 @@ public abstract class Config {
|
|||
public static boolean register = true;
|
||||
@Var(name = "signEditing")
|
||||
public static boolean editSigns = true;
|
||||
@Var(name = "passwordAuthentication")
|
||||
public static boolean passwordAuth = true;
|
||||
@Var(name = "pubkeyAuthentication")
|
||||
public static boolean pubkeyAuth = true;
|
||||
@Var(name = "requireAccessPassword")
|
||||
public static boolean accessRequired = true;
|
||||
@Var(name = "encryption")
|
||||
public static boolean encrypt = true;
|
||||
@Var(name = "requireAuthentication")
|
||||
public static boolean authenticate = true;
|
||||
|
||||
@Var(name = "keepInventory")
|
||||
public static boolean keepInventory = false;
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
package common.network;
|
||||
|
||||
import common.packet.RPacketChallenge;
|
||||
import common.packet.RPacketDisconnect;
|
||||
import common.packet.RPacketEnableCompression;
|
||||
import common.packet.RPacketLoginSuccess;
|
||||
import common.packet.RPacketRequestEncrypt;
|
||||
import common.packet.RPacketResponse;
|
||||
import common.packet.RPacketServerConfig;
|
||||
|
||||
public interface IClientLoginHandler {
|
||||
void handleDisconnect(RPacketDisconnect packet);
|
||||
void handleLoginSuccess(RPacketLoginSuccess packet);
|
||||
void handleEnableCompression(RPacketEnableCompression packet);
|
||||
void handleEncrypt(RPacketRequestEncrypt packet);
|
||||
void handleConfig(RPacketServerConfig packet);
|
||||
void handleResponse(RPacketResponse packet);
|
||||
void handleChallenge(RPacketChallenge packet);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
package common.network;
|
||||
|
||||
import common.packet.LPacketPasswordResponse;
|
||||
import common.packet.LPacketChallenge;
|
||||
import common.packet.LPacketPassword;
|
||||
import common.packet.LPacketPubkey;
|
||||
import common.packet.LPacketResponse;
|
||||
import common.packet.LPacketStartEncrypt;
|
||||
|
||||
public interface ILoginHandler {
|
||||
void processPasswordResponse(LPacketPasswordResponse packet);
|
||||
void processEncryption(LPacketStartEncrypt packet);
|
||||
void processPassword(LPacketPassword packet);
|
||||
void processPubkey(LPacketPubkey packet);
|
||||
void processResponse(LPacketResponse packet);
|
||||
void processChallenge(LPacketChallenge packet);
|
||||
}
|
||||
|
|
|
@ -22,12 +22,18 @@ import common.packet.CPacketPlayer;
|
|||
import common.packet.CPacketSign;
|
||||
import common.packet.CPacketSkin;
|
||||
import common.packet.HPacketHandshake;
|
||||
import common.packet.LPacketPasswordResponse;
|
||||
import common.packet.LPacketChallenge;
|
||||
import common.packet.LPacketPassword;
|
||||
import common.packet.LPacketPubkey;
|
||||
import common.packet.LPacketResponse;
|
||||
import common.packet.LPacketStartEncrypt;
|
||||
import common.packet.RPacketChallenge;
|
||||
import common.packet.RPacketDisconnect;
|
||||
import common.packet.RPacketEnableCompression;
|
||||
import common.packet.RPacketLoginSuccess;
|
||||
import common.packet.RPacketRequestEncrypt;
|
||||
import common.packet.RPacketResponse;
|
||||
import common.packet.RPacketServerConfig;
|
||||
import common.packet.SPacketEntityRelMove;
|
||||
import common.packet.SPacketEntityLook;
|
||||
import common.packet.SPacketEntityLookMove;
|
||||
|
@ -101,11 +107,17 @@ public enum PacketRegistry {
|
|||
LOGIN {{
|
||||
this.server(RPacketDisconnect.class);
|
||||
this.server(RPacketRequestEncrypt.class);
|
||||
this.server(RPacketResponse.class);
|
||||
this.server(RPacketChallenge.class);
|
||||
this.server(RPacketServerConfig.class);
|
||||
this.server(RPacketLoginSuccess.class);
|
||||
this.server(RPacketEnableCompression.class);
|
||||
|
||||
this.client(LPacketStartEncrypt.class);
|
||||
this.client(LPacketPasswordResponse.class);
|
||||
this.client(LPacketPassword.class);
|
||||
this.client(LPacketChallenge.class);
|
||||
this.client(LPacketPubkey.class);
|
||||
this.client(LPacketResponse.class);
|
||||
}},
|
||||
PLAY {{
|
||||
this.server(SPacketKeepAlive.class);
|
||||
|
|
37
common/src/main/java/common/packet/LPacketChallenge.java
Normal file
37
common/src/main/java/common/packet/LPacketChallenge.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import common.network.ILoginHandler;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
import common.util.EncryptUtil;
|
||||
|
||||
public class LPacketChallenge implements Packet<ILoginHandler> {
|
||||
private byte[] token;
|
||||
|
||||
public LPacketChallenge() {
|
||||
}
|
||||
|
||||
public LPacketChallenge(PublicKey pubkey, byte[] token) {
|
||||
this.token = EncryptUtil.encryptData(pubkey, token);
|
||||
}
|
||||
|
||||
public final void readPacketData(PacketBuffer buf) throws IOException {
|
||||
this.token = buf.readByteArray();
|
||||
}
|
||||
|
||||
public final void writePacketData(PacketBuffer buf) throws IOException {
|
||||
buf.writeByteArray(this.token);
|
||||
}
|
||||
|
||||
public void processPacket(ILoginHandler handler) {
|
||||
handler.processChallenge(this);
|
||||
}
|
||||
|
||||
public byte[] getToken(PrivateKey key) {
|
||||
return EncryptUtil.decryptData(key, this.token);
|
||||
}
|
||||
}
|
|
@ -7,20 +7,20 @@ import common.network.IPlayer;
|
|||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
|
||||
public class LPacketPasswordResponse implements Packet<ILoginHandler>
|
||||
public class LPacketPassword implements Packet<ILoginHandler>
|
||||
{
|
||||
private String user;
|
||||
private String access;
|
||||
private String password;
|
||||
|
||||
public LPacketPasswordResponse()
|
||||
public LPacketPassword()
|
||||
{
|
||||
}
|
||||
|
||||
public LPacketPasswordResponse(String userIn, String accessIn, String passwordIn)
|
||||
public LPacketPassword(String user, String access, String passwordIn)
|
||||
{
|
||||
this.user = userIn;
|
||||
this.access = accessIn;
|
||||
this.user = user;
|
||||
this.access = access;
|
||||
this.password = passwordIn;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class LPacketPasswordResponse implements Packet<ILoginHandler>
|
|||
*/
|
||||
public void processPacket(ILoginHandler handler)
|
||||
{
|
||||
handler.processPasswordResponse(this);
|
||||
handler.processPassword(this);
|
||||
}
|
||||
|
||||
public String getUser()
|
53
common/src/main/java/common/packet/LPacketPubkey.java
Normal file
53
common/src/main/java/common/packet/LPacketPubkey.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import common.network.ILoginHandler;
|
||||
import common.network.IPlayer;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
import common.util.EncryptUtil;
|
||||
|
||||
public class LPacketPubkey implements Packet<ILoginHandler> {
|
||||
private String user;
|
||||
private String access;
|
||||
private PublicKey key;
|
||||
|
||||
public LPacketPubkey() {
|
||||
}
|
||||
|
||||
public LPacketPubkey(String user, String access, PublicKey key) {
|
||||
this.user = user;
|
||||
this.access = access;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public final void readPacketData(PacketBuffer buf) throws IOException {
|
||||
this.user = buf.readString(IPlayer.MAX_USER_LENGTH);
|
||||
this.access = buf.readString(IPlayer.MAX_PASS_LENGTH);
|
||||
this.key = EncryptUtil.decodePublicKey(buf.readByteArray());
|
||||
}
|
||||
|
||||
public final void writePacketData(PacketBuffer buf) throws IOException {
|
||||
buf.writeString(this.user);
|
||||
buf.writeString(this.access);
|
||||
buf.writeByteArray(this.key.getEncoded());
|
||||
}
|
||||
|
||||
public void processPacket(ILoginHandler handler) {
|
||||
handler.processPubkey(this);
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
public String getAccess() {
|
||||
return this.access;
|
||||
}
|
||||
|
||||
public PublicKey getKey() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
33
common/src/main/java/common/packet/LPacketResponse.java
Normal file
33
common/src/main/java/common/packet/LPacketResponse.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import common.network.ILoginHandler;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
|
||||
public class LPacketResponse implements Packet<ILoginHandler> {
|
||||
private byte[] token = new byte[0];
|
||||
|
||||
public LPacketResponse() {
|
||||
}
|
||||
|
||||
public LPacketResponse(byte[] token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public void readPacketData(PacketBuffer buf) throws IOException {
|
||||
this.token = buf.readByteArray();
|
||||
}
|
||||
|
||||
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||
buf.writeByteArray(this.token);
|
||||
}
|
||||
|
||||
public void processPacket(ILoginHandler handler) {
|
||||
handler.processResponse(this);
|
||||
}
|
||||
|
||||
public byte[] getToken() {
|
||||
return this.token;
|
||||
}
|
||||
}
|
|
@ -42,6 +42,6 @@ public class LPacketStartEncrypt implements Packet<ILoginHandler> {
|
|||
}
|
||||
|
||||
public byte[] getToken(PrivateKey key) {
|
||||
return key == null ? this.token : EncryptUtil.decryptData(key, this.token);
|
||||
return EncryptUtil.decryptData(key, this.token);
|
||||
}
|
||||
}
|
||||
|
|
37
common/src/main/java/common/packet/RPacketChallenge.java
Normal file
37
common/src/main/java/common/packet/RPacketChallenge.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import common.network.IClientLoginHandler;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
import common.util.EncryptUtil;
|
||||
|
||||
public class RPacketChallenge implements Packet<IClientLoginHandler> {
|
||||
private byte[] token;
|
||||
|
||||
public RPacketChallenge() {
|
||||
}
|
||||
|
||||
public RPacketChallenge(PublicKey pubkey, byte[] token) {
|
||||
this.token = EncryptUtil.encryptData(pubkey, token);
|
||||
}
|
||||
|
||||
public final void readPacketData(PacketBuffer buf) throws IOException {
|
||||
this.token = buf.readByteArray();
|
||||
}
|
||||
|
||||
public final void writePacketData(PacketBuffer buf) throws IOException {
|
||||
buf.writeByteArray(this.token);
|
||||
}
|
||||
|
||||
public void processPacket(IClientLoginHandler handler) {
|
||||
handler.handleChallenge(this);
|
||||
}
|
||||
|
||||
public byte[] getToken(PrivateKey key) {
|
||||
return EncryptUtil.decryptData(key, this.token);
|
||||
}
|
||||
}
|
33
common/src/main/java/common/packet/RPacketResponse.java
Normal file
33
common/src/main/java/common/packet/RPacketResponse.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import common.network.IClientLoginHandler;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
|
||||
public class RPacketResponse implements Packet<IClientLoginHandler> {
|
||||
private byte[] token = new byte[0];
|
||||
|
||||
public RPacketResponse() {
|
||||
}
|
||||
|
||||
public RPacketResponse(byte[] token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public void readPacketData(PacketBuffer buf) throws IOException {
|
||||
this.token = buf.readByteArray();
|
||||
}
|
||||
|
||||
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||
buf.writeByteArray(this.token);
|
||||
}
|
||||
|
||||
public void processPacket(IClientLoginHandler handler) {
|
||||
handler.handleResponse(this);
|
||||
}
|
||||
|
||||
public byte[] getToken() {
|
||||
return this.token;
|
||||
}
|
||||
}
|
60
common/src/main/java/common/packet/RPacketServerConfig.java
Normal file
60
common/src/main/java/common/packet/RPacketServerConfig.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
package common.packet;
|
||||
|
||||
import java.io.IOException;
|
||||
import common.network.IClientLoginHandler;
|
||||
import common.network.Packet;
|
||||
import common.network.PacketBuffer;
|
||||
|
||||
public class RPacketServerConfig implements Packet<IClientLoginHandler> {
|
||||
private boolean requiresAccess;
|
||||
private boolean requiresAuth;
|
||||
private boolean passwordAuth;
|
||||
private boolean pubkeyAuth;
|
||||
|
||||
public RPacketServerConfig() {
|
||||
}
|
||||
|
||||
public RPacketServerConfig(boolean requiresAccess, boolean requiresAuth, boolean passwordAuth, boolean pubkeyAuth) {
|
||||
this.requiresAccess = requiresAccess;
|
||||
this.requiresAuth = requiresAuth;
|
||||
this.passwordAuth = passwordAuth;
|
||||
this.pubkeyAuth = pubkeyAuth;
|
||||
}
|
||||
|
||||
public final void readPacketData(PacketBuffer buf) throws IOException {
|
||||
byte flags = buf.readByte();
|
||||
this.requiresAccess = (flags & 1) != 0;
|
||||
this.requiresAuth = (flags & 2) != 0;
|
||||
this.passwordAuth = (flags & 4) != 0;
|
||||
this.pubkeyAuth = (flags & 8) != 0;
|
||||
}
|
||||
|
||||
public final void writePacketData(PacketBuffer buf) throws IOException {
|
||||
byte flags = 0;
|
||||
flags |= this.requiresAccess ? 1 : 0;
|
||||
flags |= this.requiresAuth ? 2 : 0;
|
||||
flags |= this.passwordAuth ? 4 : 0;
|
||||
flags |= this.pubkeyAuth ? 8 : 0;
|
||||
buf.writeByte(flags);
|
||||
}
|
||||
|
||||
public void processPacket(IClientLoginHandler handler) {
|
||||
handler.handleConfig(this);
|
||||
}
|
||||
|
||||
public boolean hasAccessPassword() {
|
||||
return this.requiresAccess;
|
||||
}
|
||||
|
||||
public boolean isAuthenticating() {
|
||||
return this.passwordAuth;
|
||||
}
|
||||
|
||||
public boolean canUsePassword() {
|
||||
return this.passwordAuth;
|
||||
}
|
||||
|
||||
public boolean canUsePubkey() {
|
||||
return this.pubkeyAuth;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import java.security.PublicKey;
|
|||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.EncodedKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
|
@ -59,6 +60,18 @@ public class EncryptUtil {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static PrivateKey decodePrivateKey(byte[] encoded) {
|
||||
try {
|
||||
EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
|
||||
KeyFactory factory = KeyFactory.getInstance("RSA");
|
||||
return factory.generatePrivate(spec);
|
||||
}
|
||||
catch(NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
Log.SYSTEM.error(e, "Privater Schlüssel konnte nicht dekodiert werden");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SecretKey decryptSharedKey(PrivateKey key, byte[] secret) {
|
||||
return new SecretKeySpec(decryptData(key, secret), "AES");
|
||||
|
|
|
@ -408,4 +408,27 @@ int utf_len(const char *str) {
|
|||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String getHexString(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int z = 0; z < bytes.length; z++) {
|
||||
sb.append(String.format("%02x", bytes[z]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] fromHexString(String str) {
|
||||
if((str.length() & 1) == 1)
|
||||
str = "0" + str;
|
||||
byte[] bytes = new byte[str.length() / 2];
|
||||
try {
|
||||
for(int z = 0; z < bytes.length; z++) {
|
||||
bytes[z] = (byte)Integer.parseUnsignedInt(str.substring(z * 2, (z + 1) * 2), 16);
|
||||
}
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue