Verification Result Functions
#include <keychain/keychain_headers.h>
Overview
Verification result functions work with the results of cryptographic verification operations. These objects contain detailed information about signature verification, including validity status, signer information, and any verification errors.
Object Lifecycle Functions
kc_verification_result_destruct()
int kc_verification_result_destruct(kc_verification_result_t** verification_result_ptr)
Destructs a verification result object and frees its resources.
Parameters:
-
verification_result_ptr
- Pointer to verification result pointer (set to NULL on success)
Returns: Error code (0 = success)
Example:
kc_verification_result_t* result = NULL;
// ... perform verification to get result ...
int ret = kc_verification_result_destruct(&result);
if (ret == 0) {
// result is now NULL
printf("Verification result destructed\n");
}
Verification Status Functions
kc_verification_result_is_valid()
int kc_verification_result_is_valid(
const kc_verification_result_t* verification_result_ptr,
bool* out_is_valid
)
Checks whether the verification was successful.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_is_valid
- Pointer to validity status (output, true = valid, false = invalid)
Returns: Error code (0 = success)
Example:
bool is_valid = false;
int result = kc_verification_result_is_valid(verify_result, &is_valid);
if (result == 0) {
if (is_valid) {
printf("Signature verification: VALID\n");
} else {
printf("Signature verification: INVALID\n");
}
}
kc_verification_result_error_code()
int kc_verification_result_error_code(
const kc_verification_result_t* verification_result_ptr,
unsigned int* out_error_code
)
Gets the error code from the verification result.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_error_code
- Pointer to error code (output, 0 = no error)
Returns: Error code (0 = success)
Example:
unsigned int error_code = 0;
int result = kc_verification_result_error_code(verify_result, &error_code);
if (result == 0) {
if (error_code == 0) {
printf("No verification errors\n");
} else {
printf("Verification error code: %u\n", error_code);
}
}
kc_verification_result_error_message()
int kc_verification_result_error_message(
const kc_verification_result_t* verification_result_ptr,
char** out_message,
unsigned int* out_size
)
Gets the error message from the verification result.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_message
- Pointer to error message string (output, caller must free) -
out_size
- Pointer to message size (output)
Returns: Error code (0 = success)
Example:
char* error_message = NULL;
unsigned int message_size = 0;
int result = kc_verification_result_error_message(verify_result, &error_message, &message_size);
if (result == 0 && error_message) {
printf("Verification error: %.*s\n", message_size, error_message);
kc_common_delete_buffer(&error_message);
}
Signer Information Functions
kc_verification_result_signer_did()
int kc_verification_result_signer_did(
const kc_verification_result_t* verification_result_ptr,
char** out_did,
unsigned int* out_size
)
Gets the DID of the signer from the verification result.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_did
- Pointer to DID string (output, caller must free) -
out_size
- Pointer to DID string size (output)
Returns: Error code (0 = success)
Example:
char* signer_did = NULL;
unsigned int did_size = 0;
int result = kc_verification_result_signer_did(verify_result, &signer_did, &did_size);
if (result == 0 && signer_did) {
printf("Signed by: %.*s\n", did_size, signer_did);
kc_common_delete_buffer(&signer_did);
}
kc_verification_result_signer_public_key()
int kc_verification_result_signer_public_key(
const kc_verification_result_t* verification_result_ptr,
char** out_public_key,
unsigned int* out_size
)
Gets the public key used for verification.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_public_key
- Pointer to public key string (output, caller must free) -
out_size
- Pointer to key size (output)
Returns: Error code (0 = success)
Timestamp Functions
kc_verification_result_timestamp()
int kc_verification_result_timestamp(
const kc_verification_result_t* verification_result_ptr,
uint64_t* out_timestamp
)
Gets the timestamp when the verification was performed.
Parameters:
-
verification_result_ptr
- Verification result to query -
out_timestamp
- Pointer to timestamp in milliseconds since epoch (output)
Returns: Error code (0 = success)
Example:
uint64_t verify_timestamp = 0;
int result = kc_verification_result_timestamp(verify_result, &verify_timestamp);
if (result == 0) {
time_t verify_time = verify_timestamp / 1000;
printf("Verified at: %s", ctime(&verify_time));
}
Query Functions
kc_verification_result_equals()
int kc_verification_result_equals(
const kc_verification_result_t* lhs_ptr,
bool* out_is_equal,
const kc_verification_result_t* rhs_ptr
)
Tests equality of two verification results.
Parameters:
-
lhs_ptr
- First verification result to compare -
out_is_equal
- Pointer to equality result (output) -
rhs_ptr
- Second verification result to compare
Returns: Error code (0 = success)
kc_verification_result_is_null()
int kc_verification_result_is_null(
const kc_verification_result_t* verification_result_ptr,
bool* out_is_null
)
Checks whether the verification result is null.
Parameters:
-
verification_result_ptr
- Verification result to check -
out_is_null
- Pointer to null status (output)
Returns: Error code (0 = success)
Example: Comprehensive Verification Result Analysis
void analyze_verification_result(kc_verification_result_t* verify_result) {
// Check if result is valid
bool is_null = false;
int result = kc_verification_result_is_null(verify_result, &is_null);
if (result != 0 || is_null) {
printf("Verification result is null or invalid\n");
return;
}
// Check verification status
bool is_valid = false;
result = kc_verification_result_is_valid(verify_result, &is_valid);
if (result == 0) {
printf("Verification status: %s\n", is_valid ? "VALID" : "INVALID");
}
// Get error information if verification failed
if (!is_valid) {
unsigned int error_code = 0;
result = kc_verification_result_error_code(verify_result, &error_code);
if (result == 0 && error_code != 0) {
printf("Error code: %u\n", error_code);
// Get error message
char* error_message = NULL;
unsigned int message_size = 0;
result = kc_verification_result_error_message(verify_result, &error_message, &message_size);
if (result == 0 && error_message) {
printf("Error message: %.*s\n", message_size, error_message);
kc_common_delete_buffer(&error_message);
}
}
}
// Get signer information
char* signer_did = NULL;
unsigned int did_size = 0;
result = kc_verification_result_signer_did(verify_result, &signer_did, &did_size);
if (result == 0 && signer_did) {
printf("Signer DID: %.*s\n", did_size, signer_did);
kc_common_delete_buffer(&signer_did);
}
// Get public key information
char* public_key = NULL;
unsigned int key_size = 0;
result = kc_verification_result_signer_public_key(verify_result, &public_key, &key_size);
if (result == 0 && public_key) {
printf("Signer public key (%u bytes): %.40s...\n", key_size, public_key);
kc_common_delete_buffer(&public_key);
}
// Get verification timestamp
uint64_t verify_timestamp = 0;
result = kc_verification_result_timestamp(verify_result, &verify_timestamp);
if (result == 0) {
time_t verify_time = verify_timestamp / 1000;
printf("Verification performed at: %s", ctime(&verify_time));
}
}
Example: Verification Workflow with Result Analysis
void demonstrate_verification_workflow(kc_gateway_t* gateway) {
kc_persona_t* alice = NULL;
kc_persona_t* bob = NULL;
kc_verifiable_data_t* signed_data = NULL;
kc_verification_result_t* verify_result = NULL;
// Get personas (implementation omitted)
// ...
// Create and sign some data with Alice
kc_serialized_data_t* document = NULL;
const char* content = "Contract between Alice and Bob - Payment due in 30 days";
int result = kc_serialized_data_construct_from_string(&document,
content, strlen(content), TKC_DATA_TYPE_UTF8_STRING);
if (result == 0) {
result = kc_gateway_sign(gateway, &signed_data, alice, document,
false, NULL, NULL);
if (result == 0) {
printf("Document signed by Alice\n");
// Bob verifies Alice's signature
result = kc_gateway_verify(gateway, &verify_result, bob, signed_data);
if (result == 0) {
printf("\n=== Verification Result Analysis ===\n");
analyze_verification_result(verify_result);
// Check if verification was successful
bool is_valid = false;
kc_verification_result_is_valid(verify_result, &is_valid);
if (is_valid) {
printf("\n✓ Signature verification successful - document is authentic\n");
} else {
printf("\n✗ Signature verification failed - document may be tampered\n");
}
kc_verification_result_destruct(&verify_result);
} else {
printf("Verification operation failed: %d\n", result);
}
kc_verifiable_data_destruct(&signed_data);
}
kc_serialized_data_destruct(&document);
}
// Cleanup
if (alice) kc_persona_destruct(&alice);
if (bob) kc_persona_destruct(&bob);
}
Example: Batch Verification
void verify_multiple_signatures(kc_gateway_t* gateway, kc_persona_t* verifier,
kc_verifiable_data_t** documents, unsigned int doc_count) {
printf("Verifying %u signed documents...\n", doc_count);
unsigned int valid_count = 0;
unsigned int invalid_count = 0;
for (unsigned int i = 0; i < doc_count; i++) {
kc_verification_result_t* result = NULL;
int ret = kc_gateway_verify(gateway, &result, verifier, documents[i]);
if (ret == 0) {
bool is_valid = false;
kc_verification_result_is_valid(result, &is_valid);
printf("Document %u: ", i + 1);
if (is_valid) {
printf("VALID");
valid_count++;
// Get signer info
char* signer_did = NULL;
unsigned int did_size = 0;
if (kc_verification_result_signer_did(result, &signer_did, &did_size) == 0) {
printf(" (signed by: %.20s...)", signer_did);
kc_common_delete_buffer(&signer_did);
}
} else {
printf("INVALID");
invalid_count++;
// Get error information
char* error_msg = NULL;
unsigned int msg_size = 0;
if (kc_verification_result_error_message(result, &error_msg, &msg_size) == 0) {
printf(" (error: %.*s)", msg_size, error_msg);
kc_common_delete_buffer(&error_msg);
}
}
printf("\n");
kc_verification_result_destruct(&result);
} else {
printf("Document %u: VERIFICATION FAILED (error: %d)\n", i + 1, ret);
invalid_count++;
}
}
printf("\nVerification Summary:\n");
printf(" Valid signatures: %u\n", valid_count);
printf(" Invalid signatures: %u\n", invalid_count);
printf(" Total processed: %u\n", doc_count);
}
Memory Management
-
Use
kc_verification_result_destruct()
to free verification result objects -
Use
kc_common_delete_buffer()
for string outputs (DIDs, public keys, error messages) -
Always check return codes before using output parameters
-
Verification results are typically created by gateway verification functions
Best Practices
-
Always check the validity status before trusting verification results
-
Log error messages for failed verifications for debugging
-
Store verification timestamps for audit trails
-
Verify signer identity matches expected signers for critical operations
See Also
-
Gateway Cryptographic Operations - Creating verification results
-
Verifiable Data - Signed data objects
-
Persona Functions - Identity verification
-
C++ Verification Result Class - Object-oriented interface