Attestation Functions
#include <keychain/keychain_headers.h>
Overview
Attestation functions work with digital signature objects that provide cryptographic proof of data authenticity and integrity. An attestation is an encapsulation of a digital signature and additional metadata that represents the main mechanism by which verifiable data, credentials, and transactions are verified.
The signature of an attestation authenticates: - The original data object’s serialized data - The serialization of all previous attestations in order - The metadata of the current attestation
Object Lifecycle Functions
kc_attestation_construct_from_serialized_string()
int kc_attestation_construct_from_serialized_string(
kc_attestation_t** out_attestation_ptr,
const char* serialized_string,
const unsigned int serialized_string_size,
const tkc_serialization_format serialization_format
)
Deserializes an attestation from a string representation.
Parameters:
-
out_attestation_ptr
- Pointer to attestation pointer (output, caller must free) -
serialized_string
- String serialization of the attestation -
serialized_string_size
- Number of bytes in the serialized string -
serialization_format
- Expected serialization format (JSON, XML, or PROTOBUF)
Returns: Error code (0 = success)
Example:
kc_attestation_t* attestation = NULL;
const char* serialized = "{\"signature\":\"...\",\"timestamp\":1234567890}";
int result = kc_attestation_construct_from_serialized_string(&attestation,
serialized, strlen(serialized), TKC_SERIALIZATION_FORMAT_JSON);
if (result == 0) {
// Use attestation...
kc_attestation_destruct(&attestation);
}
kc_attestation_construct_from_copy()
int kc_attestation_construct_from_copy(
kc_attestation_t** out_attestation_ptr,
const kc_attestation_t* rhs_attestation_ptr
)
Creates a deep copy of an attestation object.
Parameters:
-
out_attestation_ptr
- Pointer to new attestation pointer (output, caller must free) -
rhs_attestation_ptr
- Attestation object to copy
Returns: Error code (0 = success)
Example:
kc_attestation_t* original_attestation = NULL;
kc_attestation_t* copied_attestation = NULL;
// ... create original_attestation ...
int result = kc_attestation_construct_from_copy(&copied_attestation, original_attestation);
if (result == 0) {
// Use copied attestation...
kc_attestation_destruct(&copied_attestation);
}
Signature Access Functions
kc_attestation_signature()
int kc_attestation_signature(
const kc_attestation_t* attestation_ptr,
char** out_signature_hex,
unsigned int* out_size
)
Gets the signature from the attestation in hexadecimal format.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_signature_hex
- Pointer to signature string pointer (output, caller must free) -
out_size
- Pointer to signature string size (output)
Returns: Error code (0 = success)
Example:
char* signature = NULL;
unsigned int sig_size = 0;
int result = kc_attestation_signature(attestation, &signature, &sig_size);
if (result == 0) {
printf("Signature: %.*s\n", sig_size, signature);
kc_common_delete_buffer(&signature);
}
kc_attestation_prev_signature()
int kc_attestation_prev_signature(
const kc_attestation_t* attestation_ptr,
char** out_prev_signature_hex,
unsigned int* out_size
)
Gets the previous signature from the attestation chain in hexadecimal format.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_prev_signature_hex
- Pointer to previous signature string pointer (output, caller must free) -
out_size
- Pointer to signature string size (output)
Returns: Error code (0 = success)
Example:
char* prev_signature = NULL;
unsigned int prev_size = 0;
int result = kc_attestation_prev_signature(attestation, &prev_signature, &prev_size);
if (result == 0) {
printf("Previous signature: %.*s\n", prev_size, prev_signature);
kc_common_delete_buffer(&prev_signature);
}
kc_attestation_public_key()
int kc_attestation_public_key(
const kc_attestation_t* attestation_ptr,
char** out_public_key_hex,
unsigned int* out_size
)
Gets the public key used to create the signature.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_public_key_hex
- Pointer to public key string pointer (output, caller must free) -
out_size
- Pointer to public key string size (output)
Returns: Error code (0 = success)
Example:
char* public_key = NULL;
unsigned int key_size = 0;
int result = kc_attestation_public_key(attestation, &public_key, &key_size);
if (result == 0) {
printf("Signer public key: %.*s\n", key_size, public_key);
kc_common_delete_buffer(&public_key);
}
Metadata Access Functions
kc_attestation_index()
int kc_attestation_index(
const kc_attestation_t* attestation_ptr,
unsigned int* out_index
)
Gets the sequence number (index) of this attestation in the chain.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_index
- Pointer to index number (output)
Returns: Error code (0 = success)
Example:
unsigned int index = 0;
int result = kc_attestation_index(attestation, &index);
if (result == 0) {
printf("Attestation index: %u\n", index);
}
kc_attestation_timestamp()
int kc_attestation_timestamp(
const kc_attestation_t* attestation_ptr,
uint64_t* out_timestamp
)
Gets the timestamp when the attestation was created.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_timestamp
- Pointer to timestamp in milliseconds since epoch (output)
Returns: Error code (0 = success)
Example:
uint64_t timestamp = 0;
int result = kc_attestation_timestamp(attestation, ×tamp);
if (result == 0) {
time_t creation_time = timestamp / 1000;
printf("Attestation created: %s", ctime(&creation_time));
}
kc_attestation_algorithm()
int kc_attestation_algorithm(
const kc_attestation_t* attestation_ptr,
tkc_signature_scheme* out_algorithm
)
Gets the cryptographic algorithm used to produce the signature.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_algorithm
- Pointer to signature scheme (output)
Returns: Error code (0 = success)
Example:
tkc_signature_scheme algorithm;
int result = kc_attestation_algorithm(attestation, &algorithm);
if (result == 0) {
printf("Signature algorithm: %d\n", algorithm);
}
kc_attestation_version()
int kc_attestation_version(
const kc_attestation_t* attestation_ptr,
tkc_version* out_version
)
Gets the data format version of the attestation.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_version
- Pointer to version information (output)
Returns: Error code (0 = success)
kc_attestation_data_type()
int kc_attestation_data_type(
const kc_attestation_t* attestation_ptr,
tkc_data_type* out_data_type
)
Gets the data type value indicating this is an attestation.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_data_type
- Pointer to data type value (output)
Returns: Error code (0 = success)
Status and Configuration Functions
kc_attestation_is_approval()
int kc_attestation_is_approval(
const kc_attestation_t* attestation_ptr,
bool* out_is_approval
)
Checks whether the attestation signals approval or rejection.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_is_approval
- Pointer to approval status (output, true = approval, false = rejection)
Returns: Error code (0 = success)
Example:
bool is_approval = false;
int result = kc_attestation_is_approval(attestation, &is_approval);
if (result == 0) {
printf("Attestation type: %s\n", is_approval ? "Approval" : "Rejection");
}
kc_attestation_is_reattachable()
int kc_attestation_is_reattachable(
const kc_attestation_t* attestation_ptr,
bool* out_is_reattachable
)
Checks whether the attestation can be reattached to another verifiable object.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_is_reattachable
- Pointer to reattachable status (output)
Returns: Error code (0 = success)
Example:
bool is_reattachable = false;
int result = kc_attestation_is_reattachable(attestation, &is_reattachable);
if (result == 0) {
if (is_reattachable) {
printf("Attestation can be reattached to other objects\n");
} else {
printf("Attestation is bound to its current object\n");
}
}
Tag and Variable Functions
kc_attestation_tags()
int kc_attestation_tags(
const kc_attestation_t* attestation_ptr,
kc_tag_set_t** out_tags
)
Gets the tag set containing application-level metadata covered by the signature.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_tags
- Pointer to tag set pointer (output, caller must free)
Returns: Error code (0 = success)
Example:
kc_tag_set_t* tags = NULL;
int result = kc_attestation_tags(attestation, &tags);
if (result == 0) {
unsigned int tag_count = 0;
kc_tag_set_size(tags, &tag_count);
printf("Attestation has %u metadata tags\n", tag_count);
kc_tag_set_destruct(&tags);
}
kc_attestation_variables()
int kc_attestation_variables(
const kc_attestation_t* attestation_ptr,
kc_tag_set_t** out_vars
)
Gets the tag set containing mutable application-level stack variables.
Parameters:
-
attestation_ptr
- Attestation object to query -
out_vars
- Pointer to variables tag set pointer (output, caller must free)
Returns: Error code (0 = success)
Example:
kc_tag_set_t* vars = NULL;
int result = kc_attestation_variables(attestation, &vars);
if (result == 0) {
bool has_context = false;
kc_tag_set_has_key(vars, "execution_context", &has_context);
if (has_context) {
char* context = NULL;
unsigned int context_size = 0;
kc_tag_set_get_string(vars, "execution_context", &context, &context_size);
printf("Execution context: %.*s\n", context_size, context);
kc_common_delete_buffer(&context);
}
kc_tag_set_destruct(&vars);
}
Serialization Functions
kc_attestation_serialize()
int kc_attestation_serialize(
const kc_attestation_t* attestation_ptr,
char** out_serialized_string,
unsigned int* out_size
)
Serializes the attestation to a string in protobuf format.
Parameters:
-
attestation_ptr
- Attestation object to serialize -
out_serialized_string
- Pointer to serialized string pointer (output, caller must free) -
out_size
- Pointer to string size (output)
Returns: Error code (0 = success)
Example:
char* serialized = NULL;
unsigned int serialized_size = 0;
int result = kc_attestation_serialize(attestation, &serialized, &serialized_size);
if (result == 0) {
printf("Serialized attestation (%u bytes): %.*s\n",
serialized_size, serialized_size, serialized);
kc_common_delete_buffer(&serialized);
}
Query Functions
kc_attestation_equals()
int kc_attestation_equals(
const kc_attestation_t* lhs_attestation_ptr,
bool* out_is_equal,
const kc_attestation_t* rhs_attestation_ptr
)
Tests equality of two attestation objects.
Parameters:
-
lhs_attestation_ptr
- First attestation to compare -
out_is_equal
- Pointer to equality result (output) -
rhs_attestation_ptr
- Second attestation to compare
Returns: Error code (0 = success)
Example: Attestation Chain Analysis
void analyze_attestation_chain(kc_verifiable_data_t* verifiable_data) {
// Get all attestations from verifiable data
kc_attestation_t** attestations = NULL;
unsigned int attestation_count = 0;
int result = kc_verifiable_data_attestations(verifiable_data,
&attestations, &attestation_count);
if (result != 0) {
printf("Failed to get attestations: %d\n", result);
return;
}
printf("Analyzing attestation chain with %u attestations:\n", attestation_count);
for (unsigned int i = 0; i < attestation_count; i++) {
kc_attestation_t* attestation = attestations[i];
// Get attestation index
unsigned int index = 0;
kc_attestation_index(attestation, &index);
// Get timestamp
uint64_t timestamp = 0;
kc_attestation_timestamp(attestation, ×tamp);
time_t creation_time = timestamp / 1000;
// Get approval status
bool is_approval = false;
kc_attestation_is_approval(attestation, &is_approval);
// Get algorithm
tkc_signature_scheme algorithm;
kc_attestation_algorithm(attestation, &algorithm);
// Get public key
char* public_key = NULL;
unsigned int key_size = 0;
kc_attestation_public_key(attestation, &public_key, &key_size);
printf("\nAttestation #%u:\n", index);
printf(" Timestamp: %s", ctime(&creation_time));
printf(" Type: %s\n", is_approval ? "Approval" : "Rejection");
printf(" Algorithm: %d\n", algorithm);
printf(" Signer key: %.20s...\n", public_key ? public_key : "Unknown");
// Check for metadata
kc_tag_set_t* tags = NULL;
result = kc_attestation_tags(attestation, &tags);
if (result == 0) {
unsigned int tag_count = 0;
kc_tag_set_size(tags, &tag_count);
if (tag_count > 0) {
printf(" Metadata tags: %u\n", tag_count);
// List tag keys
char** keys = NULL;
unsigned int key_count = 0;
kc_tag_set_keys(tags, &keys, &key_count);
if (keys) {
printf(" Tag keys: ");
for (unsigned int j = 0; j < key_count; j++) {
printf("%s%s", keys[j], (j < key_count - 1) ? ", " : "");
}
printf("\n");
kc_common_delete_buffer_array(&keys, key_count);
}
}
kc_tag_set_destruct(&tags);
}
// Check for variables
kc_tag_set_t* vars = NULL;
result = kc_attestation_variables(attestation, &vars);
if (result == 0) {
unsigned int var_count = 0;
kc_tag_set_size(vars, &var_count);
if (var_count > 0) {
printf(" Stack variables: %u\n", var_count);
}
kc_tag_set_destruct(&vars);
}
if (public_key) kc_common_delete_buffer(&public_key);
}
// Cleanup attestation array
if (attestations) {
for (unsigned int i = 0; i < attestation_count; i++) {
kc_attestation_destruct(&attestations[i]);
}
kc_common_delete_buffer_array((char**)&attestations, attestation_count);
}
printf("\nAttestation chain analysis complete.\n");
}
Example: Creating Custom Attestation Metadata
void demonstrate_attestation_metadata(kc_persona_t* approver,
kc_verifiable_data_t* document) {
// Create approval attestation with custom metadata
kc_tag_set_t* approval_tags = NULL;
kc_tag_set_t* approval_vars = NULL;
// Create tags for approval metadata
int result = kc_tag_set_construct(&approval_tags);
if (result != 0) return;
kc_tag_set_add_string(approval_tags, "approval_type", "legal_review");
kc_tag_set_add_string(approval_tags, "reviewer_role", "Legal Counsel");
kc_tag_set_add_string(approval_tags, "review_category", "Contract Approval");
kc_tag_set_add_bool(approval_tags, "requires_countersignature", true);
// Create variables for execution context
result = kc_tag_set_construct(&approval_vars);
if (result != 0) {
kc_tag_set_destruct(&approval_tags);
return;
}
kc_tag_set_add_string(approval_vars, "execution_context", "production");
kc_tag_set_add_string(approval_vars, "client_version", "1.2.3");
kc_tag_set_add_int64(approval_vars, "process_id", getpid());
// Sign document with metadata
kc_verifiable_data_t* approved_document = NULL;
result = kc_persona_sign_verifiable_data(approver, &approved_document,
document, true, // is_approval
approval_tags, approval_vars);
if (result == 0) {
printf("Document approved with comprehensive metadata\n");
// Retrieve and display the latest attestation
kc_attestation_t** attestations = NULL;
unsigned int attestation_count = 0;
result = kc_verifiable_data_attestations(approved_document,
&attestations, &attestation_count);
if (result == 0 && attestation_count > 0) {
kc_attestation_t* latest = attestations[attestation_count - 1];
// Verify it's an approval
bool is_approval = false;
kc_attestation_is_approval(latest, &is_approval);
printf("Latest attestation is %s\n",
is_approval ? "an approval" : "a rejection");
// Display metadata
kc_tag_set_t* tags = NULL;
kc_attestation_tags(latest, &tags);
if (tags) {
char* approval_type = NULL;
unsigned int type_size = 0;
kc_tag_set_get_string(tags, "approval_type", &approval_type, &type_size);
if (approval_type) {
printf("Approval type: %.*s\n", type_size, approval_type);
kc_common_delete_buffer(&approval_type);
}
kc_tag_set_destruct(&tags);
}
// Cleanup attestations
for (unsigned int i = 0; i < attestation_count; i++) {
kc_attestation_destruct(&attestations[i]);
}
kc_common_delete_buffer_array((char**)&attestations, attestation_count);
}
kc_verifiable_data_destruct(&approved_document);
}
kc_tag_set_destruct(&approval_tags);
kc_tag_set_destruct(&approval_vars);
}
Memory Management
-
Use
kc_attestation_destruct()
to free attestation objects -
Use
kc_tag_set_destruct()
for tag sets returned by metadata functions -
Use
kc_common_delete_buffer()
for string outputs (signatures, public keys, serialized data) -
Use
kc_common_delete_buffer_array()
for arrays of attestations -
Always check return codes before using output parameters
Best Practices
-
Examine attestation chains in chronological order by index
-
Verify signatures using the corresponding public keys
-
Use metadata tags for immutable attestation properties
-
Use variables for mutable execution context information
-
Check approval status for workflow-related attestations
-
Preserve attestation order when processing chains
See Also
-
Verifiable Data - Objects that contain attestations
-
Tag Set Functions - Metadata storage
-
Persona Functions - Creating attestations through signing
-
Verification Result - Attestation verification
-
C++ Attestation Class - Object-oriented interface