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:

  • add the corresponding header and cpp files to the application sources;
  • build a static library from the corresponding header and source files, and add it to the project together with the header files.
In both cases, the main library for the corresponding platform is needed (either a dynamic or a static one). The first way allows to optimize the size of the resulting application by excluding the unnecessary files and classes. The second way simplifies the application development.

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.dylib
	
it 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.dylib
	
Use 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:

  • modify the Include Directories (IncludePath) option and add "<SecureBlackbox>\WrapperSources\include\all;<SecureBlackbox>\WrapperSources\include" to it;
  • modify the Library Directories (LibraryPath) option and add "<SecureBlackbox>\WrapperSources\" to it;
  • modify the Additional Dependencies option and add "libsbbimp.lib" to it.

Finally, either copy the dynamic library "<SecureBlackbox>\Libraries\All\Win32\libsbb.dll" to the same directory, where your compiled EXE file is placed by the compiler, or adjust the system PATH variable to include the location of this DLL.

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;
}
	
	

General instructions of using C++ edition

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;
	}
}
	
	

Discuss this help topic in SecureBlackbox Forum