├── mini ├── tor │ ├── circuit_node.cpp │ ├── common.h │ ├── crypto │ │ ├── hybrid_encryption.h │ │ ├── key_agreement_ntor.h │ │ ├── key_agreement.h │ │ ├── key_agreement_tap.h │ │ └── hybrid_encryption.cpp │ ├── circuit_node_crypto_state.h │ ├── parsers │ │ ├── introduction_point_parser.h │ │ ├── onion_router_descriptor_parser.h │ │ ├── hidden_service_descriptor_parser.h │ │ ├── hidden_service_descriptor_parser.cpp │ │ ├── introduction_point_parser.cpp │ │ └── onion_router_descriptor_parser.cpp │ ├── hidden_service.h │ ├── circuit_node.h │ ├── relay_cell.cpp │ ├── tor_stream.h │ ├── tor_socket.h │ ├── consensus.h │ └── relay_cell.h ├── crypto │ ├── ext │ │ ├── detail │ │ │ ├── curve25519-donna.cpp │ │ │ └── curve25519-donna.h │ │ ├── base32.h │ │ ├── key.h │ │ ├── curve25519.h │ │ ├── curve25519.cpp │ │ └── base32.cpp │ ├── base16.h │ ├── base32.h │ ├── base64.h │ ├── sha1.h │ ├── curve25519.h │ ├── hmac_sha256.h │ ├── base │ │ └── key.h │ ├── capi │ │ ├── base16.h │ │ ├── base64.h │ │ ├── detail │ │ │ ├── base_encode.h │ │ │ └── base_encode.cpp │ │ ├── random.cpp │ │ ├── provider.h │ │ ├── random.h │ │ ├── provider.cpp │ │ ├── hmac.h │ │ ├── base64.cpp │ │ ├── base16.cpp │ │ ├── hmac.inl │ │ ├── hash.h │ │ └── key.h │ ├── random.h │ ├── aes.h │ ├── dh.h │ ├── rsa.h │ ├── cng │ │ ├── random.cpp │ │ ├── random.h │ │ ├── hmac.h │ │ ├── provider.h │ │ ├── hmac.inl │ │ └── hash.h │ ├── rfc5869.h │ └── common.h ├── ctl.h ├── ctl │ ├── cctype.h │ ├── cstring.h │ └── cstdlib.h ├── threading │ ├── common.h │ ├── thread_function.h │ ├── locked_value.h │ ├── mutex.cpp │ ├── event.h │ ├── mutex.h │ ├── thread.h │ ├── event.cpp │ ├── locked_value.inl │ └── thread.cpp ├── net │ ├── http.h │ ├── http.cpp │ ├── ssl_stream.h │ ├── ssl_socket.h │ ├── tcp_socket.h │ ├── ssl_socket.cpp │ ├── ssl_stream.cpp │ ├── ip_address.h │ └── uri.h ├── byte_buffer.h ├── common.cpp ├── compare.h ├── console.h ├── crt │ └── msvcrt.def ├── io │ ├── file.h │ ├── file.cpp │ ├── stream_reader.h │ ├── file_attributes.cpp │ ├── file_attributes.h │ ├── path.h │ ├── file_enumerator.h │ ├── file_enumerator.cpp │ ├── stream.h │ ├── path.cpp │ └── memory_stream.h ├── byte_buffer_ref.h ├── win32 │ ├── api_set │ │ ├── common.h │ │ ├── api_set_enumerator.cpp │ │ └── api_set_value_enumerator.cpp │ └── pe │ │ ├── section_enumerator.cpp │ │ ├── relocation_fixup_enumerator.cpp │ │ ├── import_thunk_enumerator.cpp │ │ ├── import_directory_enumerator.cpp │ │ ├── export_directory_enumerator.cpp │ │ ├── relocation_directory_enumerator.cpp │ │ ├── tls_directory_enumerator.cpp │ │ └── resource_directory_enumerator.cpp ├── console.cpp ├── memory.h ├── time.h ├── logger.cpp ├── stack_buffer.h ├── ptr.h ├── hash.h ├── algorithm.h ├── time.cpp ├── flags.h ├── logger.h └── stack_buffer.inl ├── .gitignore ├── appveyor.yml ├── LICENSE.txt ├── doc └── example-descriptors │ ├── introduction-point.txt │ ├── server-descriptor-847b1f850344d7876491a54892f904934e4eb85d.txt │ └── hidden-service-descriptor-4frkg4jpbmbjhlsrbyjpbmu3slphz7ts.txt └── README.md /mini/tor/circuit_node.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbenny/mini-tor/HEAD/mini/tor/circuit_node.cpp -------------------------------------------------------------------------------- /mini/crypto/ext/detail/curve25519-donna.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbenny/mini-tor/HEAD/mini/crypto/ext/detail/curve25519-donna.cpp -------------------------------------------------------------------------------- /mini/ctl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // compile-time library 5 | // 6 | 7 | #include "ctl/cctype.h" 8 | #include "ctl/cstdlib.h" 9 | #include "ctl/cstring.h" 10 | -------------------------------------------------------------------------------- /mini/ctl/cctype.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mini::ctl { 4 | 5 | constexpr static bool 6 | isdigit( 7 | char c 8 | ) 9 | { 10 | return c >= '0' && c <= '9'; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /mini/crypto/base16.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/base16.h" 4 | 5 | namespace mini::crypto { 6 | 7 | using base16 = MINI_CRYPTO_BASE16_NAMESPACE::base16; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /mini/crypto/base32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "ext/base32.h" 4 | 5 | namespace mini::crypto { 6 | 7 | using base32 = MINI_CRYPTO_BASE32_NAMESPACE::base32; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /mini/crypto/base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/base64.h" 4 | 5 | namespace mini::crypto { 6 | 7 | using base64 = MINI_CRYPTO_BASE64_NAMESPACE::base64; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /mini/crypto/sha1.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/hash.h" 4 | #include "cng/hash.h" 5 | 6 | namespace mini::crypto { 7 | 8 | using sha1 = MINI_CRYPTO_HASH_NAMESPACE::hash; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mini/crypto/ext/detail/curve25519-donna.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mini::crypto::ext::detail { 4 | 5 | int 6 | curve25519_donna( 7 | uint8_t *mypublic, 8 | const uint8_t *secret, 9 | const uint8_t *basepoint 10 | ); 11 | 12 | } 13 | 14 | -------------------------------------------------------------------------------- /mini/crypto/curve25519.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "cng/curve25519.h" 4 | #include "ext/curve25519.h" 5 | 6 | namespace mini::crypto { 7 | 8 | using curve25519 = MINI_CRYPTO_CURVE25519_NAMESPACE::curve25519; 9 | // using curve25519 = ext::curve25519; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /mini/crypto/hmac_sha256.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/hmac.h" 4 | #include "cng/hmac.h" 5 | 6 | namespace mini::crypto { 7 | 8 | using hmac_sha256 = MINI_CRYPTO_HMAC_NAMESPACE::hmac>; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mini/crypto/base/key.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mini::crypto::base { 4 | 5 | class key 6 | { 7 | public: 8 | virtual ~key( 9 | void 10 | ) = default; 11 | 12 | virtual void 13 | destroy( 14 | void 15 | ) = 0; 16 | 17 | protected: 18 | key( 19 | void 20 | ) = default; 21 | }; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /mini/crypto/ext/base32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini::crypto::ext { 6 | 7 | class base32 8 | { 9 | public: 10 | static string 11 | encode( 12 | const byte_buffer_ref input 13 | ); 14 | 15 | static byte_buffer 16 | decode( 17 | const string_ref input 18 | ); 19 | }; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mini/crypto/capi/base16.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini::crypto::capi { 6 | 7 | class base16 8 | { 9 | public: 10 | static string 11 | encode( 12 | const byte_buffer_ref input 13 | ); 14 | 15 | static byte_buffer 16 | decode( 17 | const string_ref input 18 | ); 19 | }; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mini/crypto/capi/base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini::crypto::capi { 6 | 7 | class base64 8 | { 9 | public: 10 | static string 11 | encode( 12 | const byte_buffer_ref input 13 | ); 14 | 15 | static byte_buffer 16 | decode( 17 | const string_ref input 18 | ); 19 | }; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mini/threading/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::threading { 5 | 6 | enum class wait_result : DWORD 7 | { 8 | success = WAIT_OBJECT_0, 9 | abandoned = WAIT_ABANDONED_0, 10 | timeout = WAIT_TIMEOUT, 11 | failed = WAIT_FAILED, 12 | }; 13 | 14 | #define mini_wait_success(result) ((result) == ::mini::threading::wait_result::success) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /mini/net/http.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini::net::http::client { 6 | 7 | string 8 | get( 9 | const string_ref host, 10 | uint16_t port, 11 | const string_ref path 12 | ); 13 | 14 | string 15 | get( 16 | const string_ref host, 17 | uint16_t port, 18 | const string_ref path, 19 | io::stream& sock 20 | ); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /mini/crypto/random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/random.h" 4 | #include "cng/random.h" 5 | 6 | namespace mini::crypto { 7 | 8 | using random = MINI_CRYPTO_RANDOM_NAMESPACE::random; 9 | 10 | // 11 | // TODO: 12 | // it would be great to come up with better 13 | // solution than this. 14 | // 15 | static auto& random_device = MINI_CRYPTO_RANDOM_NAMESPACE::random_device; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /mini/ctl/cstring.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mini::ctl { 4 | 5 | constexpr static const char* 6 | strchr( 7 | const char* s, 8 | int c 9 | ) 10 | { 11 | return *s == static_cast(c) ? s 12 | : !*s ? nullptr 13 | : strchr(s + 1, c); 14 | } 15 | 16 | constexpr static int strlen( 17 | const char* s 18 | ) 19 | { 20 | return *s == '\0' 21 | ? 0 22 | : strlen(s + 1) + 1; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /mini/byte_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini { 6 | 7 | using byte_buffer = collections::list; 8 | 9 | template<> 10 | struct hash 11 | { 12 | size_type operator()(const byte_buffer& value) const noexcept 13 | { 14 | return detail::hash_array_representation(value.get_buffer(), value.get_size()); 15 | } 16 | }; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.obj 3 | *.slo 4 | *.lo 5 | *.o 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | 11 | # Compiled Static libraries 12 | *.lai 13 | *.la 14 | *.a 15 | 16 | # Binaries 17 | *.exe 18 | *.dll 19 | *.lib 20 | *.ilk 21 | *.pdb 22 | 23 | # Project files 24 | bin/** 25 | 26 | # Visual Studio files 27 | obj/** 28 | ipch 29 | *.psess 30 | *.vspx 31 | *.suo 32 | *.sdf 33 | *.opensdf 34 | *.VC.db 35 | *.VC.opendb 36 | -------------------------------------------------------------------------------- /mini/crypto/aes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/aes.h" 4 | #include "cng/aes.h" 5 | 6 | namespace mini::crypto { 7 | 8 | template < 9 | cipher_mode AES_MODE, 10 | size_type KEY_SIZE 11 | > 12 | using aes_key = MINI_CRYPTO_AES_NAMESPACE::aes_key; 13 | 14 | template < 15 | cipher_mode AES_MODE, 16 | size_type KEY_SIZE 17 | > 18 | using aes = MINI_CRYPTO_AES_NAMESPACE::aes; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /mini/ctl/cstdlib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cctype.h" 3 | 4 | namespace mini::ctl { 5 | 6 | constexpr static int 7 | atoi_impl( 8 | const char* str, 9 | int value 10 | ) 11 | { 12 | return *str 13 | ? isdigit(*str) 14 | ? atoi_impl(str + 1, (*str - '0') + value * 10) 15 | : value 16 | : value; 17 | } 18 | 19 | constexpr static int 20 | atoi( 21 | const char* str 22 | ) 23 | { 24 | return atoi_impl(str, 0); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /mini/crypto/dh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/dh.h" 4 | #include "cng/dh.h" 5 | 6 | namespace mini::crypto { 7 | 8 | template < 9 | size_type KEY_SIZE 10 | > 11 | using dh = MINI_CRYPTO_DH_NAMESPACE::dh; 12 | 13 | template < 14 | size_type KEY_SIZE 15 | > 16 | using dh_public_key = MINI_CRYPTO_DH_NAMESPACE::dh_public_key; 17 | 18 | template < 19 | size_type KEY_SIZE 20 | > 21 | using dh_private_key = MINI_CRYPTO_DH_NAMESPACE::dh_private_key; 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /mini/crypto/rsa.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "capi/rsa.h" 4 | #include "cng/rsa.h" 5 | 6 | namespace mini::crypto { 7 | 8 | template < 9 | size_type KEY_SIZE 10 | > 11 | using rsa = MINI_CRYPTO_RSA_NAMESPACE::rsa; 12 | 13 | template < 14 | size_type KEY_SIZE 15 | > 16 | using rsa_public_key = MINI_CRYPTO_RSA_NAMESPACE::rsa_public_key; 17 | 18 | template < 19 | size_type KEY_SIZE 20 | > 21 | using rsa_private_key = MINI_CRYPTO_RSA_NAMESPACE::rsa_private_key; 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /mini/crypto/capi/detail/base_encode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | namespace mini::crypto::capi::detail { 8 | 9 | void 10 | base_encode_impl( 11 | DWORD flags, 12 | const byte_type* input, 13 | size_type input_size, 14 | char* output, 15 | size_type& output_size 16 | ); 17 | 18 | void 19 | base_decode_impl( 20 | DWORD flags, 21 | const char* input, 22 | size_type input_size, 23 | byte_type* output, 24 | size_type& output_size 25 | ); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /mini/common.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | 4 | namespace mini { 5 | 6 | void 7 | assert( 8 | int expression, 9 | const char* expression_str, 10 | const char* filename, 11 | int line 12 | ) 13 | { 14 | #ifndef MINI_CONFIG_DEBUG 15 | MINI_UNREFERENCED(expression_str); 16 | MINI_UNREFERENCED(filename); 17 | MINI_UNREFERENCED(line); 18 | #endif 19 | 20 | if (!expression) 21 | { 22 | mini_error("!! assertion failed !! %s at %s:%i)", expression_str, filename, line); 23 | __debugbreak(); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /mini/compare.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mini { 4 | 5 | template < 6 | typename T = void 7 | > 8 | struct equal_to 9 | { 10 | constexpr bool 11 | operator()( 12 | const T& lhs, 13 | const T& rhs 14 | ) const 15 | { 16 | return (lhs == rhs); 17 | } 18 | }; 19 | 20 | template < 21 | typename T = void 22 | > 23 | struct less 24 | { 25 | constexpr bool 26 | operator()( 27 | const T& lhs, 28 | const T& rhs 29 | ) const 30 | { 31 | return (lhs < rhs); 32 | } 33 | }; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /mini/crypto/capi/random.cpp: -------------------------------------------------------------------------------- 1 | #include "random.h" 2 | #include "provider.h" 3 | 4 | namespace mini::crypto::capi { 5 | 6 | byte_buffer 7 | random::get_random_bytes( 8 | size_type byte_count 9 | ) 10 | { 11 | byte_buffer result(byte_count); 12 | get_random_bytes(result); 13 | 14 | return result; 15 | } 16 | 17 | void 18 | random::get_random_bytes( 19 | mutable_byte_buffer_ref output 20 | ) 21 | { 22 | CryptGenRandom( 23 | provider_factory.get_rsa_aes_handle(), 24 | static_cast(output.get_size()), 25 | output.get_buffer()); 26 | } 27 | 28 | random random_device; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /mini/crypto/cng/random.cpp: -------------------------------------------------------------------------------- 1 | #include "random.h" 2 | #include "provider.h" 3 | 4 | namespace mini::crypto::cng { 5 | 6 | byte_buffer 7 | random::get_random_bytes( 8 | size_type byte_count 9 | ) 10 | { 11 | byte_buffer result(byte_count); 12 | get_random_bytes(result); 13 | 14 | return result; 15 | } 16 | 17 | void 18 | random::get_random_bytes( 19 | mutable_byte_buffer_ref output 20 | ) 21 | { 22 | BCryptGenRandom( 23 | provider_factory.get_rng_handle(), 24 | output.get_buffer(), 25 | static_cast(output.get_size()), 26 | 0); 27 | } 28 | 29 | random random_device; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mini/crypto/ext/key.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../base/key.h" 3 | #include 4 | 5 | namespace mini::crypto::ext { 6 | 7 | // 8 | // MS CryptoAPI key. 9 | // 10 | 11 | class key 12 | : public base::key 13 | { 14 | public: 15 | ~key( 16 | void 17 | ) override 18 | { 19 | 20 | } 21 | 22 | void 23 | destroy( 24 | void 25 | ) override 26 | { 27 | 28 | } 29 | 30 | protected: 31 | key( 32 | void 33 | ) = default; 34 | 35 | void 36 | swap( 37 | key& /*other*/ 38 | ) 39 | { 40 | 41 | } 42 | }; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /mini/console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | namespace mini::console { 8 | 9 | void 10 | write( 11 | const char* format, 12 | ... 13 | ); 14 | 15 | void 16 | write_with_color( 17 | WORD color, 18 | const char* format, 19 | ... 20 | ); 21 | 22 | void 23 | write_args( 24 | const char* format, 25 | va_list args 26 | ); 27 | 28 | void 29 | write_with_color_args( 30 | WORD color, 31 | const char* format, 32 | va_list args 33 | ); 34 | 35 | WORD 36 | get_color( 37 | void 38 | ); 39 | 40 | void 41 | set_color( 42 | WORD color 43 | ); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /mini/tor/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "onion_router.h" 6 | 7 | namespace mini::tor { 8 | 9 | using circuit_id_type = uint32_t; 10 | using circuit_id_v3_type = uint16_t; 11 | using tor_stream_id_type = uint16_t; 12 | using payload_size_type = uint16_t; 13 | using protocol_version_type = uint16_t; 14 | 15 | enum class circuit_node_type 16 | { 17 | normal, 18 | introduction_point, 19 | }; 20 | 21 | enum class handshake_type 22 | { 23 | tap, 24 | ntor 25 | }; 26 | 27 | static constexpr handshake_type preferred_handshake_type = handshake_type::ntor; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.1.{build} 2 | branches: 3 | only: 4 | - master 5 | skip_tags: true 6 | image: Visual Studio 2017 7 | configuration: Release_Small 8 | platform: x86 9 | before_build: 10 | - cmd: curl -L -o kkrunchy.zip http://www.farbrausch.de/~fg/kkrunchy/kkrunchy_023a2.zip && 7z e kkrunchy.zip *.exe -r 11 | build: 12 | project: mini-tor.sln 13 | parallel: true 14 | verbosity: minimal 15 | artifacts: 16 | - path: bin\x86\$(Configuration)\*.exe 17 | name: mini-tor 18 | deploy: 19 | - provider: GitHub 20 | tag: v$(appveyor_build_version) 21 | auth_token: 22 | secure: bBXezT+UC8HSipR8wUFj1RrOPgsFjRvJxoBERczc7dJuFH08RhqfPuuJcvpQQsCR 23 | prerelease: false 24 | -------------------------------------------------------------------------------- /mini/crt/msvcrt.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | 3 | ; 4 | ; cstdio 5 | ; 6 | 7 | printf 8 | sprintf 9 | snprintf 10 | vprintf 11 | vsprintf_s 12 | _vscprintf 13 | 14 | scanf 15 | sscanf 16 | 17 | ; 18 | ; cstdlib 19 | ; 20 | 21 | malloc 22 | calloc 23 | realloc 24 | free 25 | 26 | abort 27 | exit 28 | atexit 29 | 30 | ; 31 | ; cstring 32 | ; 33 | 34 | strstr 35 | strlen 36 | 37 | memset 38 | memchr 39 | memcmp 40 | memcpy 41 | memmove 42 | 43 | ; 44 | ; cwchar 45 | ; 46 | 47 | wcslen 48 | wcstombs 49 | 50 | ; 51 | ; ctime 52 | ; 53 | 54 | time 55 | _mkgmtime 56 | 57 | ; 58 | ; CRT 59 | ; 60 | 61 | _EH_prolog 62 | __CxxFrameHandler3 63 | -------------------------------------------------------------------------------- /mini/threading/thread_function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "thread.h" 3 | 4 | #include 5 | 6 | namespace mini::threading { 7 | 8 | class thread_function 9 | : public thread 10 | { 11 | MINI_MAKE_NONCOPYABLE(thread_function); 12 | 13 | public: 14 | thread_function( 15 | const function& functor 16 | ) 17 | : _functor(functor) 18 | { 19 | 20 | } 21 | 22 | thread_function( 23 | function&& functor 24 | ) 25 | : _functor(std::move(functor)) 26 | { 27 | 28 | } 29 | 30 | private: 31 | void 32 | thread_procedure( 33 | void 34 | ) override 35 | { 36 | _functor(); 37 | } 38 | 39 | function _functor; 40 | }; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /mini/io/file.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "file_attributes.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::io { 8 | 9 | class file 10 | { 11 | public: 12 | static file_attributes 13 | get_attributes( 14 | const string_ref path 15 | ); 16 | 17 | static bool 18 | exists( 19 | const string_ref path 20 | ); 21 | 22 | static string 23 | read_to_string( 24 | const string_ref path 25 | ); 26 | 27 | static collections::list 28 | read_all_lines( 29 | const string_ref path 30 | ); 31 | 32 | static void 33 | write_from_string( 34 | const string_ref path, 35 | const byte_buffer_ref content 36 | ); 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /mini/byte_buffer_ref.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini { 6 | 7 | using byte_buffer_ref = buffer_ref; 8 | using mutable_byte_buffer_ref = mutable_buffer_ref; 9 | 10 | template<> 11 | struct hash 12 | { 13 | size_type operator()(const byte_buffer_ref& value) const noexcept 14 | { 15 | return detail::hash_array_representation(value.get_buffer(), value.get_size()); 16 | } 17 | }; 18 | 19 | template<> 20 | struct hash 21 | { 22 | size_type operator()(const mutable_byte_buffer_ref& value) const noexcept 23 | { 24 | return detail::hash_array_representation(value.get_buffer(), value.get_size()); 25 | } 26 | }; 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /mini/tor/crypto/hybrid_encryption.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::tor::hybrid_encryption { 5 | 6 | // 7 | // tor-spec.txt 8 | // 0.3. 9 | // 10 | static constexpr size_type KEY_LEN = 16; 11 | static constexpr size_type PK_ENC_LEN = 128; 12 | static constexpr size_type PK_PAD_LEN = 42; 13 | 14 | static constexpr size_type PK_DATA_LEN = PK_ENC_LEN - PK_PAD_LEN; 15 | static constexpr size_type PK_DATA_LEN_WITH_KEY = PK_DATA_LEN - KEY_LEN; 16 | 17 | // 18 | // Encrypt the entire contents of the byte array "data" with the given "TorPublicKey" 19 | // according to the "hybrid encryption" scheme described in the main Tor specification(tor-spec.txt). 20 | // 21 | byte_buffer 22 | encrypt( 23 | const byte_buffer_ref data, 24 | const byte_buffer_ref public_key 25 | ); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /mini/crypto/capi/provider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::crypto::capi { 8 | 9 | class provider 10 | { 11 | MINI_MAKE_NONCOPYABLE(provider); 12 | 13 | public: 14 | provider( 15 | void 16 | ); 17 | 18 | ~provider( 19 | void 20 | ); 21 | 22 | HCRYPTPROV 23 | get_rsa_aes_handle( 24 | void 25 | ); 26 | 27 | HCRYPTPROV 28 | get_dh_handle( 29 | void 30 | ); 31 | 32 | private: 33 | void 34 | init( 35 | void 36 | ); 37 | 38 | void 39 | destroy( 40 | void 41 | ); 42 | 43 | HCRYPTPROV _provider_rsa_aes_handle = 0; 44 | HCRYPTPROV _provider_dh_handle = 0; 45 | }; 46 | 47 | extern provider provider_factory; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /mini/win32/api_set/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::win32 { 5 | 6 | struct api_set_namespace_t 7 | { 8 | uint32_t version; 9 | uint32_t size; 10 | uint32_t flags; 11 | uint32_t count; 12 | uint32_t entry_offset; 13 | uint32_t hash_offset; 14 | uint32_t hash_factor; 15 | }; 16 | 17 | struct api_set_hash_entry_t 18 | { 19 | uint32_t hash; 20 | uint32_t index; 21 | }; 22 | 23 | struct api_set_namespace_entry_t 24 | { 25 | uint32_t flags; 26 | uint32_t name_offset; 27 | uint32_t name_length; 28 | uint32_t hashed_length; 29 | uint32_t value_offset; 30 | uint32_t value_count; 31 | }; 32 | 33 | struct api_set_value_entry_t 34 | { 35 | uint32_t flags; 36 | uint32_t name_offset; 37 | uint32_t name_length; 38 | uint32_t value_offset; 39 | uint32_t value_length; 40 | }; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /mini/tor/circuit_node_crypto_state.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cell.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mini::tor { 9 | 10 | class relay_cell; 11 | 12 | class circuit_node_crypto_state 13 | { 14 | MINI_MAKE_NONCOPYABLE(circuit_node_crypto_state); 15 | 16 | public: 17 | circuit_node_crypto_state( 18 | const byte_buffer_ref key_material 19 | ); 20 | 21 | ~circuit_node_crypto_state( 22 | void 23 | ) = default; 24 | 25 | void 26 | encrypt_forward_cell( 27 | relay_cell& cell 28 | ); 29 | 30 | bool 31 | decrypt_backward_cell( 32 | cell& cell 33 | ); 34 | 35 | private: 36 | using aes_ctr_128 = crypto::aes; 37 | 38 | aes_ctr_128 _forward_cipher; 39 | aes_ctr_128 _backward_cipher; 40 | 41 | crypto::sha1 _forward_digest; 42 | crypto::sha1 _backward_digest; 43 | }; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /mini/crypto/capi/detail/base_encode.cpp: -------------------------------------------------------------------------------- 1 | #include "base_encode.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace mini::crypto::capi::detail { 7 | 8 | void 9 | base_encode_impl( 10 | DWORD flags, 11 | const byte_type* input, 12 | size_type input_size, 13 | char* output, 14 | size_type& output_size 15 | ) 16 | { 17 | if (!output) 18 | { 19 | output_size = 0; 20 | } 21 | 22 | CryptBinaryToString( 23 | input, 24 | static_cast(input_size), 25 | flags, 26 | output, 27 | reinterpret_cast(&output_size)); 28 | } 29 | 30 | void 31 | base_decode_impl( 32 | DWORD flags, 33 | const char* input, 34 | size_type input_size, 35 | byte_type* output, 36 | size_type& output_size 37 | ) 38 | { 39 | if (!output) 40 | { 41 | output_size = 0; 42 | } 43 | 44 | CryptStringToBinary( 45 | input, 46 | static_cast(input_size), 47 | flags, 48 | output, 49 | reinterpret_cast(&output_size), 50 | NULL, 51 | NULL); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /mini/tor/crypto/key_agreement_ntor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "key_agreement.h" 3 | 4 | #include 5 | 6 | namespace mini::tor { 7 | 8 | class key_agreement_ntor 9 | : public key_agreement 10 | { 11 | public: 12 | key_agreement_ntor( 13 | onion_router* router 14 | ); 15 | 16 | key_agreement_ntor( 17 | onion_router* router, 18 | crypto::curve25519::private_key&& private_key 19 | ); 20 | 21 | byte_buffer_ref 22 | get_public_key( 23 | void 24 | ) const override; 25 | 26 | byte_buffer_ref 27 | get_private_key( 28 | void 29 | ) const override; 30 | 31 | byte_buffer 32 | compute_shared_secret( 33 | const byte_buffer_ref handshake_data 34 | ) override; 35 | 36 | byte_buffer 37 | compute_shared_secret( 38 | const byte_buffer_ref other_public_key, 39 | const byte_buffer_ref derivative_key_data 40 | ) override; 41 | 42 | private: 43 | crypto::curve25519::private_key _private_key; 44 | }; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /mini/tor/crypto/key_agreement.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../onion_router.h" 3 | 4 | #include 5 | 6 | namespace mini::tor { 7 | 8 | class key_agreement 9 | { 10 | public: 11 | key_agreement( 12 | onion_router* router 13 | ) 14 | : _onion_router(router) 15 | { 16 | 17 | } 18 | 19 | virtual ~key_agreement( 20 | void 21 | ) = default; 22 | 23 | virtual byte_buffer_ref 24 | get_public_key( 25 | void 26 | ) const = 0; 27 | 28 | virtual byte_buffer_ref 29 | get_private_key( 30 | void 31 | ) const = 0; 32 | 33 | virtual byte_buffer 34 | compute_shared_secret( 35 | const byte_buffer_ref handshake_data 36 | ) = 0; 37 | 38 | virtual byte_buffer 39 | compute_shared_secret( 40 | const byte_buffer_ref other_public_key, 41 | const byte_buffer_ref verification_data // derivative key data (KH), for verification of derivation 42 | ) = 0; 43 | 44 | protected: 45 | onion_router* _onion_router; 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /mini/tor/crypto/key_agreement_tap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "key_agreement.h" 3 | 4 | #include 5 | 6 | namespace mini::tor { 7 | 8 | class key_agreement_tap 9 | : public key_agreement 10 | { 11 | public: 12 | using dh1024 = crypto::dh<1024>; 13 | 14 | key_agreement_tap( 15 | onion_router* router 16 | ); 17 | 18 | key_agreement_tap( 19 | onion_router* router, 20 | dh1024::private_key&& private_key 21 | ); 22 | 23 | byte_buffer_ref 24 | get_public_key( 25 | void 26 | ) const override; 27 | 28 | byte_buffer_ref 29 | get_private_key( 30 | void 31 | ) const override; 32 | 33 | byte_buffer 34 | compute_shared_secret( 35 | const byte_buffer_ref handshake_data 36 | ) override; 37 | 38 | byte_buffer 39 | compute_shared_secret( 40 | const byte_buffer_ref other_public_key, 41 | const byte_buffer_ref verification_data 42 | ) override; 43 | 44 | private: 45 | dh1024::private_key _private_key; 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /mini/net/http.cpp: -------------------------------------------------------------------------------- 1 | #include "http.h" 2 | 3 | #include "tcp_socket.h" 4 | #include 5 | 6 | namespace mini::net::http::client { 7 | 8 | string 9 | get( 10 | const string_ref host, 11 | uint16_t port, 12 | const string_ref path 13 | ) 14 | { 15 | tcp_socket sock; 16 | 17 | if (sock.connect(host, port)) 18 | { 19 | return get(host, port, path, sock); 20 | } 21 | 22 | return string(); 23 | } 24 | 25 | string 26 | get( 27 | const string_ref host, 28 | uint16_t port, 29 | const string_ref path, 30 | io::stream& sock 31 | ) 32 | { 33 | MINI_UNREFERENCED(port); 34 | 35 | string req = string::format("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", path.get_buffer(), host.get_buffer()); 36 | sock.write(req); 37 | 38 | io::stream_reader sr(sock); 39 | string result = sr.read_string_to_end(); 40 | 41 | auto header_position = result.index_of("\r\n\r\n"); 42 | if (header_position != mini::string::not_found) 43 | { 44 | header_position += 4; 45 | result = result.substring(header_position); 46 | } 47 | 48 | return result; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /mini/tor/parsers/introduction_point_parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mini::tor { 9 | 10 | struct introduction_point_parser 11 | { 12 | onion_router_list introduction_point_list; 13 | 14 | enum class document_location 15 | { 16 | control_word, 17 | 18 | service_key, 19 | service_key_content, 20 | }; 21 | 22 | enum control_word_type 23 | { 24 | control_word_introduction_point, 25 | control_word_service_key, 26 | 27 | control_word_key_begin, 28 | control_word_key_end, 29 | }; 30 | 31 | using control_word_list = stack_buffer; 32 | static constexpr control_word_list control_words = { { 33 | "introduction-point", 34 | "service-key", 35 | "-----BEGIN RSA PUBLIC KEY-----", 36 | "-----END RSA PUBLIC KEY-----", 37 | } }; 38 | 39 | void 40 | parse( 41 | consensus& consensus, 42 | const string_ref descriptor 43 | ); 44 | }; 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /mini/threading/locked_value.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "mutex.h" 3 | #include "event.h" 4 | 5 | namespace mini::threading { 6 | 7 | template < 8 | typename T 9 | > 10 | class locked_value 11 | { 12 | MINI_MAKE_NONCOPYABLE(locked_value); 13 | 14 | public: 15 | locked_value( 16 | locked_value&& other 17 | ) = default; 18 | 19 | locked_value( 20 | const T& initial_value = T() 21 | ); 22 | 23 | ~locked_value( 24 | void 25 | ) = default; 26 | 27 | const T& 28 | get_value( 29 | void 30 | ) const; 31 | 32 | void 33 | set_value( 34 | const T& value 35 | ); 36 | 37 | wait_result 38 | wait_for_value( 39 | const T& value, 40 | timeout_type timeout = wait_infinite 41 | ); 42 | 43 | wait_result 44 | wait_for_change( 45 | timeout_type timeout = wait_infinite 46 | ); 47 | 48 | void 49 | cancel_all_waits( 50 | void 51 | ); 52 | 53 | private: 54 | mutable mutex _mutex; 55 | event _event; 56 | event _cancel_event; 57 | T _value; 58 | }; 59 | 60 | } 61 | 62 | #include "locked_value.inl" 63 | -------------------------------------------------------------------------------- /mini/tor/parsers/onion_router_descriptor_parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mini::tor { 8 | 9 | struct onion_router_descriptor_parser 10 | { 11 | enum class document_location 12 | { 13 | control_word, 14 | 15 | onion_key, 16 | onion_key_content, 17 | 18 | signing_key, 19 | signing_key_content, 20 | 21 | ntor_onion_key, 22 | }; 23 | 24 | enum control_word_type 25 | { 26 | control_word_onion_key, 27 | control_word_signing_key, 28 | 29 | control_word_key_begin, 30 | control_word_key_end, 31 | 32 | control_word_ntor_onion_key, 33 | }; 34 | 35 | using control_word_list = stack_buffer; 36 | static constexpr control_word_list control_words = { { 37 | "onion-key", 38 | "signing-key", 39 | "-----BEGIN RSA PUBLIC KEY-----", 40 | "-----END RSA PUBLIC KEY-----", 41 | "ntor-onion-key", 42 | } }; 43 | 44 | void 45 | parse( 46 | onion_router* router, 47 | const string_ref descriptor 48 | ); 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Petr Benes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /mini/crypto/capi/random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | namespace mini::crypto::capi { 7 | 8 | class random 9 | { 10 | MINI_MAKE_NONCOPYABLE(random); 11 | 12 | public: 13 | random( 14 | void 15 | ) = default; 16 | 17 | byte_buffer 18 | get_random_bytes( 19 | size_type byte_count 20 | ); 21 | 22 | void 23 | get_random_bytes( 24 | mutable_byte_buffer_ref output 25 | ); 26 | 27 | template < 28 | typename T, 29 | typename = std::enable_if_t> 30 | > 31 | T 32 | get_random( 33 | void 34 | ) 35 | { 36 | T result; 37 | get_random_bytes(mutable_byte_buffer_ref( 38 | reinterpret_cast(&result), 39 | reinterpret_cast(&result) + sizeof(T))); 40 | 41 | return result; 42 | } 43 | 44 | template < 45 | typename T, 46 | typename = std::enable_if_t> 47 | > 48 | T 49 | get_random( 50 | T max 51 | ) 52 | { 53 | return get_random>() % max; 54 | } 55 | }; 56 | 57 | extern random random_device; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /mini/crypto/cng/random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | namespace mini::crypto::cng { 7 | 8 | class random 9 | { 10 | MINI_MAKE_NONCOPYABLE(random); 11 | 12 | public: 13 | random( 14 | void 15 | ) = default; 16 | 17 | byte_buffer 18 | get_random_bytes( 19 | size_type byte_count 20 | ); 21 | 22 | void 23 | get_random_bytes( 24 | mutable_byte_buffer_ref output 25 | ); 26 | 27 | template < 28 | typename T, 29 | typename = std::enable_if_t> 30 | > 31 | T 32 | get_random( 33 | void 34 | ) 35 | { 36 | T result; 37 | get_random_bytes(mutable_byte_buffer_ref( 38 | reinterpret_cast(&result), 39 | reinterpret_cast(&result) + sizeof(T))); 40 | 41 | return result; 42 | } 43 | 44 | template < 45 | typename T, 46 | typename = std::enable_if_t> 47 | > 48 | T 49 | get_random( 50 | T max 51 | ) 52 | { 53 | return get_random>() % max; 54 | } 55 | }; 56 | 57 | extern random random_device; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /mini/tor/parsers/hidden_service_descriptor_parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mini::tor { 13 | 14 | struct hidden_service_descriptor_parser 15 | { 16 | onion_router_list introduction_point_list; 17 | 18 | enum class document_location 19 | { 20 | control_word, 21 | 22 | introduction_points, 23 | introduction_points_content, 24 | }; 25 | 26 | enum control_word_type 27 | { 28 | control_word_introduction_points, 29 | 30 | control_word_message_begin, 31 | control_word_message_end, 32 | }; 33 | 34 | using control_word_list = stack_buffer; 35 | static constexpr control_word_list control_words = { { 36 | "introduction-points", 37 | "-----BEGIN MESSAGE-----", 38 | "-----END MESSAGE-----", 39 | } }; 40 | 41 | void 42 | parse( 43 | consensus& consensus, 44 | const string_ref descriptor 45 | ); 46 | }; 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /mini/io/file.cpp: -------------------------------------------------------------------------------- 1 | #include "file.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace mini::io { 8 | 9 | file_attributes 10 | file::get_attributes( 11 | const string_ref path 12 | ) 13 | { 14 | return file_attributes(GetFileAttributes(path.get_buffer())); 15 | } 16 | 17 | bool 18 | file::exists( 19 | const string_ref path 20 | ) 21 | { 22 | auto attributes = get_attributes(path.get_buffer()); 23 | 24 | return 25 | attributes != file_attributes::invalid && 26 | !attributes.is_directory(); 27 | } 28 | 29 | string 30 | file::read_to_string( 31 | const string_ref path 32 | ) 33 | { 34 | io::file_stream f(path, io::file_access::read); 35 | 36 | string result; 37 | result.resize(f.get_size()); 38 | f.read(&result[0], f.get_size()); 39 | 40 | return result; 41 | } 42 | 43 | collections::list 44 | file::read_all_lines( 45 | const string_ref path 46 | ) 47 | { 48 | return read_to_string(path).split("\n"); 49 | } 50 | 51 | void 52 | file::write_from_string( 53 | const string_ref path, 54 | const byte_buffer_ref content 55 | ) 56 | { 57 | io::file_stream f(path, io::file_access::write); 58 | f.write(content.get_buffer(), content.get_size()); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /mini/io/stream_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stream.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::io { 8 | 9 | class stream_reader 10 | { 11 | public: 12 | stream_reader( 13 | stream& stream 14 | ) 15 | : _stream(stream) 16 | { 17 | 18 | } 19 | 20 | byte_buffer 21 | read_to_end( 22 | void 23 | ) 24 | { 25 | byte_buffer result; 26 | 27 | static constexpr size_type buffer_size = 4096; 28 | byte_type buffer[buffer_size]; 29 | 30 | size_type bytes_read; 31 | while (stream::success(bytes_read = _stream.read(buffer, buffer_size))) 32 | { 33 | result.add_many(byte_buffer_ref(buffer, buffer + bytes_read)); 34 | } 35 | 36 | return result; 37 | } 38 | 39 | string 40 | read_string_to_end( 41 | void 42 | ) 43 | { 44 | string result; 45 | 46 | static constexpr size_type buffer_size = 4096; 47 | char buffer[buffer_size]; 48 | 49 | size_type bytes_read; 50 | while (stream::success(bytes_read = _stream.read(buffer, buffer_size))) 51 | { 52 | result.append(buffer, bytes_read); 53 | } 54 | 55 | return result; 56 | } 57 | 58 | 59 | private: 60 | stream& _stream; 61 | }; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mini/io/file_attributes.cpp: -------------------------------------------------------------------------------- 1 | #include "file_attributes.h" 2 | 3 | namespace mini::io { 4 | 5 | const file_attributes file_attributes::invalid; 6 | 7 | file_attributes::file_attributes( 8 | void 9 | ) 10 | : _attributes(INVALID_FILE_ATTRIBUTES) 11 | { 12 | 13 | } 14 | 15 | file_attributes::file_attributes( 16 | uint32_t attributes 17 | ) 18 | : _attributes(attributes) 19 | { 20 | 21 | } 22 | 23 | bool 24 | file_attributes::is_hidden( 25 | void 26 | ) const 27 | { 28 | return !!(_attributes & FILE_ATTRIBUTE_HIDDEN); 29 | } 30 | 31 | bool 32 | file_attributes::is_system( 33 | void 34 | ) const 35 | { 36 | return !!(_attributes & FILE_ATTRIBUTE_SYSTEM); 37 | } 38 | 39 | bool 40 | file_attributes::is_file( 41 | void 42 | ) const 43 | { 44 | return !!(_attributes & FILE_ATTRIBUTE_NORMAL) && 45 | !(_attributes & FILE_ATTRIBUTE_DIRECTORY); 46 | } 47 | 48 | bool 49 | file_attributes::is_directory( 50 | void 51 | ) const 52 | { 53 | return !!(_attributes & FILE_ATTRIBUTE_DIRECTORY); 54 | } 55 | 56 | bool 57 | file_attributes::operator!=( 58 | const file_attributes& other 59 | ) const 60 | { 61 | return !operator==(other); 62 | } 63 | 64 | bool 65 | file_attributes::operator==( 66 | const file_attributes& other 67 | ) const 68 | { 69 | return _attributes == other._attributes; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /mini/tor/hidden_service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace mini::tor { 7 | 8 | using replica_type = uint8_t; 9 | 10 | class hidden_service 11 | { 12 | public: 13 | hidden_service( 14 | circuit* circuit, 15 | const string_ref onion 16 | ); 17 | 18 | bool 19 | connect( 20 | void 21 | ); 22 | 23 | private: 24 | byte_buffer 25 | get_secret_id( 26 | replica_type replica 27 | ); 28 | 29 | byte_buffer 30 | get_descriptor_id( 31 | replica_type replica 32 | ); 33 | 34 | void 35 | find_responsible_directories( 36 | void 37 | ); 38 | 39 | onion_router_list::size_type 40 | fetch_hidden_service_descriptor( 41 | onion_router_list::size_type responsible_directory_index = 0 42 | ); 43 | 44 | void 45 | introduce( 46 | void 47 | ); 48 | 49 | circuit* _rendezvous_circuit; 50 | tor_socket& _socket; 51 | consensus& _consensus; 52 | 53 | string _onion; 54 | byte_buffer _permanent_id; // crypto::base32::decode(_onion) 55 | 56 | onion_router_list _responsible_directory_list; 57 | onion_router_list _introduction_point_list; 58 | 59 | stack_byte_buffer<20> _rendezvous_cookie; 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mini/threading/mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "mutex.h" 2 | 3 | namespace mini::threading { 4 | 5 | // 6 | // mutex implementation. 7 | // 8 | 9 | mutex::mutex( 10 | void 11 | ) 12 | { 13 | InitializeCriticalSection(&_critical_section); 14 | } 15 | 16 | mutex::~mutex( 17 | void 18 | ) 19 | { 20 | DeleteCriticalSection(&_critical_section); 21 | } 22 | 23 | void 24 | mutex::acquire( 25 | void 26 | ) 27 | { 28 | EnterCriticalSection(&_critical_section); 29 | } 30 | 31 | void 32 | mutex::release( 33 | void 34 | ) 35 | { 36 | LeaveCriticalSection(&_critical_section); 37 | } 38 | 39 | // 40 | // mutex holder implementation. 41 | // 42 | 43 | mutex_holder::mutex_holder( 44 | mutex& mutex 45 | ) 46 | : _mutex(mutex) 47 | { 48 | _mutex.acquire(); 49 | } 50 | 51 | mutex_holder::~mutex_holder( 52 | void 53 | ) 54 | { 55 | _mutex.release(); 56 | } 57 | 58 | mutex_holder::operator bool( 59 | void 60 | ) const 61 | { 62 | return false; 63 | } 64 | 65 | // 66 | // mutex holder implementation. 67 | // 68 | 69 | mutex_unholder::mutex_unholder( 70 | mutex& mutex 71 | ) 72 | : _mutex(mutex) 73 | { 74 | _mutex.release(); 75 | } 76 | 77 | mutex_unholder::~mutex_unholder( 78 | void 79 | ) 80 | { 81 | _mutex.acquire(); 82 | } 83 | 84 | mutex_unholder::operator bool( 85 | void 86 | ) const 87 | { 88 | return false; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /mini/tor/crypto/hybrid_encryption.cpp: -------------------------------------------------------------------------------- 1 | #include "hybrid_encryption.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mini::tor::hybrid_encryption { 8 | 9 | byte_buffer 10 | encrypt( 11 | const byte_buffer_ref data, 12 | const byte_buffer_ref public_key 13 | ) 14 | { 15 | using rsa1024 = crypto::rsa<1024>; 16 | using aes_ctr_128 = crypto::aes; 17 | 18 | if (data.get_size() < PK_DATA_LEN) 19 | { 20 | return rsa1024::public_key::make_from_der(public_key).encrypt( 21 | data, 22 | crypto::rsa_encryption_padding::oaep_sha1, 23 | true); 24 | } 25 | 26 | byte_buffer random_key = crypto::random_device.get_random_bytes(KEY_LEN); 27 | 28 | // 29 | // RSA( K | M1 ) --> C1 30 | // 31 | byte_buffer k_and_m1 = { random_key, data.slice(0, PK_DATA_LEN_WITH_KEY) }; 32 | 33 | auto c1 = rsa1024::public_key::make_from_der(public_key).encrypt( 34 | k_and_m1, 35 | crypto::rsa_encryption_padding::oaep_sha1, 36 | true); 37 | 38 | // 39 | // AES_CTR(M2) --> C2 40 | // 41 | byte_buffer_ref m2 = data.slice(PK_DATA_LEN_WITH_KEY); 42 | auto c2 = aes_ctr_128::crypt(aes_ctr_128::key(random_key), m2); 43 | 44 | // 45 | // C1 | C2 46 | // 47 | byte_buffer result = { c1, c2 }; 48 | 49 | return result; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mini/io/file_attributes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | namespace mini::io { 7 | 8 | class file_attributes 9 | { 10 | public: 11 | static const file_attributes invalid; 12 | 13 | file_attributes( 14 | void 15 | ); 16 | 17 | file_attributes( 18 | uint32_t attributes 19 | ); 20 | 21 | file_attributes( 22 | const file_attributes& other 23 | ) = default; 24 | 25 | file_attributes( 26 | file_attributes&& other 27 | ) = default; 28 | 29 | ~file_attributes( 30 | void 31 | ) = default; 32 | 33 | file_attributes& 34 | operator=( 35 | const file_attributes& other 36 | ) = default; 37 | 38 | file_attributes& 39 | operator=( 40 | file_attributes&& other 41 | ) = default; 42 | 43 | bool 44 | operator==( 45 | const file_attributes& other 46 | ) const; 47 | 48 | bool 49 | operator!=( 50 | const file_attributes& other 51 | ) const; 52 | 53 | bool 54 | is_directory( 55 | void 56 | ) const; 57 | 58 | bool 59 | is_file( 60 | void 61 | ) const; 62 | 63 | bool 64 | is_system( 65 | void 66 | ) const; 67 | 68 | bool 69 | is_hidden( 70 | void 71 | ) const; 72 | 73 | private: 74 | uint32_t _attributes; 75 | }; 76 | 77 | } 78 | -------------------------------------------------------------------------------- /mini/io/path.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::io { 5 | 6 | class path 7 | { 8 | public: 9 | static constexpr auto directory_separator = string_ref("\\"); 10 | static constexpr auto alternative_directory_separator = string_ref("/"); 11 | static constexpr auto extension_separator = string_ref("."); 12 | 13 | static string 14 | combine( 15 | const string_ref p1, 16 | const string_ref p2 17 | ); 18 | 19 | template < 20 | typename ...ARGS 21 | > 22 | static string 23 | combine( 24 | const string_ref p1, 25 | const string_ref p2, 26 | ARGS... pX 27 | ) 28 | { 29 | // 30 | // TODO: 31 | // ARGS should be verified to be convertible to string_ref. 32 | // 33 | return combine(combine(p1, p2), pX...); 34 | } 35 | 36 | static string_collection 37 | split( 38 | const string_ref p 39 | ); 40 | 41 | static string_ref 42 | get_file_name( 43 | const string_ref p 44 | ); 45 | 46 | static string_ref 47 | get_directory_name( 48 | const string_ref p 49 | ); 50 | 51 | static string_ref 52 | get_filename_without_extension( 53 | const string_ref p 54 | ); 55 | 56 | static string_ref 57 | get_extension( 58 | const string_ref p 59 | ); 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mini/threading/event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace mini::threading { 11 | 12 | enum class reset_type : uint8_t 13 | { 14 | auto_reset, 15 | manual_reset, 16 | }; 17 | 18 | class event 19 | { 20 | MINI_MAKE_NONCOPYABLE(event); 21 | 22 | public: 23 | event( 24 | event&& other 25 | ) = default; 26 | 27 | event( 28 | reset_type type = reset_type::manual_reset, 29 | bool initial_state = false 30 | ); 31 | 32 | ~event( 33 | void 34 | ); 35 | 36 | void 37 | set( 38 | void 39 | ); 40 | 41 | void 42 | reset( 43 | void 44 | ); 45 | 46 | wait_result 47 | wait( 48 | timeout_type timeout = wait_infinite 49 | ); 50 | 51 | static wait_result 52 | wait_for_all( 53 | buffer_ref events, 54 | timeout_type timeout = wait_infinite 55 | ); 56 | 57 | static wait_result 58 | wait_for_any( 59 | buffer_ref events, 60 | timeout_type timeout = wait_infinite 61 | ); 62 | 63 | static int 64 | index_from_wait_result( 65 | wait_result result 66 | ); 67 | 68 | bool 69 | is_signaled( 70 | void 71 | ); 72 | 73 | private: 74 | HANDLE _event; 75 | }; 76 | 77 | } 78 | -------------------------------------------------------------------------------- /mini/win32/pe/section_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "section_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_section_enumerator; 7 | template class pe_section_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_section_enumerator::pe_section_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _section_table = reinterpret_cast( 18 | reinterpret_cast(&_pe->nt_headers()) + 19 | offsetof(image_nt_headers_32_t, optional_header) + 20 | _pe->nt_headers().file_header.size_of_optional_header 21 | ); 22 | 23 | _count = _pe->nt_headers().file_header.number_of_sections; 24 | } 25 | 26 | template < 27 | typename TImageTraits 28 | > 29 | pe_section_enumerator::iterator::iterator( 30 | const pe_section_enumerator* enumerator, 31 | size_t index /*= 0 */ 32 | ) 33 | : _enumerator(enumerator) 34 | , _index(index) 35 | { 36 | 37 | } 38 | 39 | template < 40 | typename TImageTraits 41 | > 42 | typename pe_section_enumerator::iterator::reference 43 | pe_section_enumerator::iterator::value( 44 | void 45 | ) const 46 | { 47 | value_type result; 48 | 49 | result._image_base = _enumerator->_pe->_image_base; 50 | result._section_header = &_enumerator->_section_table[_index]; 51 | 52 | return result; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /mini/crypto/cng/hmac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "hash.h" 3 | 4 | namespace mini::crypto::cng { 5 | 6 | template < 7 | typename HASH_TYPE 8 | > 9 | class hmac 10 | : public HASH_TYPE 11 | { 12 | public: 13 | static constexpr size_type hash_size = HASH_TYPE::hash_size; 14 | static constexpr size_type hash_size_in_bytes = HASH_TYPE::hash_size_in_bytes; 15 | static constexpr hash_algorithm_type hash_algorithm = HASH_TYPE::hash_algorithm; 16 | 17 | // 18 | // constructors. 19 | // 20 | 21 | hmac( 22 | const byte_buffer_ref key 23 | ); 24 | 25 | hmac( 26 | const hmac& other 27 | ); 28 | 29 | hmac( 30 | hmac&& other 31 | ); 32 | 33 | // 34 | // destructor. 35 | // 36 | 37 | ~hmac( 38 | void 39 | ); 40 | 41 | // 42 | // assign operators. 43 | // 44 | 45 | hmac& 46 | operator=( 47 | const hmac& other 48 | ); 49 | 50 | hmac& 51 | operator=( 52 | hmac&& other 53 | ); 54 | 55 | hmac 56 | duplicate( 57 | void 58 | ); 59 | 60 | // 61 | // swap. 62 | // 63 | 64 | void 65 | swap( 66 | hmac& other 67 | ); 68 | 69 | // 70 | // operations. 71 | // 72 | 73 | static byte_buffer 74 | compute( 75 | const byte_buffer_ref key, 76 | const byte_buffer_ref input 77 | ); 78 | }; 79 | 80 | } 81 | 82 | #include "hmac.inl" 83 | -------------------------------------------------------------------------------- /mini/win32/api_set/api_set_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "api_set_enumerator.h" 2 | #include "../api_set.h" 3 | 4 | namespace mini::win32 { 5 | 6 | api_set_enumerator::api_set_enumerator( 7 | const api_set_t* api_set 8 | ) 9 | : _api_set(api_set) 10 | { 11 | _count = _api_set->_api_set_namespace->count; 12 | } 13 | 14 | 15 | api_set_enumerator::iterator::iterator( 16 | const api_set_enumerator* enumerator, 17 | size_t index /*= 0 */ 18 | ) 19 | : _enumerator(enumerator) 20 | , _index(index) 21 | { 22 | 23 | } 24 | 25 | api_set_enumerator::iterator::value_type 26 | api_set_enumerator::iterator::value( 27 | void 28 | ) const 29 | { 30 | auto& entry = reinterpret_cast( 31 | _enumerator->_api_set->_api_set_namespace_base + _enumerator->_api_set->_api_set_namespace->entry_offset 32 | )[_index]; 33 | 34 | value_type result; 35 | result._name = reinterpret_cast( 36 | _enumerator->_api_set->_api_set_namespace_base + entry.name_offset 37 | ); 38 | 39 | result._name_length = entry.name_length; 40 | result._api_set_namespace_base = _enumerator->_api_set->_api_set_namespace_base; 41 | result._api_set_value_table = reinterpret_cast( 42 | _enumerator->_api_set->_api_set_namespace_base + entry.value_offset 43 | ); 44 | 45 | result._api_set_value_count = entry.value_count; 46 | return result; 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /mini/win32/api_set/api_set_value_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "api_set_value_enumerator.h" 2 | #include "../api_set.h" 3 | 4 | namespace mini::win32 { 5 | 6 | api_set_value_enumerator::api_set_value_enumerator( 7 | uint8_t* api_set_namespace_base, 8 | api_set_value_entry_t* api_set_value_table, 9 | size_t count 10 | ) 11 | : _api_set_namespace_base(api_set_namespace_base) 12 | , _api_set_value_table(api_set_value_table) 13 | { 14 | _count = count; 15 | } 16 | 17 | 18 | api_set_value_enumerator::iterator::iterator( 19 | const api_set_value_enumerator* enumerator, 20 | size_t index /*= 0 */ 21 | ) 22 | : _enumerator(enumerator) 23 | , _index(index) 24 | { 25 | 26 | } 27 | 28 | api_set_value_enumerator::iterator::value_type 29 | api_set_value_enumerator::iterator::value( 30 | void 31 | ) const 32 | { 33 | auto& entry = reinterpret_cast(_enumerator->_api_set_value_table)[_index]; 34 | 35 | value_type result; 36 | 37 | // 38 | // name_offset can be 0. 39 | // 40 | 41 | result._name = entry.name_offset ? 42 | reinterpret_cast(_enumerator->_api_set_namespace_base + entry.name_offset) 43 | : nullptr; 44 | result._name_length = entry.name_length / sizeof(wchar_t); 45 | result._value = reinterpret_cast(_enumerator->_api_set_namespace_base + entry.value_offset); 46 | result._value_length = entry.value_length / sizeof(wchar_t); 47 | result._flags = entry.flags; 48 | 49 | return result; 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /mini/win32/pe/relocation_fixup_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "relocation_fixup_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_relocation_fixup_enumerator; 7 | template class pe_relocation_fixup_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_relocation_fixup_enumerator::pe_relocation_fixup_enumerator( 13 | uint8_t* image_base, 14 | typename TImageTraits::image_base_relocation_t* relocation 15 | ) 16 | : _image_base(image_base) 17 | , _relocation(relocation) 18 | { 19 | _count = (relocation->size_of_block - sizeof(typename TImageTraits::image_base_relocation_t)) / sizeof(uint16_t); 20 | } 21 | 22 | template < 23 | typename TImageTraits 24 | > 25 | pe_relocation_fixup_enumerator::iterator::iterator( 26 | const pe_relocation_fixup_enumerator* enumerator, 27 | size_t index /*= 0 */ 28 | ) 29 | : _enumerator(enumerator) 30 | , _index(index) 31 | { 32 | 33 | } 34 | 35 | template < 36 | typename TImageTraits 37 | > 38 | typename pe_relocation_fixup_enumerator::iterator::value_type 39 | pe_relocation_fixup_enumerator::iterator::value( 40 | void 41 | ) const 42 | { 43 | value_type result; 44 | 45 | result._image_base = _enumerator->_image_base; 46 | result._relocation_base = _enumerator->_relocation->virtual_address; 47 | result._fixup_item = reinterpret_cast(_enumerator->_relocation + 1) + _index; 48 | 49 | return result; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mini/crypto/capi/provider.cpp: -------------------------------------------------------------------------------- 1 | #include "provider.h" 2 | 3 | namespace mini::crypto::capi { 4 | 5 | provider provider_factory; 6 | 7 | provider::provider( 8 | void 9 | ) 10 | { 11 | init(); 12 | } 13 | 14 | provider::~provider( 15 | void 16 | ) 17 | { 18 | destroy(); 19 | } 20 | 21 | HCRYPTPROV 22 | provider::get_rsa_aes_handle( 23 | void 24 | ) 25 | { 26 | return _provider_rsa_aes_handle; 27 | } 28 | 29 | HCRYPTPROV 30 | provider::get_dh_handle( 31 | void 32 | ) 33 | { 34 | return _provider_dh_handle; 35 | } 36 | 37 | void 38 | provider::init( 39 | void 40 | ) 41 | { 42 | // 43 | // alternative provider 44 | // 45 | if (GetEnvironmentVariable( 46 | TEXT("csp_alt_prov"), 47 | nullptr, 48 | 0)) 49 | { 50 | LoadLibrary(TEXT("csp_alt.dll")); 51 | } 52 | 53 | CryptAcquireContext( 54 | &_provider_rsa_aes_handle, 55 | NULL, 56 | MS_ENH_RSA_AES_PROV, 57 | PROV_RSA_AES, 58 | CRYPT_VERIFYCONTEXT); 59 | 60 | CryptAcquireContext( 61 | &_provider_dh_handle, 62 | NULL, 63 | MS_ENH_DSS_DH_PROV, 64 | PROV_DSS_DH, 65 | CRYPT_VERIFYCONTEXT); 66 | } 67 | 68 | void 69 | provider::destroy( 70 | void 71 | ) 72 | { 73 | if (_provider_dh_handle) 74 | { 75 | CryptReleaseContext( 76 | _provider_dh_handle, 77 | 0); 78 | _provider_dh_handle = 0; 79 | } 80 | 81 | if (_provider_rsa_aes_handle) 82 | { 83 | CryptReleaseContext( 84 | _provider_rsa_aes_handle, 85 | 0); 86 | _provider_rsa_aes_handle = 0; 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /mini/crypto/capi/hmac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "hash.h" 3 | 4 | namespace mini::crypto::capi { 5 | 6 | template < 7 | typename HASH_TYPE 8 | > 9 | class hmac 10 | : public HASH_TYPE 11 | { 12 | public: 13 | static constexpr size_type hash_size = HASH_TYPE::hash_size; 14 | static constexpr size_type hash_size_in_bytes = HASH_TYPE::hash_size_in_bytes; 15 | static constexpr hash_algorithm_type hash_algorithm = HASH_TYPE::hash_algorithm; 16 | 17 | // 18 | // constructors. 19 | // 20 | 21 | hmac( 22 | const byte_buffer_ref key 23 | ); 24 | 25 | hmac( 26 | const hmac& other 27 | ); 28 | 29 | hmac( 30 | hmac&& other 31 | ); 32 | 33 | // 34 | // destructor. 35 | // 36 | 37 | ~hmac( 38 | void 39 | ); 40 | 41 | // 42 | // assign operators. 43 | // 44 | 45 | hmac& 46 | operator=( 47 | const hmac& other 48 | ); 49 | 50 | hmac& 51 | operator=( 52 | hmac&& other 53 | ); 54 | 55 | hmac 56 | duplicate( 57 | void 58 | ); 59 | 60 | // 61 | // swap. 62 | // 63 | 64 | void 65 | swap( 66 | hmac& other 67 | ); 68 | 69 | // 70 | // operations. 71 | // 72 | 73 | static byte_buffer 74 | compute( 75 | const byte_buffer_ref key, 76 | const byte_buffer_ref input 77 | ); 78 | 79 | private: 80 | void 81 | destroy( 82 | void 83 | ); 84 | 85 | HCRYPTKEY _key_handle = 0; 86 | }; 87 | 88 | } 89 | 90 | #include "hmac.inl" 91 | -------------------------------------------------------------------------------- /mini/io/file_enumerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "file_attributes.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace mini::io { 9 | 10 | // 11 | // file_info. 12 | // 13 | 14 | struct file_info 15 | { 16 | string full_name; 17 | file_size_type size; 18 | file_attributes attributes; 19 | }; 20 | 21 | // 22 | // file_iterator. 23 | // 24 | 25 | class file_iterator 26 | { 27 | public: 28 | static const file_iterator invalid; 29 | 30 | file_iterator( 31 | void 32 | ); 33 | 34 | file_iterator( 35 | const string_ref path 36 | ); 37 | 38 | file_iterator& 39 | operator++( 40 | void 41 | ); 42 | 43 | file_iterator 44 | operator++( 45 | int 46 | ); 47 | 48 | bool 49 | operator==( 50 | const file_iterator& other 51 | ); 52 | 53 | bool 54 | operator!=( 55 | const file_iterator& other 56 | ); 57 | 58 | file_info& 59 | operator*( 60 | void 61 | ); 62 | 63 | file_info* 64 | operator->( 65 | void 66 | ); 67 | 68 | private: 69 | file_info _cached_file_info; 70 | WIN32_FIND_DATAA _find_data; 71 | HANDLE _find_handle; 72 | bool _is_invalid; 73 | }; 74 | 75 | // 76 | // file_enumerator. 77 | // 78 | 79 | class file_enumerator 80 | { 81 | public: 82 | file_enumerator( 83 | const string_ref path 84 | ); 85 | 86 | file_iterator 87 | begin( 88 | void 89 | ) const; 90 | 91 | file_iterator 92 | end( 93 | void 94 | ) const; 95 | 96 | private: 97 | string _path; 98 | }; 99 | 100 | } 101 | -------------------------------------------------------------------------------- /mini/crypto/capi/base64.cpp: -------------------------------------------------------------------------------- 1 | #include "base64.h" 2 | #include "detail/base_encode.h" 3 | 4 | #include 5 | 6 | namespace mini::crypto::capi { 7 | 8 | static void 9 | encode_impl( 10 | const byte_type* input, 11 | size_type input_size, 12 | char* output, 13 | size_type& output_size 14 | ) 15 | { 16 | detail::base_encode_impl( 17 | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, 18 | input, 19 | input_size, 20 | output, 21 | output_size); 22 | } 23 | 24 | static void 25 | decode_impl( 26 | const char* input, 27 | size_type input_size, 28 | byte_type* output, 29 | size_type& output_size 30 | ) 31 | { 32 | // 33 | // CRYPT_STRING_BASE64_ANY: 34 | // 35 | // Tries the following, in order: 36 | // CRYPT_STRING_BASE64HEADER 37 | // CRYPT_STRING_BASE64 38 | // 39 | 40 | detail::base_decode_impl( 41 | CRYPT_STRING_BASE64_ANY, 42 | input, 43 | input_size, 44 | output, 45 | output_size); 46 | } 47 | 48 | string 49 | base64::encode( 50 | const byte_buffer_ref input 51 | ) 52 | { 53 | string output; 54 | size_type output_size; 55 | 56 | encode_impl(input.get_buffer(), input.get_size(), nullptr, output_size); 57 | 58 | output.resize(output_size - 1); 59 | encode_impl(input.get_buffer(), input.get_size(), output.get_buffer(), output_size); 60 | 61 | return output; 62 | } 63 | 64 | byte_buffer 65 | base64::decode( 66 | const string_ref input 67 | ) 68 | { 69 | byte_buffer output; 70 | size_type output_size; 71 | 72 | decode_impl(input.get_buffer(), input.get_size(), nullptr, output_size); 73 | 74 | output.resize(output_size); 75 | decode_impl(input.get_buffer(), input.get_size(), output.get_buffer(), output_size); 76 | 77 | return output; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /mini/win32/pe/import_thunk_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "import_thunk_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_import_thunk_enumerator; 7 | template class pe_import_thunk_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_import_thunk_enumerator::pe_import_thunk_enumerator( 13 | uint8_t* image_base, 14 | typename TImageTraits::image_import_descriptor_t* import_descriptor 15 | ) 16 | : _image_base(image_base) 17 | { 18 | _name_thunk_data = reinterpret_cast(image_base + import_descriptor->original_first_thunk); 19 | _address_thunk_data = reinterpret_cast(image_base + import_descriptor->first_thunk); 20 | 21 | _count = 0; 22 | for ( 23 | auto current_name_thunk_data = _name_thunk_data; 24 | current_name_thunk_data->address_of_data; 25 | current_name_thunk_data += 1 26 | ) 27 | { 28 | _count += 1; 29 | } 30 | } 31 | 32 | template < 33 | typename TImageTraits 34 | > 35 | pe_import_thunk_enumerator::iterator::iterator( 36 | const pe_import_thunk_enumerator* enumerator, 37 | size_t index /*= 0 */ 38 | ) 39 | : _enumerator(enumerator) 40 | , _index(index) 41 | { 42 | 43 | } 44 | 45 | template < 46 | typename TImageTraits 47 | > 48 | typename pe_import_thunk_enumerator::iterator::value_type 49 | pe_import_thunk_enumerator::iterator::value( 50 | void 51 | ) const 52 | { 53 | value_type result; 54 | 55 | result._image_base = _enumerator->_image_base; 56 | result._name_thunk_data = &_enumerator->_name_thunk_data[_index]; 57 | 58 | return result; 59 | } 60 | 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /mini/crypto/rfc5869.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "hmac_sha256.h" 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace mini::crypto { 10 | 11 | template < 12 | typename HMAC_CLASS 13 | > 14 | class rfc5869 15 | { 16 | MINI_MAKE_NONCONSTRUCTIBLE(rfc5869); 17 | 18 | public: 19 | // static_assert(std::is_base_of_v, "HMAC_CLASS must be derived from hmac_base!"); 20 | 21 | static 22 | byte_buffer 23 | derive_key( 24 | const byte_buffer_ref initial_key_material, 25 | const byte_buffer_ref info, 26 | const byte_buffer_ref salt, 27 | size_type output_size 28 | ) 29 | { 30 | return expand(HMAC_CLASS::compute(salt, initial_key_material), info, output_size); 31 | } 32 | 33 | private: 34 | static 35 | byte_buffer 36 | expand( 37 | const byte_buffer_ref pseudo_random_key, 38 | const byte_buffer_ref info, 39 | size_type output_size 40 | ) 41 | { 42 | mini_assert(output_size <= 255 * HMAC_CLASS::hash_size_in_bytes); 43 | 44 | byte_buffer result; 45 | byte_buffer result_block; 46 | size_type bytes_remaining = output_size; 47 | 48 | for (byte_type i = 1; bytes_remaining > 0; i++) 49 | { 50 | byte_buffer message; 51 | message.add_many(result_block); 52 | message.add_many(info); 53 | message.add(i); 54 | 55 | result_block = HMAC_CLASS::compute(pseudo_random_key, message); 56 | 57 | size_type bytes_processed = algorithm::min(result_block.get_size(), bytes_remaining); 58 | result.add_many(result_block.slice(0, bytes_processed)); 59 | 60 | bytes_remaining -= bytes_processed; 61 | } 62 | 63 | return result; 64 | } 65 | }; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /mini/net/ssl_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tcp_socket.h" 3 | #include "detail/ssl_context.h" 4 | 5 | #include 6 | 7 | namespace mini::net { 8 | 9 | class ssl_stream 10 | : public io::stream 11 | { 12 | public: 13 | ssl_stream( 14 | io::stream& underlying_stream, 15 | const string_ref target_name = string_ref() 16 | ); 17 | 18 | ~ssl_stream( 19 | void 20 | ); 21 | 22 | void 23 | close( 24 | void 25 | ) override; 26 | 27 | bool 28 | can_read( 29 | void 30 | ) const override; 31 | 32 | bool 33 | can_write( 34 | void 35 | ) const override; 36 | 37 | bool 38 | can_seek( 39 | void 40 | ) const override; 41 | 42 | bool 43 | handshake( 44 | const string_ref host, 45 | uint16_t port 46 | ); 47 | 48 | size_type 49 | seek( 50 | intptr_t offset, 51 | seek_origin origin = seek_origin::current 52 | ) override; 53 | 54 | void 55 | flush( 56 | void 57 | ) override; 58 | 59 | size_type 60 | get_size( 61 | void 62 | ) const override; 63 | 64 | size_type 65 | get_position( 66 | void 67 | ) const override; 68 | 69 | io::stream& 70 | get_underlying_stream( 71 | void 72 | ); 73 | 74 | bool 75 | is_handshake_established( 76 | void 77 | ) const; 78 | 79 | private: 80 | size_type 81 | read_impl( 82 | void* buffer, 83 | size_type size 84 | ) override; 85 | 86 | size_type 87 | write_impl( 88 | const void* buffer, 89 | size_type size 90 | ) override; 91 | 92 | using ssl_context = detail::ssl_context; 93 | 94 | io::stream& _underlying_stream; 95 | ssl_context _context; 96 | }; 97 | 98 | } 99 | -------------------------------------------------------------------------------- /mini/net/ssl_socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "tcp_socket.h" 3 | #include "ssl_stream.h" 4 | 5 | #include 6 | 7 | namespace mini::net { 8 | 9 | class ssl_socket 10 | : public io::stream 11 | { 12 | public: 13 | ssl_socket( 14 | const string_ref host = string_ref() 15 | ); 16 | 17 | ssl_socket( 18 | const string_ref host, 19 | uint16_t port 20 | ); 21 | 22 | ~ssl_socket( 23 | void 24 | ); 25 | 26 | void 27 | close( 28 | void 29 | ) override; 30 | 31 | bool 32 | can_read( 33 | void 34 | ) const override; 35 | 36 | bool 37 | can_write( 38 | void 39 | ) const override; 40 | 41 | bool 42 | can_seek( 43 | void 44 | ) const override; 45 | 46 | bool 47 | connect( 48 | const string_ref host, 49 | uint16_t port 50 | ); 51 | 52 | size_type 53 | seek( 54 | intptr_t offset, 55 | seek_origin origin = seek_origin::current 56 | ) override; 57 | 58 | void 59 | flush( 60 | void 61 | ) override; 62 | 63 | size_type 64 | get_size( 65 | void 66 | ) const override; 67 | 68 | size_type 69 | get_position( 70 | void 71 | ) const override; 72 | 73 | tcp_socket& 74 | get_underlying_socket( 75 | void 76 | ); 77 | 78 | bool 79 | is_connected( 80 | void 81 | ) const; 82 | 83 | private: 84 | size_type 85 | read_impl( 86 | void* buffer, 87 | size_type size 88 | ) override; 89 | 90 | size_type 91 | write_impl( 92 | const void* buffer, 93 | size_type size 94 | ) override; 95 | 96 | tcp_socket _socket; 97 | ssl_stream _ssl_stream; 98 | }; 99 | 100 | } 101 | -------------------------------------------------------------------------------- /mini/crypto/capi/base16.cpp: -------------------------------------------------------------------------------- 1 | #include "base16.h" 2 | #include "detail/base_encode.h" 3 | 4 | #include 5 | 6 | namespace mini::crypto::capi { 7 | 8 | static void 9 | encode_impl( 10 | const byte_type* input, 11 | size_type input_size, 12 | char* output, 13 | size_type& output_size 14 | ) 15 | { 16 | // 17 | // note that CRYPT_STRING_HEXRAW is not supported on Windows XP. 18 | // 19 | 20 | detail::base_encode_impl( 21 | CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF, 22 | input, 23 | input_size, 24 | output, 25 | output_size); 26 | } 27 | 28 | static void 29 | decode_impl( 30 | const char* input, 31 | size_type input_size, 32 | byte_type* output, 33 | size_type& output_size 34 | ) 35 | { 36 | // 37 | // CRYPT_STRING_HEX_ANY: 38 | // 39 | // Tries the following, in order: 40 | // CRYPT_STRING_HEXADDR 41 | // CRYPT_STRING_HEXASCIIADDR 42 | // CRYPT_STRING_HEX 43 | // CRYPT_STRING_HEXRAW 44 | // CRYPT_STRING_HEXASCII 45 | // 46 | 47 | detail::base_decode_impl( 48 | CRYPT_STRING_HEX_ANY, 49 | input, 50 | input_size, 51 | output, 52 | output_size); 53 | } 54 | 55 | string 56 | base16::encode( 57 | const byte_buffer_ref input 58 | ) 59 | { 60 | string output; 61 | size_type output_size; 62 | encode_impl(input.get_buffer(), input.get_size(), nullptr, output_size); 63 | 64 | output.resize(output_size - 1); 65 | encode_impl(input.get_buffer(), input.get_size(), output.get_buffer(), output_size); 66 | 67 | return output; 68 | } 69 | 70 | byte_buffer 71 | base16::decode( 72 | const string_ref input 73 | ) 74 | { 75 | byte_buffer output; 76 | size_type output_size; 77 | 78 | decode_impl(input.get_buffer(), input.get_size(), nullptr, output_size); 79 | 80 | output.resize(output_size); 81 | decode_impl(input.get_buffer(), input.get_size(), output.get_buffer(), output_size); 82 | 83 | return output; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /mini/console.cpp: -------------------------------------------------------------------------------- 1 | #include "console.h" 2 | 3 | #include 4 | 5 | // 6 | // functions 7 | // 8 | 9 | #ifndef MINI_MSVCRT_LIB 10 | # include 11 | # include 12 | #else 13 | 14 | extern "C" { 15 | 16 | int sscanf( 17 | const char* buffer, 18 | const char* format, 19 | ... 20 | ); 21 | 22 | int printf( 23 | const char* format, 24 | ... 25 | ); 26 | 27 | } 28 | 29 | #endif 30 | 31 | namespace mini::console { 32 | 33 | threading::mutex g_console_output_mutex; 34 | 35 | void 36 | write( 37 | const char* format, 38 | ... 39 | ) 40 | { 41 | va_list args; 42 | va_start(args, format); 43 | write_args(format, args); 44 | va_end(args); 45 | } 46 | 47 | void 48 | write_with_color( 49 | WORD color, 50 | const char* format, 51 | ... 52 | ) 53 | { 54 | va_list args; 55 | va_start(args, format); 56 | write_with_color_args(color, format, args); 57 | va_end(args); 58 | } 59 | 60 | void 61 | write_args( 62 | const char* format, 63 | va_list args 64 | ) 65 | { 66 | mini_lock(g_console_output_mutex) 67 | { 68 | vprintf(format, args); 69 | } 70 | } 71 | 72 | void 73 | write_with_color_args( 74 | WORD color, 75 | const char* format, 76 | va_list args 77 | ) 78 | { 79 | mini_lock(g_console_output_mutex) 80 | { 81 | WORD previous_color = get_color(); 82 | set_color(color); 83 | vprintf(format, args); 84 | set_color(previous_color); 85 | } 86 | } 87 | 88 | 89 | WORD 90 | get_color( 91 | void 92 | ) 93 | { 94 | CONSOLE_SCREEN_BUFFER_INFO console_info; 95 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &console_info); 96 | 97 | return console_info.wAttributes; 98 | } 99 | 100 | void 101 | set_color( 102 | WORD color 103 | ) 104 | { 105 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /mini/memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::memory { 5 | 6 | void* 7 | allocate( 8 | size_t size 9 | ); 10 | 11 | void* 12 | reallocate( 13 | void* ptr, 14 | size_t new_size 15 | ); 16 | 17 | void 18 | free( 19 | void* ptr 20 | ); 21 | 22 | void* 23 | copy( 24 | void* destination, 25 | const void* source, 26 | size_t size 27 | ); 28 | 29 | void* 30 | reverse( 31 | void* destination, 32 | size_t size 33 | ); 34 | 35 | void* 36 | reverse_copy( 37 | void* destination, 38 | const void* source, 39 | size_t size 40 | ); 41 | 42 | void* 43 | move( 44 | void* destination, 45 | const void* source, 46 | size_t size 47 | ); 48 | 49 | int 50 | compare( 51 | const void* lhs, 52 | const void* rhs, 53 | size_t size 54 | ); 55 | 56 | bool 57 | equal( 58 | const void* rhs, 59 | const void* lhs, 60 | size_t size 61 | ); 62 | 63 | void* 64 | find( 65 | const void *haystack, 66 | size_t haystack_size, 67 | const void *needle, 68 | size_t needle_size 69 | ); 70 | 71 | void* 72 | reverse_find( 73 | const void *haystack, 74 | size_t haystack_size, 75 | const void *needle, 76 | size_t needle_size 77 | ); 78 | 79 | void* 80 | set( 81 | void* destination, 82 | int value, 83 | size_t size 84 | ); 85 | 86 | void* 87 | zero( 88 | void* destination, 89 | size_t size 90 | ); 91 | 92 | template < 93 | typename T 94 | > 95 | T& 96 | zero( 97 | T& destination 98 | ) 99 | { 100 | static_assert(std::is_pod_v); 101 | return *reinterpret_cast(zero(&destination, sizeof(destination))); 102 | } 103 | 104 | template < 105 | typename T, 106 | size_t N 107 | > 108 | T* 109 | zero( 110 | T (&destination)[N] 111 | ) 112 | { 113 | static_assert(std::is_pod_v); 114 | return reinterpret_cast(zero(destination, sizeof(T) * N)); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /doc/example-descriptors/introduction-point.txt: -------------------------------------------------------------------------------- 1 | introduction-point pdcpzyefdsm2jycvmpdpkiggr4ul3elo 2 | ip-address 213.136.71.21 3 | onion-port 9001 4 | onion-key 5 | -----BEGIN RSA PUBLIC KEY----- 6 | MIGJAoGBALUrnOKjN6HGKOkr0PQaIhG42PFGvKFiVbwBQ0N8DVMK/4V6VuOrDfHN 7 | 1WzesMJUElw9hOZJ82gcqVWaAobol87I080UOR4/Ze5ypXmi/IwkE7tL7O0Moois 8 | NibWf5gM/RXyo8ts7gh5+Wl+RvOr0hsjSTpmuH1xyIaRazojXn3HAgMBAAE= 9 | -----END RSA PUBLIC KEY----- 10 | service-key 11 | -----BEGIN RSA PUBLIC KEY----- 12 | MIGJAoGBAM0B34xNkYWqp7NxOc32R6HwMs7Oja862Y+Efe9mXDuJf/aF9aHYSw5m 13 | xpz5U8mP1kGu9NY+aW+Q4aN6a2MjnK02Eyg2azaVKz0ZvIWdAgBEWM1LzNT9szLN 14 | gK4vTFR8eNMv8qAyhJvKIbMnS0WfGt3fJawtpRahT7pFwyftuo0pAgMBAAE= 15 | -----END RSA PUBLIC KEY----- 16 | introduction-point cvghvd3r4f3qzzpiwthy4nodimu3angb 17 | ip-address 163.172.214.75 18 | onion-port 9001 19 | onion-key 20 | -----BEGIN RSA PUBLIC KEY----- 21 | MIGJAoGBALYteFkw+PkqdOejkPMjv98v63Kv3SlsNlsKfZRHSK/2mfSEUO2gqHN7 22 | 4J/0oxhlWSSAPPN+9bdOz1emg6IEL2OVdKJfgoiblHMhv+Xx1+jMXKF016J60zk3 23 | WLA4S0/Hjf94aHVRk3kRK6SSViDGNJ1fteEPi5xp9CDQZyFZ1+jVAgMBAAE= 24 | -----END RSA PUBLIC KEY----- 25 | service-key 26 | -----BEGIN RSA PUBLIC KEY----- 27 | MIGJAoGBALAASV+QqFXFt7ykrmvTLxmJj/6BCVEl1yVw0RopbVILQ5cfhaOAeD57 28 | KCCleWdtthM2RVJk+oLoc+DMUxoeEQmJ9rKAn/bsdqkMDSu5A2cpUwj8WnzbxwJp 29 | J79jLbYe3HWsCEw2JLCXh/BdNm1N9Ql7qW42lnrEC5LzdJiF0nIJAgMBAAE= 30 | -----END RSA PUBLIC KEY----- 31 | introduction-point xvggi5iicyxvts2e4tp4dqvsxcutq7gk 32 | ip-address 163.172.35.115 33 | onion-port 9001 34 | onion-key 35 | -----BEGIN RSA PUBLIC KEY----- 36 | MIGJAoGBALReAPZf+K1yd7CDqCgLWdsv7jw8AezsatqnrP7tojF4uw2fLHLJEJMv 37 | VpgFgHHRC3bsz0KvTqvHtEW0XGZJWfhVSW3JAGhz/Yqu53SEC9ZGMslHfr2xlRIr 38 | 7dBEiCBAG8dPkULfC6EcyHPzApH1i9wuzcltuJ0zFQmJElB/jSNPAgMBAAE= 39 | -----END RSA PUBLIC KEY----- 40 | service-key 41 | -----BEGIN RSA PUBLIC KEY----- 42 | MIGJAoGBALNMW5HolfaS3sjZNhwvTwjT9+OsY2aMWZ5byvrCZs0nqCmEivENSAmZ 43 | f9olT4zmxMHY4KIaUFqnYw5y59oHj8xlul4K1DkMMyudQi3appnikAXfaRJmEsJF 44 | 3nOMzWzRcx0mk0XQa8x9atGa5Rs/WiviYXPESbIJ0iNfaRqc2KHXAgMBAAE= 45 | -----END RSA PUBLIC KEY----- 46 | -------------------------------------------------------------------------------- /mini/crypto/cng/provider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../common.h" 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace mini::crypto::cng { 10 | 11 | class provider 12 | { 13 | MINI_MAKE_NONCOPYABLE(provider); 14 | 15 | public: 16 | provider( 17 | void 18 | ); 19 | 20 | ~provider( 21 | void 22 | ); 23 | 24 | template < 25 | cipher_mode AES_MODE 26 | > 27 | BCRYPT_ALG_HANDLE 28 | get_aes_handle( 29 | void 30 | ) 31 | { 32 | return get_aes_handle(AES_MODE); 33 | } 34 | 35 | BCRYPT_ALG_HANDLE 36 | get_aes_handle( 37 | cipher_mode mode 38 | ); 39 | 40 | BCRYPT_ALG_HANDLE 41 | get_rsa_handle( 42 | void 43 | ); 44 | 45 | BCRYPT_ALG_HANDLE 46 | get_dh_handle( 47 | void 48 | ); 49 | 50 | BCRYPT_ALG_HANDLE 51 | get_curve25519_handle( 52 | void 53 | ); 54 | 55 | BCRYPT_ALG_HANDLE 56 | get_rng_handle( 57 | void 58 | ); 59 | 60 | BCRYPT_ALG_HANDLE 61 | get_hash_sha1_handle( 62 | void 63 | ); 64 | 65 | BCRYPT_ALG_HANDLE 66 | get_hash_hmac_sha256_handle( 67 | void 68 | ); 69 | 70 | private: 71 | void 72 | init( 73 | void 74 | ); 75 | 76 | void 77 | destroy( 78 | void 79 | ); 80 | 81 | void 82 | init_win10( 83 | void 84 | ); 85 | 86 | void 87 | destroy_win10( 88 | void 89 | ); 90 | 91 | BCRYPT_ALG_HANDLE _provider_aes[static_cast(cipher_mode::max)]; 92 | BCRYPT_ALG_HANDLE _provider_rsa = nullptr; 93 | BCRYPT_ALG_HANDLE _provider_dh = nullptr; 94 | BCRYPT_ALG_HANDLE _provider_curve25519 = nullptr; 95 | BCRYPT_ALG_HANDLE _provider_rng = nullptr; 96 | BCRYPT_ALG_HANDLE _provider_hash_sha1 = nullptr; 97 | BCRYPT_ALG_HANDLE _provider_hash_hmac_sha256 = nullptr; 98 | }; 99 | 100 | extern provider provider_factory; 101 | 102 | } 103 | -------------------------------------------------------------------------------- /mini/crypto/cng/hmac.inl: -------------------------------------------------------------------------------- 1 | #include "hmac.h" 2 | #include "provider.h" 3 | 4 | namespace mini::crypto::cng { 5 | 6 | // 7 | // constructors. 8 | // 9 | 10 | template < 11 | typename HASH_TYPE 12 | > 13 | hmac::hmac( 14 | const byte_buffer_ref key 15 | ) 16 | : HASH_TYPE(provider_factory.get_hash_hmac_sha256_handle(), key) 17 | { 18 | 19 | } 20 | 21 | template < 22 | typename HASH_TYPE 23 | > 24 | hmac::hmac( 25 | const hmac& other 26 | ) 27 | { 28 | duplicate_internal(other); 29 | } 30 | 31 | template < 32 | typename HASH_TYPE 33 | > 34 | hmac::hmac( 35 | hmac&& other 36 | ) 37 | { 38 | swap(other); 39 | } 40 | 41 | // 42 | // destructor. 43 | // 44 | 45 | template < 46 | typename HASH_TYPE 47 | > 48 | hmac::~hmac( 49 | void 50 | ) 51 | { 52 | this->destroy(); 53 | } 54 | 55 | // 56 | // assign operators. 57 | // 58 | 59 | template < 60 | typename HASH_TYPE 61 | > 62 | hmac& 63 | hmac::operator=( 64 | const hmac& other 65 | ) 66 | { 67 | duplicate_internal(other); 68 | return *this; 69 | } 70 | 71 | template < 72 | typename HASH_TYPE 73 | > 74 | hmac& 75 | hmac::operator=( 76 | hmac&& other 77 | ) 78 | { 79 | swap(other); 80 | return *this; 81 | } 82 | 83 | template < 84 | typename HASH_TYPE 85 | > 86 | hmac 87 | hmac::duplicate( 88 | void 89 | ) 90 | { 91 | return hmac(*this); 92 | } 93 | 94 | // 95 | // swap. 96 | // 97 | 98 | template < 99 | typename HASH_TYPE 100 | > 101 | void 102 | hmac::swap( 103 | hmac& other 104 | ) 105 | { 106 | HASH_TYPE::swap(other._hash); 107 | } 108 | 109 | // 110 | // operations. 111 | // 112 | 113 | template < 114 | typename HASH_TYPE 115 | > 116 | byte_buffer 117 | hmac::compute( 118 | const byte_buffer_ref key, 119 | const byte_buffer_ref input 120 | ) 121 | { 122 | hmac md(key); 123 | md.update(input); 124 | return md.get(); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /mini/tor/parsers/hidden_service_descriptor_parser.cpp: -------------------------------------------------------------------------------- 1 | #include "hidden_service_descriptor_parser.h" 2 | 3 | namespace mini::tor { 4 | 5 | constexpr hidden_service_descriptor_parser::control_word_list hidden_service_descriptor_parser::control_words; 6 | 7 | void 8 | hidden_service_descriptor_parser::parse( 9 | consensus& consensus, 10 | const string_ref descriptor 11 | ) 12 | { 13 | string_collection lines = static_cast(descriptor).split("\n"); 14 | document_location current_location = document_location::control_word; 15 | string current_message; 16 | 17 | for (auto&& line : lines) 18 | { 19 | // 20 | // introduction-points 21 | // 22 | if (line == control_words[control_word_introduction_points]) 23 | { 24 | current_location = document_location::introduction_points; 25 | continue; 26 | } 27 | // 28 | // -----BEGIN MESSAGE----- 29 | // 30 | else if (line == control_words[control_word_message_begin]) 31 | { 32 | current_location = document_location::introduction_points_content; 33 | continue; 34 | } 35 | // 36 | // -----END MESSAGE----- 37 | // 38 | else if (line == control_words[control_word_message_end]) 39 | { 40 | current_location = document_location::control_word; 41 | break; 42 | } 43 | else if (current_location == document_location::introduction_points_content) 44 | { 45 | current_message += line; 46 | } 47 | } 48 | 49 | // 50 | // introduction points are base64 encoded. 51 | // 52 | byte_buffer introduction_point_descriptor = crypto::base64::decode(current_message); 53 | string introduction_point_descriptor_string; 54 | introduction_point_descriptor_string.assign( 55 | (char*)introduction_point_descriptor.get_buffer(), 56 | introduction_point_descriptor.get_size()); 57 | 58 | // 59 | // parse the introduction point descriptor. 60 | // 61 | introduction_point_parser parser; 62 | parser.parse(consensus, introduction_point_descriptor_string); 63 | 64 | introduction_point_list = std::move(parser.introduction_point_list); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /mini/net/tcp_socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace mini::net { 9 | 10 | class tcp_socket 11 | : public io::stream 12 | { 13 | public: 14 | tcp_socket( 15 | void 16 | ); 17 | 18 | tcp_socket( 19 | const string_ref host, 20 | uint16_t port 21 | ); 22 | 23 | ~tcp_socket( 24 | void 25 | ); 26 | 27 | void 28 | close( 29 | void 30 | ) override; 31 | 32 | bool 33 | can_read( 34 | void 35 | ) const override; 36 | 37 | bool 38 | can_write( 39 | void 40 | ) const override; 41 | 42 | bool 43 | can_seek( 44 | void 45 | ) const override; 46 | 47 | string_ref 48 | get_host( 49 | void 50 | ) const; 51 | 52 | const ip_address& 53 | get_ip( 54 | void 55 | ) const; 56 | 57 | uint16_t 58 | get_port( 59 | void 60 | ) const; 61 | 62 | bool 63 | connect( 64 | const string_ref host, 65 | uint16_t port 66 | ); 67 | 68 | public: 69 | size_type 70 | seek( 71 | intptr_t offset, 72 | seek_origin origin = seek_origin::current 73 | ) override; 74 | 75 | void 76 | flush( 77 | void 78 | ) override; 79 | 80 | size_type 81 | get_size( 82 | void 83 | ) const override; 84 | 85 | size_type 86 | get_position( 87 | void 88 | ) const override; 89 | 90 | bool 91 | is_connected( 92 | void 93 | ) const; 94 | 95 | private: 96 | size_type 97 | read_impl( 98 | void* buffer, 99 | size_type size 100 | ) override; 101 | 102 | size_type 103 | write_impl( 104 | const void* buffer, 105 | size_type size 106 | ) override; 107 | 108 | string _host; 109 | ip_address _ip; 110 | 111 | SOCKET _socket = INVALID_SOCKET; 112 | uint16_t _port = 0; 113 | }; 114 | 115 | } 116 | -------------------------------------------------------------------------------- /mini/time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini { 5 | 6 | // 7 | // number of seconds since midnight 1. 1. 1970. 8 | // 9 | using time_type = uint32_t; 10 | 11 | // 12 | // timeout type - number of milliseconds. 13 | // 14 | using timeout_type = int32_t; 15 | static const timeout_type no_wait = 0; 16 | static const timeout_type wait_infinite = (timeout_type)-1; 17 | 18 | using timestamp_type = uint32_t; 19 | 20 | class time 21 | { 22 | public: 23 | // 24 | // constructors. 25 | // 26 | 27 | time( 28 | void 29 | ); 30 | 31 | time( 32 | uint32_t value 33 | ); 34 | 35 | time( 36 | const time& other 37 | ) = default; 38 | 39 | // 40 | // destructor. 41 | // 42 | 43 | ~time( 44 | void 45 | ) = default; 46 | 47 | // 48 | // conversion. 49 | // 50 | 51 | void 52 | parse( 53 | const string_ref value 54 | ); 55 | 56 | time_type 57 | to_timestamp( 58 | void 59 | ) const; 60 | 61 | // 62 | // static methods. 63 | // 64 | 65 | static time 66 | now( 67 | void 68 | ); 69 | 70 | static timestamp_type 71 | timestamp( 72 | void 73 | ); 74 | 75 | // 76 | // operators. 77 | // 78 | 79 | friend bool 80 | operator==( 81 | const time& lhs, 82 | const time& rhs 83 | ); 84 | 85 | friend bool 86 | operator!=( 87 | const time& lhs, 88 | const time& rhs 89 | ); 90 | 91 | friend bool 92 | operator<( 93 | const time& lhs, 94 | const time& rhs 95 | ); 96 | 97 | friend bool 98 | operator>( 99 | const time& lhs, 100 | const time& rhs 101 | ); 102 | 103 | friend bool 104 | operator<=( 105 | const time& lhs, 106 | const time& rhs 107 | ); 108 | 109 | friend bool 110 | operator>=( 111 | const time& lhs, 112 | const time& rhs 113 | ); 114 | 115 | private: 116 | time_type _timestamp; 117 | }; 118 | 119 | } 120 | -------------------------------------------------------------------------------- /mini/win32/pe/import_directory_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "import_directory_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_import_directory_enumerator; 7 | template class pe_import_directory_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_import_directory_enumerator::pe_import_directory_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _import_descriptor = _pe->directory_entry(); 18 | 19 | _count = 0; 20 | 21 | if (_import_descriptor.size > 0) 22 | { 23 | for ( 24 | auto current_import_descriptor = _import_descriptor.entry; 25 | current_import_descriptor->name && current_import_descriptor->original_first_thunk; 26 | current_import_descriptor += 1 27 | ) 28 | { 29 | _count += 1; 30 | } 31 | } 32 | } 33 | 34 | template< 35 | typename TImageTraits 36 | > 37 | pe_import_thunk_enumerator 38 | pe_import_directory_enumerator::proxy::import_thunks( 39 | void 40 | ) const 41 | { 42 | return pe_import_thunk_enumerator(_image_base, _import_descriptor_entry); 43 | } 44 | 45 | template < 46 | typename TImageTraits 47 | > 48 | uint32_t 49 | pe_import_directory_enumerator::characteristics( 50 | void 51 | ) const 52 | { 53 | return _import_descriptor.entry->characteristics; 54 | } 55 | 56 | template < 57 | typename TImageTraits 58 | > 59 | pe_import_directory_enumerator::iterator::iterator( 60 | const pe_import_directory_enumerator* enumerator, 61 | size_t index /*= 0 */ 62 | ) 63 | : _enumerator(enumerator) 64 | , _index(index) 65 | { 66 | 67 | } 68 | 69 | template < 70 | typename TImageTraits 71 | > 72 | typename pe_import_directory_enumerator::iterator::value_type 73 | pe_import_directory_enumerator::iterator::value( 74 | void 75 | ) const 76 | { 77 | value_type result; 78 | 79 | result._image_base = _enumerator->_pe->_image_base; 80 | result._import_descriptor_entry = &_enumerator->_import_descriptor.entry[_index]; 81 | 82 | return result; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /mini/io/file_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "file_enumerator.h" 2 | 3 | namespace mini::io { 4 | 5 | // 6 | // file_iterator. 7 | // 8 | 9 | const file_iterator file_iterator::invalid; 10 | 11 | file_iterator::file_iterator( 12 | void 13 | ) 14 | : _is_invalid(true) 15 | { 16 | 17 | } 18 | 19 | file_iterator::file_iterator( 20 | const string_ref path 21 | ) 22 | { 23 | _find_handle = FindFirstFileA(path.get_buffer(), &_find_data); 24 | _is_invalid = _find_handle == INVALID_HANDLE_VALUE; 25 | } 26 | 27 | file_iterator& 28 | file_iterator::operator++( 29 | void 30 | ) 31 | { 32 | if (!_is_invalid) 33 | { 34 | _is_invalid = !FindNextFileA(_find_handle, &_find_data); 35 | } 36 | 37 | return *this; 38 | } 39 | 40 | file_iterator 41 | file_iterator::operator++( 42 | int 43 | ) 44 | { 45 | file_iterator result = *this; 46 | operator++(); 47 | return result; 48 | } 49 | 50 | bool 51 | file_iterator::operator==( 52 | const file_iterator& other 53 | ) 54 | { 55 | return _is_invalid && other._is_invalid; 56 | } 57 | 58 | bool 59 | file_iterator::operator!=( 60 | const file_iterator& other 61 | ) 62 | { 63 | return !operator==(other); 64 | } 65 | 66 | file_info& 67 | file_iterator::operator*( 68 | void 69 | ) 70 | { 71 | _cached_file_info = file_info { 72 | _find_data.cFileName, 73 | static_cast(_find_data.nFileSizeHigh) << 32 | 74 | static_cast(_find_data.nFileSizeLow), 75 | _find_data.dwFileAttributes 76 | }; 77 | 78 | return _cached_file_info; 79 | } 80 | 81 | file_info* 82 | file_iterator::operator->( 83 | void 84 | ) 85 | { 86 | return &_cached_file_info; 87 | } 88 | 89 | // 90 | // file_enumerator. 91 | // 92 | 93 | file_enumerator::file_enumerator( 94 | const string_ref path 95 | ) 96 | : _path(path) 97 | { 98 | 99 | } 100 | 101 | file_iterator 102 | file_enumerator::begin( 103 | void 104 | ) const 105 | { 106 | return file_iterator(_path); 107 | } 108 | 109 | file_iterator 110 | file_enumerator::end( 111 | void 112 | ) const 113 | { 114 | return file_iterator::invalid; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /mini/win32/pe/export_directory_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "export_directory_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_export_directory_enumerator; 7 | template class pe_export_directory_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_export_directory_enumerator::pe_export_directory_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _export_directory = _pe->directory_entry(); 18 | 19 | _count = _export_directory.size > 0 20 | ? _export_directory.entry->number_of_names 21 | : 0; 22 | } 23 | 24 | template < 25 | typename TImageTraits 26 | > 27 | uint32_t 28 | pe_export_directory_enumerator::characteristics( 29 | void 30 | ) const 31 | { 32 | return _export_directory.entry->characteristics; 33 | } 34 | 35 | template < 36 | typename TImageTraits 37 | > 38 | pe_export_directory_enumerator::iterator::iterator( 39 | const pe_export_directory_enumerator* enumerator, 40 | size_t index /*= 0 */ 41 | ) 42 | : _enumerator(enumerator) 43 | , _index(index) 44 | { 45 | _function_table = reinterpret_cast(_enumerator->_pe->_image_base + _enumerator->_export_directory.entry->address_of_functions); 46 | _name_table = reinterpret_cast(_enumerator->_pe->_image_base + _enumerator->_export_directory.entry->address_of_names); 47 | _ordinal_table = reinterpret_cast(_enumerator->_pe->_image_base + _enumerator->_export_directory.entry->address_of_name_ordinals); 48 | } 49 | 50 | template < 51 | typename TImageTraits 52 | > 53 | typename pe_export_directory_enumerator::iterator::value_type 54 | pe_export_directory_enumerator::iterator::value( 55 | void 56 | ) const 57 | { 58 | value_type result; 59 | 60 | result._image_base = _enumerator->_pe->_image_base; 61 | result._export_directory = _enumerator->_export_directory; 62 | result._name = _name_table[_index]; 63 | result._ordinal = _ordinal_table[_index]; 64 | result._function = _function_table[result._ordinal]; 65 | 66 | return result; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /mini/threading/mutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #define mini_lock(mutex_instance) \ 7 | if (::mini::threading::mutex_holder __h = mutex_instance) \ 8 | { \ 9 | MINI_UNREACHABLE; \ 10 | } \ 11 | else 12 | 13 | #define mini_unlock(mutex_instance) \ 14 | if (::mini::threading::mutex_unholder __h = mutex_instance) \ 15 | { \ 16 | MINI_UNREACHABLE; \ 17 | } \ 18 | else 19 | 20 | namespace mini::threading { 21 | 22 | class mutex 23 | { 24 | MINI_MAKE_NONCOPYABLE(mutex); 25 | 26 | public: 27 | mutex( 28 | void 29 | ); 30 | 31 | mutex( 32 | mutex&& other 33 | ) = default; 34 | 35 | ~mutex( 36 | void 37 | ); 38 | 39 | void 40 | acquire( 41 | void 42 | ); 43 | 44 | void 45 | release( 46 | void 47 | ); 48 | 49 | private: 50 | CRITICAL_SECTION _critical_section; 51 | }; 52 | 53 | class mutex_holder 54 | { 55 | MINI_MAKE_NONCOPYABLE(mutex_holder); 56 | 57 | public: 58 | mutex_holder( 59 | mutex_holder&& other 60 | ) = default; 61 | 62 | mutex_holder( 63 | mutex& mutex 64 | ); 65 | 66 | ~mutex_holder( 67 | void 68 | ); 69 | 70 | operator bool( 71 | void 72 | ) const; 73 | 74 | private: 75 | mutex& _mutex; 76 | }; 77 | 78 | class mutex_unholder 79 | { 80 | MINI_MAKE_NONCOPYABLE(mutex_unholder); 81 | 82 | public: 83 | mutex_unholder( 84 | mutex_unholder&& other 85 | ) = default; 86 | 87 | mutex_unholder( 88 | mutex& mutex 89 | ); 90 | 91 | ~mutex_unholder( 92 | void 93 | ); 94 | 95 | operator bool( 96 | void 97 | ) const; 98 | 99 | private: 100 | mutex& _mutex; 101 | }; 102 | 103 | } 104 | -------------------------------------------------------------------------------- /mini/net/ssl_socket.cpp: -------------------------------------------------------------------------------- 1 | #include "ssl_socket.h" 2 | 3 | namespace mini::net { 4 | 5 | ssl_socket::ssl_socket( 6 | const string_ref host 7 | ) 8 | : _ssl_stream(_socket, host) 9 | { 10 | 11 | } 12 | 13 | ssl_socket::ssl_socket( 14 | const string_ref host, 15 | uint16_t port 16 | ) 17 | : ssl_socket(host) 18 | { 19 | connect(host, port); 20 | } 21 | 22 | ssl_socket::~ssl_socket( 23 | void 24 | ) 25 | { 26 | close(); 27 | } 28 | 29 | void 30 | ssl_socket::close( 31 | void 32 | ) 33 | { 34 | _ssl_stream.close(); 35 | _socket.close(); 36 | } 37 | 38 | bool 39 | ssl_socket::can_read( 40 | void 41 | ) const 42 | { 43 | return true; 44 | } 45 | 46 | bool 47 | ssl_socket::can_write( 48 | void 49 | ) const 50 | { 51 | return true; 52 | } 53 | 54 | bool 55 | ssl_socket::can_seek( 56 | void 57 | ) const 58 | { 59 | return false; 60 | } 61 | 62 | bool 63 | ssl_socket::connect( 64 | const string_ref host, 65 | uint16_t port 66 | ) 67 | { 68 | return 69 | _socket.connect(host, port) && 70 | _ssl_stream.handshake(host, port); 71 | } 72 | 73 | size_type 74 | ssl_socket::seek( 75 | intptr_t offset, 76 | seek_origin origin 77 | ) 78 | { 79 | MINI_UNREFERENCED(offset); 80 | MINI_UNREFERENCED(origin); 81 | 82 | return 0; 83 | } 84 | 85 | void 86 | ssl_socket::flush() 87 | { 88 | 89 | } 90 | 91 | size_type 92 | ssl_socket::get_size( 93 | void 94 | ) const 95 | { 96 | return 0; 97 | } 98 | 99 | size_type 100 | ssl_socket::get_position( 101 | void 102 | ) const 103 | { 104 | return 0; 105 | } 106 | 107 | tcp_socket& 108 | ssl_socket::get_underlying_socket( 109 | void 110 | ) 111 | { 112 | return _socket; 113 | } 114 | 115 | bool 116 | ssl_socket::is_connected( 117 | void 118 | ) const 119 | { 120 | return 121 | _socket.is_connected() && 122 | _ssl_stream.is_handshake_established(); 123 | } 124 | 125 | size_type 126 | ssl_socket::read_impl( 127 | void* buffer, 128 | size_type size 129 | ) 130 | { 131 | return _ssl_stream.read(buffer, size); 132 | } 133 | 134 | size_type 135 | ssl_socket::write_impl( 136 | const void* buffer, 137 | size_type size 138 | ) 139 | { 140 | return _ssl_stream.write(buffer, size); 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /mini/tor/circuit_node.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "circuit_node_crypto_state.h" 3 | #include "crypto/key_agreement.h" 4 | 5 | #include 6 | #include 7 | 8 | namespace mini::tor { 9 | 10 | class circuit; 11 | 12 | class circuit_node 13 | { 14 | public: 15 | circuit_node( 16 | circuit* circuit, 17 | onion_router* router, 18 | circuit_node_type node_type = circuit_node_type::normal 19 | ); 20 | 21 | circuit* 22 | get_circuit( 23 | void 24 | ); 25 | 26 | circuit_node_type 27 | get_circuit_node_type( 28 | void 29 | ) const; 30 | 31 | onion_router* 32 | get_onion_router( 33 | void 34 | ); 35 | 36 | key_agreement& 37 | get_key_agreement( 38 | void 39 | ); 40 | 41 | byte_buffer 42 | create_onion_skin( 43 | void 44 | ); 45 | 46 | byte_buffer 47 | create_onion_skin_ntor( 48 | void 49 | ); 50 | 51 | void 52 | compute_shared_secret( 53 | const byte_buffer_ref cell_payload 54 | ); 55 | 56 | bool 57 | has_valid_crypto_state( 58 | void 59 | ) const; 60 | 61 | void 62 | encrypt_forward_cell( 63 | relay_cell& cell 64 | ); 65 | 66 | bool 67 | decrypt_backward_cell( 68 | cell& cell 69 | ); 70 | 71 | // 72 | // flow control. 73 | // 74 | 75 | void 76 | decrement_package_window( 77 | void 78 | ); 79 | 80 | void 81 | increment_package_window( 82 | void 83 | ); 84 | 85 | void 86 | decrement_deliver_window( 87 | void 88 | ); 89 | 90 | bool 91 | consider_sending_sendme( 92 | void 93 | ); 94 | 95 | private: 96 | static constexpr size_type window_start = 1000; 97 | static constexpr size_type window_increment = 100; 98 | 99 | circuit* _circuit; 100 | circuit_node_type _type; 101 | 102 | onion_router* _onion_router; 103 | ptr _crypto_state; 104 | ptr _handshake; 105 | 106 | size_type _package_window = window_start; 107 | size_type _deliver_window = window_start; 108 | threading::mutex _window_mutex; 109 | }; 110 | 111 | } 112 | -------------------------------------------------------------------------------- /mini/win32/pe/relocation_directory_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "relocation_directory_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_relocation_directory_enumerator; 7 | template class pe_relocation_directory_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_relocation_directory_enumerator::pe_relocation_directory_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _base_relocation = _pe->directory_entry(); 18 | _base_relocation_end = reinterpret_cast(uintptr_t(_base_relocation.entry) + _base_relocation.size); 19 | } 20 | 21 | 22 | template< 23 | typename TImageTraits 24 | > 25 | pe_relocation_fixup_enumerator 26 | pe_relocation_directory_enumerator::proxy::fixups( 27 | void 28 | ) const 29 | { 30 | return pe_relocation_fixup_enumerator(_image_base, _relocation); 31 | } 32 | 33 | template < 34 | typename TImageTraits 35 | > 36 | pe_relocation_directory_enumerator::iterator::iterator( 37 | const pe_relocation_directory_enumerator* enumerator, 38 | typename TImageTraits::image_base_relocation_t* current_relocation 39 | ) 40 | : _enumerator(enumerator) 41 | , _relocation_current(current_relocation) 42 | , _relocation_end(enumerator->_base_relocation_end) 43 | { 44 | 45 | } 46 | 47 | template < 48 | typename TImageTraits 49 | > 50 | void 51 | pe_relocation_directory_enumerator::iterator::advance( 52 | void 53 | ) 54 | { 55 | _relocation_current = reinterpret_cast( 56 | uintptr_t(_relocation_current) + _relocation_current->size_of_block 57 | ); 58 | 59 | if (_relocation_current > _relocation_end) 60 | { 61 | _relocation_current = _relocation_end; 62 | } 63 | } 64 | 65 | template < 66 | typename TImageTraits 67 | > 68 | typename pe_relocation_directory_enumerator::iterator::value_type 69 | pe_relocation_directory_enumerator::iterator::value( 70 | void 71 | ) const 72 | { 73 | value_type result; 74 | 75 | result._image_base = _enumerator->_pe->_image_base; 76 | result._relocation = _relocation_current; 77 | 78 | return result; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /mini/logger.cpp: -------------------------------------------------------------------------------- 1 | #include "logger.h" 2 | #include "console.h" 3 | 4 | namespace mini { 5 | 6 | logger log; 7 | 8 | static constexpr WORD level_colors[] = { 9 | FOREGROUND_INTENSITY | FOREGROUND_GREEN /* | FOREGROUND_BLUE */, // debug 10 | FOREGROUND_INTENSITY | FOREGROUND_GREEN, // info 11 | FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED, // warning 12 | FOREGROUND_INTENSITY | FOREGROUND_RED, // error 13 | }; 14 | 15 | void 16 | logger::log( 17 | level l, 18 | const char* format, 19 | ... 20 | ) 21 | { 22 | va_list args; 23 | va_start(args, format); 24 | log_args(l, format, args); 25 | va_end(args); 26 | } 27 | 28 | void 29 | logger::log_args( 30 | level l, 31 | const char* format, 32 | va_list args 33 | ) 34 | { 35 | if (l >= _level) 36 | { 37 | SYSTEMTIME local_time; 38 | GetLocalTime(&local_time); 39 | 40 | console::write_with_color( 41 | level_colors[(int)l], 42 | "[%02u:%02u:%02u.%03u] ", 43 | local_time.wHour, 44 | local_time.wMinute, 45 | local_time.wSecond, 46 | local_time.wMilliseconds); 47 | 48 | console::write_with_color_args(level_colors[(int)l], format, args); 49 | } 50 | } 51 | 52 | void 53 | logger::debug( 54 | const char* format, 55 | ... 56 | ) 57 | { 58 | va_list args; 59 | va_start(args, format); 60 | log(level::debug, format, args); 61 | va_end(args); 62 | } 63 | 64 | void 65 | logger::info( 66 | const char* format, 67 | ... 68 | ) 69 | { 70 | va_list args; 71 | va_start(args, format); 72 | log(level::info, format, args); 73 | va_end(args); 74 | } 75 | 76 | void 77 | logger::warning( 78 | const char* format, 79 | ... 80 | ) 81 | { 82 | va_list args; 83 | va_start(args, format); 84 | log(level::warning, format, args); 85 | va_end(args); 86 | } 87 | 88 | void 89 | logger::error( 90 | const char* format, 91 | ... 92 | ) 93 | { 94 | va_list args; 95 | va_start(args, format); 96 | log(level::error, format, args); 97 | va_end(args); 98 | } 99 | 100 | logger::level 101 | logger::get_level( 102 | void 103 | ) const 104 | { 105 | return _level; 106 | } 107 | 108 | void 109 | logger::set_level( 110 | level new_level 111 | ) 112 | { 113 | _level = new_level; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /mini/tor/parsers/introduction_point_parser.cpp: -------------------------------------------------------------------------------- 1 | #include "introduction_point_parser.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mini::tor { 8 | 9 | constexpr introduction_point_parser::control_word_list introduction_point_parser::control_words; 10 | 11 | void 12 | introduction_point_parser::parse( 13 | consensus& consensus, 14 | const string_ref descriptor 15 | ) 16 | { 17 | string_collection lines = static_cast(descriptor).split("\n"); 18 | document_location current_location = document_location::control_word; 19 | onion_router* current_router = nullptr; 20 | string current_key; 21 | 22 | for (auto&& line : lines) 23 | { 24 | string_collection splitted_line = line.split(" "); 25 | string_hash control_word_hash = splitted_line[0]; 26 | 27 | // 28 | // introduction-point 29 | // 30 | if (control_word_hash == control_words[control_word_introduction_point]) 31 | { 32 | auto identity_fingerprint = crypto::base32::decode(splitted_line[1]); 33 | current_router = consensus.get_onion_router_by_identity_fingerprint(identity_fingerprint); 34 | continue; 35 | } 36 | // 37 | // service-key 38 | // 39 | else if (control_word_hash == control_words[control_word_service_key]) 40 | { 41 | current_location = document_location::service_key; 42 | continue; 43 | } 44 | // 45 | // -----BEGIN RSA PUBLIC KEY----- 46 | // 47 | else if (line == control_words[control_word_key_begin] && current_location == document_location::service_key) 48 | { 49 | current_location = document_location::service_key_content; 50 | continue; 51 | } 52 | // 53 | // -----END RSA PUBLIC KEY----- 54 | // 55 | else if (line == control_words[control_word_key_end] && current_location == document_location::service_key_content) 56 | { 57 | if (current_router) 58 | { 59 | current_router->set_service_key(crypto::base64::decode(current_key)); 60 | introduction_point_list.add(current_router); 61 | } 62 | 63 | current_location = document_location::control_word; 64 | current_key.clear(); 65 | } 66 | else if (current_location == document_location::service_key_content) 67 | { 68 | current_key += line; 69 | } 70 | } 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /mini/crypto/cng/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../common.h" 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace mini::crypto::cng { 9 | 10 | template < 11 | hash_algorithm_type HASH_ALGORITHM 12 | > 13 | class hash 14 | { 15 | public: 16 | static constexpr size_type hash_size = hash_algorithm_to_bit_size(HASH_ALGORITHM); 17 | static constexpr size_type hash_size_in_bytes = hash_size / 8; 18 | static constexpr hash_algorithm_type hash_algorithm = HASH_ALGORITHM; 19 | 20 | // 21 | // constructors. 22 | // 23 | 24 | hash( 25 | void 26 | ); 27 | 28 | hash( 29 | const hash& other 30 | ); 31 | 32 | hash( 33 | hash&& other 34 | ); 35 | 36 | // 37 | // destructor. 38 | // 39 | 40 | ~hash( 41 | void 42 | ); 43 | 44 | // 45 | // assign operators. 46 | // 47 | 48 | hash& 49 | operator=( 50 | const hash& other 51 | ); 52 | 53 | hash& 54 | operator=( 55 | hash&& other 56 | ); 57 | 58 | hash 59 | duplicate( 60 | void 61 | ); 62 | 63 | // 64 | // swap. 65 | // 66 | 67 | void 68 | swap( 69 | hash& other 70 | ); 71 | 72 | // 73 | // operations. 74 | // 75 | 76 | void 77 | update( 78 | const byte_buffer_ref input 79 | ); 80 | 81 | static byte_buffer 82 | compute( 83 | const byte_buffer_ref input 84 | ); 85 | 86 | // 87 | // accessors. 88 | // 89 | 90 | void 91 | get( 92 | mutable_byte_buffer_ref output 93 | ); 94 | 95 | byte_buffer 96 | get( 97 | void 98 | ); 99 | 100 | protected: 101 | hash( 102 | BCRYPT_ALG_HANDLE alg_handle, 103 | const byte_buffer_ref key 104 | ); 105 | 106 | void 107 | init( 108 | BCRYPT_ALG_HANDLE alg_handle 109 | ); 110 | 111 | void 112 | init( 113 | BCRYPT_ALG_HANDLE alg_handle, 114 | const byte_buffer_ref key 115 | ); 116 | 117 | void 118 | destroy( 119 | void 120 | ); 121 | 122 | void 123 | duplicate_internal( 124 | const hash& other 125 | ); 126 | 127 | private: 128 | BCRYPT_HASH_HANDLE _hash_handle = nullptr; 129 | }; 130 | 131 | } 132 | 133 | #include "hash.inl" 134 | -------------------------------------------------------------------------------- /mini/threading/thread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace mini::threading { 10 | 11 | class thread; 12 | 13 | namespace detail { 14 | void 15 | thread_dispatcher( 16 | thread* thread_instance 17 | ); 18 | } 19 | 20 | class thread 21 | { 22 | MINI_MAKE_NONCOPYABLE(thread); 23 | 24 | public: 25 | using id = uint32_t; 26 | struct current_thread_tag {}; 27 | 28 | // 29 | // constructors. 30 | // 31 | 32 | thread( 33 | void 34 | ) = default; 35 | 36 | thread( 37 | thread&& other 38 | ); 39 | 40 | thread( 41 | current_thread_tag 42 | ); 43 | 44 | // 45 | // destructor. 46 | // 47 | 48 | virtual ~thread( 49 | void 50 | ); 51 | 52 | // 53 | // swap. 54 | // 55 | 56 | void 57 | swap( 58 | thread& other 59 | ); 60 | 61 | // 62 | // operations. 63 | // 64 | 65 | void 66 | start( 67 | void 68 | ); 69 | 70 | void 71 | stop( 72 | void 73 | ); 74 | 75 | wait_result 76 | join( 77 | timeout_type timeout = wait_infinite 78 | ); 79 | 80 | // 81 | // observers. 82 | // 83 | 84 | id 85 | get_id( 86 | void 87 | ) const; 88 | 89 | bool 90 | is_alive( 91 | void 92 | ) const; 93 | 94 | // 95 | // static methods. 96 | // 97 | 98 | static thread 99 | get_current_thread( 100 | void 101 | ); 102 | 103 | static void 104 | sleep( 105 | timeout_type milliseconds 106 | ); 107 | 108 | protected: 109 | 110 | // 111 | // virtual methods. 112 | // 113 | 114 | virtual void 115 | thread_procedure( 116 | void 117 | ); 118 | 119 | private: 120 | friend void detail::thread_dispatcher( 121 | thread* thread_instance 122 | ); 123 | 124 | // 125 | // it's quite important to not use the INVALID_HANDLE_VALUE constant, 126 | // because the value is same as "current process" pseudo-handle. 127 | // 128 | HANDLE _thread_handle = 0; 129 | DWORD _thread_id = 0; 130 | bool _has_been_terminated = false; 131 | }; 132 | 133 | void 134 | swap( 135 | thread& lhs, 136 | thread& rhs 137 | ); 138 | 139 | } 140 | -------------------------------------------------------------------------------- /mini/crypto/capi/hmac.inl: -------------------------------------------------------------------------------- 1 | #include "hmac.h" 2 | #include "provider.h" 3 | 4 | namespace mini::crypto::capi { 5 | 6 | // 7 | // constructors. 8 | // 9 | 10 | template < 11 | typename HASH_TYPE 12 | > 13 | hmac::hmac( 14 | const byte_buffer_ref key 15 | ) 16 | : HASH_TYPE(detail::hash_algorithm_type_map[static_cast(hash_algorithm)], key, _key_handle) 17 | { 18 | 19 | } 20 | 21 | template < 22 | typename HASH_TYPE 23 | > 24 | hmac::hmac( 25 | const hmac& other 26 | ) 27 | { 28 | duplicate_internal(other); 29 | } 30 | 31 | template < 32 | typename HASH_TYPE 33 | > 34 | hmac::hmac( 35 | hmac&& other 36 | ) 37 | { 38 | swap(other); 39 | } 40 | 41 | // 42 | // destructor. 43 | // 44 | 45 | template < 46 | typename HASH_TYPE 47 | > 48 | hmac::~hmac( 49 | void 50 | ) 51 | { 52 | destroy(); 53 | } 54 | 55 | // 56 | // assign operators. 57 | // 58 | 59 | template < 60 | typename HASH_TYPE 61 | > 62 | hmac& 63 | hmac::operator=( 64 | const hmac& other 65 | ) 66 | { 67 | duplicate_internal(other); 68 | return *this; 69 | } 70 | 71 | template < 72 | typename HASH_TYPE 73 | > 74 | hmac& 75 | hmac::operator=( 76 | hmac&& other 77 | ) 78 | { 79 | swap(other); 80 | return *this; 81 | } 82 | 83 | template < 84 | typename HASH_TYPE 85 | > 86 | hmac 87 | hmac::duplicate( 88 | void 89 | ) 90 | { 91 | return hmac(*this); 92 | } 93 | 94 | // 95 | // swap. 96 | // 97 | 98 | template < 99 | typename HASH_TYPE 100 | > 101 | void 102 | hmac::swap( 103 | hmac& other 104 | ) 105 | { 106 | HASH_TYPE::swap(other); 107 | mini::swap(_key_handle, other._key_handle); 108 | } 109 | 110 | // 111 | // operations. 112 | // 113 | 114 | template < 115 | typename HASH_TYPE 116 | > 117 | byte_buffer 118 | hmac::compute( 119 | const byte_buffer_ref key, 120 | const byte_buffer_ref input 121 | ) 122 | { 123 | hmac md(key); 124 | md.update(input); 125 | return md.get(); 126 | } 127 | 128 | template < 129 | typename HASH_TYPE 130 | > 131 | void 132 | hmac::destroy( 133 | void 134 | ) 135 | { 136 | HASH_TYPE::destroy(); 137 | 138 | if (_key_handle) 139 | { 140 | CryptDestroyKey(_key_handle); 141 | _key_handle = 0; 142 | } 143 | } 144 | 145 | 146 | } 147 | -------------------------------------------------------------------------------- /mini/net/ssl_stream.cpp: -------------------------------------------------------------------------------- 1 | #include "ssl_stream.h" 2 | 3 | namespace mini::net { 4 | 5 | ssl_stream::ssl_stream( 6 | io::stream& underlying_stream, 7 | const string_ref target_name 8 | ) 9 | : _underlying_stream(underlying_stream) 10 | { 11 | _context.initialize(_underlying_stream, target_name); 12 | } 13 | 14 | ssl_stream::~ssl_stream( 15 | void 16 | ) 17 | { 18 | close(); 19 | } 20 | 21 | void 22 | ssl_stream::close( 23 | void 24 | ) 25 | { 26 | _context.disconnect(); 27 | } 28 | 29 | bool 30 | ssl_stream::can_read( 31 | void 32 | ) const 33 | { 34 | return true; 35 | } 36 | 37 | bool 38 | ssl_stream::can_write( 39 | void 40 | ) const 41 | { 42 | return true; 43 | } 44 | 45 | bool 46 | ssl_stream::can_seek( 47 | void 48 | ) const 49 | { 50 | return false; 51 | } 52 | 53 | bool 54 | ssl_stream::handshake( 55 | const string_ref host, 56 | uint16_t port 57 | ) 58 | { 59 | MINI_UNREFERENCED(host); 60 | MINI_UNREFERENCED(port); 61 | 62 | return _context.handshake() == SEC_E_OK; 63 | } 64 | 65 | size_type 66 | ssl_stream::seek( 67 | intptr_t offset, 68 | seek_origin origin 69 | ) 70 | { 71 | MINI_UNREFERENCED(offset); 72 | MINI_UNREFERENCED(origin); 73 | 74 | return 0; 75 | } 76 | 77 | void 78 | ssl_stream::flush() 79 | { 80 | 81 | } 82 | 83 | size_type 84 | ssl_stream::get_size( 85 | void 86 | ) const 87 | { 88 | return 0; 89 | } 90 | 91 | size_type 92 | ssl_stream::get_position( 93 | void 94 | ) const 95 | { 96 | return 0; 97 | } 98 | 99 | io::stream& 100 | ssl_stream::get_underlying_stream( 101 | void 102 | ) 103 | { 104 | return _underlying_stream; 105 | } 106 | 107 | bool 108 | ssl_stream::is_handshake_established( 109 | void 110 | ) const 111 | { 112 | return _context.is_valid(); 113 | } 114 | 115 | size_type 116 | ssl_stream::read_impl( 117 | void* buffer, 118 | size_type size 119 | ) 120 | { 121 | mutable_byte_buffer_ref buf( 122 | static_cast(buffer), 123 | static_cast(buffer) + size); 124 | 125 | return _context.read(buf); 126 | } 127 | 128 | size_type 129 | ssl_stream::write_impl( 130 | const void* buffer, 131 | size_type size 132 | ) 133 | { 134 | byte_buffer_ref buf( 135 | static_cast(buffer), 136 | static_cast(buffer) + size); 137 | 138 | return _context.write(buf); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /mini/crypto/capi/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../common.h" 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace mini::crypto::capi { 9 | 10 | template < 11 | hash_algorithm_type HASH_ALGORITHM 12 | > 13 | class hash 14 | { 15 | public: 16 | static constexpr size_type hash_size = hash_algorithm_to_bit_size(HASH_ALGORITHM); 17 | static constexpr size_type hash_size_in_bytes = hash_size / 8; 18 | static constexpr hash_algorithm_type hash_algorithm = HASH_ALGORITHM; 19 | 20 | // 21 | // constructors. 22 | // 23 | 24 | hash( 25 | void 26 | ); 27 | 28 | hash( 29 | const hash& other 30 | ); 31 | 32 | hash( 33 | hash&& other 34 | ); 35 | 36 | // 37 | // destructor. 38 | // 39 | 40 | ~hash( 41 | void 42 | ); 43 | 44 | // 45 | // assign operators. 46 | // 47 | 48 | hash& 49 | operator=( 50 | const hash& other 51 | ); 52 | 53 | hash& 54 | operator=( 55 | hash&& other 56 | ); 57 | 58 | hash 59 | duplicate( 60 | void 61 | ); 62 | 63 | // 64 | // swap. 65 | // 66 | 67 | void 68 | swap( 69 | hash& other 70 | ); 71 | 72 | // 73 | // operations. 74 | // 75 | 76 | void 77 | update( 78 | const byte_buffer_ref input 79 | ); 80 | 81 | static byte_buffer 82 | compute( 83 | const byte_buffer_ref input 84 | ); 85 | 86 | // 87 | // accessors. 88 | // 89 | 90 | void 91 | get( 92 | mutable_byte_buffer_ref output 93 | ); 94 | 95 | byte_buffer 96 | get( 97 | void 98 | ); 99 | 100 | protected: 101 | hash( 102 | ALG_ID alg_id, 103 | const byte_buffer_ref key, 104 | HCRYPTKEY& key_handle 105 | ); 106 | 107 | void 108 | init( 109 | ALG_ID alg_id 110 | ); 111 | 112 | void 113 | init( 114 | ALG_ID alg_id, 115 | const byte_buffer_ref key, 116 | HCRYPTKEY& key_handle 117 | ); 118 | 119 | void 120 | destroy( 121 | void 122 | ); 123 | 124 | void 125 | duplicate_internal( 126 | const hash& other 127 | ); 128 | 129 | private: 130 | HCRYPTHASH _hash_handle = 0; 131 | }; 132 | 133 | } 134 | 135 | #include "hash.inl" 136 | -------------------------------------------------------------------------------- /mini/win32/pe/tls_directory_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "tls_directory_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_tls_directory_enumerator; 7 | template class pe_tls_directory_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_tls_directory_enumerator::pe_tls_directory_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _tls_directory = _pe->directory_entry(); 18 | _count = 0; 19 | 20 | if (_tls_directory.size > 0) 21 | { 22 | _tls_callback_table = reinterpret_cast(uintptr_t(_tls_directory.entry->address_of_callbacks)); 23 | 24 | for ( 25 | auto current_tls_callback = _tls_callback_table; 26 | *current_tls_callback; 27 | current_tls_callback += 1 28 | ) 29 | { 30 | _count += 1; 31 | } 32 | } 33 | } 34 | 35 | template < 36 | typename TImageTraits 37 | > 38 | uint32_t 39 | pe_tls_directory_enumerator::characteristics( 40 | void 41 | ) const 42 | { 43 | return _tls_directory.entry->characteristics; 44 | } 45 | 46 | template < 47 | typename TImageTraits 48 | > 49 | void* 50 | pe_tls_directory_enumerator::data( 51 | void 52 | ) const 53 | { 54 | return reinterpret_cast(_pe->_image_base + _tls_directory.entry->start_address_of_raw_data); 55 | } 56 | 57 | template < 58 | typename TImageTraits 59 | > 60 | size_t 61 | pe_tls_directory_enumerator::data_size( 62 | void 63 | ) const 64 | { 65 | return 66 | reinterpret_cast(_pe->_image_base + _tls_directory.entry->end_address_of_raw_data) - 67 | reinterpret_cast(_pe->_image_base + _tls_directory.entry->start_address_of_raw_data); 68 | } 69 | 70 | template < 71 | typename TImageTraits 72 | > 73 | pe_tls_directory_enumerator::iterator::iterator( 74 | const pe_tls_directory_enumerator* enumerator, 75 | size_t index /*= 0 */ 76 | ) 77 | : _enumerator(enumerator) 78 | , _index(index) 79 | { 80 | 81 | } 82 | 83 | template < 84 | typename TImageTraits 85 | > 86 | typename pe_tls_directory_enumerator::iterator::value_type 87 | pe_tls_directory_enumerator::iterator::value( 88 | void 89 | ) const 90 | { 91 | value_type result; 92 | 93 | result._tls_callback = _enumerator->_tls_callback_table[_index]; 94 | 95 | return result; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /mini/net/ip_address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | namespace mini::net { 8 | 9 | class ip_address 10 | { 11 | public: 12 | constexpr ip_address( 13 | void 14 | ) = default; 15 | 16 | constexpr ip_address( 17 | const ip_address& other 18 | ) = default; 19 | 20 | constexpr ip_address( 21 | ip_address&& other 22 | ) = default; 23 | 24 | constexpr ip_address( 25 | uint32_t value 26 | ) 27 | : _ip(value) 28 | { 29 | 30 | } 31 | 32 | ip_address( 33 | const string_ref value 34 | ) 35 | : _ip(inet_addr(value.get_buffer())) 36 | { 37 | 38 | } 39 | 40 | ip_address& 41 | operator=( 42 | const ip_address& other 43 | ) = default; 44 | 45 | ip_address& 46 | operator=( 47 | ip_address&& other 48 | ) = default; 49 | 50 | static constexpr ip_address 51 | from_int( 52 | uint32_t value 53 | ) 54 | { 55 | return ip_address(value); 56 | } 57 | 58 | static constexpr ip_address 59 | from_string( 60 | const char* value 61 | ) 62 | { 63 | return ip_address(ip_string_to_int(value)); 64 | } 65 | 66 | static constexpr uint32_t 67 | to_int( 68 | const char* value 69 | ) 70 | { 71 | return ip_string_to_int(value); 72 | } 73 | 74 | string 75 | to_string( 76 | void 77 | ) const 78 | { 79 | return string(inet_ntoa(to_in_addr())); 80 | } 81 | 82 | in_addr 83 | to_in_addr( 84 | void 85 | ) const 86 | { 87 | in_addr result; 88 | result.S_un.S_addr = _ip; 89 | 90 | return result; 91 | } 92 | 93 | constexpr uint32_t 94 | to_int( 95 | void 96 | ) const 97 | { 98 | return _ip; 99 | } 100 | 101 | private: 102 | static constexpr uint32_t 103 | ip_string_to_int( 104 | const char* value 105 | ) 106 | { 107 | return 108 | static_cast(ctl::atoi(value)) | 109 | static_cast(ctl::atoi(ctl::strchr(value, '.') + 1)) << 8 | 110 | static_cast(ctl::atoi(ctl::strchr(ctl::strchr(value, '.') + 1, '.') + 1)) << 16 | 111 | static_cast(ctl::atoi(ctl::strchr(ctl::strchr(ctl::strchr(value, '.') + 1, '.') + 1, '.') + 1)) << 24; 112 | } 113 | 114 | uint32_t _ip = 0; 115 | }; 116 | 117 | } 118 | -------------------------------------------------------------------------------- /mini/threading/event.cpp: -------------------------------------------------------------------------------- 1 | #include "event.h" 2 | #include 3 | 4 | #include 5 | 6 | namespace mini::threading { 7 | 8 | event::event( 9 | reset_type type, 10 | bool initial_state 11 | ) 12 | { 13 | _event = CreateEvent(NULL, (BOOL)type, initial_state, NULL); 14 | } 15 | 16 | event::~event( 17 | void 18 | ) 19 | { 20 | CloseHandle(_event); 21 | } 22 | 23 | void 24 | event::set( 25 | void 26 | ) 27 | { 28 | SetEvent(_event); 29 | } 30 | 31 | void 32 | event::reset( 33 | void 34 | ) 35 | { 36 | ResetEvent(_event); 37 | } 38 | 39 | wait_result 40 | event::wait( 41 | timeout_type timeout 42 | ) 43 | { 44 | return static_cast(WaitForSingleObject(_event, timeout)); 45 | } 46 | 47 | wait_result 48 | event::wait_for_all( 49 | buffer_ref events, 50 | timeout_type timeout 51 | ) 52 | { 53 | collections::list handles; 54 | 55 | for (auto&& event : events) 56 | { 57 | handles.add(event->_event); 58 | } 59 | 60 | return static_cast(WaitForMultipleObjects( 61 | static_cast(handles.get_size()), 62 | // 63 | // dirty hack - as long as 'event' class 64 | // consists only from one HANDLE member, 65 | // this should work just fine. 66 | // 67 | &handles[0], 68 | TRUE, 69 | timeout)); 70 | } 71 | 72 | wait_result 73 | event::wait_for_any( 74 | buffer_ref events, 75 | timeout_type timeout 76 | ) 77 | { 78 | collections::list handles; 79 | 80 | for (auto&& event : events) 81 | { 82 | handles.add(event->_event); 83 | } 84 | 85 | return static_cast(WaitForMultipleObjects( 86 | static_cast(handles.get_size()), 87 | // 88 | // dirty hack - as long as 'event' class 89 | // consists only from one HANDLE member, 90 | // this should work just fine. 91 | // 92 | &handles[0], 93 | FALSE, 94 | timeout)); 95 | } 96 | 97 | int 98 | event::index_from_wait_result( 99 | wait_result result 100 | ) 101 | { 102 | return 103 | result == wait_result::timeout ? -1 : 104 | result == wait_result::failed ? -1 : 105 | result > wait_result::abandoned ? (static_cast(result) - static_cast(wait_result::abandoned)) : 106 | static_cast(result) - static_cast(wait_result::success); 107 | } 108 | 109 | bool 110 | event::is_signaled( 111 | void 112 | ) 113 | { 114 | return wait(0) == wait_result::success; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /mini/win32/pe/resource_directory_enumerator.cpp: -------------------------------------------------------------------------------- 1 | #include "resource_directory_enumerator.h" 2 | #include "../pe.h" 3 | 4 | namespace mini::win32 { 5 | 6 | template class pe_resource_directory_enumerator; 7 | template class pe_resource_directory_enumerator; 8 | 9 | template < 10 | typename TImageTraits 11 | > 12 | pe_resource_directory_enumerator::pe_resource_directory_enumerator( 13 | const pe_file* pe 14 | ) 15 | : _pe(pe) 16 | { 17 | _resource_directory = _pe->directory_entry(); 18 | 19 | _count = _resource_directory.size > 0 20 | ? _resource_directory.entry->number_of_named_entries + _resource_directory.entry->number_of_id_entries 21 | : 0; 22 | 23 | _top_resource_directory = _resource_directory; 24 | } 25 | 26 | template < 27 | typename TImageTraits 28 | > 29 | pe_resource_directory_enumerator::pe_resource_directory_enumerator( 30 | const pe_file* pe, 31 | pe_directory resource_directory, 32 | pe_directory top_resource_directory 33 | ) 34 | : _pe(pe) 35 | { 36 | _resource_directory = resource_directory; 37 | 38 | _count = _resource_directory.size > 0 39 | ? _resource_directory.entry->number_of_named_entries + _resource_directory.entry->number_of_id_entries 40 | : 0; 41 | 42 | _top_resource_directory = top_resource_directory; 43 | } 44 | 45 | template < 46 | typename TImageTraits 47 | > 48 | uint32_t 49 | pe_resource_directory_enumerator::characteristics( 50 | void 51 | ) const 52 | { 53 | return _resource_directory.entry->characteristics; 54 | } 55 | 56 | template < 57 | typename TImageTraits 58 | > 59 | pe_resource_directory_enumerator::iterator::iterator( 60 | const pe_resource_directory_enumerator* enumerator, 61 | size_t index /*= 0 */ 62 | ) 63 | : _enumerator(enumerator) 64 | , _index(index) 65 | { 66 | _resource_entry_table = reinterpret_cast(_enumerator->_resource_directory.entry + 1); 67 | } 68 | 69 | template < 70 | typename TImageTraits 71 | > 72 | typename pe_resource_directory_enumerator::iterator::value_type 73 | pe_resource_directory_enumerator::iterator::value( 74 | void 75 | ) const 76 | { 77 | value_type result; 78 | 79 | result._pe = _enumerator->_pe; 80 | result._top_resource_directory = _enumerator->_top_resource_directory; 81 | result._resource_directory_entry = &_resource_entry_table[_index]; 82 | 83 | return result; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /mini/tor/parsers/onion_router_descriptor_parser.cpp: -------------------------------------------------------------------------------- 1 | #include "onion_router_descriptor_parser.h" 2 | 3 | #include 4 | 5 | namespace mini::tor { 6 | 7 | constexpr onion_router_descriptor_parser::control_word_list onion_router_descriptor_parser::control_words; 8 | 9 | void 10 | onion_router_descriptor_parser::parse( 11 | onion_router* router, 12 | const string_ref descriptor 13 | ) 14 | { 15 | string_collection lines = static_cast(descriptor).split("\n"); 16 | document_location current_location = document_location::control_word; 17 | string current_key; 18 | 19 | for (auto&& line : lines) 20 | { 21 | string_collection splitted_line = line.split(" "); 22 | string_hash control_word_hash = splitted_line[0]; 23 | 24 | // 25 | // onion-key 26 | // 27 | if (line == control_words[control_word_onion_key]) 28 | { 29 | current_location = document_location::onion_key; 30 | continue; 31 | } 32 | // 33 | // signing-key 34 | // 35 | else if (line == control_words[control_word_signing_key]) 36 | { 37 | current_location = document_location::signing_key; 38 | continue; 39 | } 40 | // 41 | // -----BEGIN RSA PUBLIC KEY----- 42 | // 43 | else if (line == control_words[control_word_key_begin]) 44 | { 45 | if (current_location == document_location::onion_key) 46 | { 47 | current_location = document_location::onion_key_content; 48 | } 49 | else if (current_location == document_location::signing_key) 50 | { 51 | current_location = document_location::signing_key_content; 52 | } 53 | continue; 54 | } 55 | // 56 | // -----END RSA PUBLIC KEY----- 57 | // 58 | else if (line == control_words[control_word_key_end]) 59 | { 60 | if (current_location == document_location::onion_key_content) 61 | { 62 | router->set_onion_key(crypto::base64::decode(current_key)); 63 | } 64 | else if (current_location == document_location::signing_key_content) 65 | { 66 | router->set_signing_key(crypto::base64::decode(current_key)); 67 | } 68 | current_location = document_location::control_word; 69 | current_key.clear(); 70 | } 71 | else if (current_location == document_location::onion_key_content || 72 | current_location == document_location::signing_key_content) 73 | { 74 | current_key += line; 75 | } 76 | else if (control_word_hash == control_words[control_word_ntor_onion_key]) 77 | { 78 | router->set_ntor_onion_key(crypto::base64::decode(splitted_line[1])); 79 | } 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /mini/stack_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini { 6 | 7 | template < 8 | typename T, 9 | size_type N 10 | > 11 | class stack_buffer 12 | { 13 | public: 14 | using value_type = T; 15 | using size_type = size_type; 16 | using pointer_difference_type = pointer_difference_type; 17 | 18 | using pointer = value_type*; 19 | using const_pointer = const value_type*; 20 | 21 | using reference = value_type&; 22 | using const_reference = const value_type&; 23 | 24 | using iterator = pointer; 25 | using const_iterator = const_pointer; 26 | 27 | static constexpr size_type not_found = (size_type)-1; 28 | 29 | // 30 | // swap. 31 | // 32 | 33 | void 34 | swap( 35 | stack_buffer& other 36 | ); 37 | 38 | // 39 | // element access. 40 | // 41 | 42 | reference 43 | operator[]( 44 | size_type index 45 | ); 46 | 47 | constexpr const_reference 48 | operator[]( 49 | size_type index 50 | ) const; 51 | 52 | reference 53 | at( 54 | size_type index 55 | ); 56 | 57 | constexpr const_reference 58 | at( 59 | size_type index 60 | ) const; 61 | 62 | value_type* 63 | get_buffer( 64 | void 65 | ); 66 | 67 | const value_type* 68 | get_buffer( 69 | void 70 | ) const; 71 | 72 | // 73 | // iterators. 74 | // 75 | 76 | iterator 77 | begin( 78 | void 79 | ); 80 | 81 | const_iterator 82 | begin( 83 | void 84 | ) const; 85 | 86 | iterator 87 | end( 88 | void 89 | ); 90 | 91 | const_iterator 92 | end( 93 | void 94 | ) const; 95 | 96 | // 97 | // lookup. 98 | // 99 | 100 | constexpr size_type 101 | index_of( 102 | const T& item, 103 | size_type from_offset = 0 104 | ) const; 105 | 106 | // 107 | // capacity. 108 | // 109 | 110 | constexpr size_type 111 | get_size( 112 | void 113 | ) const; 114 | 115 | operator buffer_ref( 116 | void 117 | ) const; 118 | 119 | operator mutable_buffer_ref( 120 | void 121 | ); 122 | 123 | // 124 | // public buffer. 125 | // 126 | T buffer[N]; 127 | }; 128 | 129 | template < 130 | size_type N 131 | > 132 | using stack_byte_buffer = stack_buffer; 133 | 134 | } 135 | 136 | #include "stack_buffer.inl" 137 | -------------------------------------------------------------------------------- /doc/example-descriptors/server-descriptor-847b1f850344d7876491a54892f904934e4eb85d.txt: -------------------------------------------------------------------------------- 1 | router tor26 86.59.21.38 443 0 80 2 | identity-ed25519 3 | -----BEGIN ED25519 CERT----- 4 | AQQABkOxASTqCHFXm3umN0NYOlIfUHpu0elZrvvdJQIKiwEytEVIAQAgBACRd0Dl 5 | 2YiFduUCq4zHQzQClYkngkZAYuyNRKfzpxshpVAWZQcho/HH9PTCjkntnqfCVBlp 6 | Qz0azrqvzrm+ORY6lLoL3SwF6e83iwhXDz3Xl1eQNttdM0py0SgM1guAews= 7 | -----END ED25519 CERT----- 8 | master-key-ed25519 kXdA5dmIhXblAquMx0M0ApWJJ4JGQGLsjUSn86cbIaU 9 | or-address [2001:858:2:2:aabb:0:563b:1526]:443 10 | platform Tor 0.2.8.5-rc on Linux 11 | protocols Link 1 2 Circuit 1 12 | published 2016-07-20 06:17:03 13 | fingerprint 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D 14 | uptime 657305 15 | bandwidth 76800 1073741824 2436786 16 | extra-info-digest 4823F98D08CD81FF18BDFC7539D2117023F4A2BF gh1tclm7Gfwhhus3My4od7NpzOVddwLP9vl2SJEbkkM 17 | caches-extra-info 18 | onion-key 19 | -----BEGIN RSA PUBLIC KEY----- 20 | MIGJAoGBAMMbFxRKUYujEKnXEORyrA1bokmMJ64p6uJn0r9LdKRgOPMnaLFGNLwV 21 | VNXWW22XZh/+B/e5SWUZDrrVpDuPc2b+jS91czHC6j4zErP9GljhV2QEi9Y31/ib 22 | ilYaEcZh/fgXFUEUCQunw3Hcy1IiCd1ZCCkt644SvJqpPE3SYRUBAgMBAAE= 23 | -----END RSA PUBLIC KEY----- 24 | signing-key 25 | -----BEGIN RSA PUBLIC KEY----- 26 | MIGJAoGBAMQgV2gXLbXgesWgeAsj8P1Uvm/zibrFXqwDq27lLKNgWGYGX2ax3LyT 27 | 3nzI1Y5oLs4kPKTsMM5ft9aokwf417lKoCRlZc9ptfRbgxDx90c9GtWVmkrmDvCK 28 | ae59TMoXIiGfZiwWT6KKq5Zm9/Fu2Il3B2vHGkKJYKixmiBJRKp/AgMBAAE= 29 | -----END RSA PUBLIC KEY----- 30 | onion-key-crosscert 31 | -----BEGIN CROSSCERT----- 32 | B6uutyCOCqEzoxldF4jOvWdSinCbmd2vWiRix5qYV8OVxhGlwGvby0cyYzCOuxDW 33 | FdKzl+8idwUokJnVrfmIAQT4UvDJrlPYsVrH+OJ/WHV01A7cy4SH7Od8QRIBDhFy 34 | AlzCLMWjUS2U6Os2qfLAALIQS5IJXGZFNaKK2KPQuco= 35 | -----END CROSSCERT----- 36 | ntor-onion-key-crosscert 1 37 | -----BEGIN ED25519 CERT----- 38 | AQoABjqfAZF3QOXZiIV25QKrjMdDNAKViSeCRkBi7I1Ep/OnGyGlAFFzHPrLfNnI 39 | PSczV2yNoywGUwc4P5YLxYXhuzJCcvBuWcJJsqj7OOOqAnZqDwdQoTKoo4XsJW8B 40 | Masq4RFHrgo= 41 | -----END ED25519 CERT----- 42 | family $01C5B10C5C6B1DEB47612E66EBF315B7C64DE803 $03FF94D9E5001DD2290BC3B19FA7F59CE1E30279 $6BD2FF175484CD7925A81DC42D89B3953252DBAD $995D0FE5A89563D79A383CCC2444D0E26C6BE625 $CA1DDA678A477BD2F19714F88A3C0613C7AD3C10 43 | hidden-service-dir 44 | contact Peter Palfrader 45 | ntor-onion-key Bo7lvTWfIi+Wo8zLi7rTU1VTbfUPde/l1xep/YnrHWY= 46 | reject *:* 47 | tunnelled-dir-server 48 | router-sig-ed25519 PPdfXRuQBWE94/ApWcxAg5auci7xpHgfnp6AHQDxGQH0YVag7cEFba4ubJEw+2RNYIFEPXzAE3vTFZUZItRWBQ 49 | router-signature 50 | -----BEGIN SIGNATURE----- 51 | aF7kwzH6UHfviZkAd8Ga/UFmMZqNJt4rXRcCOUG7+cnyVnzJ2c6Y6uuHIfINuarc 52 | +rEsE4+OBswnBTQbxi/YpEijZkzambmeLPtY3okyy4PqLA1rPmh9pirp/zB3n6Co 53 | kCou0AEO5POcpT1D+yJnYny7qKjkxnvNuGvuRzE7OkE= 54 | -----END SIGNATURE----- 55 | -------------------------------------------------------------------------------- /mini/io/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace mini::io { 6 | 7 | class stream 8 | { 9 | public: 10 | // 11 | // this value is returned when a stream has been closed during read. 12 | // 13 | static constexpr size_type closed = (size_type)0; 14 | 15 | // 16 | // this value is returned when a stream has encountered an error. 17 | // 18 | static constexpr size_type error = (size_type)-1; 19 | 20 | static bool 21 | success( 22 | size_type return_value 23 | ) 24 | { 25 | return 26 | return_value != closed && 27 | return_value != error; 28 | } 29 | 30 | enum seek_origin 31 | { 32 | begin, 33 | current, 34 | end, 35 | }; 36 | 37 | virtual ~stream( 38 | void 39 | ) 40 | { 41 | 42 | } 43 | 44 | virtual void 45 | close( 46 | void 47 | ) = 0; 48 | 49 | virtual bool 50 | can_read( 51 | void 52 | ) const = 0; 53 | 54 | virtual bool 55 | can_write( 56 | void 57 | ) const = 0; 58 | 59 | virtual bool 60 | can_seek( 61 | void 62 | ) const = 0; 63 | 64 | virtual size_type 65 | read( 66 | void* buffer, 67 | size_type size 68 | ) 69 | { 70 | return read_impl(buffer, size); 71 | } 72 | 73 | virtual size_type 74 | read( 75 | mutable_byte_buffer_ref buffer 76 | ) 77 | { 78 | return read_impl(buffer.get_buffer(), buffer.get_size()); 79 | } 80 | 81 | virtual size_type 82 | write( 83 | const void* buffer, 84 | size_type size 85 | ) 86 | { 87 | return write_impl(buffer, size); 88 | } 89 | 90 | virtual size_type 91 | write( 92 | const byte_buffer_ref buffer 93 | ) 94 | { 95 | return write_impl(buffer.get_buffer(), buffer.get_size()); 96 | } 97 | 98 | virtual size_type 99 | seek( 100 | intptr_t offset, 101 | seek_origin origin = seek_origin::current 102 | ) = 0; 103 | 104 | virtual void 105 | flush( 106 | void 107 | ) = 0; 108 | 109 | virtual size_type 110 | get_size( 111 | void 112 | ) const = 0; 113 | 114 | virtual size_type 115 | get_position( 116 | void 117 | ) const = 0; 118 | 119 | protected: 120 | virtual size_type 121 | read_impl( 122 | void* buffer, 123 | size_type size 124 | ) = 0; 125 | 126 | virtual size_type 127 | write_impl( 128 | const void* buffer, 129 | size_type size 130 | ) = 0; 131 | }; 132 | 133 | } 134 | -------------------------------------------------------------------------------- /mini/crypto/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // 5 | // configuration of crypto classes. 6 | // in [] is noted which namespaces are currently supported.w 7 | // 8 | // unless stated otherwise, capi & cng are supported on win7+. 9 | // 10 | 11 | // 12 | // base[N] encoding/decoding 13 | // 14 | #ifndef MINI_CRYPTO_BASE16_NAMESPACE 15 | #define MINI_CRYPTO_BASE16_NAMESPACE capi // [capi] 16 | #endif 17 | 18 | #ifndef MINI_CRYPTO_BASE32_NAMESPACE 19 | #define MINI_CRYPTO_BASE32_NAMESPACE ext // [ext] 20 | #endif 21 | 22 | #ifndef MINI_CRYPTO_BASE64_NAMESPACE 23 | #define MINI_CRYPTO_BASE64_NAMESPACE capi // [capi] 24 | #endif 25 | 26 | // 27 | // symmetric crypto 28 | // 29 | #ifndef MINI_CRYPTO_AES_NAMESPACE 30 | #define MINI_CRYPTO_AES_NAMESPACE cng // [capi, cng] 31 | #endif 32 | 33 | // 34 | // asymmetric crypto 35 | // 36 | #ifndef MINI_CRYPTO_CURVE25519_NAMESPACE 37 | #define MINI_CRYPTO_CURVE25519_NAMESPACE cng // [cng(win10+), ext] 38 | #endif 39 | 40 | #ifndef MINI_CRYPTO_DH_NAMESPACE 41 | #define MINI_CRYPTO_DH_NAMESPACE cng // [capi, cng(win8.1+)] 42 | #endif 43 | 44 | #ifndef MINI_CRYPTO_RSA_NAMESPACE 45 | #define MINI_CRYPTO_RSA_NAMESPACE cng // [capi, cng] 46 | #endif 47 | 48 | // 49 | // hash/hmac 50 | // 51 | #ifndef MINI_CRYPTO_HASH_NAMESPACE 52 | #define MINI_CRYPTO_HASH_NAMESPACE cng // [capi, cng] 53 | #endif 54 | 55 | #ifndef MINI_CRYPTO_HMAC_NAMESPACE 56 | #define MINI_CRYPTO_HMAC_NAMESPACE cng // [capi, cng] 57 | #endif 58 | 59 | // 60 | // random device 61 | // 62 | #ifndef MINI_CRYPTO_RANDOM_NAMESPACE 63 | #define MINI_CRYPTO_RANDOM_NAMESPACE cng // [capi, cng] 64 | #endif 65 | 66 | namespace mini::crypto { 67 | 68 | // 69 | // supported cipher modes for block encryption algorithms. 70 | // 71 | enum class cipher_mode 72 | { 73 | cbc, 74 | ecb, 75 | ofb, 76 | cfb, 77 | cts, 78 | ctr, 79 | 80 | max, 81 | }; 82 | 83 | // 84 | // supported RSA encryption padding schemes. 85 | // 86 | enum class rsa_encryption_padding 87 | { 88 | pkcs1, 89 | oaep_sha1, 90 | 91 | max, 92 | }; 93 | 94 | // 95 | // supported hash algorithms. 96 | // 97 | enum class hash_algorithm_type 98 | { 99 | md5, 100 | sha1, 101 | sha256, 102 | sha512, 103 | 104 | max, 105 | }; 106 | 107 | static constexpr size_type 108 | hash_algorithm_to_bit_size( 109 | hash_algorithm_type hash_algorithm 110 | ) 111 | { 112 | return 113 | hash_algorithm == hash_algorithm_type::md5 ? 128 : 114 | hash_algorithm == hash_algorithm_type::sha1 ? 160 : 115 | hash_algorithm == hash_algorithm_type::sha256 ? 256 : 116 | hash_algorithm == hash_algorithm_type::sha512 ? 512 : 117 | 0; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /mini/ptr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | namespace mini { 7 | 8 | template < 9 | typename T 10 | > 11 | class ptr 12 | { 13 | public: 14 | using element_type = T; 15 | 16 | using pointer = T*; 17 | using const_pointer = const T*; 18 | 19 | using reference = T&; 20 | using const_reference = const T&; 21 | 22 | // 23 | // constructors. 24 | // 25 | 26 | ptr( 27 | void 28 | ) = default; 29 | 30 | ptr( 31 | ptr&& other 32 | ); 33 | 34 | /*explicit*/ ptr( 35 | pointer p 36 | ); 37 | 38 | // 39 | // destructor. 40 | // 41 | 42 | ~ptr( 43 | void 44 | ); 45 | 46 | // 47 | // assign operators. 48 | // 49 | 50 | // ptr& 51 | // operator=( 52 | // pointer p 53 | // ); 54 | 55 | ptr& 56 | operator=( 57 | ptr&& other 58 | ); 59 | 60 | // 61 | // pointer arithmetic. 62 | // 63 | 64 | T* 65 | operator+( 66 | size_type rhs 67 | ); 68 | 69 | T* 70 | operator-( 71 | size_type rhs 72 | ); 73 | 74 | // 75 | // swap. 76 | // 77 | 78 | void 79 | swap( 80 | ptr& other 81 | ); 82 | 83 | // 84 | // modifiers. 85 | // 86 | 87 | pointer 88 | release( 89 | void 90 | ); 91 | 92 | void 93 | reset( 94 | pointer p = nullptr 95 | ); 96 | 97 | // 98 | // observers. 99 | // 100 | 101 | pointer 102 | get( 103 | void 104 | ); 105 | 106 | const_pointer 107 | get( 108 | void 109 | ) const; 110 | 111 | explicit operator bool( 112 | void 113 | ) const; 114 | 115 | std::add_lvalue_reference_t 116 | operator*( 117 | void 118 | ) const; 119 | 120 | pointer 121 | operator->( 122 | void 123 | ) const; 124 | 125 | T& 126 | operator[]( 127 | size_type index 128 | ) const; 129 | 130 | // friend bool 131 | // operator==( 132 | // const ptr& lhs, 133 | // std::nullptr_t 134 | // ); 135 | // 136 | // friend bool 137 | // operator!=( 138 | // const ptr& lhs, 139 | // std::nullptr_t 140 | // ); 141 | 142 | private: 143 | pointer _raw_pointer = nullptr; 144 | }; 145 | 146 | template < 147 | typename T, 148 | typename... Args 149 | > 150 | ptr 151 | make_ptr(Args&&... args) 152 | { 153 | return ptr(new T(std::forward(args)...)); 154 | } 155 | 156 | template < 157 | typename T 158 | > 159 | void 160 | swap( 161 | ptr& lhs, 162 | ptr& rhs 163 | ); 164 | 165 | } 166 | 167 | #include "ptr.inl" 168 | -------------------------------------------------------------------------------- /mini/crypto/capi/key.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "provider.h" 3 | #include "../base/key.h" 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace mini::crypto::capi { 11 | 12 | // 13 | // MS CryptoAPI key. 14 | // 15 | 16 | class key 17 | : public base::key 18 | { 19 | public: 20 | ~key( 21 | void 22 | ) override 23 | { 24 | destroy(); 25 | } 26 | 27 | void 28 | destroy( 29 | void 30 | ) override 31 | { 32 | if (_key_handle) 33 | { 34 | CryptDestroyKey(_key_handle); 35 | _key_handle = 0; 36 | } 37 | } 38 | 39 | HCRYPTKEY 40 | get_handle( 41 | void 42 | ) const 43 | { 44 | return _key_handle; 45 | } 46 | 47 | operator bool( 48 | void 49 | ) const 50 | { 51 | return _key_handle != 0; 52 | } 53 | 54 | protected: 55 | key( 56 | void 57 | ) = default; 58 | 59 | void 60 | swap( 61 | key& other 62 | ) 63 | { 64 | mini::swap(_key_handle, other._key_handle); 65 | } 66 | 67 | template < 68 | typename BLOB_TYPE 69 | > 70 | void 71 | import_from_blob( 72 | const BLOB_TYPE& key_blob 73 | ) 74 | { 75 | // 76 | // destroy previous key. 77 | // 78 | destroy(); 79 | 80 | // 81 | // ayy lmao. 82 | // 83 | auto key_blob_ptr = reinterpret_cast(&key_blob); 84 | auto key_blob_size = static_cast(sizeof(key_blob)); 85 | auto provider_handle = (provider_factory.*BLOB_TYPE::provider_type::get_handle)(); 86 | 87 | import_from_blob( 88 | key_blob_ptr, 89 | key_blob_size, 90 | provider_handle); 91 | } 92 | 93 | template < 94 | typename BLOB_TYPE 95 | > 96 | void 97 | export_to_blob( 98 | BLOB_TYPE& key_blob, 99 | DWORD blob_type 100 | ) const 101 | { 102 | auto key_blob_ptr = reinterpret_cast(&key_blob); 103 | auto key_blob_size = static_cast(sizeof(key_blob)); 104 | 105 | CryptExportKey( 106 | _key_handle, 107 | 0, 108 | blob_type, 109 | 0, 110 | key_blob_ptr, 111 | &key_blob_size); 112 | } 113 | 114 | HCRYPTKEY _key_handle = 0; 115 | 116 | private: 117 | void 118 | import_from_blob( 119 | const BYTE* key_blob, 120 | DWORD key_blob_size, 121 | HCRYPTPROV provider_handle 122 | ) 123 | { 124 | CryptImportKey( 125 | provider_handle, 126 | key_blob, 127 | key_blob_size, 128 | 0, 129 | CRYPT_EXPORTABLE, 130 | &_key_handle); 131 | } 132 | }; 133 | 134 | } 135 | -------------------------------------------------------------------------------- /mini/net/uri.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini::net { 5 | 6 | class uri 7 | { 8 | public: 9 | uri( 10 | const string_ref url 11 | ) 12 | : _url(url) 13 | { 14 | // 15 | // protocol 16 | // 17 | auto protocol_index = _url.index_of("://"); 18 | 19 | _protocol = protocol_index != string::not_found 20 | ? _url.substring(0, protocol_index + 3) 21 | : "http://"; 22 | 23 | // 24 | // domain. 25 | // 26 | auto domain_start_index = protocol_index != string::not_found 27 | ? protocol_index + 3 28 | : 0; 29 | 30 | auto first_slash_index = _url.index_of("/", domain_start_index); 31 | 32 | _host = first_slash_index != string::not_found 33 | ? _url.substring(domain_start_index, first_slash_index - domain_start_index) 34 | : _url.substring(domain_start_index); 35 | 36 | auto colon_index = _host.index_of(":"); 37 | auto port = colon_index != string::not_found 38 | ? _host.substring(colon_index + 1) 39 | : _protocol == "http://" ? "80" 40 | : _protocol == "https://" ? "443" 41 | : "0"; 42 | 43 | _port = static_cast(port.to_int()); 44 | 45 | if (colon_index != string::not_found) 46 | { 47 | _host = _host.substring(0, colon_index); 48 | } 49 | 50 | auto first_dot = _host.last_index_of("."); 51 | auto second_dot = first_dot == string::not_found 52 | ? string::not_found 53 | : _host.substring(0, first_dot).last_index_of("."); 54 | 55 | _domain = _host.substring(second_dot == string::not_found ? 0 : second_dot + 1); 56 | _path = first_slash_index != string::not_found 57 | ? _url.substring(first_slash_index) 58 | : "/"; 59 | } 60 | 61 | string_ref 62 | get_url( 63 | void 64 | ) const 65 | { 66 | return _url; 67 | } 68 | 69 | string_ref 70 | get_protocol( 71 | void 72 | ) const 73 | { 74 | return _protocol; 75 | } 76 | 77 | string_ref 78 | get_domain( 79 | void 80 | ) const 81 | { 82 | return _domain; 83 | } 84 | 85 | string_ref 86 | get_host( 87 | void 88 | ) const 89 | { 90 | return _host; 91 | } 92 | 93 | string_ref 94 | get_path( 95 | void 96 | ) const 97 | { 98 | return _path; 99 | } 100 | 101 | uint16_t 102 | get_port( 103 | void 104 | ) const 105 | { 106 | return _port; 107 | } 108 | 109 | private: 110 | string _url; 111 | 112 | string _protocol; 113 | string _domain; 114 | string _host; 115 | string _path; 116 | uint16_t _port; 117 | }; 118 | 119 | } 120 | -------------------------------------------------------------------------------- /mini/threading/locked_value.inl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "locked_value.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::threading { 8 | 9 | template < 10 | typename T 11 | > 12 | locked_value::locked_value( 13 | const T& initial_value 14 | ) 15 | : _event(reset_type::auto_reset, false) 16 | , _cancel_event(reset_type::auto_reset, false) 17 | { 18 | _value = initial_value; 19 | } 20 | 21 | template < 22 | typename T 23 | > 24 | const T& 25 | locked_value::get_value( 26 | void 27 | ) const 28 | { 29 | mini_lock(_mutex) 30 | { 31 | return _value; 32 | } 33 | } 34 | 35 | template < 36 | typename T 37 | > 38 | void 39 | locked_value::set_value( 40 | const T& value 41 | ) 42 | { 43 | mini_lock(_mutex) 44 | { 45 | if (value != _value) 46 | { 47 | _value = value; 48 | _event.set(); 49 | } 50 | } 51 | } 52 | 53 | template < 54 | typename T 55 | > 56 | wait_result 57 | locked_value::wait_for_value( 58 | const T& value, 59 | timeout_type timeout 60 | ) 61 | { 62 | timestamp_type start_timestamp = time::timestamp(); 63 | timeout_type remaining_timeout = timeout; 64 | 65 | mini_lock(_mutex) 66 | { 67 | // 68 | // compare is performed under the lock. 69 | // 70 | while (_value != value) 71 | { 72 | wait_result result; 73 | 74 | // 75 | // unlock the value, so anyone can change it. 76 | // 77 | mini_unlock(_mutex) 78 | { 79 | result = wait_for_change(remaining_timeout); 80 | } 81 | 82 | // 83 | // check if we've been cancelled. 84 | // wait_for_change is waiting for _event & _cancel_event. 85 | // _cancel_event is at the index #1. 86 | // 87 | if (event::index_from_wait_result(result) == 1) 88 | { 89 | return wait_result::failed; 90 | } 91 | 92 | // 93 | // value has been changed, adjust the remaining timeout. 94 | // 95 | if (timeout != wait_infinite) 96 | { 97 | timestamp_type elapsed_milliseconds = time::timestamp() - start_timestamp; 98 | remaining_timeout = timeout - elapsed_milliseconds; 99 | 100 | if (remaining_timeout <= 0) 101 | { 102 | return wait_result::timeout; 103 | } 104 | } 105 | } 106 | } 107 | 108 | return wait_result::success; 109 | } 110 | 111 | template < 112 | typename T 113 | > 114 | wait_result 115 | locked_value::wait_for_change( 116 | timeout_type timeout 117 | ) 118 | { 119 | return event::wait_for_any({ &_event, &_cancel_event }, timeout); 120 | } 121 | 122 | template < 123 | typename T 124 | > 125 | void 126 | locked_value::cancel_all_waits( 127 | void 128 | ) 129 | { 130 | _cancel_event.set(); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /mini/tor/relay_cell.cpp: -------------------------------------------------------------------------------- 1 | #include "relay_cell.h" 2 | #include "circuit_node.h" 3 | #include "circuit.h" 4 | 5 | #include 6 | #include 7 | 8 | namespace mini::tor { 9 | 10 | relay_cell::relay_cell( 11 | circuit_node* node, 12 | const cell& c 13 | ) 14 | : cell(c) 15 | , _circuit_node(node) 16 | { 17 | io::memory_stream payload_stream(c.get_payload()); 18 | io::stream_wrapper payload_buffer(payload_stream, endianness::big_endian); 19 | 20 | cell_command relay_command = payload_buffer.read(); 21 | uint16_t recognized = payload_buffer.read(); 22 | tor_stream_id_type stream_id = payload_buffer.read(); 23 | uint32_t digest = payload_buffer.read(); 24 | payload_size_type payload_length = payload_buffer.read(); 25 | 26 | MINI_UNREFERENCED(recognized); 27 | MINI_UNREFERENCED(digest); 28 | 29 | byte_buffer payload(payload_length); 30 | payload_buffer.read(payload); 31 | 32 | _relay_command = relay_command; 33 | _stream_id = stream_id; 34 | this->set_relay_payload(payload); 35 | } 36 | 37 | relay_cell::relay_cell( 38 | circuit_id_type circuit_id, 39 | cell_command command, 40 | circuit_node* node, 41 | cell_command relay_command, 42 | tor_stream_id_type stream_id, 43 | const byte_buffer_ref relay_payload 44 | ) 45 | : cell(circuit_id, command) 46 | , _circuit_node(node) 47 | , _relay_command(relay_command) 48 | , _stream_id(stream_id) 49 | { 50 | this->set_relay_payload(relay_payload); 51 | } 52 | 53 | cell_command 54 | relay_cell::get_relay_command( 55 | void 56 | ) const 57 | { 58 | return _relay_command; 59 | } 60 | 61 | tor_stream_id_type 62 | relay_cell::get_stream_id( 63 | void 64 | ) const 65 | { 66 | return _stream_id; 67 | } 68 | 69 | tor_stream* 70 | relay_cell::get_stream( 71 | void 72 | ) 73 | { 74 | return _circuit_node->get_circuit()->get_stream_by_id(_stream_id); 75 | } 76 | 77 | void 78 | relay_cell::set_digest( 79 | const byte_buffer_ref digest 80 | ) 81 | { 82 | digest.copy_to(_digest, sizeof(_digest)); 83 | } 84 | 85 | byte_buffer_ref 86 | relay_cell::get_relay_payload( 87 | void 88 | ) const 89 | { 90 | return _relay_payload; 91 | } 92 | 93 | void 94 | relay_cell::set_relay_payload( 95 | const byte_buffer_ref payload 96 | ) 97 | { 98 | _relay_payload = payload; 99 | } 100 | 101 | circuit_node* 102 | relay_cell::get_circuit_node( 103 | void 104 | ) 105 | { 106 | return _circuit_node; 107 | } 108 | 109 | bool 110 | relay_cell::is_relay_cell_valid( 111 | void 112 | ) const 113 | { 114 | // 115 | // each valid relay cell has set its circuit node. 116 | // 117 | return _circuit_node != nullptr; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /mini/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | 6 | namespace mini { 7 | 8 | namespace detail { 9 | 10 | // 11 | // Kindly borrowed from the MSVC CRT. 12 | // 13 | 14 | #if defined(MINI_ARCH_X86) || defined(MINI_ARCH_ARM32) 15 | inline constexpr size_type FNV_offset_basis = 0x811C9DC5u; 16 | inline constexpr size_type FNV_prime = 0x1000193u; 17 | #elif defined(MINI_ARCH_X64) || defined(MINI_ARCH_ARM64) 18 | inline constexpr size_type FNV_offset_basis = 0xCBF29CE484222325ull; 19 | inline constexpr size_type FNV_prime = 0x100000001B3ull; 20 | #endif 21 | 22 | inline size_type 23 | fnv1a_append_bytes( 24 | size_type value, 25 | const unsigned char* const first, 26 | const size_type count 27 | ) noexcept 28 | { 29 | for (size_type index = 0; index < count; ++index) 30 | { 31 | value ^= static_cast(first[index]); 32 | value *= FNV_prime; 33 | } 34 | 35 | return (value); 36 | } 37 | 38 | template< 39 | typename T 40 | > 41 | inline size_type 42 | fnv1a_append_range( 43 | const size_type value, 44 | const T* const first, 45 | const T* const last 46 | ) noexcept 47 | { 48 | static_assert(std::is_trivial_v, "Only trivial types can be directly hashed."); 49 | const auto firstb = reinterpret_cast(first); 50 | const auto lastb = reinterpret_cast(last); 51 | return (fnv1a_append_bytes(value, firstb, static_cast(lastb - firstb))); 52 | } 53 | 54 | template< 55 | typename T 56 | > 57 | inline size_type 58 | fnv1a_append_value( 59 | const size_type value, 60 | const T& key_value 61 | ) noexcept 62 | { 63 | static_assert(std::is_trivial_v, "Only trivial types can be directly hashed."); 64 | return (fnv1a_append_bytes( 65 | value, 66 | &reinterpret_cast(key_value), 67 | sizeof(T)) 68 | ); 69 | } 70 | 71 | template< 72 | typename T 73 | > 74 | inline size_type 75 | hash_representation( 76 | const T& key_value 77 | ) noexcept 78 | { 79 | return (fnv1a_append_value(FNV_offset_basis, key_value)); 80 | } 81 | 82 | template< 83 | typename T 84 | > 85 | inline size_type 86 | hash_array_representation( 87 | const T* const first, 88 | const size_type count 89 | ) noexcept 90 | { 91 | static_assert(std::is_trivial_v, "Only trivial types can be directly hashed."); 92 | return (fnv1a_append_bytes( 93 | FNV_offset_basis, 94 | reinterpret_cast(first), 95 | count * sizeof(T)) 96 | ); 97 | } 98 | } 99 | 100 | template < 101 | typename T 102 | > 103 | struct hash 104 | : std::hash 105 | { 106 | 107 | }; 108 | 109 | } 110 | -------------------------------------------------------------------------------- /mini/io/path.cpp: -------------------------------------------------------------------------------- 1 | #include "path.h" 2 | 3 | namespace mini::io { 4 | 5 | string 6 | path::combine( 7 | const string_ref p1, 8 | const string_ref p2 9 | ) 10 | { 11 | string result = p1; 12 | 13 | if (!p1.ends_with(directory_separator) && !p1.ends_with(alternative_directory_separator)) 14 | { 15 | result += directory_separator; 16 | } 17 | 18 | result += p2; 19 | 20 | return result; 21 | } 22 | 23 | string_collection 24 | path::split( 25 | const string_ref p 26 | ) 27 | { 28 | // 29 | // TODO: 30 | // take alternative_directory_separator into account. 31 | // 32 | auto result = p.split(directory_separator); 33 | 34 | // 35 | // always end drive letter with '\'. 36 | // 37 | if (result.get_size() > 0 && result[0].get_size() > 1) 38 | { 39 | string& drive_letter = result[0]; 40 | 41 | if (drive_letter[1] == ':') 42 | { 43 | drive_letter += directory_separator; 44 | } 45 | } 46 | 47 | return result; 48 | } 49 | 50 | string_ref 51 | path::get_file_name( 52 | const string_ref p 53 | ) 54 | { 55 | size_type name_offset = p.last_index_of(directory_separator); 56 | 57 | if (name_offset == string_ref::not_found) 58 | { 59 | name_offset = p.last_index_of(alternative_directory_separator); 60 | } 61 | 62 | if (name_offset == string_ref::not_found || (name_offset + 1) >= p.get_size()) 63 | { 64 | return string_ref(); 65 | } 66 | 67 | return p.substring(name_offset + 1); 68 | } 69 | 70 | string_ref 71 | path::get_directory_name( 72 | const string_ref p 73 | ) 74 | { 75 | size_type name_offset = p.last_index_of(directory_separator); 76 | 77 | if (name_offset == string_ref::not_found) 78 | { 79 | name_offset = p.last_index_of(alternative_directory_separator); 80 | } 81 | 82 | return p.substring(0, name_offset); 83 | } 84 | 85 | string_ref 86 | path::get_filename_without_extension( 87 | const string_ref p 88 | ) 89 | { 90 | size_type name_offset = p.last_index_of(directory_separator); 91 | 92 | if (name_offset == string_ref::not_found) 93 | { 94 | name_offset = p.last_index_of(alternative_directory_separator); 95 | } 96 | 97 | if (name_offset == string_ref::not_found || (name_offset + 1) >= p.get_size()) 98 | { 99 | return string_ref(); 100 | } 101 | 102 | string_ref result = p.substring(name_offset + 1); 103 | size_type extension_offset = result.last_index_of(extension_separator); 104 | 105 | return result.substring(0, extension_offset); 106 | } 107 | 108 | string_ref 109 | path::get_extension( 110 | const string_ref p 111 | ) 112 | { 113 | string_ref file_name = get_file_name(p); 114 | size_type extension_offset = file_name.last_index_of(extension_separator); 115 | 116 | if (extension_offset != string_ref::not_found) 117 | { 118 | return file_name.substring(extension_offset); 119 | } 120 | 121 | return string_ref(); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /mini/algorithm.h: -------------------------------------------------------------------------------- 1 | #ifdef min 2 | # undef min 3 | #endif 4 | 5 | #ifdef max 6 | # undef max 7 | #endif 8 | 9 | #ifndef MINI_ALGORITHM_INCLUDED 10 | #define MINI_ALGORITHM_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace mini::algorithm { 19 | 20 | template < 21 | typename T 22 | > 23 | inline constexpr T 24 | min( 25 | T a, 26 | T b 27 | ) 28 | { 29 | return (a < b) ? a : b; 30 | } 31 | 32 | template < 33 | typename T 34 | > 35 | inline constexpr T 36 | max( 37 | T a, 38 | T b 39 | ) 40 | { 41 | return (a > b) ? a : b; 42 | } 43 | 44 | template < 45 | typename T 46 | > 47 | inline constexpr T 48 | clamp( 49 | T value, 50 | T low, 51 | T high 52 | ) 53 | { 54 | return min(low, max(value, high)); 55 | } 56 | 57 | template < 58 | typename T 59 | > 60 | inline constexpr T 61 | round_up_to_multiple( 62 | T value, 63 | T multiple 64 | ) 65 | { 66 | return ((value + multiple - 1) / multiple) * multiple; 67 | } 68 | 69 | template < 70 | typename T 71 | > 72 | inline T 73 | nearest_power_of_2( 74 | T value 75 | ) 76 | { 77 | static_assert(std::is_unsigned_v); 78 | 79 | if (value < 1) 80 | { 81 | return 0; 82 | } 83 | 84 | --value; 85 | for (int i = 0; i; i <<= 1) 86 | { 87 | value |= value >> i; 88 | } 89 | ++value; 90 | 91 | return value; 92 | } 93 | 94 | template < 95 | typename T 96 | > 97 | inline bool 98 | is_power_of_2( 99 | T value 100 | ) 101 | { 102 | static_assert(std::is_unsigned_v); 103 | 104 | return !(value == 0) && !(value & (value - 1)); 105 | } 106 | 107 | template< 108 | class T, 109 | typename TIterator 110 | > 111 | inline void 112 | fill( 113 | TIterator first, 114 | TIterator last, 115 | const T& value 116 | ) 117 | { 118 | std::fill(first, last, value); 119 | } 120 | 121 | template < 122 | typename TIterator 123 | > 124 | inline pointer_difference_type 125 | distance( 126 | TIterator first, 127 | TIterator last 128 | ) 129 | { 130 | return std::distance(first, last); 131 | } 132 | 133 | template < 134 | typename TIterator, 135 | typename TDistance 136 | > 137 | inline void 138 | advance( 139 | TIterator& iterator, 140 | TDistance distance 141 | ) 142 | { 143 | std::advance(iterator, distance); 144 | } 145 | 146 | template < 147 | typename T, 148 | typename TIterator, 149 | typename Compare 150 | > 151 | inline TIterator 152 | lower_bound( 153 | TIterator first, 154 | TIterator last, 155 | const T& value, 156 | Compare comp 157 | ) 158 | { 159 | return std::lower_bound(first, last, value, comp); 160 | } 161 | 162 | template < 163 | typename T, 164 | typename TIterator, 165 | typename Compare 166 | > 167 | inline bool 168 | binary_search( 169 | TIterator first, 170 | TIterator last, 171 | const T& value, 172 | Compare comp 173 | ) 174 | { 175 | return std::binary_search(first, last, value, comp); 176 | } 177 | 178 | } 179 | 180 | #endif -------------------------------------------------------------------------------- /mini/time.cpp: -------------------------------------------------------------------------------- 1 | #include "time.h" 2 | 3 | #include 4 | #include 5 | 6 | // struct tm 7 | // { 8 | // int tm_sec; // seconds after the minute - [0, 60] including leap second 9 | // int tm_min; // minutes after the hour - [0, 59] 10 | // int tm_hour; // hours since midnight - [0, 23] 11 | // int tm_mday; // day of the month - [1, 31] 12 | // int tm_mon; // months since January - [0, 11] 13 | // int tm_year; // years since 1900 14 | // int tm_wday; // days since Sunday - [0, 6] 15 | // int tm_yday; // days since January 1 - [0, 365] 16 | // int tm_isdst; // daylight savings time flag 17 | // }; 18 | 19 | extern "C" 20 | uint32_t __cdecl 21 | time( 22 | uint32_t* _Time 23 | ); 24 | 25 | extern "C" 26 | uint32_t __cdecl 27 | _mkgmtime( 28 | struct tm* timeptr 29 | ); 30 | 31 | namespace mini { 32 | 33 | // 34 | // constructors. 35 | // 36 | 37 | time::time( 38 | void 39 | ) 40 | : time(0) 41 | { 42 | 43 | } 44 | 45 | time::time( 46 | uint32_t value 47 | ) 48 | : _timestamp(value) 49 | { 50 | 51 | } 52 | 53 | // 54 | // conversion. 55 | // 56 | 57 | void 58 | time::parse( 59 | const string_ref value 60 | ) 61 | { 62 | // 63 | // must be in format "2016-06-14 01:00:00" 64 | // 65 | 66 | tm system_time = { 0 }; 67 | sscanf( 68 | value.get_buffer(), 69 | "%04d-%02d-%02d %02d:%02d:%02d", 70 | &system_time.tm_year, 71 | &system_time.tm_mon, 72 | &system_time.tm_mday, 73 | &system_time.tm_hour, 74 | &system_time.tm_min, 75 | &system_time.tm_sec); 76 | 77 | system_time.tm_year -= 1900; 78 | system_time.tm_mon -= 1; 79 | system_time.tm_isdst = -1; 80 | 81 | _timestamp = _mkgmtime(&system_time); 82 | } 83 | 84 | uint32_t 85 | time::to_timestamp( 86 | void 87 | ) const 88 | { 89 | return _timestamp; 90 | } 91 | 92 | // 93 | // static methods. 94 | // 95 | 96 | time 97 | time::now( 98 | void 99 | ) 100 | { 101 | return ::time(nullptr); 102 | } 103 | 104 | timestamp_type 105 | time::timestamp( 106 | void 107 | ) 108 | { 109 | return GetTickCount(); 110 | } 111 | 112 | // 113 | // operators. 114 | // 115 | 116 | bool 117 | operator==( 118 | const time& lhs, 119 | const time& rhs 120 | ) 121 | { 122 | return lhs._timestamp == rhs._timestamp; 123 | } 124 | 125 | bool 126 | operator!=( 127 | const time& lhs, 128 | const time& rhs 129 | ) 130 | { 131 | return lhs._timestamp != rhs._timestamp; 132 | } 133 | 134 | bool 135 | operator<( 136 | const time& lhs, 137 | const time& rhs 138 | ) 139 | { 140 | return lhs._timestamp < rhs._timestamp; 141 | } 142 | 143 | bool 144 | operator>( 145 | const time& lhs, 146 | const time& rhs 147 | ) 148 | { 149 | return lhs._timestamp > rhs._timestamp; 150 | } 151 | 152 | bool 153 | operator<=( 154 | const time& lhs, 155 | const time& rhs 156 | ) 157 | { 158 | return lhs._timestamp <= rhs._timestamp; 159 | } 160 | 161 | bool 162 | operator>=( 163 | const time& lhs, 164 | const time& rhs 165 | ) 166 | { 167 | return lhs._timestamp >= rhs._timestamp; 168 | } 169 | 170 | }; 171 | 172 | -------------------------------------------------------------------------------- /mini/tor/tor_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::tor { 8 | 9 | class circuit; 10 | 11 | class tor_stream 12 | : public io::stream 13 | { 14 | public: 15 | tor_stream( 16 | tor_stream_id_type stream_id, 17 | circuit* circuit 18 | ); 19 | 20 | ~tor_stream( 21 | void 22 | ); 23 | 24 | void 25 | close( 26 | void 27 | ) override; 28 | 29 | bool 30 | can_read( 31 | void 32 | ) const override; 33 | 34 | bool 35 | can_write( 36 | void 37 | ) const override; 38 | 39 | bool 40 | can_seek( 41 | void 42 | ) const override; 43 | 44 | size_type 45 | seek( 46 | intptr_t offset, 47 | seek_origin origin = seek_origin::current 48 | ) override; 49 | 50 | void 51 | flush( 52 | void 53 | ) override; 54 | 55 | size_type 56 | get_size( 57 | void 58 | ) const override; 59 | 60 | size_type 61 | get_position( 62 | void 63 | ) const override; 64 | 65 | tor_stream_id_type 66 | get_stream_id( 67 | void 68 | ) const; 69 | 70 | private: 71 | friend class circuit; 72 | 73 | enum class state 74 | { 75 | none, 76 | connecting, 77 | ready, 78 | destroyed, 79 | }; 80 | 81 | void 82 | append_to_recv_buffer( 83 | const byte_buffer_ref buffer 84 | ); 85 | 86 | state 87 | get_state( 88 | void 89 | ) const; 90 | 91 | void 92 | set_state( 93 | state new_state 94 | ); 95 | 96 | threading::wait_result 97 | wait_for_state( 98 | state desired_state, 99 | timeout_type timeout = 30000 100 | ); 101 | 102 | // 103 | // flow control. 104 | // 105 | 106 | void 107 | decrement_package_window( 108 | void 109 | ); 110 | 111 | void 112 | increment_package_window( 113 | void 114 | ); 115 | 116 | void 117 | decrement_deliver_window( 118 | void 119 | ); 120 | 121 | bool 122 | consider_sending_sendme( 123 | void 124 | ); 125 | 126 | // 127 | // io::stream 128 | // 129 | 130 | size_type 131 | read_impl( 132 | void* buffer, 133 | size_type size 134 | ) override; 135 | 136 | size_type 137 | write_impl( 138 | const void* buffer, 139 | size_type size 140 | ) override; 141 | 142 | static constexpr size_type window_start = 500; 143 | static constexpr size_type window_increment = 50; 144 | static constexpr size_type window_max_unflushed = 10; 145 | 146 | tor_stream_id_type _stream_id; 147 | circuit* _circuit; 148 | 149 | size_type _deliver_window = window_start; 150 | size_type _package_window = window_start; 151 | threading::mutex _window_mutex; 152 | 153 | byte_buffer _buffer; 154 | threading::mutex _buffer_mutex; 155 | 156 | threading::locked_value _state = state::connecting; 157 | }; 158 | 159 | } 160 | -------------------------------------------------------------------------------- /mini/tor/tor_socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "onion_router.h" 3 | #include "cell.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define MINI_TOR_ASSUME_PROTOCOL_VERSION_PREFERRED 12 | 13 | namespace mini::tor { 14 | 15 | class circuit; 16 | 17 | class tor_socket 18 | { 19 | public: 20 | static constexpr protocol_version_type protocol_version_initial = 3; 21 | static constexpr protocol_version_type protocol_version_preferred = 4; 22 | 23 | tor_socket( 24 | onion_router* onion_router = nullptr 25 | ); 26 | 27 | ~tor_socket( 28 | void 29 | ); 30 | 31 | void 32 | connect( 33 | onion_router* router 34 | ); 35 | 36 | void 37 | close( 38 | void 39 | ); 40 | 41 | circuit* 42 | create_circuit( 43 | handshake_type handshake = preferred_handshake_type 44 | ); 45 | 46 | void 47 | remove_circuit( 48 | circuit* circuit 49 | ); 50 | 51 | void 52 | send_cell( 53 | const cell& cell 54 | ); 55 | 56 | cell 57 | recv_cell( 58 | void 59 | ); 60 | 61 | protocol_version_type 62 | get_protocol_version( 63 | void 64 | ) const; 65 | 66 | onion_router* 67 | get_onion_router( 68 | void 69 | ); 70 | 71 | circuit* 72 | get_circuit_by_id( 73 | circuit_id_type circuit_id 74 | ); 75 | 76 | bool 77 | is_connected( 78 | void 79 | ) const; 80 | 81 | bool 82 | is_ready( 83 | void 84 | ) const; 85 | 86 | private: 87 | friend class circuit; 88 | 89 | enum state 90 | { 91 | connecting, 92 | handshake_in_progress, 93 | ready, 94 | closing, 95 | closed, 96 | }; 97 | 98 | state 99 | get_state( 100 | void 101 | ) const; 102 | 103 | void 104 | set_state( 105 | state new_state 106 | ); 107 | 108 | threading::wait_result 109 | wait_for_state( 110 | state desired_state, 111 | timeout_type timeout = 30000 112 | ); 113 | 114 | void 115 | send_versions( 116 | void 117 | ); 118 | 119 | void 120 | recv_versions( 121 | void 122 | ); 123 | 124 | void 125 | send_net_info( 126 | void 127 | ); 128 | 129 | void 130 | recv_net_info( 131 | void 132 | ); 133 | 134 | void 135 | send_certificates( 136 | void 137 | ); 138 | 139 | void 140 | recv_certificates( 141 | void 142 | ); 143 | 144 | void 145 | recv_cell_loop( 146 | void 147 | ); 148 | 149 | ptr _socket; 150 | ptr _recv_cell_loop_thread; 151 | 152 | onion_router* _onion_router = nullptr; 153 | uint32_t _protocol_version = protocol_version_initial; 154 | 155 | collections::pair_list _circuit_map; 156 | threading::locked_value _state = state::closed; 157 | }; 158 | 159 | } 160 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/hjxm9hfjwljab2am?svg=true)](https://ci.appveyor.com/project/wbenny/mini-tor) 2 | 3 | # mini-tor 4 | 5 | mini-tor is a proof-of-concept utility for accessing internet content and hidden service content **(.onion)** via tor routers. this utility is aiming for as smallest size as possible (currently ~47kb, compressed with kkrunchy ~20kb), which is achieved by using Microsoft CryptoAPI/CNG instead of embedding OpenSSL. 6 | 7 | ### Usage 8 | 9 | accessing internet content via mini-tor: 10 | ```c 11 | > mini-tor.exe "http://torstatus.blutmagie.de/router_detail.php?FP=847b1f850344d7876491a54892f904934e4eb85d" 12 | ``` 13 | accessing hidden service content via mini-tor: 14 | 15 | ```c 16 | > mini-tor.exe "http://duskgytldkxiuqc6.onion/fedpapers/federndx.htm" 17 | ``` 18 | 19 | it can even access https content: 20 | ```c 21 | > mini-tor.exe "https://check.torproject.org/" 22 | > mini-tor.exe "https://www.facebookcorewwwi.onion/" 23 | ``` 24 | 25 | add -v, -vv or -vvv for verbosity: 26 | ```c 27 | > mini-tor.exe -v "http://duskgytldkxiuqc6.onion/fedpapers/federndx.htm" 28 | > mini-tor.exe -vv "https://check.torproject.org/" 29 | > mini-tor.exe -vvv "https://www.facebookcorewwwi.onion/" 30 | ``` 31 | 32 | you can disable logging by commenting out `#define MINI_LOG_ENABLED` in `mini/logger.h`. 33 | this will also result in fairly reduced size of the executable. 34 | 35 | ### Description 36 | 37 | * **mini-tor** supports both TAP & NTOR handshake. 38 | * TAP uses ordinary DH with 1024 bit exponent. 39 | * NTOR is newer type of handshake and uses curve25519. 40 | * you can control which handshake is used by default by changing `preferred_handshake_type` in `mini/tor/common.h` 41 | * **mini-tor** can use either CryptoAPI or newer CNG api. 42 | * configurable via `mini/crypto/common.h`. 43 | * note that curve25519 is supported by CNG only on win10+. 44 | * there is a *curve25519-donna* implementation included. you can enable it by setting `MINI_CRYPTO_CURVE25519_NAMESPACE` to `ext` to get it running on older systems. 45 | * note that `cng::dh<>` will work only on win8.1+, because of usage `BCRYPT_KDF_RAW_SECRET` for fetching shared secret. 46 | * you can use `capi::dh<>` by setting `MINI_CRYPTO_DH_NAMESPACE` to `capi`. 47 | * anything else should run fine on win7+ (anything older is not yet supported). 48 | * **mini-tor** creates TLS connections via SCHANNEL (look at `mini/net/ssl_socket.cpp` & `mini/net/detail/ssl_context.cpp`). 49 | * **mini-tor** does not use default CRT or STL, everything is implemented from scratch. 50 | * older version of **mini-tor** based purely on CryptoAPI can be found in git tag **ms_crypto_api** (unmaintained). 51 | 52 | ### Remarks 53 | 54 | * as i stated above, this application is proof of concept. 55 | * you can sometimes expect buggy behavior. 56 | * this is definitelly not full-blown secure replacement for tor. 57 | 58 | ### Compilation 59 | 60 | compile **mini-tor** using Visual Studio 2017. solution file is included. no other dependencies are required. 61 | 62 | 63 | ### License 64 | 65 | all the code in this repository is open-source under the MIT license. see the **LICENSE.txt** file in this repository. 66 | 67 | 68 | if you find this project interesting, you can buy me a coffee 69 | 70 | ``` 71 | BTC 3GwZMNGvLCZMi7mjL8K6iyj6qGbhkVMNMF 72 | LTC MQn5YC7bZd4KSsaj8snSg4TetmdKDkeCYk 73 | ``` 74 | -------------------------------------------------------------------------------- /mini/tor/consensus.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "onion_router.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mini::tor { 9 | 10 | class consensus 11 | { 12 | public: 13 | struct search_criteria 14 | { 15 | collections::list allowed_dir_ports; 16 | collections::list allowed_or_ports; 17 | onion_router_list forbidden_onion_routers; 18 | onion_router::status_flags flags; 19 | }; 20 | 21 | public: 22 | consensus( 23 | const string_ref cached_consensus_path = nullptr, 24 | bool force_download = false 25 | ); 26 | 27 | ~consensus( 28 | void 29 | ); 30 | 31 | void 32 | create( 33 | const string_ref cached_consensus_path = nullptr, 34 | bool force_download = false 35 | ); 36 | 37 | void 38 | destroy( 39 | void 40 | ); 41 | 42 | // 43 | // getters for onion routers 44 | // 45 | 46 | onion_router* 47 | get_onion_router_by_name( 48 | const string_ref name 49 | ) const; 50 | 51 | onion_router* 52 | get_onion_router_by_identity_fingerprint( 53 | const byte_buffer_ref identity_fingerprint 54 | ); 55 | 56 | onion_router_list 57 | get_onion_routers_by_criteria( 58 | const search_criteria& criteria 59 | ) const; 60 | 61 | onion_router* 62 | get_random_onion_router_by_criteria( 63 | const search_criteria& criteria 64 | ) const; 65 | 66 | string 67 | get_onion_router_descriptor( 68 | const byte_buffer_ref identity_fingerprint 69 | ); 70 | 71 | // 72 | // directories 73 | // 74 | 75 | onion_router::status_flags 76 | get_allowed_dir_flags( 77 | void 78 | ) const; 79 | 80 | void 81 | set_allowed_dir_flags( 82 | onion_router::status_flags allowed_dir_flags 83 | ); 84 | 85 | const collections::list& 86 | get_allowed_dir_ports( 87 | void 88 | ) const; 89 | 90 | void 91 | set_allowed_dir_ports( 92 | const collections::list& allowed_dir_ports 93 | ); 94 | 95 | size_type 96 | get_max_try_count( 97 | void 98 | ) const; 99 | 100 | void 101 | set_max_try_count( 102 | size_type max_try_count 103 | ); 104 | 105 | string 106 | download_from_random_router( 107 | const string_ref path, 108 | bool only_authorities = false 109 | ); 110 | 111 | private: 112 | friend struct consensus_parser; 113 | 114 | string 115 | download_from_random_router_impl( 116 | const string_ref path, 117 | bool only_authorities 118 | ); 119 | 120 | void 121 | parse_consensus( 122 | const string_ref consensus_content, 123 | bool reject_invalid 124 | ); 125 | 126 | onion_router::status_flags _allowed_dir_flags = 127 | onion_router::status_flag::fast | 128 | onion_router::status_flag::valid | 129 | onion_router::status_flag::running | 130 | onion_router::status_flag::v2dir; 131 | 132 | collections::list _allowed_dir_ports; 133 | size_type _max_try_count = 3; 134 | 135 | collections::pair_list _onion_router_map; 136 | time _valid_until; 137 | }; 138 | 139 | } 140 | -------------------------------------------------------------------------------- /mini/io/memory_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stream.h" 3 | 4 | #include 5 | 6 | namespace mini::io { 7 | 8 | class memory_stream 9 | : public stream 10 | { 11 | public: 12 | memory_stream( 13 | void 14 | ) 15 | : _begin(nullptr) 16 | , _end(nullptr) 17 | , _position(nullptr) 18 | { 19 | 20 | } 21 | 22 | memory_stream( 23 | const byte_buffer_ref buffer 24 | ) // : memory_stream() 25 | { 26 | attach(buffer); 27 | } 28 | 29 | void 30 | close( 31 | void 32 | ) override 33 | { 34 | 35 | } 36 | 37 | bool 38 | can_read( 39 | void 40 | ) const override 41 | { 42 | return true; 43 | } 44 | 45 | bool 46 | can_write( 47 | void 48 | ) const override 49 | { 50 | return true; 51 | } 52 | 53 | bool 54 | can_seek( 55 | void 56 | ) const override 57 | { 58 | return true; 59 | } 60 | 61 | size_type 62 | seek( 63 | intptr_t offset, 64 | seek_origin origin = seek_origin::current 65 | ) override 66 | { 67 | uint8_t* origin_pointer = origin == seek_origin::begin 68 | ? _begin : origin == seek_origin::current 69 | ? _position : origin == seek_origin::end 70 | ? _end : nullptr; 71 | 72 | _position = algorithm::clamp(origin_pointer + offset, _begin, _end); 73 | 74 | return _position - _begin; 75 | } 76 | 77 | void 78 | flush( 79 | void 80 | ) override 81 | { 82 | return; 83 | } 84 | 85 | void 86 | attach( 87 | const byte_buffer_ref buffer 88 | ) 89 | { 90 | _begin = const_cast(reinterpret_cast(buffer.begin())); 91 | _end = const_cast(reinterpret_cast(buffer.end())); 92 | _position = const_cast(reinterpret_cast(buffer.begin())); 93 | } 94 | 95 | size_type 96 | get_size( 97 | void 98 | ) const override 99 | { 100 | return _end - _begin; 101 | } 102 | 103 | size_type 104 | get_position( 105 | void 106 | ) const override 107 | { 108 | return _position - _begin; 109 | } 110 | 111 | void* 112 | get_buffer( 113 | void 114 | ) 115 | { 116 | return _begin; 117 | } 118 | 119 | const void* 120 | get_buffer( 121 | void 122 | ) const 123 | { 124 | return _begin; 125 | } 126 | 127 | private: 128 | size_type 129 | read_impl( 130 | void* buffer, 131 | size_type size 132 | ) override 133 | { 134 | size = algorithm::min(size, static_cast(_end - _position)); 135 | memory::copy(buffer, _position, size); 136 | _position += size; 137 | return size; 138 | } 139 | 140 | size_type 141 | write_impl( 142 | const void* buffer, 143 | size_type size 144 | ) override 145 | { 146 | size = algorithm::min(size, static_cast(_end - _position)); 147 | memory::copy(_position, buffer, size); 148 | _position += size; 149 | return size; 150 | } 151 | 152 | byte_type* _begin; 153 | byte_type* _end; 154 | byte_type* _position; 155 | }; 156 | 157 | } 158 | -------------------------------------------------------------------------------- /mini/flags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mini { 5 | 6 | template 7 | class flags final 8 | { 9 | typedef void** empty; 10 | 11 | public: 12 | using enum_type = T; 13 | using underlying_type = typename std::underlying_type::type; 14 | 15 | flags(empty = 0) : i(0) {} 16 | flags(T f) : i(static_cast(f)) {} 17 | template 18 | explicit flags(U f, typename std::enable_if::value, int>::type = 0) : i(f) {} 19 | 20 | flags(const flags& f) : i(f.i) {} 21 | 22 | flags& operator&=(flags f) { i &= f.i; return *this; } 23 | template 24 | typename std::enable_if::value, flags&>::type operator&=(U mask) { i &= mask; return *this; } 25 | 26 | flags& operator|=(flags f) { i |= f.i; return *this; } 27 | flags& operator^=(flags f) { i ^= f.i; return *this; } 28 | 29 | operator underlying_type() const { return i; } 30 | 31 | flags operator~() const { return flags(static_cast(~i)); } 32 | 33 | bool operator!() const { return !i; } 34 | 35 | bool test_flag(T f) const { return (i & static_cast(f)) != 0; } 36 | 37 | friend flags operator^(flags lhs, flags rhs) { return flags(static_cast(lhs.i ^ rhs.i)); } 38 | friend flags operator^(flags lhs, T f) { return flags(static_cast(lhs.i ^ static_cast(f))); } 39 | friend flags operator^(T f, flags lhs) { return lhs ^ f; } 40 | 41 | friend flags operator|(flags lhs, flags rhs) { return flags(static_cast(lhs.i | rhs.i)); } 42 | friend flags operator|(flags lhs, T f) { return flags(static_cast(lhs.i | static_cast(f))); } 43 | friend flags operator|(T f, flags lhs) { return lhs | f; } 44 | 45 | friend flags operator&(flags lhs, flags rhs) { return flags(static_cast(lhs.i & rhs.i)); } 46 | friend flags operator&(flags lhs, T rhs) { return flags(static_cast(lhs.i & static_cast(rhs))); } 47 | friend flags operator&(T lhs, flags rhs) { return lhs & rhs; } 48 | 49 | template 50 | friend typename std::enable_if::value, flags&>::type operator&(flags flags, U f) 51 | { return flags(static_cast(flags.i & f)); } 52 | 53 | template 54 | friend typename std::enable_if::value, flags&>::type operator&(U f, flags flags) 55 | { return flags(static_cast(flags.i & f)); } 56 | 57 | friend bool operator==(flags lhs, T rhs) { return lhs.i == static_cast(rhs); } 58 | friend bool operator==(T lhs, flags rhs) { return rhs == lhs; } 59 | friend bool operator!=(flags lhs, T rhs) { return !(lhs == rhs); } 60 | friend bool operator!=(T lhs, flags rhs) { return !(lhs == rhs); } 61 | 62 | private: 63 | union 64 | { 65 | underlying_type i; 66 | T _i; 67 | }; 68 | }; 69 | 70 | #define DECLARE_FLAGS_OPERATORS(f) \ 71 | inline ::mini::flags operator|(f::enum_type f1, f::enum_type f2) \ 72 | { return ::mini::flags(f1) | f2; } \ 73 | inline ::mini::flags operator~(f::enum_type f1) \ 74 | { return ~::mini::flags(f1); } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /doc/example-descriptors/hidden-service-descriptor-4frkg4jpbmbjhlsrbyjpbmu3slphz7ts.txt: -------------------------------------------------------------------------------- 1 | rendezvous-service-descriptor 4frkg4jpbmbjhlsrbyjpbmu3slphz7ts 2 | version 2 3 | permanent-key 4 | -----BEGIN RSA PUBLIC KEY----- 5 | MIGJAoGBALdj5MFZtlrjI54ousrBzA3fSyfn0NC32OBhl61BLgO67vPBiIiFFzo9 6 | YIqa4h3jZQrxdI3MeK4xTLQ6HhnQXvcM+ZR57o5zTR7fpqra89i75rwUjW5wqc9O 7 | 3roxzt1UWbJBtbzOT9FYxGSIczsYdG6MQRg9BK/2v391Oz9NbDb1AgMBAAE= 8 | -----END RSA PUBLIC KEY----- 9 | secret-id-part 7mnzxwe2gg2eoxp2hek4dzkv2chupfxy 10 | publication-time 2016-07-20 08:00:00 11 | protocol-versions 2,3 12 | introduction-points 13 | -----BEGIN MESSAGE----- 14 | aW50cm9kdWN0aW9uLXBvaW50IHBkY3B6eWVmZHNtMmp5Y3ZtcGRwa2lnZ3I0dWwz 15 | ZWxvCmlwLWFkZHJlc3MgMjEzLjEzNi43MS4yMQpvbmlvbi1wb3J0IDkwMDEKb25p 16 | b24ta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpNSUdKQW9HQkFM 17 | VXJuT0tqTjZIR0tPa3IwUFFhSWhHNDJQRkd2S0ZpVmJ3QlEwTjhEVk1LLzRWNlZ1 18 | T3JEZkhOCjFXemVzTUpVRWx3OWhPWko4MmdjcVZXYUFvYm9sODdJMDgwVU9SNC9a 19 | ZTV5cFhtaS9Jd2tFN3RMN08wTW9vaXMKTmliV2Y1Z00vUlh5bzh0czdnaDUrV2wr 20 | UnZPcjBoc2pTVHBtdUgxeHlJYVJhem9qWG4zSEFnTUJBQUU9Ci0tLS0tRU5EIFJT 21 | QSBQVUJMSUMgS0VZLS0tLS0Kc2VydmljZS1rZXkKLS0tLS1CRUdJTiBSU0EgUFVC 22 | TElDIEtFWS0tLS0tCk1JR0pBb0dCQU0wQjM0eE5rWVdxcDdOeE9jMzJSNkh3TXM3 23 | T2phODYyWStFZmU5bVhEdUpmL2FGOWFIWVN3NW0KeHB6NVU4bVAxa0d1OU5ZK2FX 24 | K1E0YU42YTJNam5LMDJFeWcyYXphVkt6MFp2SVdkQWdCRVdNMUx6TlQ5c3pMTgpn 25 | SzR2VEZSOGVOTXY4cUF5aEp2S0liTW5TMFdmR3QzZkphd3RwUmFoVDdwRnd5ZnR1 26 | bzBwQWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQppbnRyb2R1 27 | Y3Rpb24tcG9pbnQgY3ZnaHZkM3I0ZjNxenpwaXd0aHk0bm9kaW11M2FuZ2IKaXAt 28 | YWRkcmVzcyAxNjMuMTcyLjIxNC43NQpvbmlvbi1wb3J0IDkwMDEKb25pb24ta2V5 29 | Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpNSUdKQW9HQkFMWXRlRmt3 30 | K1BrcWRPZWprUE1qdjk4djYzS3YzU2xzTmxzS2ZaUkhTSy8ybWZTRVVPMmdxSE43 31 | CjRKLzBveGhsV1NTQVBQTis5YmRPejFlbWc2SUVMMk9WZEtKZmdvaWJsSE1oditY 32 | eDErak1YS0YwMTZKNjB6azMKV0xBNFMwL0hqZjk0YUhWUmsza1JLNlNTVmlER05K 33 | MWZ0ZUVQaTV4cDlDRFFaeUZaMStqVkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJM 34 | SUMgS0VZLS0tLS0Kc2VydmljZS1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtF 35 | WS0tLS0tCk1JR0pBb0dCQUxBQVNWK1FxRlhGdDd5a3JtdlRMeG1Kai82QkNWRWwx 36 | eVZ3MFJvcGJWSUxRNWNmaGFPQWVENTcKS0NDbGVXZHR0aE0yUlZKaytvTG9jK0RN 37 | VXhvZUVRbUo5cktBbi9ic2Rxa01EU3U1QTJjcFV3ajhXbnpieHdKcApKNzlqTGJZ 38 | ZTNIV3NDRXcySkxDWGgvQmRObTFOOVFsN3FXNDJsbnJFQzVMemRKaUYwbklKQWdN 39 | QkFBRT0KLS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQppbnRyb2R1Y3Rpb24t 40 | cG9pbnQgeHZnZ2k1aWljeXh2dHMyZTR0cDRkcXZzeGN1dHE3Z2sKaXAtYWRkcmVz 41 | cyAxNjMuMTcyLjM1LjExNQpvbmlvbi1wb3J0IDkwMDEKb25pb24ta2V5Ci0tLS0t 42 | QkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpNSUdKQW9HQkFMUmVBUFpmK0sxeWQ3 43 | Q0RxQ2dMV2RzdjdqdzhBZXpzYXRxbnJQN3RvakY0dXcyZkxITEpFSk12ClZwZ0Zn 44 | SEhSQzNic3owS3ZUcXZIdEVXMFhHWkpXZmhWU1czSkFHaHovWXF1NTNTRUM5WkdN 45 | c2xIZnIyeGxSSXIKN2RCRWlDQkFHOGRQa1VMZkM2RWN5SFB6QXBIMWk5d3V6Y2x0 46 | dUowekZRbUpFbEIvalNOUEFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZ 47 | LS0tLS0Kc2VydmljZS1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0t 48 | Ck1JR0pBb0dCQUxOTVc1SG9sZmFTM3NqWk5od3ZUd2pUOStPc1kyYU1XWjVieXZy 49 | Q1pzMG5xQ21FaXZFTlNBbVoKZjlvbFQ0em14TUhZNEtJYVVGcW5ZdzV5NTlvSGo4 50 | eGx1bDRLMURrTU15dWRRaTNhcHBuaWtBWGZhUkptRXNKRgozbk9Neld6UmN4MG1r 51 | MFhRYTh4OWF0R2E1UnMvV2l2aVlYUEVTYklKMGlOZmFScWMyS0hYQWdNQkFBRT0K 52 | LS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQoK 53 | -----END MESSAGE----- 54 | signature 55 | -----BEGIN SIGNATURE----- 56 | aDxMNhtGWBV7lMJPTfamvHNXVFD7wFTTRz68JEhmmfLVuuZ+erUfjDHsUa3bF3zR 57 | tNvPBYbQdWj2vl8WzdzwlchXS56iqgQ672y19/hx4THiuPyjGUj/dtc7L4qINl1V 58 | cgBWo0Lezfnyc+5laQboMsEsjQa4SqJyQNamjmS2soo= 59 | -----END SIGNATURE----- 60 | -------------------------------------------------------------------------------- /mini/threading/thread.cpp: -------------------------------------------------------------------------------- 1 | #include "thread.h" 2 | 3 | namespace mini::threading { 4 | 5 | namespace detail { 6 | 7 | void 8 | thread_dispatcher( 9 | thread* thread_instance 10 | ) 11 | { 12 | thread_instance->thread_procedure(); 13 | } 14 | 15 | DWORD WINAPI 16 | native_thread_dispatcher( 17 | LPVOID lpParam 18 | ) 19 | { 20 | thread_dispatcher(reinterpret_cast(lpParam)); 21 | return 0; 22 | } 23 | 24 | } 25 | 26 | // 27 | // constructors. 28 | // 29 | 30 | thread::thread( 31 | thread&& other 32 | ) 33 | { 34 | swap(other); 35 | } 36 | 37 | thread::thread( 38 | current_thread_tag 39 | ) 40 | : _thread_handle(GetCurrentThread()) 41 | , _thread_id(GetCurrentThreadId()) 42 | { 43 | 44 | } 45 | 46 | // 47 | // destructor 48 | // 49 | 50 | thread::~thread( 51 | void 52 | ) 53 | { 54 | stop(); 55 | } 56 | 57 | // 58 | // swap. 59 | // 60 | 61 | void 62 | thread::swap( 63 | thread& other 64 | ) 65 | { 66 | mini::swap(_thread_handle, other._thread_handle); 67 | mini::swap(_thread_id, other._thread_id); 68 | } 69 | 70 | // 71 | // operations. 72 | // 73 | 74 | void 75 | thread::start( 76 | void 77 | ) 78 | { 79 | if (_thread_handle != 0) 80 | { 81 | // 82 | // thread is already running. 83 | // 84 | return; 85 | } 86 | 87 | if (_has_been_terminated) 88 | { 89 | // 90 | // do not start terminated thread again. 91 | // 92 | return; 93 | } 94 | 95 | _thread_handle = CreateThread( 96 | NULL, // default security attributes 97 | 0, // use default stack size 98 | &detail::native_thread_dispatcher, // thread function name 99 | (LPVOID)this, // argument to thread function 100 | 0, // use default creation flags 101 | &_thread_id); // returns the thread identifier 102 | } 103 | 104 | void 105 | thread::stop( 106 | void 107 | ) 108 | { 109 | if (_thread_handle == 0) 110 | { 111 | // 112 | // thread is not running or is already terminated. 113 | // 114 | return; 115 | } 116 | 117 | TerminateThread(_thread_handle, 0); 118 | CloseHandle(_thread_handle); 119 | 120 | _thread_handle = 0; 121 | _thread_id = 0; 122 | _has_been_terminated = true; 123 | } 124 | 125 | wait_result 126 | thread::join( 127 | timeout_type timeout 128 | ) 129 | { 130 | return static_cast(WaitForSingleObject( 131 | _thread_handle, 132 | (DWORD)timeout 133 | )); 134 | } 135 | 136 | // 137 | // observers. 138 | // 139 | 140 | thread::id 141 | thread::get_id( 142 | void 143 | ) const 144 | { 145 | return _thread_id; 146 | } 147 | 148 | bool 149 | thread::is_alive( 150 | void 151 | ) const 152 | { 153 | return 154 | _thread_handle != 0 && 155 | WaitForSingleObject(_thread_handle, 0) == WAIT_TIMEOUT; 156 | } 157 | 158 | // 159 | // static methods. 160 | // 161 | 162 | thread 163 | thread::get_current_thread( 164 | void 165 | ) 166 | { 167 | return thread(current_thread_tag()); 168 | } 169 | 170 | void 171 | thread::sleep( 172 | timeout_type milliseconds 173 | ) 174 | { 175 | Sleep(milliseconds); 176 | } 177 | 178 | // 179 | // virtual methods. 180 | // 181 | 182 | void 183 | thread::thread_procedure( 184 | void 185 | ) 186 | { 187 | 188 | } 189 | 190 | void 191 | swap( 192 | thread& lhs, 193 | thread& rhs 194 | ) 195 | { 196 | lhs.swap(rhs); 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /mini/crypto/ext/curve25519.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "key.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace mini::crypto::ext { 8 | 9 | class curve25519_public_key; 10 | class curve25519_private_key; 11 | 12 | class curve25519_public_key 13 | : public key 14 | { 15 | MINI_MAKE_NONCOPYABLE(curve25519_public_key); 16 | 17 | public: 18 | static constexpr size_type key_size = 255; 19 | static constexpr size_type key_size_in_bytes = 32; 20 | 21 | curve25519_public_key( 22 | void 23 | ) = default; 24 | 25 | curve25519_public_key( 26 | const byte_buffer_ref key 27 | ); 28 | 29 | curve25519_public_key( 30 | curve25519_public_key&& other 31 | ); 32 | 33 | curve25519_public_key& 34 | operator=( 35 | curve25519_public_key&& other 36 | ); 37 | 38 | void 39 | swap( 40 | curve25519_public_key& other 41 | ); 42 | 43 | // 44 | // import. 45 | // 46 | 47 | void 48 | import( 49 | const byte_buffer_ref key 50 | ); 51 | 52 | // 53 | // getters. 54 | // 55 | 56 | byte_buffer 57 | get_public_key_buffer( 58 | void 59 | ) const; 60 | 61 | public: 62 | struct blob 63 | { 64 | byte_type X[key_size_in_bytes]; 65 | }; 66 | 67 | private: 68 | blob _blob; 69 | 70 | friend class curve25519_private_key; 71 | }; 72 | 73 | class curve25519_private_key 74 | : public key 75 | { 76 | MINI_MAKE_NONCOPYABLE(curve25519_private_key); 77 | 78 | public: 79 | static constexpr size_type key_size = 255; 80 | static constexpr size_type key_size_in_bytes = 32; 81 | 82 | curve25519_private_key( 83 | void 84 | ) = default; 85 | 86 | curve25519_private_key( 87 | const byte_buffer_ref key 88 | ); 89 | 90 | curve25519_private_key( 91 | curve25519_private_key&& other 92 | ); 93 | 94 | curve25519_private_key& 95 | operator=( 96 | curve25519_private_key&& other 97 | ); 98 | 99 | void 100 | swap( 101 | curve25519_private_key& other 102 | ); 103 | 104 | // 105 | // import. 106 | // 107 | 108 | static curve25519_private_key 109 | generate( 110 | void 111 | ); 112 | 113 | void 114 | import( 115 | const byte_buffer_ref key 116 | ); 117 | 118 | // 119 | // export. 120 | // 121 | 122 | curve25519_public_key 123 | export_public_key( 124 | void 125 | ) const; 126 | 127 | // 128 | // getters. 129 | // 130 | 131 | byte_buffer_ref 132 | get_public_key_buffer( 133 | void 134 | ) const; 135 | 136 | byte_buffer_ref 137 | get_private_key_buffer( 138 | void 139 | ) const; 140 | 141 | byte_buffer 142 | get_shared_secret( 143 | const curve25519_public_key& other_public_key 144 | ) const; 145 | 146 | public: 147 | struct blob 148 | { 149 | byte_type X[key_size_in_bytes]; 150 | byte_type d[key_size_in_bytes]; 151 | }; 152 | 153 | private: 154 | blob _blob; 155 | }; 156 | 157 | class curve25519 158 | { 159 | MINI_MAKE_NONCONSTRUCTIBLE(curve25519); 160 | 161 | public: 162 | static constexpr size_type key_size = 255; 163 | static constexpr size_type key_size_in_bytes = 32; 164 | 165 | using public_key = curve25519_public_key; 166 | using private_key = curve25519_private_key; 167 | }; 168 | 169 | } 170 | 171 | -------------------------------------------------------------------------------- /mini/crypto/ext/curve25519.cpp: -------------------------------------------------------------------------------- 1 | #include "curve25519.h" 2 | #include "detail/curve25519-donna.h" 3 | #include "../random.h" 4 | 5 | namespace mini::crypto::ext { 6 | 7 | static const uint8_t basepoint_9[32] = { 9 }; 8 | 9 | // 10 | // curve25519 11 | // public key. 12 | // 13 | 14 | curve25519_public_key::curve25519_public_key( 15 | const byte_buffer_ref key 16 | ) 17 | { 18 | import(key); 19 | } 20 | 21 | curve25519_public_key::curve25519_public_key( 22 | curve25519_public_key&& other 23 | ) 24 | { 25 | swap(other); 26 | } 27 | 28 | curve25519_public_key& 29 | curve25519_public_key::operator=( 30 | curve25519_public_key&& other 31 | ) 32 | { 33 | swap(other); 34 | return *this; 35 | } 36 | 37 | void 38 | curve25519_public_key::swap( 39 | curve25519_public_key& other 40 | ) 41 | { 42 | key::swap(other); 43 | mini::swap(_blob, other._blob); 44 | } 45 | 46 | // 47 | // import. 48 | // 49 | 50 | void 51 | curve25519_public_key::import( 52 | const byte_buffer_ref key 53 | ) 54 | { 55 | memory::copy(_blob.X, key.get_buffer(), key_size_in_bytes); 56 | } 57 | 58 | // 59 | // getters. 60 | // 61 | 62 | byte_buffer 63 | curve25519_public_key::get_public_key_buffer( 64 | void 65 | ) const 66 | { 67 | return _blob.X; 68 | } 69 | 70 | // 71 | // curve25519 72 | // private key. 73 | // 74 | 75 | curve25519_private_key::curve25519_private_key( 76 | const byte_buffer_ref key 77 | ) 78 | { 79 | import(key); 80 | } 81 | 82 | curve25519_private_key::curve25519_private_key( 83 | curve25519_private_key&& other 84 | ) 85 | { 86 | swap(other); 87 | } 88 | 89 | curve25519_private_key& 90 | curve25519_private_key::operator=( 91 | curve25519_private_key&& other 92 | ) 93 | { 94 | swap(other); 95 | return *this; 96 | } 97 | 98 | void 99 | curve25519_private_key::swap( 100 | curve25519_private_key& other 101 | ) 102 | { 103 | key::swap(other); 104 | mini::swap(_blob, other._blob); 105 | } 106 | 107 | // 108 | // import. 109 | // 110 | 111 | curve25519_private_key 112 | curve25519_private_key::generate( 113 | void 114 | ) 115 | { 116 | auto random_private_key = random_device.get_random_bytes(key_size_in_bytes); 117 | random_private_key[0] &= 248; 118 | random_private_key[31] &= 127; 119 | random_private_key[31] |= 64; 120 | 121 | return curve25519_private_key(random_private_key); 122 | } 123 | 124 | void 125 | curve25519_private_key::import( 126 | const byte_buffer_ref key 127 | ) 128 | { 129 | memory::copy(_blob.d, key.get_buffer(), key_size_in_bytes); 130 | detail::curve25519_donna(_blob.X, _blob.d, basepoint_9); 131 | } 132 | 133 | // 134 | // export. 135 | // 136 | 137 | curve25519_public_key 138 | curve25519_private_key::export_public_key( 139 | void 140 | ) const 141 | { 142 | curve25519_public_key result; 143 | detail::curve25519_donna(result._blob.X, _blob.d, basepoint_9); 144 | return result; 145 | } 146 | 147 | // 148 | // getters. 149 | // 150 | 151 | byte_buffer_ref 152 | curve25519_private_key::get_public_key_buffer( 153 | void 154 | ) const 155 | { 156 | return _blob.X; 157 | } 158 | 159 | byte_buffer_ref 160 | curve25519_private_key::get_private_key_buffer( 161 | void 162 | ) const 163 | { 164 | return _blob.d; 165 | } 166 | 167 | byte_buffer 168 | curve25519_private_key::get_shared_secret( 169 | const curve25519_public_key& other_public_key 170 | ) const 171 | { 172 | byte_buffer result(key_size_in_bytes); 173 | detail::curve25519_donna(&result[0], _blob.d, other_public_key._blob.X); 174 | return result; 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /mini/tor/relay_cell.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cell.h" 3 | #include 4 | 5 | namespace mini::tor { 6 | 7 | class circuit_node; 8 | class tor_stream; 9 | 10 | // 11 | // 6.3. 12 | // 13 | // The payload of a RELAY_END cell begins with a single 'reason' byte to 14 | // describe why the stream is closing, plus optional data(depending on 15 | // the reason.) 16 | // 17 | 18 | enum class relay_end_reason : uint8_t 19 | { 20 | misc = 1, // catch-all for unlisted reasons 21 | resolve_failed = 2, // couldn't look up hostname 22 | connection_refused = 3, // remote host refused connection 23 | exit_policy = 4, // OR refuses to connect to host or port 24 | destroy = 5, // circuit is being destroyed 25 | done = 6, // anonymized TCP connection was closed 26 | timeout = 7, // connection timed out, or OR timed out while connecting 27 | no_route = 8, // routing error while attempting to contact destination 28 | hibernating = 9, // OR is temporarily hibernating 29 | internal = 10, // internal error at the OR 30 | resource_limit = 11, // OR has no resources to fulfill request 31 | connection_reset = 12, // connection was unexpectedly reset 32 | tor_protocol_violation = 13, // sent when closing connection because of Tor protocol violations 33 | not_directory = 14, // client sent RELAY_BEGIN_DIR to a non - directory relay 34 | }; 35 | 36 | class relay_cell 37 | : public cell 38 | { 39 | public: 40 | static constexpr size_type payload_data_size = cell::payload_size - 11; 41 | 42 | relay_cell( 43 | void 44 | ) = default; 45 | 46 | relay_cell( 47 | circuit_node* node, 48 | const cell& cell 49 | ); 50 | 51 | relay_cell( 52 | circuit_id_type circuit_id, 53 | cell_command command, 54 | circuit_node* node, 55 | cell_command relay_command, 56 | tor_stream_id_type stream_id, 57 | const byte_buffer_ref relay_payload 58 | ); 59 | 60 | cell_command 61 | get_relay_command( 62 | void 63 | ) const; 64 | 65 | tor_stream_id_type 66 | get_stream_id( 67 | void 68 | ) const; 69 | 70 | tor_stream* 71 | get_stream( 72 | void 73 | ); 74 | 75 | void 76 | set_digest( 77 | const byte_buffer_ref digest 78 | ); 79 | 80 | byte_buffer_ref 81 | get_relay_payload( 82 | void 83 | ) const; 84 | 85 | void 86 | set_relay_payload( 87 | const byte_buffer_ref payload 88 | ); 89 | 90 | circuit_node* 91 | get_circuit_node( 92 | void 93 | ); 94 | 95 | bool 96 | is_relay_cell_valid( 97 | void 98 | ) const; 99 | 100 | private: 101 | circuit_node* _circuit_node = nullptr; 102 | 103 | // 104 | // tor-spec.txt 105 | // 6.1. 106 | // 107 | // The payload of each unencrypted RELAY cell consists of: 108 | // Relay command [1 byte] 109 | // 'Recognized' [2 bytes] 110 | // StreamID [2 bytes] 111 | // Digest [4 bytes] 112 | // Length [2 bytes] 113 | // Data [PAYLOAD_LEN-11 bytes] 114 | // 115 | cell_command _relay_command = (cell_command)0; 116 | tor_stream_id_type _stream_id = 0; 117 | stack_byte_buffer<4> _digest; 118 | byte_buffer _relay_payload; 119 | }; 120 | 121 | } 122 | -------------------------------------------------------------------------------- /mini/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #define MINI_LOG_ENABLED 1 7 | 8 | #if defined(MINI_CONFIG_DEBUG) || defined(MINI_LOG_ENABLED) 9 | 10 | // 11 | // variadic macro rape 12 | // 13 | 14 | #define MINI_MACRO_EVAL(...) MINI_MACRO_EVAL_IMPL(MINI_MACRO_EVAL_IMPL(MINI_MACRO_EVAL_IMPL(__VA_ARGS__))) 15 | #define MINI_MACRO_EVAL_IMPL(...) __VA_ARGS__ 16 | 17 | #define MINI_MACRO_EXPAND(expr) expr 18 | #define MINI_MACRO_DISPATCHER(func, ...) MINI_MACRO_EXPAND(MINI_MACRO_DISPATCHER2(func, MINI_VA_NUM_ARGS(func ## _NUM_ARGS_TABLE, __VA_ARGS__))) 19 | #define MINI_MACRO_DISPATCHER2(func, nargs) MINI_MACRO_DISPATCHER3(func, nargs) 20 | #define MINI_MACRO_DISPATCHER3(func, nargs) func ## nargs 21 | 22 | #define MINI_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N 23 | #define MINI_VA_NUM_ARGS(table, ...) MINI_MACRO_EXPAND(MINI_VA_NUM_ARGS_IMPL(__VA_ARGS__, table)) 24 | 25 | #define MINI_VA_FUNCTION(function, ...) MINI_MACRO_EXPAND(MINI_MACRO_DISPATCHER(function, __VA_ARGS__)(__VA_ARGS__)) 26 | 27 | // 28 | // MINI_LOG 29 | // 30 | 31 | #define MINI_LOG_NUM_ARGS_TABLE 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 32 | 33 | #define MINI_LOG0(level, format) ::mini::log.log(level, format "\n") 34 | #define MINI_LOG1(level, format, ...) ::mini::log.log(level, format "\n", __VA_ARGS__) 35 | 36 | // 37 | // mini_log 38 | // 39 | 40 | # define mini_log(...) MINI_VA_FUNCTION(MINI_LOG, ::mini::logger::level::info, __VA_ARGS__) 41 | # define mini_debug(...) MINI_VA_FUNCTION(MINI_LOG, ::mini::logger::level::debug, __VA_ARGS__) 42 | # define mini_info(...) MINI_VA_FUNCTION(MINI_LOG, ::mini::logger::level::info, __VA_ARGS__) 43 | # define mini_warning(...) MINI_VA_FUNCTION(MINI_LOG, ::mini::logger::level::warning, __VA_ARGS__) 44 | # define mini_error(...) MINI_VA_FUNCTION(MINI_LOG, ::mini::logger::level::error, __VA_ARGS__) 45 | #else 46 | # define mini_log(format, ...) 47 | # define mini_debug(format, ...) 48 | # define mini_info(format, ...) 49 | # define mini_warning(format, ...) 50 | # define mini_error(format, ...) 51 | #endif 52 | 53 | namespace mini { 54 | 55 | class logger 56 | { 57 | public: 58 | MINI_MAKE_NONCOPYABLE(logger); 59 | 60 | logger( 61 | void 62 | ) = default; 63 | 64 | enum class level 65 | { 66 | debug, 67 | info, 68 | warning, 69 | error, 70 | off, 71 | }; 72 | 73 | void 74 | log( 75 | level l, 76 | const char* format, 77 | ... 78 | ); 79 | 80 | void 81 | log_args( 82 | level l, 83 | const char* format, 84 | va_list args 85 | ); 86 | 87 | void 88 | debug( 89 | const char* format, 90 | ... 91 | ); 92 | 93 | void 94 | info( 95 | const char* format, 96 | ... 97 | ); 98 | 99 | void 100 | warning( 101 | const char* format, 102 | ... 103 | ); 104 | 105 | void 106 | error( 107 | const char* format, 108 | ... 109 | ); 110 | 111 | level 112 | get_level( 113 | void 114 | ) const; 115 | 116 | void 117 | set_level( 118 | level new_level 119 | ); 120 | 121 | private: 122 | level _level = level::info; 123 | }; 124 | 125 | extern logger log; 126 | 127 | } 128 | -------------------------------------------------------------------------------- /mini/stack_buffer.inl: -------------------------------------------------------------------------------- 1 | #include "stack_buffer.h" 2 | 3 | namespace mini { 4 | 5 | // 6 | // swap. 7 | // 8 | 9 | template < 10 | typename T, 11 | size_type N 12 | > 13 | void 14 | stack_buffer::swap( 15 | stack_buffer& other 16 | ) 17 | { 18 | 19 | } 20 | 21 | // 22 | // element access. 23 | // 24 | 25 | template < 26 | typename T, 27 | size_type N 28 | > 29 | typename stack_buffer::reference 30 | stack_buffer::operator[]( 31 | size_type index 32 | ) 33 | { 34 | return at(index); 35 | } 36 | 37 | template < 38 | typename T, 39 | size_type N 40 | > 41 | constexpr typename stack_buffer::const_reference 42 | stack_buffer::operator[]( 43 | size_type index 44 | ) const 45 | { 46 | return at(index); 47 | } 48 | 49 | template < 50 | typename T, 51 | size_type N 52 | > 53 | typename stack_buffer::reference 54 | stack_buffer::at( 55 | size_type index 56 | ) 57 | { 58 | return buffer[index]; 59 | } 60 | 61 | template < 62 | typename T, 63 | size_type N 64 | > 65 | constexpr typename stack_buffer::const_reference 66 | stack_buffer::at( 67 | size_type index 68 | ) const 69 | { 70 | return buffer[index]; 71 | } 72 | 73 | template < 74 | typename T, 75 | size_type N 76 | > 77 | typename stack_buffer::value_type* 78 | stack_buffer::get_buffer( 79 | void 80 | ) 81 | { 82 | return buffer; 83 | } 84 | 85 | template < 86 | typename T, 87 | size_type N 88 | > 89 | const typename stack_buffer::value_type* 90 | stack_buffer::get_buffer( 91 | void 92 | ) const 93 | { 94 | return buffer; 95 | } 96 | 97 | // 98 | // iterators. 99 | // 100 | 101 | template < 102 | typename T, 103 | size_type N 104 | > 105 | typename stack_buffer::iterator 106 | stack_buffer::begin( 107 | void 108 | ) 109 | { 110 | return buffer; 111 | } 112 | 113 | template < 114 | typename T, 115 | size_type N 116 | > 117 | typename stack_buffer::const_iterator 118 | stack_buffer::begin( 119 | void 120 | ) const 121 | { 122 | return buffer; 123 | } 124 | 125 | template < 126 | typename T, 127 | size_type N 128 | > 129 | typename stack_buffer::iterator 130 | stack_buffer::end( 131 | void 132 | ) 133 | { 134 | return buffer + N; 135 | } 136 | 137 | template < 138 | typename T, 139 | size_type N 140 | > 141 | typename stack_buffer::const_iterator 142 | stack_buffer::end( 143 | void 144 | ) const 145 | { 146 | return buffer + N; 147 | } 148 | 149 | // 150 | // lookup. 151 | // 152 | 153 | template < 154 | typename T, 155 | size_type N 156 | > 157 | constexpr size_type 158 | stack_buffer::index_of( 159 | const T& item, 160 | size_type from_offset 161 | ) const 162 | { 163 | return 164 | from_offset >= N 165 | ? not_found 166 | : buffer[from_offset] == item 167 | ? from_offset 168 | : index_of(item, from_offset + 1); 169 | } 170 | 171 | // 172 | // capacity. 173 | // 174 | 175 | template < 176 | typename T, 177 | size_type N 178 | > 179 | constexpr typename stack_buffer::size_type 180 | stack_buffer::get_size( 181 | void 182 | ) const 183 | { 184 | return N; 185 | } 186 | 187 | template < 188 | typename T, 189 | size_type N 190 | > 191 | stack_buffer::operator buffer_ref( 192 | void 193 | ) const 194 | { 195 | return buffer_ref(begin(), end()); 196 | } 197 | 198 | template < 199 | typename T, 200 | size_type N 201 | > 202 | stack_buffer::operator mutable_buffer_ref( 203 | void 204 | ) 205 | { 206 | return mutable_buffer_ref(begin(), end()); 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /mini/crypto/ext/base32.cpp: -------------------------------------------------------------------------------- 1 | #include "base32.h" 2 | 3 | #include 4 | 5 | namespace mini::crypto::ext { 6 | 7 | // 8 | // RFC 4648 alphabet. 9 | // 10 | 11 | // 12 | // functions. 13 | // 14 | 15 | static size_type 16 | get_encode_length( 17 | size_type bytes 18 | ) 19 | { 20 | size_type bits = bytes * 8; 21 | size_type length = bits / 5; 22 | 23 | if ((bits % 5) > 0) 24 | { 25 | length++; 26 | } 27 | 28 | return length; 29 | } 30 | 31 | static size_type 32 | get_decode_length( 33 | size_type bytes 34 | ) 35 | { 36 | size_type bits = bytes * 5; 37 | size_type length = bits / 8; 38 | 39 | return length; 40 | } 41 | 42 | static void 43 | encode_chunk( 44 | const byte_type input[5], 45 | byte_type output[8] 46 | ) 47 | { 48 | // 49 | // pack 5 bytes 50 | // 51 | uint64_t buffer = 0; 52 | 53 | for (int i = 0; i < 5; i++) 54 | { 55 | buffer = (buffer << 8) | input[i]; 56 | } 57 | 58 | // 59 | // output 8 bytes 60 | // 61 | for (int i = 7; i >= 0; i--) 62 | { 63 | buffer <<= (24 + (7 - i) * 5); 64 | buffer >>= (24 + (7 - i) * 5); 65 | 66 | byte_type c = (byte_type)(buffer >> (i * 5)); 67 | output[7 - i] = c + (c < 0x1a ? 'a' : ('2' - 0x1a)); 68 | } 69 | } 70 | 71 | static void 72 | decode_chunk( 73 | const byte_type input[8], 74 | byte_type output[5] 75 | ) 76 | { 77 | // 78 | // pack 8 bytes 79 | // 80 | uint64_t buffer = 0; 81 | 82 | for (int i = 0; i < 8; i++) 83 | { 84 | buffer = (buffer << 5) | (byte_type)(input[i] - (input[i] >= 'a' ? 'a' : ('2' - 0x1a))); 85 | } 86 | 87 | // 88 | // output 5 bytes 89 | // 90 | for (int j = 4; j >= 0; j--) 91 | { 92 | output[4 - j] = (byte_type)(buffer >> (j * 8)); 93 | } 94 | } 95 | 96 | string 97 | base32::encode( 98 | const byte_buffer_ref input 99 | ) 100 | { 101 | string output(get_encode_length(input.get_size())); 102 | 103 | // 104 | // get quotient & remainder. 105 | // 106 | size_type q = input.get_size() / 5; 107 | size_type r = input.get_size() % 5; 108 | 109 | byte_type out_chunk_buffer[8]; 110 | for (size_type j = 0; j < q; j++) 111 | { 112 | encode_chunk(&input[j * 5], &out_chunk_buffer[0]); 113 | memmove(&output[j * 8], &out_chunk_buffer[0], sizeof(byte_type) * 8); 114 | } 115 | 116 | byte_type out_padding_buffer[5] = { 0 }; 117 | for (size_type i = 0; i < r; i++) 118 | { 119 | out_padding_buffer[i] = input[input.get_size() - r + i]; 120 | } 121 | 122 | encode_chunk(&out_padding_buffer[0], &out_chunk_buffer[0]); 123 | memmove(&output[q * 8], &out_chunk_buffer[0], sizeof(byte_type) * get_encode_length(r)); 124 | 125 | return output; 126 | } 127 | 128 | byte_buffer 129 | base32::decode( 130 | const string_ref input 131 | ) 132 | { 133 | byte_buffer output(get_decode_length(input.get_size())); 134 | 135 | // 136 | // get quotient & remainder. 137 | // 138 | size_type q = input.get_size() / 8; 139 | size_type r = input.get_size() % 8; 140 | 141 | byte_type out_chunk_buffer[5]; 142 | for (size_type j = 0; j < q; j++) 143 | { 144 | decode_chunk((byte_type*)&input[j * 8], &out_chunk_buffer[0]); 145 | memmove(&output[j * 5], &out_chunk_buffer[0], sizeof(byte_type) * 5); 146 | } 147 | 148 | byte_type out_padding_buffer[8] = { 0 }; 149 | for (size_type i = 0; i < r; i++) 150 | { 151 | out_padding_buffer[i] = input[input.get_size() - r + i]; 152 | } 153 | 154 | decode_chunk(&out_padding_buffer[0], &out_chunk_buffer[0]); 155 | memmove(&output[q * 5], &out_chunk_buffer[0], sizeof(byte_type) * get_decode_length(r)); 156 | 157 | return output; 158 | } 159 | 160 | } 161 | --------------------------------------------------------------------------------