Discuss this help topic in SecureBlackbox Forum
Building and using C++ classes in C++ applications
C/C++ edition consists of the dynamic library (static library for Mac OS and iOS), stored in <SecureBlackbox>\Libraries folder, and wrappers, stored in <SecureBlackbox>\WrapperSources\cpp and <SecureBlackbox>\WrapperSources\include folders.
There are two ways to build C++ applications using these libraries:
The script for building the static library can be found in <SecureBlackbox>\WrapperSources\Makefile.cmd for Windows, and in <SecureBlackbox>\WrapperSources\makefile.sh for other platforms.
Using static library in macOS and iOS
When using the static library on macOS and iOS, you need to link "libresolv" library to your project. Functions from this library are used by the low-level socket code of SecureBlackbox.
Using dynamic library in macOS
When using the dynamic library on macOS, it is a good idea to change its default install path, or put the library in the default location to prevent build errors.
You can use the otool utility in the terminal to check the library paths. If called in the following way:
otool -L <<path where the SBB archive has been unpacked>>/secbboxcpp_mac-110244/Libraries/MacOS64/libsbb.dylibit returns multiple results. The first entry is what you need, it contains the current installation path to the libsbbphp.dylib. Alternatively, to get only the path to the libsbbphp.dylib:
otool -D <<path where the SBB archive has been unpacked>>/secbboxcpp_mac-110244/Libraries/MacOS64/libsbb.dylib libsbb.dylibUse the following comand to change this path:
install_name_tool -id "<new_path>/libsbb.dylib" <current path>/libsbb.dylib
Building the static library with Microsoft Visual C++
To use C++ edition with Microsoft Visual C++ you need:
1. Build a static library from *.cpp wrapper files by running "<SecureBlackbox>\WrapperSources\Makefile.cmd vc".
The script finds and uses the latest version of VC++.
If you installed VC++ in a different location than the default "Program Files (x86)" or "Program Files",
then you would need to create/set "VC_PATH" environment variable and assign the path to VC++ to this variable.
By default the static library is built with the "Multi-threaded DLL (/MD)" option on.
If you are building your application with another setting (for example, with "Multi-threaded (/MT)" option),
then you need to either set "TGT" environment variable to "STATIC", or modify CPPFLAGS variable in "Makefile.vc" file.
2. To use the static library, you need to modify the configuration properties of your project in the following way:
Using the static library with Microsoft Visual C++
All classes, functions and types are defined in the namespace SecureBlackbox. All functions in C++ may throw exceptions of type SBException. Some functions in C don't have analogous C++ functions that throw exceptions. To check the status of such function, just call SBCheckError(func()), for example:
try
{
SetLicenseKey("AC...30");
}
catch (SBException E)
{
std::cout << "Failed to set license key: " << E.what() << std::endl;
}
Every wrapper class has its own handle, which is just a reference to the wrapped class, and a flag that defines whether to free the wrapped class when the wrapper is disposed.
Examples of class creation:
TElSimpleSSHClient Client (NULL);
TElX509Certificate Cert (handle, false);
As C++ does not support such concept as object's property, the corresponding put_ and get_ pseudonyms should be used to access the properties:
Client.set_Address(address);
port = Client.get_Port();
Properties that return an object, return its reference:
TElPDFSignature *Sig = Document.get_Signatures(index);
Sig->set_Handler(PublicKeyHandler);
Note that after a next call to the property, the reference may change.
Methods that return an object, return its handle:
TElXMLDOMElementHandle h = doc.CreateElement("root");
TElXMLDOMElement El (h, false);
doc.AppendChild(El);
Both native and SecureBlackbox streams may be used. TElCallbackStream is used as a proxy for native streams, for example:
std::fstream fs;
fs.open (filename.c_str(), std::ios::binary | std::ios::in | std::ios::out);
if (fs.is_open())
{
TElCallbackStream cs (fs);
// pass "cs" stream as a parameter
fs.close();
}
Example of using internal streams:
try
{
TFileStream fs(filename, fmOpenReadWrite);
// pass "fs" stream as a parameter
}
catch (SBException E)
{
std::cout << E.what() << std::endl;
}
Setting of a callback function consists of setting the function reference and setting the object reference, e.g.:
Client.set_OnKeyValidate(&Client_OnKeyValidate, NULL);
void SB_CALLBACK Client_OnKeyValidate(void * /* objData */, TObjectHandle /* hSender */, TElSSHKeyHandle hServerKey, int8_t * Validate)
{
try
{
TElSSHKey ServerKey (hServerKey, false);
TMessageDigest128 M128;
ServerKey.get_FingerprintMD5(M128);
std::string dgst;
DigestToStr(M128, true, dgst);
std::cout << "Server key received, fingerprint " << dgst << std::endl;
*Validate = true; // NEVER do this. You MUST check the key validity somehow
}
catch (SBException E)
{
std::cout << E.what() << std::endl;
*Validate = false;
}
}