1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#![recursion_limit = "128"] #[macro_use] extern crate error_chain; extern crate byteorder; extern crate clacks_mtproto; extern crate openssl; extern crate rand; pub mod error { error_chain! { links { Mtproto(::clacks_mtproto::error::Error, ::clacks_mtproto::error::ErrorKind); } foreign_links { Io(::std::io::Error); Utf8(::std::str::Utf8Error); FromUtf8(::std::string::FromUtf8Error); Openssl(::openssl::error::ErrorStack); } errors { InvalidData {} BoxedAsBare {} ReceivedSendType {} UnsupportedLayer {} NoAuthKey {} NoSalts {} WrongAuthKey {} InvalidLength {} Unknown {} FactorizationFailure {} AuthenticationFailure {} } } } pub mod asymm; pub mod symm; enum Padding { Total255, Mod16, } fn sha1_bytes(parts: &[&[u8]]) -> ::error::Result<::openssl::hash::DigestBytes> { let mut hasher = ::openssl::hash::Hasher::new(::openssl::hash::MessageDigest::sha1())?; for part in parts { hasher.update(part)?; } Ok(hasher.finish()?) } fn sha1_and_or_pad(input: &[u8], prepend_sha1: bool, padding: Padding) -> ::error::Result<Vec<u8>> { let mut ret = if prepend_sha1 { sha1_bytes(&[input])?.to_vec() } else { vec![] }; ret.extend(input); match padding { Padding::Total255 => { while ret.len() < 255 { ret.push(0); } }, Padding::Mod16 if ret.len() % 16 != 0 => { for _ in 0..16 - (ret.len() % 16) { ret.push(0); } }, _ => (), } Ok(ret) }