1#![doc = include_str!("../README.md")]
2
3pub mod offline;
4#[cfg(feature = "signing")]
5pub mod signing;
6
7use aes::{
8 Aes128,
9 cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit, inout::InOutBuf},
10};
11use rand::{TryRngCore, rngs::OsRng};
12use sha1::{Digest, Sha1};
13
14#[cfg(feature = "signing")]
15#[doc(hidden)]
16#[deprecated = "moved to `signing::MessageSignature`."]
17pub type MessageSignature = signing::MessageSignature;
18
19#[cfg(feature = "signing")]
20#[doc(hidden)]
21#[deprecated = "moved to `signing::SignChatMessageOptions`."]
22pub type SignChatMessageOptions = signing::SignChatMessageOptions;
23
24#[cfg(feature = "signing")]
25#[doc(hidden)]
26#[deprecated = "moved to `signing::make_salt`."]
27pub fn make_salt() -> u64 {
28 signing::make_salt()
29}
30
31fn generate_secret_key() -> [u8; 16] {
32 let mut key = [0u8; 16];
33 OsRng.try_fill_bytes(&mut key).unwrap();
34 key
35}
36
37pub fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec<u8> {
38 let mut digest = Sha1::new();
39 digest.update(server_id);
40 digest.update(private_key);
41 digest.update(public_key);
42 digest.finalize().to_vec()
43}
44
45pub fn hex_digest(digest: &[u8]) -> String {
46 num_bigint::BigInt::from_signed_bytes_be(digest).to_str_radix(16)
53}
54
55#[derive(Debug)]
56pub struct EncryptResult {
57 pub secret_key: [u8; 16],
58 pub encrypted_public_key: Vec<u8>,
59 pub encrypted_challenge: Vec<u8>,
60}
61
62pub fn encrypt(public_key: &[u8], challenge: &[u8]) -> Result<EncryptResult, String> {
63 let secret_key = generate_secret_key();
67 let encrypted_public_key: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, &secret_key)?;
73 let encrypted_challenge: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, challenge)?;
74
75 Ok(EncryptResult {
76 secret_key,
77 encrypted_public_key,
78 encrypted_challenge,
79 })
80}
81
82pub type Aes128CfbEnc = cfb8::Encryptor<Aes128>;
83pub type Aes128CfbDec = cfb8::Decryptor<Aes128>;
84
85pub fn create_cipher(key: &[u8]) -> (Aes128CfbEnc, Aes128CfbDec) {
86 (
87 Aes128CfbEnc::new_from_slices(key, key).unwrap(),
88 Aes128CfbDec::new_from_slices(key, key).unwrap(),
89 )
90}
91
92pub fn encrypt_packet(cipher: &mut Aes128CfbEnc, packet: &mut [u8]) {
93 let (chunks, rest) = InOutBuf::from(packet).into_chunks();
94 assert!(rest.is_empty());
95 cipher.encrypt_blocks_inout_mut(chunks);
96}
97pub fn decrypt_packet(cipher: &mut Aes128CfbDec, packet: &mut [u8]) {
98 let (chunks, rest) = InOutBuf::from(packet).into_chunks();
99 assert!(rest.is_empty());
100 cipher.decrypt_blocks_inout_mut(chunks);
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_generate_secret_key() {
109 let key = generate_secret_key();
110 assert_eq!(key.len(), 16);
111 }
112
113 #[test]
114 fn test_hex_digest() {
115 let digest = hex_digest(&digest_data(b"Notch", &[], &[]));
116 assert_eq!(digest, "4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48");
117
118 let digest = hex_digest(&digest_data(b"jeb_", &[], &[]));
119 assert_eq!(digest, "-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1");
120
121 let digest = hex_digest(&digest_data(b"simon", &[], &[]));
122 assert_eq!(digest, "88e16a1019277b15d58faf0541e11910eb756f6");
123 }
124
125 #[test]
126 fn encode_packet_twice() {
127 let mut packet = vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
128 let (mut enc_cipher, _dec_cipher) = create_cipher(b"1234567890123456");
129 encrypt_packet(&mut enc_cipher, &mut packet);
130 assert_eq!(packet, vec![117, 151, 183, 45, 229, 232, 43, 181, 121, 16]);
131 let mut packet = vec![0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13];
132 encrypt_packet(&mut enc_cipher, &mut packet);
133 assert_eq!(
134 packet,
135 vec![185, 223, 129, 153, 173, 140, 133, 239, 59, 168]
136 );
137 }
138
139 #[test]
140 fn encode_packet_long() {
141 let mut packet = (0..=255).collect::<Vec<u8>>();
142 let (mut enc_cipher, _dec_cipher) = create_cipher(b"1234567890123456");
143 encrypt_packet(&mut enc_cipher, &mut packet);
144 assert_eq!(
145 packet,
146 vec![
147 117, 151, 183, 45, 229, 232, 43, 181, 121, 16, 185, 223, 129, 153, 173, 140, 133,
148 239, 59, 168, 148, 39, 97, 19, 22, 219, 78, 70, 116, 143, 21, 223, 155, 99, 201,
149 62, 133, 77, 244, 152, 254, 36, 135, 147, 45, 25, 66, 236, 2, 12, 101, 39, 140, 62,
150 7, 57, 19, 101, 217, 91, 142, 243, 0, 3, 100, 142, 160, 21, 219, 145, 151, 37, 11,
151 30, 190, 176, 26, 90, 143, 63, 255, 188, 254, 40, 41, 92, 163, 197, 8, 8, 111, 175,
152 49, 234, 82, 34, 5, 96, 162, 7, 217, 42, 77, 38, 127, 213, 207, 251, 34, 173, 34,
153 132, 23, 12, 118, 59, 51, 216, 173, 199, 137, 95, 132, 222, 243, 195, 81, 60, 205,
154 52, 65, 209, 125, 137, 5, 52, 219, 165, 248, 35, 173, 57, 200, 182, 162, 148, 70,
155 62, 102, 21, 220, 158, 71, 98, 47, 231, 196, 58, 8, 70, 160, 177, 159, 50, 20, 187,
156 31, 249, 68, 26, 142, 171, 239, 193, 10, 174, 14, 80, 238, 114, 124, 185, 253, 246,
157 47, 67, 37, 69, 70, 9, 69, 135, 13, 195, 253, 8, 241, 175, 170, 75, 231, 7, 92, 18,
158 38, 132, 65, 146, 202, 130, 238, 224, 30, 113, 168, 241, 159, 131, 238, 67, 1, 244,
159 74, 172, 86, 95, 192, 236, 198, 188, 81, 67, 49, 230, 166, 52, 224, 238, 11, 252,
160 0, 179, 56, 209, 231, 62, 146, 106, 18, 217, 138, 89, 110, 240, 255, 192
161 ]
162 );
163 }
164
165 #[test]
166 fn encode_decode_packet() {
167 let mut packet = vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
168 let (mut enc_cipher, mut dec_cipher) = create_cipher(b"1234567890123456");
169 encrypt_packet(&mut enc_cipher, &mut packet);
170 decrypt_packet(&mut dec_cipher, &mut packet);
171 assert_eq!(
172 packet,
173 vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]
174 );
175 }
176}