UDP-WG Implementation
Loading...
Searching...
No Matches
crypto::string Class Reference

A cryptographically secure string. More...

#include <crypto.h>

Public Member Functions

 string (const size_t &l=0)
 Construct a string with a fixed, zeroed size.
 
 string (const std::string &string)
 Construct a string from a std::string.
 
 string (const unsigned char *string, const size_t &l)
 Construct a string from a character array and size.
 
 string (const char *string)
 Construct a string from a character array.
 
 ~string ()
 Destroy the string.
 
string substr (const size_t &start, const size_t &count=std::string::npos) const
 Return a subset of the string.
 
void resize (const size_t &n, const unsigned char &v=0)
 Resize the string.
 
void append (const string &s)
 Append another string to end of the caller.
 
std::string str ()
 Return a hexadecimal representation of the crypto::string.
 
const size_t length () const
 Return the length of the string.
 
unsigned char * bytes ()
 Return a mutable byte array that can be directly manipulated.
 
const unsigned char * bytes () const
 Return a immutable byte array of the internal values.
 
std::string to () const
 Return a std::string representation of the string.
 
unsigned char & operator[] (const size_t &pos)
 Index the string.
 
const bool operator== (const string &cmp) const
 Equivalence operator.
 
string operator+ (const string &a) const
 Concatonation operator.
 

Detailed Description

A cryptographically secure string.

Remarks
Originally, the reason for this class' existence was because OpenSSL deals with unsigned characters, whereas the std::string deals with signed. Usually C++ is nice and will implicitly cast types, but apparently there are irreconciable differences between how these two datatypes are stored, and as such the ISO forbids implicit casting. Therefore, this object was little more than a std::string imitator that implemented the key functions, but with unsigned characters in the back, and with the ability to easily convert back and forth. However, this object quickly became ubiqutous, to the point that there was no reason to convert back to std::string. This provides an opportunity to make the object more cryptographically secure. In essence, all it does is zero any information that was stored in it during its destruction. I toyed with encrypting the stored data, perhaps using the time or something similar, but also didn't want to over complicated something that isn't the main focus of this project. I bring this up because it's strongly recommended not to use interpereted languages like Python or Shell Scripting Languages like Bash for cryptographic implementations, chiefly because their abstraction of memory makes it difficult to wipe sensitive data.

Constructor & Destructor Documentation

◆ string() [1/4]

crypto::string::string ( const size_t & l = 0)
inline

Construct a string with a fixed, zeroed size.

Parameters
lThe size of the object (It can still grow/shrink, but this allows us to pass it into memcpy where it expects a certain size).
Remarks
This is the wonderful reason why we can do crypto::string a = 32, and have a 32 byte string.

◆ string() [2/4]

crypto::string::string ( const std::string & string)
inline

Construct a string from a std::string.

Parameters
stringThe string.

◆ string() [3/4]

crypto::string::string ( const unsigned char * string,
const size_t & l )
inline

Construct a string from a character array and size.

Parameters
stringThe input string.
lThe size of the string.
Warning
This function does not check if the provided size is bounded by the size of the string!

◆ string() [4/4]

crypto::string::string ( const char * string)
inline

Construct a string from a character array.

Parameters
stringThe input string.
Remarks
This function is used for constructing from string literals IE crypto::string a = "Hello!";
Warning
This function uses strlen to determine length. If your string is not null terminated, this function will read out of bounds!

◆ ~string()

crypto::string::~string ( )
inline

Destroy the string.

Remarks
Zeros the content.
A brief aside on memory management, and an interesting feature of the STL (Or, in other words, skip this if you don't want to read a wall of C++ semantics) One utility that I use for every C/C++ program is Valgrind; basically, the dynamic memory allocators like malloc/calloc/realloc are prone to erroneous use, and this program will run underneath the one you've created, hooking those functions and reporting when you use them incorrectly (Failing to free dynamic memory, trying to free it twice, etc). These functions are often pointed to when people claim that C/C++ is a antiquated language, recommending instead the ridiculously slow Python, or the ridiculously convulted ownership/reference system of Rust (I speak from personal experience on both counts). In my, truthfully biased opinion, I don't consider this argument particularly compelling, because the dynamic memory functions work excellently, and errors arise not because of the language, but because of the the programmer using it. All that said, if you run Valgrind with this program, you'll notice some strange "Still Accessible" remarks, which technically aren't errors, or anything to worry about, but they all come from this class. I found this exceptionally confusing, because we don't use any dynamic allocators, we use the std::vector specifically to avoid manual memory handling. Turns out, one reason that the STL classes are so fast is because they pool memory between each other. In essence, the STL will create a a massive pool of memory allocated in one massive block at the start of the program run, and then everything from std::string, std::list, std::queue, and std::any will draw upon this pool, and will "free" it by simply setting it to nullptr. This is brilliant, not only because it could be done by something so prolifically used as the STL, but because it ensures a single allocation and free, effectively eliminating the issue of memory leaking, while improving performance. The only downside of this approach is that Valgrind wasn't built to understand this, so when the std::vector calls its destructor, Valgrind notices that there's still a handle to this pool, which could be indicative of having two pointers to the same dynamic address, freeing one, and then trying to access that freed memory with the second (Exceptionally bad).

Member Function Documentation

◆ append()

void crypto::string::append ( const string & s)
inline

Append another string to end of the caller.

Parameters
sThe string to append.

◆ bytes() [1/2]

unsigned char * crypto::string::bytes ( )
inline

Return a mutable byte array that can be directly manipulated.

Returns
The beginning of the string.
Remarks
This relies on the fact that vector's store their information contiguously: https://en.cppreference.com/w/cpp/container/vector

◆ bytes() [2/2]

const unsigned char * crypto::string::bytes ( ) const
inline

Return a immutable byte array of the internal values.

Returns
The byte array.
Remarks
Typically, function overloads (IE two functions with identical names) Cannot be solely distinguished by return type. This makes sense, because if you have two functions A(), and do something like auto ret = A(), the compiler has no way to know which version you wanted. However, constant overloads allow this. In essence, this function just means, if the crypto::string is a constant value (IE const std::crypto my_string), then rather than returning a mutable character array (Which would circumvent the constant qualifier, and thus the compiler would refuse it), we return a constant pointer.

◆ length()

const size_t crypto::string::length ( ) const
inline

Return the length of the string.

Returns
The length.

◆ operator+()

string crypto::string::operator+ ( const string & a) const
inline

Concatonation operator.

Parameters
aThe string to append.
Returns
The caller concatenated with the input.

◆ operator==()

const bool crypto::string::operator== ( const string & cmp) const
inline

Equivalence operator.

Parameters
cmpThe string to compare against.
Returns
Whether the strings are equal.

◆ operator[]()

unsigned char & crypto::string::operator[] ( const size_t & pos)
inline

Index the string.

Parameters
posThe position.
Returns
The mutable byte at that position.
Exceptions
std::out_of_rangeif the position is out of bounds.

◆ resize()

void crypto::string::resize ( const size_t & n,
const unsigned char & v = 0 )
inline

Resize the string.

Parameters
nThe new size.
vThe character to use to fill new spaces

◆ str()

std::string crypto::string::str ( )
inline

Return a hexadecimal representation of the crypto::string.

Returns
The hex string.

◆ substr()

string crypto::string::substr ( const size_t & start,
const size_t & count = std::string::npos ) const
inline

Return a subset of the string.

Parameters
startThe left bound
countThe amount of characters to read from the left bound. std::string::npos means everything until the end of the string.
Returns
The substring.

◆ to()

std::string crypto::string::to ( ) const
inline

Return a std::string representation of the string.

Returns
The string.

The documentation for this class was generated from the following file: