diff --git a/Cargo.lock b/Cargo.lock index c037630d..c460835d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,6 +64,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" name = "azalea-auth" version = "0.1.0" dependencies = [ + "num-bigint", + "rand", + "sha-1", "uuid", ] @@ -133,6 +136,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +dependencies = [ + "generic-array", +] + [[package]] name = "bot" version = "0.1.0" @@ -198,6 +210,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.0" @@ -289,6 +310,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "csv" version = "1.1.6" @@ -317,6 +347,17 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer", + "crypto-common", + "generic-array", +] + [[package]] name = "either" version = "1.6.1" @@ -419,6 +460,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -640,6 +691,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -651,6 +713,16 @@ dependencies = [ "syn", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -959,6 +1031,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "slab" version = "0.4.5" @@ -1133,6 +1216,12 @@ dependencies = [ "trust-dns-proto", ] +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + [[package]] name = "unicode-bidi" version = "0.3.7" @@ -1184,6 +1273,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "walkdir" version = "2.3.2" diff --git a/azalea-auth/Cargo.toml b/azalea-auth/Cargo.toml index aa9b7bdb..cb807776 100644 --- a/azalea-auth/Cargo.toml +++ b/azalea-auth/Cargo.toml @@ -6,4 +6,7 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +num-bigint = "^0.4.3" +rand = {version = "^0.8.4", features = ["getrandom"]} +sha-1 = "^0.10.0" uuid = "^0.8.2" diff --git a/azalea-auth/src/encryption.rs b/azalea-auth/src/encryption.rs new file mode 100644 index 00000000..334d8cb3 --- /dev/null +++ b/azalea-auth/src/encryption.rs @@ -0,0 +1,53 @@ +use rand::{rngs::OsRng, RngCore}; +use sha1::{Digest, Sha1}; + +fn generate_secret_key() -> [u8; 16] { + let mut key = [0u8; 16]; + OsRng.fill_bytes(&mut key); + key +} + +fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec { + let mut digest = Sha1::new(); + digest.update(server_id); + digest.update(public_key); + digest.update(private_key); + digest.finalize().to_vec() +} + +fn hex_digest(digest: &[u8]) -> String { + // Note that the Sha1.hexdigest() method used by minecraft is non standard. + // It doesn't match the digest method found in most programming languages + // and libraries. It works by treating the sha1 output bytes as one large + // integer in two's complement and then printing the integer in base 16, + // placing a minus sign if the interpreted number is negative. + num_bigint::BigInt::from_signed_bytes_be(digest).to_str_radix(16) +} + +fn encrypt(public_key: &[u8], server_id: String, nonce: &[u8]) { + let secret_key = generate_secret_key(); + let hash = hex_digest(&digest_data(server_id.as_bytes(), public_key, &secret_key)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_generate_secret_key() { + let key = generate_secret_key(); + assert_eq!(key.len(), 16); + } + + #[test] + fn test_hex_digest() { + let digest = hex_digest(&digest_data(b"Notch", &[], &[])); + assert_eq!(digest, "4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48"); + + let digest = hex_digest(&digest_data(b"jeb_", &[], &[])); + assert_eq!(digest, "-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1"); + + let digest = hex_digest(&digest_data(b"simon", &[], &[])); + assert_eq!(digest, "88e16a1019277b15d58faf0541e11910eb756f6"); + } +} diff --git a/azalea-auth/src/lib.rs b/azalea-auth/src/lib.rs index 773ea1d9..afe9eb33 100644 --- a/azalea-auth/src/lib.rs +++ b/azalea-auth/src/lib.rs @@ -1,3 +1,6 @@ //! Handle Minecraft authentication. pub mod game_profile; +pub mod encryption; + + diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 90cb3ad7..7d987eab 100644 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -39,6 +39,7 @@ pub async fn join_server(address: &ServerAddress) -> Result<(), String> { Ok(packet) => match packet { LoginPacket::ClientboundHelloPacket(p) => { println!("Got encryption request {:?} {:?}", p.nonce, p.public_key); + panic!(""); } LoginPacket::ClientboundLoginCompressionPacket(p) => { println!("Got compression request {:?}", p.compression_threshold); @@ -73,7 +74,7 @@ pub async fn join_server(address: &ServerAddress) -> Result<(), String> { _ => panic!("unhandled packet"), }, Err(e) => { - println!("Error: {:?}", e); + panic!("Error: {:?}", e); } } } diff --git a/bot/src/main.rs b/bot/src/main.rs index 1041e765..435803e2 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -4,8 +4,8 @@ use azalea_client::connect::join_server; async fn main() { println!("Hello, world!"); - let address = "95.111.249.143:10000"; - // let address = "localhost:63482"; + // let address = "95.111.249.143:10000"; + let address = "localhost:58566"; let _response = join_server(&address.try_into().unwrap()).await.unwrap(); // println!("{}", response.description.to_ansi(None)); println!("connected");