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.

Identity Management

Personas

Local cryptographic identity operations

Contacts

External identity operations Note: DID and keychain element documentation is currently being developed.

Utility Functions

Note: Utility function documentation is currently 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.