Advertisement
Guest User

C++17 BOTAN DTLS Server

a guest
Apr 26th, 2019
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.73 KB | None | 0 0
  1. /****
  2.     DTLSPolicy.hpp
  3. ****/
  4.  
  5. #pragma once
  6.  
  7. #include<botan/tls_policy.h>
  8. #include<array>
  9. #include<any>
  10.  
  11. //ENUM Class for Future Versions
  12. //DTLS_ANY is for a possible future feature if you can exclude some Versions. DTLS_ANY will show that no Version is excluded.
  13. //e.g. if there were 1.0 , 1.2 , 1.5 ,2.0 you could set up DTLS_1_0 and exclude DTLS_1_5 as accepted. If DTLS_ANY is set it is not.
  14. enum class DTLSVersion : unsigned int {
  15.     DTLS_ANY = 0,
  16.     DTLS_1_0 = 1,
  17.     DTLS_1_2 = 2
  18. };
  19.  
  20. constexpr std::array<const char*,19> ACCEPT_ALL_CIPHERS{"AES-256/OCB(12)","AES-128/OCB(12)","ChaCha20Poly1305","AES-256/GCM","AES-128/GCM","AES-256/CCM","AES-128/CCM","AES-256/CCM(8)","AES-128/CCM(8)","Camellia-256/GCM","Camellia-128/GCM","ARIA-256/GCM", "ARIA-128/GCM", "AES-256", "AES-128","Camellia-256", "Camellia-128", "SEED","3DES" };
  21. constexpr std::array<const char*, 4> ACCEPT_ALL_SIGNATURE_HASHES{ "SHA-512","SHA-384","SHA-256","SHA-1", };
  22. constexpr std::array<const char*, 4> ACCEPT_ALL_MACS{ "AEAD","SHA-256","SHA-384","SHA-1" };
  23. constexpr std::array<const char*, 8> ACCEPT_ALL_KEY_EXCHANGE_METHODS{ "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK", "CECPQ1", "ECDH", "DH", "RSA" };
  24. constexpr std::array<const char*, 5> ACCEPT_ALL_SIGNATURE_METHODS{ "ECDSA","RSA","DSA","IMPLICIT","ANONYMOUS" };
  25.  
  26. class DTLSPolicy : public Botan::TLS::Policy
  27. {
  28. public:
  29.     enum class DTLSPolicyOptions : unsigned int {
  30.         //1-9 ALLOWED FEATURES
  31.         DTLS_OPTION_SET_ALLOWED_CIPHERS = 1,
  32.         DTLS_OPTION_SET_ALLOWED_SIGNATURE_HASHES = 2,
  33.         DTLS_OPTION_SET_ALLOWED_MACS = 3,
  34.         DTLS_OPTION_SET_ALLOW_KEY_EXCHANGE_METHODS = 4,
  35.         DTLS_OPTION_SET_ALLOW_SIGNATURE_METHODS = 5,
  36.         //10+ OTHER FEATURES
  37.         DTLS_OPTION_EXCLUDE_DTLS_VERSION = 10,
  38.     };
  39.     DTLSPolicy(DTLSVersion minimum);
  40.     ~DTLSPolicy();
  41.     void setOption(DTLSPolicy::DTLSPolicyOptions option, std::any data);
  42.    
  43.  
  44.  
  45.     //OVERRIDE FUNCTIONS
  46.     bool allow_dtls10() const override {
  47.         return this->dtls10_enabled;
  48.     }
  49.     bool allow_dtls12() const override {
  50.         return this->dtls12_enabled;
  51.     }
  52.  
  53.     bool allow_tls10() {
  54.         return false;
  55.     }
  56.  
  57.     bool allow_tls11() {
  58.         return false;
  59.     }
  60.  
  61.     std::vector<std::string> allowed_ciphers() const override {
  62.         return this->allowedCiphersVec;
  63.     }
  64.  
  65.     std::vector<std::string> allowed_signature_hashes() const override {
  66.         return this->allowedSignatureHashesVec;
  67.     }
  68.  
  69.     std::vector<std::string> allowed_macs() const override {
  70.         return this->allowedMacsVec;
  71.     }
  72.  
  73.     std::vector<std::string> allowed_key_exchange_methods() const override {
  74.         return this->allowedKeyExchangeMethodsVec;
  75.     }
  76.  
  77.     std::vector<std::string> allowed_signature_methods() const override {
  78.         return this->allowedSignatureMethodsVec;
  79.     }
  80.  
  81.  
  82.  
  83. private:
  84.     bool dtls10_enabled = false;
  85.     bool dtls12_enabled = false;
  86.     std::vector<std::string> allowedCiphersVec;
  87.     std::vector<std::string> allowedSignatureHashesVec;
  88.     std::vector<std::string> allowedMacsVec;
  89.     std::vector<std::string> allowedKeyExchangeMethodsVec;
  90.     std::vector<std::string> allowedSignatureMethodsVec;
  91.     bool noexclusion = false;
  92.  
  93.     void excludeVersion(DTLSVersion version);
  94. };
  95.  
  96. // END
  97.  
  98. /***
  99.         DTLSPolicy.cpp
  100. ***/
  101.  
  102. #include "DTLSPolicy.hpp"
  103. #include<iostream>
  104.  
  105.  
  106. DTLSPolicy::DTLSPolicy(DTLSVersion minimum)
  107. {
  108.     switch (minimum) {
  109.     case DTLSVersion::DTLS_ANY:
  110.         this->noexclusion = true;
  111.     case DTLSVersion::DTLS_1_0:
  112.         this->dtls10_enabled = true;
  113.     case DTLSVersion::DTLS_1_2:
  114.         this->dtls12_enabled = true;
  115.         break;
  116.     default:
  117.         std::cerr << "This should not be reached!\n";
  118.         break;
  119.     }
  120. }
  121.  
  122. DTLSPolicy::~DTLSPolicy()
  123. {
  124. }
  125.  
  126.  
  127. //std::any for future options!
  128. void DTLSPolicy::setOption(DTLSPolicy::DTLSPolicyOptions option, std::any data)
  129. {
  130.     switch (option) {
  131.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_CIPHERS:
  132.         {
  133.             this->allowedCiphersVec = std::any_cast<std::vector<std::string>>(data);
  134.         }
  135.         return;
  136.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_SIGNATURE_HASHES:
  137.         {
  138.             this->allowedSignatureHashesVec = std::any_cast<std::vector<std::string>>(data);
  139.         }
  140.         return;
  141.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_MACS:
  142.         {
  143.             this->allowedMacsVec = std::any_cast<std::vector<std::string>>(data);
  144.         }
  145.         return;
  146.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOW_KEY_EXCHANGE_METHODS:
  147.         {
  148.             this->allowedKeyExchangeMethodsVec = std::any_cast<std::vector<std::string>>(data);
  149.         }
  150.         return;
  151.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOW_SIGNATURE_METHODS:
  152.         {
  153.             this->allowedSignatureMethodsVec = std::any_cast<std::vector<std::string>>(data);
  154.         }
  155.         return;
  156.         case DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_EXCLUDE_DTLS_VERSION:
  157.         {
  158.             this->excludeVersion(std::any_cast<DTLSVersion>(data));
  159.         }
  160.         return;
  161.         default:
  162.             std::cerr << "This should not be reached!\n";
  163.             return;
  164.     }
  165. }
  166.  
  167. void DTLSPolicy::excludeVersion(DTLSVersion version)
  168. {
  169.     if (this->noexclusion) return;
  170.     switch (version) {
  171.     case DTLSVersion::DTLS_1_0:
  172.         this->dtls10_enabled = false;
  173.         return;
  174.     case DTLSVersion::DTLS_1_2:
  175.         this->dtls12_enabled = false;
  176.         return;
  177.     case DTLSVersion::DTLS_ANY:
  178.     default:
  179.         std::cerr << "OPERATION NOT POSSIBLE\n";
  180.         return;
  181.     }
  182. }
  183.  
  184. //END
  185.  
  186. /***
  187.         DTLS.hpp
  188. ***/
  189. #pragma once
  190. #define _WINSOCKAPI_ // stop windows.h including winsock.h
  191.  
  192. #pragma comment(lib,"botan.lib")
  193. #include<iostream>
  194. //BOTAN
  195. #include<botan/tls_server.h>
  196. #include <botan/tls_client.h>
  197. #include <botan/tls_callbacks.h>
  198. #include <botan/tls_session_manager.h>
  199. #include <botan/tls_policy.h>
  200. #include <botan/auto_rng.h>
  201. #include <botan/certstor.h>
  202. #include <botan/pk_keys.h>
  203. #include<botan/hex.h>
  204. #include<botan/certstor.h>
  205. #include<botan/pkcs8.h>
  206. #include<botan/data_src.h>
  207. #pragma comment(lib,"ws2_32.lib")
  208. #include<WinSock2.h>
  209. #include<fstream>
  210.  
  211. #include"DTLSPolicy.hpp"
  212.  
  213.  
  214.  
  215. class Server_Credentials : public Botan::Credentials_Manager
  216. {
  217. private:
  218.     std::unique_ptr<Botan::Private_Key> m_key;
  219. //  Botan::DataSource_Stream stream;
  220.     std::ifstream file;
  221. public:
  222.     Server_Credentials()
  223.     {
  224.     }
  225.  
  226.     std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(
  227.         const std::string& type,
  228.         const std::string& context) override
  229.     {
  230.         // if client authentication is required, this function
  231.         // shall return a list of certificates of CAs we trust
  232.         // for tls client certificates, otherwise return an empty list
  233.         return std::vector<Botan::Certificate_Store*>();
  234.     }
  235.  
  236.     std::vector<Botan::X509_Certificate> cert_chain(
  237.         const std::vector<std::string>& cert_key_types,
  238.         const std::string& type,
  239.         const std::string& context) override
  240.     {
  241.         // return the certificate chain being sent to the tls client
  242.         // e.g., the certificate file "botan.randombit.net.crt"
  243.         return { Botan::X509_Certificate("botan.randombit.net.crt") };
  244.     }
  245.  
  246.     Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert,
  247.         const std::string& type,
  248.         const std::string& context) override
  249.     {
  250.         // return the private key associated with the leaf certificate,
  251.         // in this case the one associated with "botan.randombit.net.crt"
  252.         return &*m_key;
  253.     }
  254.  
  255.  
  256. };
  257.  
  258. class DTLS : public Botan::TLS::Callbacks
  259. {
  260. public:
  261.     DTLS(const std::string& ip, unsigned int port, Botan::TLS::Policy& policy);
  262.     ~DTLS();
  263.  
  264.     void startReceiving();
  265.     void tls_emit_data(const uint8_t buf[], size_t length) override {
  266.         sendto(this->servSocket, (char*)buf, length, 0, (SOCKADDR*)& this->clientAddr, sizeof(SOCKADDR_IN));
  267.         startReceiving();
  268.     }
  269.  
  270.     void tls_alert(Botan::TLS::Alert alert) override {
  271.         std::cout << alert.type_string();
  272.     }
  273.  
  274.     void tls_record_received(uint64_t seq_no, const uint8_t input[], size_t length) override {
  275.         std::string t = "";
  276.         for (size_t i = 0; i < length; ++i) {
  277.             t += static_cast<char>(input[i]);
  278.  
  279.             if (t[t.length() - 1] == '\t') {
  280.                 std::cout << t << '\n';
  281.                 t.clear();
  282.             }
  283.         }
  284.     }
  285.  
  286.     bool tls_session_established(const Botan::TLS::Session& session) override {
  287.         std::cout << "DETAILS:\n"
  288.             << "SESSION ID=" << Botan::hex_encode(session.session_id()) << '\n'
  289.             << "Session Ticket=" << Botan::hex_encode(session.session_ticket()) << '\n';
  290.         return true;
  291.     }
  292.  
  293.  
  294.  
  295. private:
  296.     Botan::AutoSeeded_RNG rng;
  297.     Botan::TLS::Session_Manager_In_Memory session_mgr;
  298.     Botan::Credentials_Manager creds;
  299.     Botan::TLS::Policy policy;
  300.     Botan::TLS::Server server;
  301.     SOCKET servSocket;
  302.     SOCKADDR_IN servAddr;
  303.     SOCKADDR_IN clientAddr;
  304. };
  305.  
  306. //END
  307.  
  308. /***
  309.         DTLS.cpp
  310. ***/
  311. #include "DTLS.hpp"
  312. #include<botan/exceptn.h>
  313.  
  314. #include<ws2tcpip.h>
  315.  
  316. DTLS::DTLS(const std::string& ip, unsigned int port, Botan::TLS::Policy& policy) : policy(policy),session_mgr(this->rng), server(*this,this->session_mgr,this->creds,this->policy,this->rng,true)
  317. {
  318.     WSAData d;
  319.     WSAStartup(MAKEWORD(2, 0), &d);
  320.     this->servSocket = socket(AF_INET, SOCK_DGRAM, 0);
  321.     this->servAddr.sin_family = AF_INET;
  322.     this->servAddr.sin_port = htons(port);
  323.     char addr[666];
  324.     if (ip != "ANY")
  325.         this->servAddr.sin_addr.S_un.S_addr = ADDR_ANY;
  326.     else
  327.         this->servAddr.sin_addr.S_un.S_addr = ADDR_ANY;
  328.     auto rc = bind(this->servSocket, (SOCKADDR*)& this->servAddr, sizeof(SOCKADDR_IN));
  329. #ifndef _NO_DEBUG
  330.     if (rc == SOCKET_ERROR)
  331.         std::cout << "COULD NOT BIND!\n";
  332.     else
  333.         std::cout << "SUCCESSFULLY SOCKET BIND\n";
  334. #endif
  335.  
  336. }
  337.  
  338.  
  339. DTLS::~DTLS()
  340. {
  341.     WSACleanup();
  342. }
  343.  
  344. void DTLS::startReceiving()
  345. {
  346.     try {
  347.         uint8_t buffer[1024];
  348.         memset(buffer, 0, sizeof(buffer));
  349.         int size = sizeof(SOCKADDR_IN);
  350.         auto rc = recvfrom(this->servSocket, (char*)buffer, sizeof(buffer), 0, (SOCKADDR*)& this->clientAddr, &size);
  351.         buffer[rc] = '\0';
  352.         std::cout << buffer << '\n';
  353.         this->server.received_data(buffer, rc);
  354.     }
  355.     catch (Botan::Exception & ex) {
  356.         std::cout << ex.what();
  357.         system("pause");
  358.     }
  359. }
  360. //END
  361.  
  362. /***
  363.     Quelle.cpp TESTMAIN
  364. ***/
  365.  
  366. #include"DTLS.hpp"
  367.  
  368. int main() {
  369.     DTLSPolicy policy(DTLSVersion::DTLS_ANY);
  370.     policy.setOption(DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_CIPHERS, std::vector<std::string>(ACCEPT_ALL_CIPHERS.begin(), ACCEPT_ALL_CIPHERS.end()));
  371.     policy.setOption(DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_MACS, std::vector<std::string>(ACCEPT_ALL_MACS.begin(), ACCEPT_ALL_MACS.end()));
  372.     policy.setOption(DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOWED_SIGNATURE_HASHES, std::vector<std::string>(ACCEPT_ALL_SIGNATURE_HASHES.begin(), ACCEPT_ALL_SIGNATURE_HASHES.end()));
  373.     policy.setOption(DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOW_KEY_EXCHANGE_METHODS, std::vector<std::string>(ACCEPT_ALL_KEY_EXCHANGE_METHODS.begin(), ACCEPT_ALL_KEY_EXCHANGE_METHODS.end()));
  374.     policy.setOption(DTLSPolicy::DTLSPolicyOptions::DTLS_OPTION_SET_ALLOW_SIGNATURE_METHODS, std::vector<std::string>(ACCEPT_ALL_SIGNATURE_METHODS.begin(), ACCEPT_ALL_SIGNATURE_METHODS.end()));
  375.     Botan::TLS::Default_Policy p;
  376.     DTLS test("192.168.1.119", 999,p);
  377.     while (true) {
  378.         test.startReceiving();
  379.         Sleep(500);
  380.     }
  381.     system("pause");
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement