Utility Functions

The libc2pa library provides the following utility functions for your convenience.

build_exif_gps_float_string()

Creates the JSON string to pass to the add_assertion() method when specifying GPS coordinates.

  • double longitude_degrees - The longitude coordinate, in degrees.
  • double latitude_degrees - The latitude coordinate, in degrees.
  • double altitude - The altitude above the reference ellipsoid, in meters.
  • double horizontal_accuracy - The radius of the margin of error, in meters.
  • long long time - UTC timestamp since epoch, in seconds.
#include "common/common_utils.hpp"

builder->add_assertion(
  "metadata",
  common_utils::build_exif_gps_float_string(
    -74.16229075664843,
    40.38991694141019,
    534.123,
    25.0,
    1635091732
  )
);

build_exif_make_model_string()

Creates the JSON string to pass to the add_assertion() method when specifying the make and model of the device.

  • std::string make - The name of the device maker.
  • std::sting model - The name of the device model.
#include "common/common_utils.hpp"

builder->add_assertion(
  "metadata",
  common_utils::build_exif_make_model_string(
    "Google",
    "Pixel 7"
  )
);

build_exif_date_time_original_string()

Creates the JSON string to pass to the add_assertion() method when specifying a timestamp for when the image was created.

  • std::string date_time - The timestamp should be specified in the format: YYYY-MM-DDThh:mm:ssZ. For example, 2020-09-24T10:40:18Z.
#include "common/common_utils.hpp"

builder->add_assertion(
  "metadata",
  common_utils::build_exif_date_time_original_string("2020-09-24T10:40:18Z")
);

can_generate_thumbnail_for_file()

Buffer version

As of v3.8.7

Returns a boolean indicating whether or not the library is capable of generating a thumbnail for the input file. This capability varies with compilation flags, and library version.

  • std::vector<unit8_t> data - The file (as a byte array) to check for thumbnail support.
#include "common/common_utils.hpp"

auto thumbnail_supported = common_utils::can_generate_thumbnail_for_file(file_bytes);

can_generate_thumbnail_for_file()

Stream version

As of v3.8.7

Returns a boolean indicating whether or not the library is capable of generating a thumbnail for the input file. This capability varies with compilation flags, and library version.

  • std::istream data - The file (as an input stream) to check for thumbnail support.
#include "common/common_utils.hpp"

auto thumbnail_supported = common_utils::can_generate_thumbnail_for_file(file_data_stream);

can_generate_thumbnail_for_file()

File version

As of v3.8.7

Returns a boolean indicating whether or not the library is capable of generating a thumbnail for the input file. This capability varies with compilation flags, and library version.

  • std::string file_path - The path to the file to check for thumbnail support.
#include "common/common_utils.hpp"

auto thumbnail_supported = common_utils::can_generate_thumbnail_for_file("file.jpg");

can_generate_thumbnail_for_file()

Asset version

As of v4.0.15

Returns a boolean indicating whether or not the library is capable of generating a thumbnail for the input file. This capability varies with compilation flags, and library version.

  • c2pa::ReadOnlyAssetPtr asset - An Asset object representing the file to check for thumbnail support.
#include "common/common_utils.hpp"

auto thumbnail_supported = common_utils::can_generate_thumbnail_for_file(jpeg_asset);

check_c2pa_file_type()

This will read the provided media file and return a c2pa_file_type indicating the media format. Possible return values are:

  • JPEG
  • PNG
  • BMFF
  • RIFF
  • NotSupported

There are three forms of this method: buffer, stream, and file.

Buffer version

  • uint8_t* data - A pointer to the raw media data buffer.
  • unsigned long data_size - The size of the media data buffer.
#include "common/common_utils.hpp"

auto file_type  = common_utils::check_file_type(data, data_size);

Stream version

  • std::istream data - An input stream containing the raw media data.
#include "common/common_utils.hpp"

auto file_type  = common_utils::check_file_type(data_stream);

File version

  • std::string file_path - A path to the media file.
#include "common/common_utils.hpp"

auto file_type  = common_utils::check_file_type("images/image.jpg");

Asset version

As of v4.0.15
  • c2pa::ReadOnlyAssetPtr asset - An Asset object representing the media file.
#include "common/common_utils.hpp"

auto file_type  = common_utils::check_file_type("images/image.jpg");

extract_ecdsa_der_signature()

Many signing platforms return a DER structure when performing an ECDSA signature. The COSE specification requires that ECDSA signatures be simply the R and S values (result of the signing operation) concatenated together. This helper function can convert an ECDSA digest in DER format into the proper format needed for a C2PA signature.

  • std::vector<uint8_t> der_signature - The signature digest in DER format.
  • std::vector<uint8_t>& signature - A buffer to store the converted signature digest into.
#include "external/ECDSA_utils.hpp"

std::vector<uint8_t> signature;
extract_ecdsa_der_signature(der_signature, signature);

format_now()

Returns a std::string containing the current time in the format: YYYY-MM-DDThh:mm:ssZ. For example, 2020-09-24T10:40:18Z.

#include "common/common_utils.hpp"

auto date_time = common_utils::format_now();

format_time()

Returns a std::string containing the provided time in the format: YYYY-MM-DDThh:mm:ssZ. For example, 2020-09-24T10:40:18Z. There are two versions of the function. One takes a std::tm as input, and the other takes a time_t as input.

The time_t version converts the provided time (seconds since epoch) from the local timezone to UTC time before formatting it.

#include "common/common_utils.hpp"

auto now = std::time(nullptr);
auto date_time = common_utils::format_time(now);

get_c2pa_library_version()

Returns a std::string containing the version of libc2pa.

#include "common/common_utils.hpp"

auto version = common_utils::get_c2pa_library_version();

get_certificate_validity_range()

Parses the provided X509 certificate and returns a cert_validity_range structure containing two fields: not_before and not_after.

  • std::vector<uint8_t>* cert_der - A pointer to a buffer containing an X509 certificate in DER format.
#include "common/common_utils.hpp"

auto validity_range = common_utils::get_certificate_validity_range(cert_der);

get_ecdsa_certificate()

Provides a self-signed, short-term certificate that matches the private key used by sign_with_ecdsa(). The certificate will expire 20 minutes after this function is called. It is returned as a std::vector<uint8_t> byte buffer containing an X509 certificate in DER format.

#include "C2PA/client_signers.hpp"

auto certificate = get_ecdsa_certificate();

get_RFC4112_UUID()

Returns a std::string containing a generated GUID.

#include "common/common_utils.hpp"

auto guid = common_utils::get_RFC4112_UUID();

get_rsa_pss_certificate()

Provides a self-signed, short-term certificate that matches the private key used by sign_with_rsa_pss(). The certificate will expire 20 minutes after this function is called. It is returned as a std::vector<uint8_t> byte buffer containing an X509 certificate in DER format.

#include "C2PA/client_signers.hpp"

auto certificate = get_rsa_pss_certificate();

get_x509_certificate_from_pkcs7()

As of v3.8.2

PKCS#7 is an ASN.1 "wrapper" that can be used to encapsulate one or more certificates. This function will extract an X509 certificate from a PKCS#7 structure and return it as a std::vector<uint8_t> byte buffer of DER data.

NOTE: If there is more than one certificate in the PKCS#7 structure then this function will only return the first certificate found.

  • std::vector<uint8_t> in_der - The PKCS#7 structure, in DER format.
#include "common/common_utils.hpp"

auto certificate = common_utils::get_x509_certificate_from_pkcs7(cert_der);

JSONErrorFormatter::FormatError()

Converts a common::runtime_error_with_context into a std::string in JSON format. See libc2pa Exceptions.

#include "common/JSONErrorFormatter.hpp"

try {
  ...
} catch (common::runtime_error_with_context& e) {
  std::cerr << JSONErrorFormatter::FormatError(e) << std::endl;
}

load_certificate_chain_from_pem_file()

Reads in a sequence of X509 certificates from a PEM file on disk and converts it to an array of buffers, each containing one X509 certificate in DER format.

  • std::string file_path - A path to the PEM file to read.
  • std::vector<std::vector<uint8_t>>& cert_chain - A vector of vectors to store the DER bytes into.
#include "common/common_utils.hpp"

std::vector<std::vector<uint8_t>> cert_chain;
common_utils::load_certificate_chain_from_pem_file(
  "pki/cert_chain.pem",
  cert_chain
);

load_certificate_from_pem_file()

Reads in an X509 certificate from a PEM file on disk and converts it to a buffer containing the X509 data in DER format.

  • std::string file_path - A path to the PEM file to read.
  • std::vector<uint8_t>& cert_der - A vector to store the DER bytes into.
#include "common/common_utils.hpp"

std::vector<uint8_t> cert_der;
common_utils::load_certificate_from_pem_file(
  "pki/cert.pem",
  cert_der
);

load_private_key_from_pem_file()

Reads in a private key from a PEM file on disk and converts it to a buffer containing the private key in DER format. It also returns the type of key found. Possible return values are C2PA_KEY_TYPE_RSA and C2PA_KEY_TYPE_ECDSA.

  • std::string file_path - A path to the PEM file to read.
  • std::vector<uint8_t>& key_der - A vector to store the DER bytes into.
#include "common/common_utils.hpp"

std::vector<uint8_t> key_der;
auto key_type = common_utils::load_private_key_from_pem_file(
  "pki/private_key.pem",
  key_der
);

make_empty_tsa_request()

Provides a TSA request buffer that can be used to perform test calls to a TSA. This buffer is returned to the calling code as a std::vector<uint8_t> byte buffer.

#include "external/TSA_utils.hpp"

auto tsa_request = make_empty_tsa_request();

move_unique_to_shared()

Takes a std::unique_ptr as an input and moves it into a std::shared_ptr. Since this is a move operation, the original std::unique_ptr will be invalid after calling this function on it.

#include "common/common_utils.hpp"

auto shared = common_utils::move_unique_to_shared(unique);

parse_trusted_timestamp()

Parses a TSA response buffer received from a request to a TSA and returns the date and time contained in the response as a std::string in the format: YYYY-MM-DDThh:mm:ssZ. For example, 2020-09-24T10:40:18Z.

  • std::vector<uint8_t> tts - The TSA response buffer received in response to a POST request to the TSA.
#include "external/TSA_utils.hpp"

auto date_and_time = parse_trusted_timestamp(tsa_response);

post_tsa_request()

Sends a POST to the specified TSA with the provided request buffer as the body. It returns the response from the TSA as a std::vector<uint8_t> byte buffer.

  • std::string url - The URL of the TSA to send the request to.
  • std::vector<uint8_t> request - The TSA request buffer to send in the POST request.

This function will be unavailable if libc2pa has been compiled without libcurl support.

#include "C2PA/client_signers.hpp"

auto tsa_response = post_tsa_request("http://the.tsa.url", tsa_request);

post_tsa_request_to_truepic_staging()

Sends a POST to Truepic's "staging" TSA with the provided request buffer as the body. It returns the response from the TSA as a std::vector<uint8_t> byte buffer.

  • std::vector<uint8_t> request - The TSA request buffer to send in the POST request.

This function will be unavailable if libc2pa has been compiled without libcurl support.

#include "C2PA/client_signers.hpp"

auto tsa_response = post_tsa_request_to_truepic_staging(tsa_request);

sign_with_ecdsa()

Performs an ECDSA signing operation on the provided to-be-signed payload using the provided private key and algorithm. It returns the signature as a std::vector<uint8_t> byte buffer.

  • std::string algorithm - The digest algorithm to use. For example, sha256.
  • std::vector<uint8_t> to_be_signed - A buffer containing the payload to be signed.
  • std::vector<uint8_t> key_der - (Optional) The private key to use in the signing operation, in DER format. If not provided, then a private key matching the certificate returned from get_ecdsa_certificate() will be used.
#include "C2PA/client_signers.hpp"

auto signature = sign_with_ecdsa("sha256", payload, key_der);

sign_with_rsa_pss()

Performs an RSA-PSS signing operation on the provided to-be-signed payload using the provided private key and algorithm. It returns the signature as a std::vector<uint8_t> byte buffer.

  • std::string algorithm - The digest algorithm to use. For example, sha256.
  • std::vector<uint8_t> to_be_signed - A buffer containing the payload to be signed.
  • std::vector<uint8_t> key_der - (Optional) The private key to use in the signing operation, in DER format. If not provided, then a private key matching the certificate returned from get_rsa_pss_certificate() will be used.
#include "C2PA/client_signers.hpp"

auto signature = sign_with_rsa_pss("sha256", payload, key_der);