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()