C API Reference
Overview
The {keychain-core} C API provides a comprehensive interface for cryptographic identity management operations. It offers full access to all Keychain functionality through a C-compatible interface suitable for integration with any programming language that supports C function calls.
Key Features
-
Complete API Coverage - All functionality available in C++ is accessible through C functions
-
Memory Management - Consistent patterns for object lifecycle management
-
Error Handling - Comprehensive error codes with detailed error messages
-
Type Safety - Opaque pointer types prevent direct memory access
-
Thread Safety - Thread-safe when used with proper synchronization
API Organization
The C API is organized into logical modules:
Core Functions
- Initialization and Cleanup
-
Library initialization, settings management, and cleanup
- Memory Management
-
Buffer allocation, deallocation, and string management
- Error Handling
-
Error code translation and message retrieval
Gateway Operations
- Gateway Operations
-
Main gateway functions and lifecycle management
- Cryptographic Functions
-
Encryption, decryption, signing, and verification
- Persona Management
-
Creating and managing local identities
- Contact Management
-
Managing external identity relationships
Data Type Functions
- Serialized Data
-
Type-safe data serialization and deserialization
- Verifiable Data
-
Digitally signed data operations
- Credentials
-
W3C verifiable credential functions
- Encrypted Data
-
Multi-recipient encryption operations Note: Additional data type documentation (transactions, attestations, key locks, tag sets) is being developed.
Enumerations
- All C Enums
-
Complete enumeration reference
Basic Usage Pattern
#include <keychain/keychain_headers.h>
int main() {
// Initialize library
kc_settings_t* settings = NULL;
unsigned int result = kc_gateway_init(&settings, "config.cfg", strlen("config.cfg"));
if (result != 0) {
// Handle error
return 1;
}
// Create gateway
kc_gateway_t* gateway = NULL;
result = kc_gateway_construct(&gateway, settings);
if (result != 0) {
kc_settings_destruct(&settings);
return 1;
}
// Start monitoring
kc_gateway_on_start(gateway);
// Your application logic here...
// Cleanup
kc_gateway_on_stop(gateway);
kc_gateway_destruct(&gateway);
kc_settings_destruct(&settings);
kc_gateway_close();
return 0;
}
Memory Management Patterns
All C API functions follow consistent memory management patterns:
Output Parameters
Functions that return objects use double pointers:
kc_persona_t* persona = NULL;
unsigned int result = kc_gateway_create_persona(
gateway, &persona, "alice", 5, "personal", 8, KC_SECURITY_LEVEL_MEDIUM, 1
);
// Check result, use persona
kc_persona_destruct(&persona); // Cleanup
String Handling
Functions that return strings allocate memory that must be freed:
char* hash_result = NULL;
unsigned int hash_size = 0;
int result = kc_gateway_hash(&hash_result, &hash_size, "data", 4);
// Use hash_result
kc_common_delete_buffer(&hash_result); // Free memory
Array Handling
Functions returning arrays provide both the array and count:
kc_persona_t** personas = NULL;
unsigned int persona_count = 0;
int result = kc_gateway_retrieve_personas(gateway, &personas, &persona_count);
// Use personas array
for (unsigned int i = 0; i < persona_count; i++) {
kc_persona_destruct(&personas[i]);
}
kc_common_delete_ptr_array_shallow((void***)&personas); // Free array
Error Handling
All functions return unsigned int
error codes:
int result = kc_gateway_encrypt(/* parameters */);
if (result != 0) {
// Get error message
char* error_message = NULL;
unsigned int message_size = 0;
kc_common_get_error_message(&error_message, &message_size, result);
printf("Error: %s\n", error_message);
kc_common_delete_buffer(&error_message);
}
Type Safety
All objects are opaque pointers providing type safety:
typedef struct kc_gateway kc_gateway_t; // Gateway operations
typedef struct kc_persona kc_persona_t; // Local identities
typedef struct kc_contact kc_contact_t; // External identities
typedef struct kc_verifiable_data kc_verifiable_data_t; // Signed data
// ... and many more
Thread Safety
The C API is not inherently thread-safe. Applications must:
-
Use separate gateway instances per thread, OR
-
Synchronize access to shared gateway instances
-
Ensure proper cleanup in multi-threaded environments
Integration Examples
Python Integration
import ctypes
# Load library
keychain = ctypes.CDLL('libkeychain.so')
# Setup function signature
keychain.kc_gateway_hash.argtypes = [
ctypes.POINTER(ctypes.c_char_p), # out_hash_hex
ctypes.POINTER(ctypes.c_uint), # out_hash_size
ctypes.c_char_p, # input_data
ctypes.c_uint # input_data_size
]
keychain.kc_gateway_hash.restype = ctypes.c_uint
# Use function
hash_ptr = ctypes.c_char_p()
hash_size = ctypes.c_uint()
result = keychain.kc_gateway_hash(
ctypes.byref(hash_ptr),
ctypes.byref(hash_size),
b"test data",
9
)
Go Integration
package main
/*
#cgo LDFLAGS: -lkeychain
#include <keychain/keychain_headers.h>
#include <stdlib.h>
*/
import "C"
import "unsafe"
func HashData(data string) (string, error) {
cdata := C.CString(data)
defer C.free(unsafe.Pointer(cdata))
var hashPtr *C.char
var hashSize C.uint
result := C.kc_gateway_hash(&hashPtr, &hashSize, cdata, C.uint(len(data)))
if result != 0 {
return "", fmt.Errorf("hash failed with code %d", result)
}
defer C.kc_common_delete_buffer(&hashPtr)
return C.GoString(hashPtr), nil
}
Version Information
To get library version information:
unsigned int major, minor;
kc_major_version(&major);
kc_minor_version(&minor);
printf("Keychain Core version: %u.%u\n", major, minor);
See Also
-
xref:../cpp.adoc[C API Reference] - Object-oriented C interface
-
Python API Reference - Python wrapper implementation Note: Setup guides and error code documentation are being developed.