-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #162 from yushijinhun/develop
Release v1.1.45
- Loading branch information
Showing
9 changed files
with
131 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2021 Haowei Wen <[email protected]> and contributors | ||
* Copyright (C) 2022 Haowei Wen <[email protected]> and contributors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as published by | ||
|
@@ -16,11 +16,18 @@ | |
*/ | ||
package moe.yushi.authlibinjector.transform.support; | ||
|
||
import static moe.yushi.authlibinjector.util.Logging.Level.DEBUG; | ||
import static org.objectweb.asm.Opcodes.ALOAD; | ||
import static org.objectweb.asm.Opcodes.ASM9; | ||
import static org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; | ||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; | ||
import static org.objectweb.asm.Opcodes.IRETURN; | ||
import java.lang.invoke.MethodHandle; | ||
import java.security.GeneralSecurityException; | ||
import java.security.PublicKey; | ||
import java.security.Signature; | ||
import java.security.SignatureException; | ||
import java.util.Base64; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
@@ -31,6 +38,8 @@ | |
import moe.yushi.authlibinjector.transform.CallbackSupport; | ||
import moe.yushi.authlibinjector.transform.TransformContext; | ||
import moe.yushi.authlibinjector.transform.TransformUnit; | ||
import moe.yushi.authlibinjector.util.Logging; | ||
import moe.yushi.authlibinjector.util.Logging.Level; | ||
|
||
public class YggdrasilKeyTransformUnit implements TransformUnit { | ||
|
||
|
@@ -49,6 +58,35 @@ public static boolean verifyPropertySignature(Object property, PublicKey mojangK | |
return false; | ||
} | ||
|
||
@CallbackMethod | ||
public static boolean verifyPropertySignatureNew(Signature mojangSignatureObj, String propertyValue, String base64Signature) { | ||
byte[] sig = Base64.getDecoder().decode(base64Signature); | ||
byte[] data = propertyValue.getBytes(); | ||
|
||
try { | ||
mojangSignatureObj.update(data); | ||
if (mojangSignatureObj.verify(sig)) | ||
return true; | ||
} catch (SignatureException e) { | ||
Logging.log(DEBUG, "Failed to verify signature with Mojang's key", e); | ||
} | ||
|
||
for (PublicKey customKey : PUBLIC_KEYS) { | ||
try { | ||
Signature signature = Signature.getInstance("SHA1withRSA"); | ||
signature.initVerify(customKey); | ||
signature.update(data); | ||
if (signature.verify(sig)) | ||
return true; | ||
} catch (GeneralSecurityException e) { | ||
Logging.log(DEBUG, "Failed to verify signature with custom key " + customKey, e); | ||
} | ||
} | ||
|
||
Logging.log(Level.WARNING, "Failed to verify property signature"); | ||
return false; | ||
} | ||
|
||
@Override | ||
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) { | ||
if ("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService".equals(className)) { | ||
|
@@ -73,6 +111,32 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri | |
} | ||
|
||
}); | ||
} else if ("com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo".equals(className)) { | ||
return Optional.of(new ClassVisitor(ASM9, writer) { | ||
@Override | ||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { | ||
if ("validateProperty".equals(name) && "(Lcom/mojang/authlib/properties/Property;)Z".equals(desc)) { | ||
ctx.markModified(); | ||
|
||
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); | ||
mv.visitCode(); | ||
mv.visitVarInsn(ALOAD, 0); | ||
mv.visitMethodInsn(INVOKEVIRTUAL, "com/mojang/authlib/yggdrasil/YggdrasilServicesKeyInfo", "signature", "()Ljava/security/Signature;", false); | ||
mv.visitVarInsn(ALOAD, 1); | ||
mv.visitMethodInsn(INVOKEVIRTUAL, "com/mojang/authlib/properties/Property", "getValue", "()Ljava/lang/String;", false); | ||
mv.visitVarInsn(ALOAD, 1); | ||
mv.visitMethodInsn(INVOKEVIRTUAL, "com/mojang/authlib/properties/Property", "getSignature", "()Ljava/lang/String;", false); | ||
CallbackSupport.invoke(ctx, mv, YggdrasilKeyTransformUnit.class, "verifyPropertySignatureNew"); | ||
mv.visitInsn(IRETURN); | ||
mv.visitMaxs(-1, -1); | ||
mv.visitEnd(); | ||
|
||
return null; | ||
} else { | ||
return super.visitMethod(access, name, desc, signature, exceptions); | ||
} | ||
} | ||
}); | ||
} else { | ||
return Optional.empty(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2019 Haowei Wen <[email protected]> and contributors | ||
* Copyright (C) 2022 Haowei Wen <[email protected]> and contributors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as published by | ||
|
@@ -18,15 +18,14 @@ | |
|
||
import static java.nio.charset.StandardCharsets.US_ASCII; | ||
import static moe.yushi.authlibinjector.util.IOUtils.asBytes; | ||
import static org.junit.Assert.assertArrayEquals; | ||
import static org.junit.Assert.assertEquals; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.EOFException; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
import org.junit.Test; | ||
import org.junit.jupiter.api.Test; | ||
|
||
@SuppressWarnings("resource") | ||
public class ChunkedInputStreamTest { | ||
|
@@ -76,99 +75,99 @@ public void testRead5() throws IOException { | |
assertEquals(underlying.read(), -1); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF1() throws IOException { | ||
byte[] data = ("a").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF2() throws IOException { | ||
byte[] data = ("a\r").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF3() throws IOException { | ||
byte[] data = ("a\r\n").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF4() throws IOException { | ||
byte[] data = ("a\r\nabc").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF5() throws IOException { | ||
byte[] data = ("a\r\n123456789a\r").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF6() throws IOException { | ||
byte[] data = ("a\r\n123456789a\r\n").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF7() throws IOException { | ||
byte[] data = ("a\r\n123456789a\r\n0\r\n\r").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = IOException.class) | ||
@Test | ||
public void testBadIn1() throws IOException { | ||
byte[] data = ("-1").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(IOException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = IOException.class) | ||
@Test | ||
public void testBadIn2() throws IOException { | ||
byte[] data = ("a\ra").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(IOException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = IOException.class) | ||
@Test | ||
public void testBadIn3() throws IOException { | ||
byte[] data = ("a\r\n123456789aa").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(IOException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = IOException.class) | ||
@Test | ||
public void testBadIn4() throws IOException { | ||
byte[] data = ("a\r\n123456789a\ra").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(IOException.class, () -> asBytes(in)); | ||
} | ||
|
||
@Test(expected = IOException.class) | ||
@Test | ||
public void testBadIn5() throws IOException { | ||
byte[] data = ("a\r\n123456789a\r\n0\r\n\r-").getBytes(US_ASCII); | ||
ByteArrayInputStream underlying = new ByteArrayInputStream(data); | ||
InputStream in = new ChunkedInputStream(underlying); | ||
asBytes(in); | ||
assertThrows(IOException.class, () -> asBytes(in)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2019 Haowei Wen <[email protected]> and contributors | ||
* Copyright (C) 2022 Haowei Wen <[email protected]> and contributors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as published by | ||
|
@@ -17,16 +17,15 @@ | |
package moe.yushi.authlibinjector.internal.fi.iki.elonen; | ||
|
||
import static moe.yushi.authlibinjector.util.IOUtils.asBytes; | ||
import static org.junit.Assert.assertArrayEquals; | ||
import static org.junit.Assert.assertEquals; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.EOFException; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.Arrays; | ||
|
||
import org.junit.Test; | ||
import org.junit.jupiter.api.Test; | ||
|
||
@SuppressWarnings("resource") | ||
public class FixedLengthInputStreamTest { | ||
|
@@ -58,10 +57,10 @@ public void testRead3() throws IOException { | |
assertEquals(underlying.read(), 0x11); | ||
} | ||
|
||
@Test(expected = EOFException.class) | ||
@Test | ||
public void testReadEOF() throws IOException { | ||
byte[] data = new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55 }; | ||
InputStream in = new FixedLengthInputStream(new ByteArrayInputStream(data), 6); | ||
asBytes(in); | ||
assertThrows(EOFException.class, () -> asBytes(in)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2020 Haowei Wen <[email protected]> and contributors | ||
* Copyright (C) 2022 Haowei Wen <[email protected]> and contributors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as published by | ||
|
@@ -18,9 +18,9 @@ | |
|
||
import static java.util.Collections.emptyList; | ||
import static java.util.Collections.emptyMap; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import java.util.Optional; | ||
import org.junit.Test; | ||
import org.junit.jupiter.api.Test; | ||
import moe.yushi.authlibinjector.APIMetadata; | ||
import moe.yushi.authlibinjector.httpd.DefaultURLRedirector; | ||
|
||
|
Oops, something went wrong.