NAWA 0.9
Web Application Framework for C++
encoding_crypto.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019-2022 Tobias Flaig.
3 *
4 * This file is part of nawa.
5 *
6 * nawa is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License,
8 * version 3, as published by the Free Software Foundation.
9 *
10 * nawa is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with nawa. If not, see <https://www.gnu.org/licenses/>.
17 */
18
24#include <catch2/catch.hpp>
26#include <nawa/util/crypto.h>
27#include <nawa/util/encoding.h>
28#include <sstream>
29
30using namespace nawa;
31using namespace std;
32
33namespace {
34 bool isInputDataInitialized = false;
35 vector<string> inputData;
36
43 std::string genRandomUnicode(size_t len, unsigned int rseed) {
44 const char cl[][50] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
45 "s", "t", "u", "v", "w", "x", "y", "z", " ", "\t", "<", ">", "\"", "=", "ä", "ö", "ü",
46 "ß",
47 "é", "ó", "ú", "𝔸", "@", "#", "$", "€", "?", "!", "/", "\\", "-", "~"};
48 stringstream ret;
49 default_random_engine dre(rseed);
50 uniform_int_distribution<size_t> distribution(0, 49);
51 for (size_t i = len; i > 0; --i) {
52 ret << cl[distribution(dre)];
53 }
54 return ret.str();
55 }
56
57 void initializeInputDataIfNotYetDone() {
58 if (isInputDataInitialized) {
59 return;
60 }
61 for (unsigned int rseed = 0; rseed < 10; ++rseed) {
62 inputData.push_back(genRandomUnicode(100, rseed));
63 }
64 isInputDataInitialized = true;
65 }
66}// namespace
67
68TEST_CASE("nawa::encoding functions", "[unit][encoding]") {
69 SECTION("punycode encoding") {
70 string punycodeEncoded = "xn--bcher-kuflich-erwrben-c2b9jut.xy";
71 string punycodeDecoded = "bücher-käuflich-erwérben.xy";
72 string asciiDomain = "example.com";
73 CHECK(encoding::punycodeEncode(punycodeDecoded) == punycodeEncoded);
74 CHECK(encoding::punycodeDecode(punycodeEncoded) == punycodeDecoded);
75 CHECK(encoding::punycodeEncode(asciiDomain) == asciiDomain);
76 }
77
78 initializeInputDataIfNotYetDone();
79 string decoded = GENERATE(from_range(inputData));
80
81 SECTION("HTML encoding") {
82 string htmlDecoded = R"(<input type="text" value="tä𝔸𝔸𝔸st">)";
83 string htmlEncoded = encoding::htmlEncode(htmlDecoded, true);
84 string htmlEncoded2 = R"(&lt;input type=&quot;text&quot; value=&quot;t&auml;&Aopf;&#x1D538;&#120120;st&quot;&gt;)";
85 CHECK(htmlEncoded.length() > htmlDecoded.length());
86 CHECK(encoding::htmlDecode(htmlEncoded) == htmlDecoded);
87 CHECK(htmlDecoded == encoding::htmlDecode(htmlEncoded2));
88 string htmlEncodedRand = encoding::htmlEncode(decoded, true);
89 string htmlEncodedRand2 = encoding::htmlEncode(decoded, false);
90 CHECK(encoding::htmlDecode(htmlEncodedRand) == decoded);
91 CHECK(encoding::htmlDecode(htmlEncodedRand2) == decoded);
92 }
93
94 SECTION("URL encoding") {
95 string urlDecoded = "bla bla bla!??xyzäßédsfsdf ";
96 auto urlEncoded = encoding::urlEncode(urlDecoded);
97 auto urlEncodedRand = encoding::urlEncode(decoded);
98 CHECK(encoding::urlDecode(urlEncoded) == urlDecoded);
99 CHECK(encoding::urlDecode(urlEncodedRand) == decoded);
100 }
101
102 SECTION("Base64 encoding") {
103 auto base64Encoded = encoding::base64Encode(decoded, 80, "\r\n");
104 CHECK(encoding::isBase64(base64Encoded, true));
105 CHECK(encoding::base64Decode(base64Encoded) == decoded);
106 }
107
108 SECTION("quoted-printable encoding") {
109 auto quotedPrintableEncoded = encoding::quotedPrintableEncode(decoded);
110 auto quotedPrintableEncodedWithUnixLineEnding = encoding::quotedPrintableEncode(decoded, "\n");
111 auto quotedPrintableEncodedReplaceCrlf = encoding::quotedPrintableEncode(decoded, "\r\n", true);
112 auto qEncoded = encoding::quotedPrintableEncode(decoded, "\r\n", false, true);
113 auto qEncodedReplaceCrlf = encoding::quotedPrintableEncode(decoded, "\r\n", true, true);
114 CHECK(encoding::quotedPrintableDecode(quotedPrintableEncoded) == decoded);
115 CHECK(encoding::quotedPrintableDecode(quotedPrintableEncodedWithUnixLineEnding) == decoded);
116 CHECK(encoding::quotedPrintableDecode(quotedPrintableEncodedReplaceCrlf) == decoded);
117 CHECK(encoding::quotedPrintableDecode(qEncoded, true) == decoded);
118 CHECK(encoding::quotedPrintableDecode(qEncodedReplaceCrlf, true) == decoded);
119 }
120}
121
122TEST_CASE("nawa::crypto functions", "[unit][crypto]") {
123 initializeInputDataIfNotYetDone();
124 string decoded = GENERATE(from_range(inputData));
125
126 SECTION("bcrypt password hashing") {
127 auto hashedPw = crypto::passwordHash(decoded, hashing::BcryptHashingEngine(8));
128 CHECK(crypto::passwordVerify(decoded, hashedPw));
129 }
130
131 SECTION("argon2 password hashing") {
132 auto hashedPw = crypto::passwordHash(decoded,
134 hashing::Argon2HashingEngine::Algorithm::ARGON2ID, 2, 1 << 16,
135 2, "", 40));
136 auto hashedPw_i = crypto::passwordHash(decoded,
138 hashing::Argon2HashingEngine::Algorithm::ARGON2I));
139 auto hashedPw_d = crypto::passwordHash(decoded,
141 hashing::Argon2HashingEngine::Algorithm::ARGON2D));
142 CHECK(crypto::passwordVerify(decoded, hashedPw));
143 CHECK(crypto::passwordVerify(decoded, hashedPw_i));
144 CHECK(crypto::passwordVerify(decoded, hashedPw_d));
145 }
146}
A bunch of useful cryptographic functions (esp. hashing), acting as a wrapper to C crypto libraries.
Namespace containing functions for text encoding and decoding.
TEST_CASE("nawa::encoding functions", "[unit][encoding]")
bool passwordVerify(std::string const &password, std::string const &hash, hashing::HashTypeTable const &hashTypeTable=hashing::DefaultHashTypeTable())
Definition: crypto.cpp:110
std::string passwordHash(std::string const &password, hashing::HashingEngine const &hashingEngine=hashing::BcryptHashingEngine())
Definition: crypto.cpp:105
std::string base64Decode(std::string const &input)
Definition: encoding.cpp:286
std::string quotedPrintableDecode(std::string input, bool qEncoding=false)
Definition: encoding.cpp:320
std::string base64Encode(std::string const &input, size_t breakAfter=0, std::string const &breakSequence="")
Definition: encoding.cpp:281
std::string quotedPrintableEncode(std::string const &input, std::string const &lineEnding="\r\n", bool replaceCrlf=false, bool qEncoding=false)
Definition: encoding.cpp:290
std::string punycodeEncode(std::string const &input)
Definition: encoding.cpp:355
std::string punycodeDecode(std::string const &input)
Definition: encoding.cpp:380
std::string urlEncode(std::string const &input)
Definition: encoding.cpp:238
bool isBase64(std::string const &input, bool allowWhitespaces=true)
Definition: encoding.cpp:270
std::string urlDecode(std::string input)
Definition: encoding.cpp:256
std::string htmlEncode(std::string input, bool encodeAll=false)
Definition: encoding.cpp:133
std::string htmlDecode(std::string input)
Definition: encoding.cpp:185
Definition: AppInit.h:31