Verifiable Data Functions

#include <keychain/keychain_headers.h>

Overview

Verifiable data functions work with digitally signed data objects. A verifiable data object contains the original data along with one or more digital signatures (attestations) that can be verified to ensure data integrity and authenticity.

Object Lifecycle Functions

kc_verifiable_data_construct_from_serialized_data()

int kc_verifiable_data_construct_from_serialized_data(
    kc_verifiable_data_t** out_verifiable_data_ptr,
    const kc_serialized_data_t* serialized_data_ptr
)

Deserializes verifiable data from a serialized data object.

Parameters:

  • out_verifiable_data_ptr - Pointer to verifiable data pointer (output, caller must free)

  • serialized_data_ptr - Serialized data containing verifiable data

Returns: Error code (0 = success)

Example:

kc_serialized_data_t* serialized = NULL;
kc_verifiable_data_t* verifiable = NULL;

// Assume serialized contains verifiable data...
int result = kc_verifiable_data_construct_from_serialized_data(&verifiable, serialized);
if (result == 0) {
    // Use verifiable data...
    kc_verifiable_data_destruct(&verifiable);
}

kc_verifiable_data_construct_from_serialized_string()

int kc_verifiable_data_construct_from_serialized_string(
    kc_verifiable_data_t** out_verifiable_data_ptr,
    const char* serialized_string,
    const unsigned int serialized_string_size,
    const tkc_serialization_format serialization_format
)

Deserializes verifiable data from a string in the specified format.

Parameters:

  • out_verifiable_data_ptr - Pointer to verifiable data pointer (output, caller must free)

  • serialized_string - String containing serialized verifiable data

  • serialized_string_size - Length of the string

  • serialization_format - Format of the serialization (JSON, XML, or PROTOBUF)

Returns: Error code (0 = success)

kc_verifiable_data_destruct()

int kc_verifiable_data_destruct(kc_verifiable_data_t** verifiable_data_ptr)

Destructs a verifiable data object and frees its resources.

Parameters:

  • verifiable_data_ptr - Pointer to verifiable data pointer (set to NULL on success)

Returns: Error code (0 = success)

Serialization Functions

kc_verifiable_data_serialize()

int kc_verifiable_data_serialize(
    const kc_verifiable_data_t* verifiable_data_ptr,
    kc_serialized_data_t** out_serialized_data_ptr
)

Serializes verifiable data to a serialized data object.

Parameters:

  • verifiable_data_ptr - Verifiable data to serialize

  • out_serialized_data_ptr - Pointer to serialized data pointer (output, caller must free)

Returns: Error code (0 = success)

kc_verifiable_data_serialize_to_string()

int kc_verifiable_data_serialize_to_string(
    const kc_verifiable_data_t* verifiable_data_ptr,
    char** out_content,
    unsigned int* out_size,
    const tkc_serialization_format serialization_format
)

Serializes verifiable data to a string in the specified format.

Parameters:

  • verifiable_data_ptr - Verifiable data to serialize

  • out_content - Pointer to string pointer (output, caller must free)

  • out_size - Pointer to string size (output)

  • serialization_format - Format for serialization (JSON, XML, or PROTOBUF)

Returns: Error code (0 = success)

Example:

char* json_string = NULL;
unsigned int json_size = 0;

int result = kc_verifiable_data_serialize_to_string(verifiable, &json_string, &json_size,
                                                   TKC_SERIALIZATION_FORMAT_JSON);
if (result == 0) {
    printf("Verifiable data as JSON: %.*s\n", json_size, json_string);
    kc_common_delete_buffer(&json_string);
}

Content Access Functions

kc_verifiable_data_cleartext()

int kc_verifiable_data_cleartext(
    const kc_verifiable_data_t* verifiable_data_ptr,
    kc_serialized_data_t** out_cleartext_ptr
)

Gets the cleartext (unsigned data) from the verifiable data object.

Parameters:

  • verifiable_data_ptr - Verifiable data to query

  • out_cleartext_ptr - Pointer to cleartext data pointer (output, caller must free)

Returns: Error code (0 = success)

Example:

kc_serialized_data_t* cleartext = NULL;
int result = kc_verifiable_data_cleartext(verifiable, &cleartext);
if (result == 0) {
    char* content = NULL;
    unsigned int content_size = 0;

    kc_serialized_data_content(cleartext, &content, &content_size);
    printf("Signed content: %.*s\n", content_size, content);

    kc_common_delete_buffer(&content);
    kc_serialized_data_destruct(&cleartext);
}

Metadata Access Functions

kc_verifiable_data_tags()

int kc_verifiable_data_tags(
    const kc_verifiable_data_t* verifiable_data_ptr,
    kc_tag_set_t** out_tags_ptr
)

Gets the metadata tags associated with the verifiable data.

Parameters:

  • verifiable_data_ptr - Verifiable data to query

  • out_tags_ptr - Pointer to tag set pointer (output, caller must free)

Returns: Error code (0 = success)

kc_verifiable_data_vars()

int kc_verifiable_data_vars(
    const kc_verifiable_data_t* verifiable_data_ptr,
    kc_tag_set_t** out_vars_ptr
)

Gets the variable metadata associated with the verifiable data.

Parameters:

  • verifiable_data_ptr - Verifiable data to query

  • out_vars_ptr - Pointer to tag set pointer (output, caller must free)

Returns: Error code (0 = success)

Attestation Access Functions

kc_verifiable_data_num_attestations()

int kc_verifiable_data_num_attestations(
    const kc_verifiable_data_t* verifiable_data_ptr,
    unsigned int* out_count
)

Gets the number of attestations (signatures) in the verifiable data.

Parameters:

  • verifiable_data_ptr - Verifiable data to query

  • out_count - Pointer to attestation count (output)

Returns: Error code (0 = success)

kc_verifiable_data_attestation()

int kc_verifiable_data_attestation(
    const kc_verifiable_data_t* verifiable_data_ptr,
    kc_attestation_t** out_attestation_ptr,
    const unsigned int index
)

Gets a specific attestation by index.

Parameters:

  • verifiable_data_ptr - Verifiable data to query

  • out_attestation_ptr - Pointer to attestation pointer (output, caller must free)

  • index - Zero-based index of the attestation to retrieve

Returns: Error code (0 = success)

Example:

unsigned int attestation_count = 0;
int result = kc_verifiable_data_num_attestations(verifiable, &attestation_count);
if (result == 0) {
    printf("Verifiable data has %u signatures\n", attestation_count);

    // Get the first attestation
    if (attestation_count > 0) {
        kc_attestation_t* attestation = NULL;
        result = kc_verifiable_data_attestation(verifiable, &attestation, 0);
        if (result == 0) {
            // Use attestation...
            kc_attestation_destruct(&attestation);
        }
    }
}

Query Functions

kc_verifiable_data_equals()

int kc_verifiable_data_equals(
    const kc_verifiable_data_t* lhs_ptr,
    bool* out_is_equal,
    const kc_verifiable_data_t* rhs_ptr
)

Tests equality of two verifiable data objects.

Parameters:

  • lhs_ptr - First verifiable data to compare

  • out_is_equal - Pointer to equality result (output)

  • rhs_ptr - Second verifiable data to compare

Returns: Error code (0 = success)

kc_verifiable_data_is_null()

int kc_verifiable_data_is_null(
    const kc_verifiable_data_t* verifiable_data_ptr,
    bool* out_is_null
)

Checks whether the verifiable data is null.

Parameters:

  • verifiable_data_ptr - Verifiable data to check

  • out_is_null - Pointer to null status (output)

Returns: Error code (0 = success)

Example: Working with Verifiable Data

void demonstrate_verifiable_data_usage(kc_verifiable_data_t* signed_data) {
    // Check if data is null
    bool is_null = false;
    int result = kc_verifiable_data_is_null(signed_data, &is_null);
    if (result != 0 || is_null) {
        printf("Verifiable data is null or invalid\n");
        return;
    }

    // Get the cleartext content
    kc_serialized_data_t* cleartext = NULL;
    result = kc_verifiable_data_cleartext(signed_data, &cleartext);
    if (result == 0) {
        char* content = NULL;
        unsigned int content_size = 0;

        kc_serialized_data_content(cleartext, &content, &content_size);
        printf("Signed content: %.*s\n", content_size, content);

        kc_common_delete_buffer(&content);
        kc_serialized_data_destruct(&cleartext);
    }

    // Check attestations
    unsigned int num_signatures = 0;
    result = kc_verifiable_data_num_attestations(signed_data, &num_signatures);
    if (result == 0) {
        printf("Document has %u signatures\n", num_signatures);

        // Examine each attestation
        for (unsigned int i = 0; i < num_signatures; i++) {
            kc_attestation_t* attestation = NULL;
            result = kc_verifiable_data_attestation(signed_data, &attestation, i);
            if (result == 0) {
                // Get attestation details...
                printf("  Signature %u present\n", i + 1);
                kc_attestation_destruct(&attestation);
            }
        }
    }

    // Serialize to JSON for storage or transmission
    char* json_output = NULL;
    unsigned int json_size = 0;
    result = kc_verifiable_data_serialize_to_string(signed_data, &json_output,
                                                   &json_size,
                                                   TKC_SERIALIZATION_FORMAT_JSON);
    if (result == 0) {
        printf("Serialized to JSON (%u bytes)\n", json_size);
        // Could save to file or send over network...
        kc_common_delete_buffer(&json_output);
    }
}

Memory Management

  • Use kc_verifiable_data_destruct() to free verifiable data objects

  • Use kc_serialized_data_destruct() for cleartext objects

  • Use kc_attestation_destruct() for attestation objects

  • Use kc_tag_set_destruct() for tag sets

  • Use kc_common_delete_buffer() for string outputs

  • Always check return codes before using output parameters

See Also