Provides APIs for key handling operations such as generating and importing a key. 
Required Header
#include <yaca/yaca_key.h>
Overview
It provides APIs for generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format.
Examples
Key generation API example 
#include <yaca_crypto.h>
#include <yaca_key.h>
#include <yaca_error.h>
int main()
{
    int ret;
    yaca_key_h key = YACA_KEY_NULL;
    yaca_key_h key_params = YACA_KEY_NULL;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    yaca_key_destroy(key);
    ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    yaca_key_destroy(key);
    ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEY_LENGTH_DH_RFC_2048_224, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    yaca_key_destroy(key);
    ret = yaca_key_generate(YACA_KEY_TYPE_EC_PRIV, YACA_KEY_LENGTH_EC_SECP384R1, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    yaca_key_destroy(key);
    
    ret = yaca_key_generate(YACA_KEY_TYPE_DH_PARAMS, YACA_KEY_LENGTH_DH_RFC_2048_256, &key_params);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate_from_parameters(key_params, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    yaca_key_destroy(key);
    yaca_key_destroy(key_params);
    ret = yaca_key_generate(YACA_KEY_TYPE_EC_PARAMS, YACA_KEY_LENGTH_EC_PRIME256V1, &key_params);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate_from_parameters(key_params, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
exit:
    yaca_key_destroy(key);
    yaca_key_destroy(key_params);
    yaca_cleanup();
    return ret;
}
 Symmetric key import/export API example 
#include <stdio.h>
#include <yaca_crypto.h>
#include <yaca_key.h>
#include <yaca_error.h>
#include "misc.h"
int main()
{
    int ret;
    yaca_key_h sym_key = YACA_KEY_NULL;
    yaca_key_h raw_imported = YACA_KEY_NULL;
    yaca_key_h b64_imported = YACA_KEY_NULL;
    char *raw = NULL;
    size_t raw_len;
    char *b64 = NULL;
    size_t b64_len;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &sym_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_export(sym_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, NULL,
                          &b64, &b64_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, b64, b64_len, &b64_imported);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    printf("\t***** BASE64 exported key: *****\n%.*s\n", (int)b64_len, b64);
    yaca_free(b64);
    b64 = NULL;
    ret = yaca_key_export(b64_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, NULL,
                          &b64, &b64_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    printf("\t***** BASE64 imported key: *****\n%.*s\n", (int)b64_len, b64);
    
    ret = yaca_key_export(sym_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, NULL,
                          &raw, &raw_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, raw, raw_len, &raw_imported);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    dump_hex(raw, raw_len, "\n\t***** RAW exported key: *****");
    yaca_free(raw);
    raw = NULL;
    ret = yaca_key_export(raw_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, NULL,
                          &raw, &raw_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    dump_hex(raw, raw_len, "\t***** RAW imported key: *****");
exit:
    yaca_key_destroy(sym_key);
    yaca_key_destroy(raw_imported);
    yaca_key_destroy(b64_imported);
    yaca_free(raw);
    yaca_free(b64);
    yaca_cleanup();
    return ret;
}
 Asymmetric key import/export API example 
#include <stdio.h>
#include <yaca_crypto.h>
#include <yaca_key.h>
#include <yaca_error.h>
#include "misc.h"
int main()
{
    int ret;
    yaca_key_h rsa_priv = YACA_KEY_NULL;
    yaca_key_h rsa_pub = YACA_KEY_NULL;
    yaca_key_h pem_priv_imported = YACA_KEY_NULL;
    yaca_key_h der_pub_imported = YACA_KEY_NULL;
    char *pem_priv = NULL;
    size_t pem_priv_len;
    char *der_pub = NULL;
    size_t der_pub_len;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, &rsa_priv);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_extract_public(rsa_priv, &rsa_pub);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_export(rsa_priv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, NULL,
                          &pem_priv, &pem_priv_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_import(YACA_KEY_TYPE_RSA_PRIV, NULL, pem_priv, pem_priv_len, &pem_priv_imported);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    printf("\t***** PEM exported private key: *****\n%.*s", (int)pem_priv_len, pem_priv);
    yaca_free(pem_priv);
    pem_priv = NULL;
    ret = yaca_key_export(pem_priv_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM,
                          NULL, &pem_priv, &pem_priv_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    printf("\t***** PEM imported private key: *****\n%.*s", (int)pem_priv_len, pem_priv);
    
    ret = yaca_key_export(rsa_pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, NULL,
                          &der_pub, &der_pub_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, der_pub, der_pub_len, &der_pub_imported);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    dump_hex(der_pub, der_pub_len, "\n\t***** DER exported public key: *****");
    yaca_free(der_pub);
    der_pub = NULL;
    ret = yaca_key_export(der_pub_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER,
                          NULL, &der_pub, &der_pub_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    dump_hex(der_pub, der_pub_len, "\t***** DER imported public key: *****");
exit:
    yaca_key_destroy(rsa_pub);
    yaca_key_destroy(rsa_priv);
    yaca_key_destroy(pem_priv_imported);
    yaca_key_destroy(der_pub_imported);
    yaca_free(pem_priv);
    yaca_free(der_pub);
    yaca_cleanup();
    return ret;
}
 Key import/export with password API example 
#include <stdio.h>
#include <yaca_crypto.h>
#include <yaca_key.h>
#include <yaca_error.h>
#include  "misc.h"
int main()
{
    int ret;
    yaca_key_h key = YACA_KEY_NULL;
    char *password = NULL;
    char *key_data = NULL;
    size_t key_data_len;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    {
        ret = read_stdin_line("encryption pass: ", &password);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        ret = yaca_key_export(key, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM, password,
                              &key_data, &key_data_len);
        if (ret == YACA_ERROR_INVALID_PARAMETER)
            printf("invalid parameter, probably a missing password for PKCS8\n");
        if (ret != YACA_ERROR_NONE)
            goto exit;
        yaca_key_destroy(key);
        key = YACA_KEY_NULL;
        yaca_free(password);
        password = NULL;
    }
    
    {
        ret = read_stdin_line("decryption pass: ", &password);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        ret = yaca_key_import(YACA_KEY_TYPE_RSA_PRIV, password, key_data, key_data_len, &key);
        if (ret == YACA_ERROR_INVALID_PASSWORD)
            printf("invalid password\n");
        if (ret != YACA_ERROR_NONE)
            goto exit;
        yaca_free(key_data);
        key_data = NULL;
        ret = yaca_key_export(key, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM, password,
                              &key_data, &key_data_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        printf("%.*s", (int)key_data_len, key_data);
    }
exit:
    yaca_free(key_data);
    yaca_free(password);
    yaca_key_destroy(key);
    yaca_cleanup();
    return ret;
}
 Diffie-Helmann key exchange API example 
#include <yaca_crypto.h>
#include <yaca_key.h>
#include <yaca_error.h>
#include "misc.h"
static yaca_key_h exchange_public_keys(const yaca_key_h peer_key)
{
    int ret;
    yaca_key_h params = YACA_KEY_NULL;
    yaca_key_h priv_key = YACA_KEY_NULL;
    yaca_key_h pub_key = YACA_KEY_NULL;
    ret = yaca_key_extract_parameters(peer_key, ¶ms);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_generate_from_parameters(params, &priv_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_extract_public(priv_key, &pub_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
exit:
    yaca_key_destroy(priv_key);
    yaca_key_destroy(params);
    return pub_key;
}
int main()
{
    int ret;
    yaca_key_h priv_key = YACA_KEY_NULL;
    yaca_key_h pub_key = YACA_KEY_NULL;
    yaca_key_h peer_key = YACA_KEY_NULL;
    yaca_key_h aes_key = YACA_KEY_NULL;
    yaca_key_h iv = YACA_KEY_NULL;
    char *secret = NULL;
    size_t secret_len;
    char *key_material = NULL;
    size_t key_material_len;
    char *iv_material = NULL;
    size_t iv_material_len;
    char *temp_material = NULL;
    size_t temp_material_len;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEY_LENGTH_DH_RFC_2048_256, &priv_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_extract_public(priv_key, &pub_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    peer_key = exchange_public_keys(pub_key);
    if (peer_key == YACA_KEY_NULL)
        goto exit;
    
    ret = yaca_key_derive_dh(priv_key, peer_key, &secret, &secret_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    key_material_len = YACA_KEY_LENGTH_256BIT / 8;
    iv_material_len = YACA_KEY_LENGTH_IV_128BIT / 8;
    temp_material_len = key_material_len + iv_material_len;
    ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_SHA512, secret, secret_len,
                              NULL, 0, temp_material_len, &temp_material);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    key_material = temp_material;
    iv_material = temp_material + key_material_len;
    ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, key_material, key_material_len, &aes_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    ret = yaca_key_import(YACA_KEY_TYPE_IV, NULL, iv_material, iv_material_len, &iv);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    dump_hex(key_material, key_material_len, "***** Derived AES key: *****");
    dump_hex(iv_material, iv_material_len, "\n***** Derived IV: *****");
exit:
    yaca_key_destroy(priv_key);
    yaca_key_destroy(pub_key);
    yaca_key_destroy(peer_key);
    yaca_key_destroy(aes_key);
    yaca_key_destroy(iv);
    yaca_free(secret);
    yaca_free(temp_material);
    yaca_cleanup();
    return ret;
}
 Key wrapping API example 
#include <yaca_crypto.h>
#include <yaca_simple.h>
#include <yaca_encrypt.h>
#include <yaca_key.h>
#include <yaca_error.h>
#include "misc.h"
int main()
{
    int ret;
    yaca_key_h aes_key = YACA_KEY_NULL;
    yaca_key_h key = YACA_KEY_NULL;
    yaca_key_h iv = YACA_KEY_NULL;
    size_t iv_bit_len;
    char *aes_key_data = NULL;
    size_t aes_key_data_len;
    char *wrapped_key_data = NULL;
    size_t wrapped_key_data_len;
    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &aes_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    
    ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_WRAP, YACA_KEY_LENGTH_256BIT,
                                         &iv_bit_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;
    if (iv_bit_len > 0) {
        ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv);
        if (ret != YACA_ERROR_NONE)
            goto exit;
    }
    
    {
        ret = yaca_key_export(aes_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, NULL,
                              &aes_key_data, &aes_key_data_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_WRAP, key, iv,
                                  aes_key_data, aes_key_data_len,
                                  &wrapped_key_data, &wrapped_key_data_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        
        dump_hex(aes_key_data, aes_key_data_len, "***** Unwrapped key:*****");
        dump_hex(wrapped_key_data, wrapped_key_data_len, "***** Wrapped key:*****");
    }
    yaca_free(aes_key_data);
    aes_key_data = NULL;
    yaca_key_destroy(aes_key);
    aes_key = YACA_KEY_NULL;
    
    {
        ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_WRAP, key, iv,
                                  wrapped_key_data, wrapped_key_data_len,
                                  &aes_key_data, &aes_key_data_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, aes_key_data, aes_key_data_len,
                              &aes_key);
        if (ret != YACA_ERROR_NONE)
            goto exit;
        
        dump_hex(aes_key_data, aes_key_data_len, "***** Unwrapped key:*****");
    }
exit:
    yaca_key_destroy(aes_key);
    yaca_key_destroy(key);
    yaca_key_destroy(iv);
    yaca_free(aes_key_data);
    yaca_free(wrapped_key_data);
    yaca_cleanup();
    return ret;
}
Functions | 
| int  | yaca_key_get_type (const yaca_key_h key, yaca_key_type_e *key_type) | 
|   | Gets key's type.  
  | 
| int  | yaca_key_get_bit_length (const yaca_key_h key, size_t *key_bit_len) | 
|   | Gets key's length (in bits).  
  | 
| int  | yaca_key_import (yaca_key_type_e key_type, const char *password, const char *data, size_t data_len, yaca_key_h *key) | 
|   | Imports a key or key generation parameters.  
  | 
| int  | yaca_key_export (const yaca_key_h key, yaca_key_format_e key_fmt, yaca_key_file_format_e key_file_fmt, const char *password, char **data, size_t *data_len) | 
|   | Exports a key or key generation parameters to arbitrary format.  
  | 
| int  | yaca_key_generate (yaca_key_type_e key_type, size_t key_bit_len, yaca_key_h *key) | 
|   | Generates a secure key or key generation parameters (or an Initialization Vector).  
  | 
| int  | yaca_key_generate_from_parameters (const yaca_key_h params, yaca_key_h *prv_key) | 
|   | Generates a secure private asymmetric key from parameters.  
  | 
| int  | yaca_key_extract_public (const yaca_key_h prv_key, yaca_key_h *pub_key) | 
|   | Extracts public key from a private one.  
  | 
| int  | yaca_key_extract_parameters (const yaca_key_h key, yaca_key_h *params) | 
|   | Extracts parameters from a private or a public key.  
  | 
| int  | yaca_key_derive_dh (const yaca_key_h prv_key, const yaca_key_h pub_key, char **secret, size_t *secret_len) | 
|   | Derives a shared secret using Diffie-Helmann or EC Diffie-Helmann key exchange protocol.  
  | 
| int  | yaca_key_derive_kdf (yaca_kdf_e kdf, yaca_digest_algorithm_e algo, const char *secret, size_t secret_len, const char *info, size_t info_len, size_t key_material_len, char **key_material) | 
|   | Derives a key material from shared secret.  
  | 
| int  | yaca_key_derive_pbkdf2 (const char *password, const char *salt, size_t salt_len, size_t iterations, yaca_digest_algorithm_e algo, size_t key_bit_len, yaca_key_h *key) | 
|   | Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm).  
  | 
| void  | yaca_key_destroy (yaca_key_h key) | 
|   | Release the key created by the library. Passing YACA_KEY_NULL is allowed.  
  | 
Defines | 
| #define  | YACA_KEY_NULL   ((yaca_key_h) NULL) | 
|   | NULL value for yaca_key_h type.  
  | 
Define Documentation
NULL value for yaca_key_h type. 
- Since :
 - 3.0 
 
 
 
Function Documentation
Derives a key material from shared secret. 
- Since :
 - 3.0
 
- Parameters:
 - 
  
    | [in] | kdf | Key derivation function  | 
    | [in] | algo | Digest algorithm that should be used in key derivation  | 
    | [in] | secret | Shared secret  | 
    | [in] | secret_len | Size of the shared secret  | 
    | [in] | info | Optional additional info, use NULL if not appending extra info  | 
    | [in] | info_len | Length of additional info, use 0 if not using additional info  | 
    | [in] | key_material_len | Length of a key material to be generated  | 
    | [out] | key_material | Newly generated key material | 
  
   
- Returns:
 - YACA_ERROR_NONE on success, negative on error 
 
- Return values:
 - 
  
  
 
- See also:
 - yaca_kdf_e 
 
- 
yaca_digest_algorithm_e 
 
- 
yaca_key_derive_dh() 
 
- 
yaca_key_import() 
 
- 
yaca_free() 
 
 
 
Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). 
- Since :
 - 3.0
 
- Parameters:
 - 
  
    | [in] | password | User password as a null-terminated string  | 
    | [in] | salt | Salt, should be a non-empty string  | 
    | [in] | salt_len | Length of the salt  | 
    | [in] | iterations | Number of iterations  | 
    | [in] | algo | Digest algorithm that should be used in key generation  | 
    | [in] | key_bit_len | Length of a key (in bits) to be generated  | 
    | [out] | key | Newly generated key | 
  
   
- Returns:
 - YACA_ERROR_NONE on success, negative on error 
 
- Return values:
 - 
  
  
 
- See also:
 - yaca_digest_algorithm_e 
 
- 
yaca_key_destroy() 
 
 
 
Exports a key or key generation parameters to arbitrary format. 
- Since :
 - 3.0
 
- Parameters:
 - 
  
    | [in] | key | Key to be exported  | 
    | [in] | key_fmt | Format of the key  | 
    | [in] | key_file_fmt | Format of the key file  | 
    | [in] | password | Password used for the encryption (can be NULL)  | 
    | [out] | data | Data, allocated by the library, containing exported key (must be freed with yaca_free())  | 
    | [out] | data_len | Size of the output data | 
  
   
- Returns:
 - YACA_ERROR_NONE on success, negative on error 
 
- Return values:
 - 
  
  
 
- See also:
 - yaca_key_format_e 
 
- 
yaca_key_file_format_e 
 
- 
yaca_key_import() 
 
- 
yaca_key_destroy() 
 
 
 
Gets key's type. 
- Since :
 - 3.0
 
- Parameters:
 - 
  
    | [in] | key | Key which type we return  | 
    | [out] | key_type | Key type | 
  
   
- Returns:
 - YACA_ERROR_NONE on success, negative on error 
 
- Return values:
 - 
  
  
 
- See also:
 - yaca_key_type_e 
 
 
 
Imports a key or key generation parameters. 
- Since :
 - 3.0
 
- Parameters:
 - 
  
    | [in] | key_type | Type of the key  | 
    | [in] | password | Null-terminated password for the key (can be NULL)  | 
    | [in] | data | Blob containing the key  | 
    | [in] | data_len | Size of the blob  | 
    | [out] | key | Returned key | 
  
   
- Returns:
 - YACA_ERROR_NONE on success, negative on error 
 
- Return values:
 - 
  
  
 
- See also:
 - yaca_key_type_e 
 
- 
yaca_key_export() 
 
- 
yaca_key_destroy()