Contact Functions
#include <keychain/keychain_headers.h>
Overview
Contact functions provide direct manipulation of contact objects, which represent cryptographic identities created and maintained by external devices. These functions allow you to work with contact objects to perform cryptographic operations with external parties.
Object Lifecycle Functions
kc_contact_destruct()
int kc_contact_destruct(kc_contact_t** contact_ptr)
Destructs a contact object and frees its resources. A contact represents a cryptographic identity that is created and maintained by an external device.
Parameters:
-
contact_ptr
- Pointer to contact pointer (set to NULL on success)
Returns: Error code (0 = success)
Example:
kc_contact_t* contact = NULL;
// ... get contact from somewhere ...
int result = kc_contact_destruct(&contact);
if (result == 0) {
// contact is now NULL
printf("Contact destructed successfully\n");
}
kc_contact_equals()
int kc_contact_equals(
const kc_contact_t* lhs_ptr,
bool* out_is_equal,
const kc_contact_t* rhs_ptr
)
Tests equality of two contacts.
Parameters:
-
lhs_ptr
- First contact to compare -
out_is_equal
- Pointer to equality result (output) -
rhs_ptr
- Second contact to compare
Returns: Error code (0 = success)
Example:
bool are_equal = false;
int result = kc_contact_equals(contact1, &are_equal, contact2);
if (result == 0) {
printf("Contacts are %s\n", are_equal ? "equal" : "different");
}
Status Query Functions
kc_contact_is_null()
int kc_contact_is_null(
const kc_contact_t* contact_ptr,
bool* out_is_null
)
Checks whether the contact is null.
Parameters:
-
contact_ptr
- Contact to check -
out_is_null
- Pointer to null status (output)
Returns: Error code (0 = success)
kc_contact_is_mature()
int kc_contact_is_mature(
const kc_contact_t* contact_ptr,
bool* out_is_mature
)
Checks whether the contact is mature (ready for cryptographic operations).
Parameters:
-
contact_ptr
- Contact to check -
out_is_mature
- Pointer to maturity status (output)
Returns: Error code (0 = success)
Example:
bool is_mature = false;
int result = kc_contact_is_mature(contact, &is_mature);
if (result == 0) {
if (is_mature) {
printf("Contact is ready for cryptographic operations\n");
} else {
printf("Contact is not yet mature\n");
}
}
Property Access Functions
kc_contact_did()
int kc_contact_did(
const kc_contact_t* contact_ptr,
kc_persona_did_t** out_did_ptr
)
Gets the contact’s DID (Decentralized Identifier).
Parameters:
-
contact_ptr
- Contact to query -
out_did_ptr
- Pointer to DID pointer (output, caller must free)
Returns: Error code (0 = success)
Example:
kc_persona_did_t* contact_did = NULL;
int result = kc_contact_did(contact, &contact_did);
if (result == 0) {
// Use the contact DID...
kc_persona_did_destruct(&contact_did);
}
kc_contact_name()
int kc_contact_name(
const kc_contact_t* contact_ptr,
char** out_name,
unsigned int* out_size
)
Gets the contact name (foreign key name). The (name, subname) pair should be unique.
Parameters:
-
contact_ptr
- Contact to query -
out_name
- Pointer to name string pointer (output, caller must free) -
out_size
- Pointer to name string size (output)
Returns: Error code (0 = success)
Example:
char* name = NULL;
unsigned int name_size = 0;
int result = kc_contact_name(contact, &name, &name_size);
if (result == 0) {
printf("Contact name: %.*s\n", name_size, name);
kc_common_delete_buffer(&name);
}
kc_contact_subname()
int kc_contact_subname(
const kc_contact_t* contact_ptr,
char** out_name,
unsigned int* out_size
)
Gets the contact subname (foreign key subname). The (name, subname) pair should be unique.
Parameters:
-
contact_ptr
- Contact to query -
out_name
- Pointer to subname string pointer (output, caller must free) -
out_size
- Pointer to subname string size (output)
Returns: Error code (0 = success)
Example:
char* subname = NULL;
unsigned int subname_size = 0;
int result = kc_contact_subname(contact, &subname, &subname_size);
if (result == 0) {
printf("Contact subname: %.*s\n", subname_size, subname);
kc_common_delete_buffer(&subname);
}
kc_contact_keychain()
int kc_contact_keychain(
const kc_contact_t* contact_ptr,
kc_keychain_element_t*** out_keychain_link_array,
unsigned int* out_array_size,
const unsigned int keychain_type
)
Gets the keychain for the specified keychain type.
Parameters:
-
contact_ptr
- Contact to query -
out_keychain_link_array
- Pointer to keychain element array (output, caller must free) -
out_array_size
- Pointer to array size (output) -
keychain_type
- Type of keychain (KC_KEYCHAIN_TYPE_ENCRYPT or KC_KEYCHAIN_TYPE_SIGN)
Returns: Error code (0 = success)
Example:
kc_keychain_element_t** encryption_keys = NULL;
unsigned int key_count = 0;
int result = kc_contact_keychain(contact, &encryption_keys, &key_count,
KC_KEYCHAIN_TYPE_ENCRYPT);
if (result == 0) {
printf("Contact has %u encryption keys\n", key_count);
// Process keys...
// Cleanup
for (unsigned int i = 0; i < key_count; i++) {
kc_keychain_element_destruct(&encryption_keys[i]);
}
kc_common_delete_ptr_array_shallow((void***)&encryption_keys);
}
Example: Contact Information Display
void display_contact_info(const kc_contact_t* contact) {
if (!contact) {
printf("Contact is NULL\n");
return;
}
// Check if contact is null
bool is_null = false;
int result = kc_contact_is_null(contact, &is_null);
if (result != 0 || is_null) {
printf("Contact is null or check failed\n");
return;
}
// Check maturity status
bool is_mature = false;
result = kc_contact_is_mature(contact, &is_mature);
if (result == 0) {
printf("Contact maturity: %s\n", is_mature ? "mature" : "not mature");
}
// Get contact name and subname
char* name = NULL;
char* subname = NULL;
unsigned int name_size, subname_size;
result = kc_contact_name(contact, &name, &name_size);
if (result == 0) {
kc_contact_subname(contact, &subname, &subname_size);
printf("Contact identity: %.*s.%.*s\n",
name_size, name, subname_size, subname);
kc_common_delete_buffer(&name);
kc_common_delete_buffer(&subname);
}
// Get DID information
kc_persona_did_t* did = NULL;
result = kc_contact_did(contact, &did);
if (result == 0) {
printf("Contact has DID information\n");
kc_persona_did_destruct(&did);
}
// Check available keychains
kc_keychain_element_t** encryption_keys = NULL;
kc_keychain_element_t** signing_keys = NULL;
unsigned int enc_count = 0, sign_count = 0;
result = kc_contact_keychain(contact, &encryption_keys, &enc_count,
KC_KEYCHAIN_TYPE_ENCRYPT);
if (result == 0) {
printf("Encryption keys available: %u\n", enc_count);
// Cleanup encryption keys
for (unsigned int i = 0; i < enc_count; i++) {
kc_keychain_element_destruct(&encryption_keys[i]);
}
kc_common_delete_ptr_array_shallow((void***)&encryption_keys);
}
result = kc_contact_keychain(contact, &signing_keys, &sign_count,
KC_KEYCHAIN_TYPE_SIGN);
if (result == 0) {
printf("Signing keys available: %u\n", sign_count);
// Cleanup signing keys
for (unsigned int i = 0; i < sign_count; i++) {
kc_keychain_element_destruct(&signing_keys[i]);
}
kc_common_delete_ptr_array_shallow((void***)&signing_keys);
}
}
Example: Contact Comparison
void compare_contacts(const kc_contact_t* contact1, const kc_contact_t* contact2) {
bool are_equal = false;
int result = kc_contact_equals(contact1, &are_equal, contact2);
if (result == 0) {
if (are_equal) {
printf("Contacts are identical\n");
} else {
printf("Contacts are different\n");
// Get names for comparison
char* name1 = NULL, *name2 = NULL;
char* subname1 = NULL, *subname2 = NULL;
unsigned int name1_size, name2_size, subname1_size, subname2_size;
if (kc_contact_name(contact1, &name1, &name1_size) == 0 &&
kc_contact_subname(contact1, &subname1, &subname1_size) == 0) {
printf("Contact 1: %.*s.%.*s\n",
name1_size, name1, subname1_size, subname1);
}
if (kc_contact_name(contact2, &name2, &name2_size) == 0 &&
kc_contact_subname(contact2, &subname2, &subname2_size) == 0) {
printf("Contact 2: %.*s.%.*s\n",
name2_size, name2, subname2_size, subname2);
}
// Cleanup
if (name1) kc_common_delete_buffer(&name1);
if (name2) kc_common_delete_buffer(&name2);
if (subname1) kc_common_delete_buffer(&subname1);
if (subname2) kc_common_delete_buffer(&subname2);
}
} else {
printf("Failed to compare contacts: %d\n", result);
}
}
Memory Management
-
Use
kc_contact_destruct()
to free contact objects -
Use
kc_common_delete_buffer()
for string outputs from name/subname functions -
Use
kc_persona_did_destruct()
for DID objects -
Use appropriate destruct functions for keychain elements
-
Use
kc_common_delete_ptr_array_shallow()
for keychain arrays after destructing individual elements -
Always check return codes before using output parameters
Security Considerations
-
Only use mature contacts for cryptographic operations
-
Verify contact identity before performing sensitive operations
-
Monitor contact keychain status for key availability
-
Validate contact names and subnames for uniqueness
Usage Guidelines
-
Contacts represent external identities - they cannot be modified locally
-
Contact keychains contain public keys for encryption and signature verification
-
Use contacts as recipients for encryption operations
-
Use contacts to verify signatures from external parties
Related Functions
-
Gateway Persona Operations - Local identity management
-
Persona Functions - Local identity operations
See Also
-
C++ Contact Class - Object-oriented interface
-
Gateway Cryptographic Operations - Using contacts for crypto operations