From 44822be1342157167807fa3602de469071411095 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 2 May 2016 17:48:47 +0200 Subject: [PATCH 01/16] Make it possible to generate private keys with yaca_key_gen() Change-Id: I7d4928ab27dad85cd52f3cff60ff9a9e61ae261f --- api/yaca/key.h | 8 ++-- src/key.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 29 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index c7e3727..e1126a6 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -113,16 +113,18 @@ int yaca_key_export(const yaca_key_h key, size_t *data_len); /** - * @brief yaca_key_gen Generates a secure symmetric key (or an initialization vector). + * @brief yaca_key_gen Generates a secure key (or an initialization vector). * - * @param[out] sym_key Newly generated key (must be freed with yaca_key_free()). + * This function is used to generate symmetric and private asymmetric keys. + * + * @param[out] key Newly generated key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key to be generated. * @param[in] key_bits Length of the key (in bits) to be generated. * * @return 0 on success, negative on error. * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_gen_pair(), yaca_key_free() */ -int yaca_key_gen(yaca_key_h *sym_key, +int yaca_key_gen(yaca_key_h *key, yaca_key_type_e key_type, size_t key_bits); diff --git a/src/key.c b/src/key.c index 5c0d43c..2ba3fe9 100644 --- a/src/key.c +++ b/src/key.c @@ -523,6 +523,88 @@ free_bio: return ret; } +int gen_simple(struct yaca_key_simple_s **out, size_t key_bits) +{ + assert(out != NULL); + + int ret; + struct yaca_key_simple_s *nk; + size_t key_byte_len = key_bits / 8; + + if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nk->bits = key_bits; + + ret = yaca_rand_bytes(nk->d, key_byte_len); + if (ret != 0) + return ret; + + *out = nk; + return 0; +} + +int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits) +{ + assert(out != NULL); + assert(key_bits > 0); + assert(key_bits % 8 == 0); + + int ret; + struct yaca_key_evp_s *nk; + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + + nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (ctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_nk; + } + + ret = EVP_PKEY_keygen_init(ctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; + } + + ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; + } + + ret = EVP_PKEY_keygen(ctx, &pkey); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; + } + + nk->evp = pkey; + + *out = nk; + nk = NULL; + ret = 0; + +free_ctx: + EVP_PKEY_CTX_free(ctx); +free_nk: + yaca_free(nk); + + return ret; +} + struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { struct yaca_key_simple_s *k; @@ -659,49 +741,51 @@ API int yaca_key_export(const yaca_key_h key, return YACA_ERROR_INVALID_ARGUMENT; } -API int yaca_key_gen(yaca_key_h *sym_key, +// TODO: this NEEDS random number generator initialized +// there is some other TODO elsewhere about it +API int yaca_key_gen(yaca_key_h *key, yaca_key_type_e key_type, size_t key_bits) { int ret; - struct yaca_key_simple_s *nk = NULL; - size_t key_byte_len = key_bits / 8; + struct yaca_key_simple_s *nk_simple = NULL; + struct yaca_key_evp_s *nk_evp = NULL; - if (sym_key == NULL || key_bits % 8 != 0) + if (key == NULL || key_bits == 0 || key_bits % 8 != 0) return YACA_ERROR_INVALID_ARGUMENT; switch(key_type) { case YACA_KEY_TYPE_SYMMETRIC: case YACA_KEY_TYPE_IV: - break; - case YACA_KEY_TYPE_DES: - return YACA_ERROR_NOT_IMPLEMENTED; - default: - return YACA_ERROR_INVALID_ARGUMENT; - } - - if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) - return YACA_ERROR_TOO_BIG_ARGUMENT; + ret = gen_simple(&nk_simple, key_bits); + if (ret != 0) + return ret; - nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); - if (nk == NULL) - return YACA_ERROR_OUT_OF_MEMORY; + nk_simple->key.type = key_type; - nk->bits = key_bits; - nk->key.type = key_type; + *key = (yaca_key_h)nk_simple; + return 0; - ret = yaca_rand_bytes(nk->d, key_byte_len); - if (ret != 0) - goto err; + case YACA_KEY_TYPE_RSA_PRIV: + ret = gen_evp_rsa(&nk_evp, key_bits); + if (ret != 0) + return ret; - *sym_key = (yaca_key_h)nk; + nk_evp->key.type = key_type; - return 0; + *key = (yaca_key_h)nk_evp; + return 0; -err: - yaca_free(nk); - return ret; + case YACA_KEY_TYPE_DES: + case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_ECDSA_PRIV: + case YACA_KEY_TYPE_ECDH_PRIV: + return YACA_ERROR_NOT_IMPLEMENTED; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } } API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) -- 2.7.4 From c74009102692e8ef59f70de4c49917efbd387c16 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 4 May 2016 13:36:27 +0200 Subject: [PATCH 02/16] Removal of yaca_key_gen_pair() and its enum values You can achieve the same now with yaca_key_gen() and yaca_key_extract_public() if/when the latter is needed. Change-Id: I5f47ed118e283b4d868f000108900f377b1260df --- api/yaca/key.h | 20 +------- api/yaca/types.h | 6 --- examples/key_exchange.c | 14 ++++-- examples/key_import_export.c | 6 ++- examples/seal.c | 10 ++-- examples/sign.c | 5 +- src/key.c | 113 ------------------------------------------- todo.txt | 1 - 8 files changed, 28 insertions(+), 147 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index e1126a6..0ffc8cf 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -122,7 +122,7 @@ int yaca_key_export(const yaca_key_h key, * @param[in] key_bits Length of the key (in bits) to be generated. * * @return 0 on success, negative on error. - * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_gen_pair(), yaca_key_free() + * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_free() */ int yaca_key_gen(yaca_key_h *key, yaca_key_type_e key_type, @@ -140,27 +140,11 @@ int yaca_key_gen(yaca_key_h *key, int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** - * @brief yaca_key_gen_pair Generates a new key pair. - * - * @param[out] prv_key Newly generated private key (must be freed with yaca_key_free()). - * @param[out] pub_key Newly generated public key (must be freed with yaca_key_free()). - * @param[in] key_type Type of the key to be generated (must be YACA_KEY_TYPE_PAIR*). - * @param[in] key_bits Length of the key (in bits) to be generated. - * - * @return 0 on success, negative on error. - * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_gen(), yaca_key_free() - */ -int yaca_key_gen_pair(yaca_key_h *prv_key, - yaca_key_h *pub_key, - yaca_key_type_e key_type, - size_t key_bits); - -/** * @brief yaca_key_free Frees the key created by the library. * Passing YACA_KEY_NULL is allowed. * * @param key Key to be freed. - * @see yaca_key_import(), yaca_key_export(), yaca_key_gen(), yaca_key_gen_pair() + * @see yaca_key_import(), yaca_key_export(), yaca_key_gen() * */ void yaca_key_free(yaca_key_h key); diff --git a/api/yaca/types.h b/api/yaca/types.h index c467121..ea9b2bd 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -87,12 +87,6 @@ typedef enum { // TODO: ECDH might not exist as a separate key type, remove? YACA_KEY_TYPE_ECDH_PUB, /**< Elliptic Curve Diffie-Hellman public key */ YACA_KEY_TYPE_ECDH_PRIV, /**< Elliptic Curve Diffie-Hellman private key */ - - YACA_KEY_TYPE_PAIR_RSA, /**< Pair of RSA keys */ - YACA_KEY_TYPE_PAIR_DSA, /**< Pair of DSA keys */ - YACA_KEY_TYPE_PAIR_DH, /**< Pair of DH keys */ - YACA_KEY_TYPE_PAIR_ECDSA, /**< Pair of ECDSA keys */ - YACA_KEY_TYPE_PAIR_ECDH /**< Pair of ECDH keys */ } yaca_key_type_e; /** diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 9192679..b3e4f05 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -43,9 +43,11 @@ void key_exchange_dh(void) long size; // generate private, public key - // add KEY_TYPE_PAIR_DH or use KEY_TYPE_PAIR_ECC and proper len? - // imo add KEY_TYPE_PAIR_DH - ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_TYPE_PAIR_DH, YACA_KEY_2048BIT); + ret = yaca_key_gen(&private_key, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_2048BIT); + if (ret < 0) + goto clean; + + ret = yaca_key_extract_public(private_key, &public_key); if (ret < 0) goto clean; @@ -101,7 +103,11 @@ void key_exchange_ecdh(void) long size; // generate private, public key - ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_TYPE_PAIR_ECDH, YACA_KEY_CURVE_P256); + ret = yaca_key_gen(&private_key, YACA_KEY_TYPE_ECDH_PRIV, YACA_KEY_CURVE_P256); + if (ret < 0) + goto clean; + + ret = yaca_key_extract_public(private_key, &public_key); if (ret < 0) goto clean; diff --git a/examples/key_import_export.c b/examples/key_import_export.c index fba4664..02fb4ab 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -213,7 +213,11 @@ int main() if (ret != 0) goto exit; - ret = yaca_key_gen_pair(&rsa_priv, &rsa_pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_1024BIT); + ret = yaca_key_gen(&rsa_priv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_1024BIT); + if (ret != 0) + goto free_sym; + + ret = yaca_key_extract_public(rsa_priv, &rsa_pub); if (ret != 0) goto free_sym; diff --git a/examples/seal.c b/examples/seal.c index a631c91..c75b721 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -54,13 +54,16 @@ void encrypt_seal(void) printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); /* Generate key pair */ - if (yaca_key_gen_pair(&key_priv, &key_pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_4096BIT) != 0) + if (yaca_key_gen(&key_priv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_4096BIT) != 0) return; + if (yaca_key_extract_public(key_priv, &key_pub) != 0) + goto ex_prvk; + /* Encrypt a.k.a. seal */ { if (yaca_seal_init(&ctx, key_pub, algo, bcm, key_bits, &aes_key, &iv) != 0) - goto ex_pk; + goto ex_pubk; if ((block_len = yaca_get_block_length(ctx)) <= 0) goto ex_ak; @@ -128,8 +131,9 @@ ex_ak: yaca_ctx_free(ctx); yaca_key_free(aes_key); yaca_key_free(iv); -ex_pk: +ex_pubk: yaca_key_free(key_pub); +ex_prvk: yaca_key_free(key_priv); } diff --git a/examples/sign.c b/examples/sign.c index 58b921f..84d5574 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -46,9 +46,12 @@ void sign_verify_rsa(void) #endif // GENERATE - if (yaca_key_gen_pair(&prv, &pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_4096BIT) != 0) + if (yaca_key_gen(&prv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_4096BIT) != 0) return; + if (yaca_key_extract_public(prv, &pub) != 0) + goto finish; + // SIGN if (yaca_sign_init(&ctx, YACA_DIGEST_SHA512, prv) != 0) goto finish; diff --git a/src/key.c b/src/key.c index 2ba3fe9..de2b48e 100644 --- a/src/key.c +++ b/src/key.c @@ -855,119 +855,6 @@ free_key: return ret; } -API int yaca_key_gen_pair(yaca_key_h *prv_key, - yaca_key_h *pub_key, - yaca_key_type_e key_type, - size_t key_bits) -{ - int ret; - struct yaca_key_evp_s *nk_prv = NULL; - struct yaca_key_evp_s *nk_pub = NULL; - RSA *rsa = NULL; - BIGNUM *bne = NULL; - - if (prv_key == NULL || pub_key == NULL) - return YACA_ERROR_INVALID_ARGUMENT; - - if (key_type != YACA_KEY_TYPE_PAIR_RSA) - return YACA_ERROR_NOT_IMPLEMENTED; - - nk_prv = yaca_zalloc(sizeof(struct yaca_key_evp_s)); - if (nk_prv == NULL) - return YACA_ERROR_OUT_OF_MEMORY; - - nk_pub = yaca_zalloc(sizeof(struct yaca_key_evp_s)); - if (nk_pub == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - goto free_prv; - } - - // TODO: this NEEDS random number generator initialized - // there is some other TODO elsewhere about it - - bne = BN_new(); - if (bne == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - ERROR_DUMP(ret); - goto free_pub; - } - - ret = BN_set_word(bne, RSA_F4); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_bne; - } - - rsa = RSA_new(); - if (rsa == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - ERROR_DUMP(ret); - goto free_bne; - } - - ret = RSA_generate_key_ex(rsa, key_bits, bne, NULL); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_rsa; - } - - nk_prv->evp = EVP_PKEY_new(); - if (nk_prv->evp == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - ERROR_DUMP(ret); - goto free_rsa; - } - - nk_pub->evp = EVP_PKEY_new(); - if (nk_prv->evp == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - ERROR_DUMP(ret); - goto free_evp_prv; - } - - ret = EVP_PKEY_assign_RSA(nk_prv->evp, RSAPrivateKey_dup(rsa)); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_evp_pub; - } - - ret = EVP_PKEY_assign_RSA(nk_pub->evp, RSAPublicKey_dup(rsa)); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_evp_pub; - } - - *prv_key = (yaca_key_h)nk_prv; - (*prv_key)->type = YACA_KEY_TYPE_RSA_PRIV; - *pub_key = (yaca_key_h)nk_pub; - (*pub_key)->type = YACA_KEY_TYPE_RSA_PUB; - - ret = 0; - -free_evp_pub: - if (ret != 0) - EVP_PKEY_free(nk_pub->evp); -free_evp_prv: - if (ret != 0) - EVP_PKEY_free(nk_prv->evp); -free_rsa: - RSA_free(rsa); -free_bne: - BN_free(bne); -free_pub: - if (ret != 0) - yaca_free(nk_pub); -free_prv: - if (ret != 0) - yaca_free(nk_prv); - - return ret; -} - API void yaca_key_free(yaca_key_h key) { struct yaca_key_simple_s *simple_key = key_get_simple(key); diff --git a/todo.txt b/todo.txt index b2e5846..a13943d 100644 --- a/todo.txt +++ b/todo.txt @@ -2,4 +2,3 @@ Global: - Rethink and possibly add verification of output buffer lengths. In other words check whether the user won't cause a buffer overflow. - Importing/exporting encrypted (passphrased) RSA keys -- What about importing RSA priv and generating PUB from it? -- 2.7.4 From dba9420e3a86166562aa8e3a18cc637b75a361d1 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 6 May 2016 11:49:23 +0200 Subject: [PATCH 03/16] Add missing example comments Change-Id: Ie67851cf21395a72519ff2d2e79973184572749c --- examples/key_import_export.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 02fb4ab..57b231c 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -44,6 +44,8 @@ void key_import_export_sym(yaca_key_h sym) yaca_key_h b64_imported = YACA_KEY_NULL; + /* BASE64 */ + ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, &b64, &b64_len); if (ret != 0) return; @@ -62,6 +64,8 @@ void key_import_export_sym(yaca_key_h sym) printf("\t***** BASE64 imported key: *****\n%*s\n", (int)b64_len, b64); + /* RAW */ + ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, &raw, &raw_len); if (ret != 0) goto free; -- 2.7.4 From 571478e61b249ae1c9a5c78f2652d164baf75bda Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 6 May 2016 16:18:53 +0200 Subject: [PATCH 04/16] Add GNU global files to .gitignore Change-Id: I6e7160af73a35b33bdcf76059c3a99be8f29c0db --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7115d13..3a844ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ build doc/html doc/man +GPATH +GRTAGS +GTAGS -- 2.7.4 From 1dcbbaa65ed769da7b54cdc1fb9ea3068cec3a75 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 6 May 2016 18:44:56 +0200 Subject: [PATCH 05/16] yaca_key_gen() and yaca_key_extract_public() for DSA There is no dedicated method to extract public key for DSA, only export/import (to temporary memory). As the latter method also works for RSA and I predict it will work for ECDSA I use it exclusively. Change-Id: Idf25df43da571cfb3d67192b5263e4a4c260feeb --- src/key.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 133 insertions(+), 37 deletions(-) diff --git a/src/key.c b/src/key.c index de2b48e..00a26d3 100644 --- a/src/key.c +++ b/src/key.c @@ -605,6 +605,90 @@ free_nk: return ret; } +int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits) +{ + assert(out != NULL); + assert(key_bits > 0); + assert(key_bits % 8 == 0); + + int ret; + struct yaca_key_evp_s *nk; + EVP_PKEY_CTX *pctx; + EVP_PKEY_CTX *kctx; + EVP_PKEY *pkey = NULL; + EVP_PKEY *params = NULL; + + nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if (pctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_nk; + } + + ret = EVP_PKEY_paramgen_init(pctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pctx; + } + + ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pctx; + } + + ret = EVP_PKEY_paramgen(pctx, ¶ms); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pctx; + } + + kctx = EVP_PKEY_CTX_new(params, NULL); + if (kctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_params; + } + + ret = EVP_PKEY_keygen_init(kctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_kctx; + } + + ret = EVP_PKEY_keygen(kctx, &pkey); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_kctx; + } + + nk->evp = pkey; + + *out = nk; + nk = NULL; + ret = 0; + +free_kctx: + EVP_PKEY_CTX_free(kctx); +free_params: + EVP_PKEY_free(params); +free_pctx: + EVP_PKEY_CTX_free(pctx); +free_nk: + yaca_free(nk); + + return ret; +} + struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { struct yaca_key_simple_s *k; @@ -777,8 +861,17 @@ API int yaca_key_gen(yaca_key_h *key, *key = (yaca_key_h)nk_evp; return 0; - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DSA_PRIV: + ret = gen_evp_dsa(&nk_evp, key_bits); + if (ret != 0) + return ret; + + nk_evp->key.type = key_type; + + *key = (yaca_key_h)nk_evp; + return 0; + + case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PRIV: case YACA_KEY_TYPE_ECDH_PRIV: @@ -792,8 +885,9 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) { int ret; struct yaca_key_evp_s *evp_key = key_get_evp(prv_key); - struct yaca_key_evp_s *nk = NULL; - RSA *rsa_pub = NULL; + struct yaca_key_evp_s *nk; + BIO *mem; + EVP_PKEY *pkey; if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -802,54 +896,56 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; - nk->evp = EVP_PKEY_new(); - if (nk->evp == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); - goto free_key; + goto free_nk; } - switch(prv_key->type) - { - case YACA_KEY_TYPE_RSA_PRIV: - assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_RSA); - - rsa_pub = RSAPublicKey_dup(EVP_PKEY_get0(evp_key->evp)); - if (rsa_pub == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_evp; - } + ret = i2d_PUBKEY_bio(mem, evp_key->evp); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } - ret = EVP_PKEY_assign_RSA(nk->evp, rsa_pub); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto free_rsa; - } + pkey = d2i_PUBKEY_bio(mem, NULL); + if (pkey == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } - *pub_key = (yaca_key_h)nk; - (*pub_key)->type = YACA_KEY_TYPE_RSA_PUB; + BIO_free(mem); + mem = NULL; - return 0; + nk->evp = pkey; + *pub_key = (yaca_key_h)nk; + switch(prv_key->type) + { + case YACA_KEY_TYPE_RSA_PRIV: + (*pub_key)->type = YACA_KEY_TYPE_RSA_PUB; + break; case YACA_KEY_TYPE_DSA_PRIV: + (*pub_key)->type = YACA_KEY_TYPE_DSA_PUB; + break; case YACA_KEY_TYPE_ECDSA_PRIV: - ret = YACA_ERROR_NOT_IMPLEMENTED; - goto free_evp; - + (*pub_key)->type = YACA_KEY_TYPE_ECDSA_PUB; + break; default: ret = YACA_ERROR_INVALID_ARGUMENT; - goto free_evp; + goto free_pkey; } - return YACA_ERROR_INVALID_ARGUMENT; + return 0; -free_rsa: - RSA_free(rsa_pub); -free_evp: - EVP_PKEY_free(nk->evp); -free_key: +free_pkey: + EVP_PKEY_free(pkey); +free_bio: + BIO_free(mem); +free_nk: yaca_free(nk); return ret; -- 2.7.4 From 82a68c8a8ab4ca140798a192c8086318ae915b00 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 12:42:54 +0200 Subject: [PATCH 06/16] yaca_key_import()/yaca_key_export() for DSA It seems that my previous import/export commit was generic enough to handle DSA as well. Only minor change was required to enable DSA. That's why this commit is so short. Change-Id: I0627c10a723b0011dde705d74d290caa36533a9d --- src/key.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index 00a26d3..2406350 100644 --- a/src/key.c +++ b/src/key.c @@ -777,10 +777,10 @@ API int yaca_key_import(yaca_key_h *key, return import_simple(key, key_type, data, data_len); case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_RSA_PRIV: - return import_evp(key, key_type, data, data_len); - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: + return import_evp(key, key_type, data, data_len); + case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PUB: -- 2.7.4 From d98b1aa22ed766ef6c311efc5940f11a13750d43 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:20:54 +0200 Subject: [PATCH 07/16] Add DSA to import/export example Improved printing a little. This example can serve partially as a test. It has been written this way as a verification tool as we don't have proper tests yet. Change-Id: Ifbda0f17e2e8fc0b734d34d49668a4a7662c337d --- examples/key_import_export.c | 100 +++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 57b231c..6dc18e1 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -31,7 +31,7 @@ #include #include -void key_import_export_sym(yaca_key_h sym) +int key_import_export_sym(yaca_key_h sym) { int ret; @@ -48,12 +48,12 @@ void key_import_export_sym(yaca_key_h sym) ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, &b64, &b64_len); if (ret != 0) - return; + return ret; ret = yaca_key_import(&b64_imported, YACA_KEY_TYPE_SYMMETRIC, b64, b64_len); if (ret != 0) goto free; - printf("\n\t***** BASE64 exported key: *****\n%*s\n", (int)b64_len, b64); + printf("\n\t***** BASE64 exported key: *****\n%.*s\n", (int)b64_len, b64); yaca_free(b64); b64 = NULL; @@ -61,7 +61,7 @@ void key_import_export_sym(yaca_key_h sym) if (ret != 0) goto free; - printf("\t***** BASE64 imported key: *****\n%*s\n", (int)b64_len, b64); + printf("\t***** BASE64 imported key: *****\n%.*s\n", (int)b64_len, b64); /* RAW */ @@ -83,14 +83,20 @@ void key_import_export_sym(yaca_key_h sym) dump_hex(raw, raw_len, "\t***** RAW imported key: *****"); + ret = 0; + free: yaca_key_free(raw_imported); yaca_key_free(b64_imported); yaca_free(raw); yaca_free(b64); + + return ret; } -void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) +int key_import_export_asym(yaca_key_h priv, yaca_key_h pub, + yaca_key_type_e priv_type, yaca_key_type_e pub_type, + const char *algo) { int ret; @@ -114,12 +120,12 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) ret = yaca_key_export(priv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_prv, &pem_prv_len); if (ret != 0) - return; - ret = yaca_key_import(&pem_prv_imported, YACA_KEY_TYPE_RSA_PRIV, pem_prv, pem_prv_len); + return ret; + ret = yaca_key_import(&pem_prv_imported, priv_type, pem_prv, pem_prv_len); if (ret != 0) goto free; - printf("\n\t***** PEM exported private key: *****\n%*s", (int)pem_prv_len, pem_prv); + printf("\n\t***** %s PEM exported private key: *****\n%.*s", algo, (int)pem_prv_len, pem_prv); yaca_free(pem_prv); pem_prv = NULL; @@ -127,7 +133,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - printf("\t***** PEM imported private key: *****\n%*s", (int)pem_prv_len, pem_prv); + printf("\t***** %s PEM imported private key: *****\n%.*s", algo, (int)pem_prv_len, pem_prv); /* DER private */ @@ -135,11 +141,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) ret = yaca_key_export(priv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_prv, &der_prv_len); if (ret != 0) goto free; - ret = yaca_key_import(&der_prv_imported, YACA_KEY_TYPE_RSA_PRIV, der_prv, der_prv_len); + ret = yaca_key_import(&der_prv_imported, priv_type, der_prv, der_prv_len); if (ret != 0) goto free; - dump_hex(der_prv, der_prv_len, "\n\t***** DER exported private key: *****"); + dump_hex(der_prv, der_prv_len, "\n\t***** %s DER exported private key: *****", algo); yaca_free(der_prv); der_prv = NULL; @@ -147,7 +153,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - dump_hex(der_prv, der_prv_len, "\t***** DER imported private key: *****"); + dump_hex(der_prv, der_prv_len, "\t***** %s DER imported private key: *****", algo); /* PEM public */ @@ -155,11 +161,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) ret = yaca_key_export(pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_pub, &pem_pub_len); if (ret != 0) goto free; - ret = yaca_key_import(&pem_pub_imported, YACA_KEY_TYPE_RSA_PUB, pem_pub, pem_pub_len); + ret = yaca_key_import(&pem_pub_imported, pub_type, pem_pub, pem_pub_len); if (ret != 0) goto free; - printf("\n\t***** PEM exported public key: *****\n%*s", (int)pem_pub_len, pem_pub); + printf("\n\t***** %s PEM exported public key: *****\n%.*s", algo, (int)pem_pub_len, pem_pub); yaca_free(pem_pub); pem_pub = NULL; @@ -167,7 +173,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - printf("\t***** PEM imported public key: *****\n%*s", (int)pem_pub_len, pem_pub); + printf("\t***** %s PEM imported public key: *****\n%.*s", algo, (int)pem_pub_len, pem_pub); /* DER public */ @@ -175,11 +181,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) ret = yaca_key_export(pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_pub, &der_pub_len); if (ret != 0) goto free; - ret = yaca_key_import(&der_pub_imported, YACA_KEY_TYPE_RSA_PUB, der_pub, der_pub_len); + ret = yaca_key_import(&der_pub_imported, pub_type, der_pub, der_pub_len); if (ret != 0) goto free; - dump_hex(der_pub, der_pub_len, "\n\t***** DER exported public key: *****"); + dump_hex(der_pub, der_pub_len, "\n\t***** %s DER exported public key: *****", algo); yaca_free(der_pub); der_pub = NULL; @@ -187,7 +193,9 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - dump_hex(der_pub, der_pub_len, "\t***** DER imported public key: *****"); + dump_hex(der_pub, der_pub_len, "\t***** %s DER imported public key: *****", algo); + + ret = 0; free: yaca_key_free(der_pub_imported); @@ -198,13 +206,17 @@ free: yaca_free(pem_pub); yaca_free(der_prv); yaca_free(pem_prv); + + return ret; } int main() { - yaca_key_h sym; - yaca_key_h rsa_priv; - yaca_key_h rsa_pub; + yaca_key_h sym = YACA_KEY_NULL; + yaca_key_h rsa_priv = YACA_KEY_NULL; + yaca_key_h rsa_pub = YACA_KEY_NULL; + yaca_key_h dsa_priv = YACA_KEY_NULL; + yaca_key_h dsa_pub = YACA_KEY_NULL; int ret; ret = yaca_init(); @@ -219,18 +231,52 @@ int main() ret = yaca_key_gen(&rsa_priv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_1024BIT); if (ret != 0) - goto free_sym; + goto free; ret = yaca_key_extract_public(rsa_priv, &rsa_pub); if (ret != 0) - goto free_sym; + goto free; - key_import_export_sym(sym); - key_import_export_rsa(rsa_priv, rsa_pub); + ret = yaca_key_gen(&dsa_priv, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_1024BIT); + if (ret != 0) + goto free; - yaca_key_free(rsa_priv); + ret = yaca_key_extract_public(dsa_priv, &dsa_pub); + if (ret != 0) + goto free; + + printf("\t***************************************\n"); + printf("\t************** SYMMETRIC **************\n"); + printf("\t***************************************\n"); + ret = key_import_export_sym(sym); + if (ret == 0) + printf("\n\t********* SYMMETRIC - success *********\n\n"); + else + printf("\n\t********* SYMMETRIC - failure *********\n\n"); + + printf("\t***************************************\n"); + printf("\t***************** RSA *****************\n"); + printf("\t***************************************\n"); + ret = key_import_export_asym(rsa_priv, rsa_pub, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, "RSA"); + if (ret == 0) + printf("\n\t************ RSA - success ************\n\n"); + else + printf("\n\t************ RSA - failure ************\n\n"); + + printf("\t***************************************\n"); + printf("\t***************** DSA *****************\n"); + printf("\t***************************************\n"); + ret = key_import_export_asym(dsa_priv, dsa_pub, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, "DSA"); + if (ret == 0) + printf("\n\t************ DSA - success ************\n\n"); + else + printf("\n\t************ DSA - failure ************\n\n"); + +free: + yaca_key_free(dsa_pub); + yaca_key_free(dsa_priv); yaca_key_free(rsa_pub); -free_sym: + yaca_key_free(rsa_priv); yaca_key_free(sym); exit: yaca_exit(); -- 2.7.4 From 3fe61dca1147ecad93699d4d27bc12bc7ece3f65 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:27:08 +0200 Subject: [PATCH 08/16] DSA sign/verify support The previous implementation was generic enough to handle DSA as well. Change-Id: I0c952e340cae3fabb05aa0e10fa5f0947319e4f8 --- src/sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sign.c b/src/sign.c index 24fe7ac..b885cc6 100644 --- a/src/sign.c +++ b/src/sign.c @@ -157,9 +157,9 @@ API int yaca_sign_init(yaca_ctx_h *ctx, { case YACA_KEY_TYPE_SYMMETRIC: case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_DSA_PRIV: nc->op_type = OP_SIGN; break; - case YACA_KEY_TYPE_DSA_PRIV: case YACA_KEY_TYPE_ECDSA_PRIV: ret = YACA_ERROR_NOT_IMPLEMENTED; goto free_ctx; @@ -277,9 +277,9 @@ API int yaca_verify_init(yaca_ctx_h *ctx, nc->op_type = OP_VERIFY_SYMMETRIC; break; case YACA_KEY_TYPE_RSA_PUB: + case YACA_KEY_TYPE_DSA_PUB: nc->op_type = OP_VERIFY_ASYMMETRIC; break; - case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_ECDSA_PUB: ret = YACA_ERROR_NOT_IMPLEMENTED; goto free_ctx; -- 2.7.4 From 5d39a9bd90ad8c1f97ccd24aa62a6c90c5a055b6 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:29:05 +0200 Subject: [PATCH 09/16] DSA sign/verify example Change-Id: I29208ed486b03f40af4a1ddd52f999b3c6d25a99 --- examples/sign.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index 84d5574..c5c9a5e 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -33,7 +33,7 @@ #define PADDING_IMPLEMENTED 0 // Signature creation and verification using advanced API -void sign_verify_rsa(void) +void sign_verify_asym(yaca_key_type_e type, const char *algo) { char* signature = NULL; size_t signature_len; @@ -46,7 +46,7 @@ void sign_verify_rsa(void) #endif // GENERATE - if (yaca_key_gen(&prv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_4096BIT) != 0) + if (yaca_key_gen(&prv, type, YACA_KEY_4096BIT) != 0) return; if (yaca_key_extract_public(prv, &pub) != 0) @@ -74,7 +74,7 @@ void sign_verify_rsa(void) if (yaca_sign_final(ctx, signature, &signature_len) != 0) goto finish; - dump_hex(signature, signature_len, "RSA Signature of lorem4096:"); + dump_hex(signature, signature_len, "%s Signature of lorem4096:", algo); // CLEANUP yaca_ctx_free(ctx); @@ -93,9 +93,9 @@ void sign_verify_rsa(void) goto finish; if (yaca_verify_final(ctx, signature, signature_len) != 0) - printf("RSA verification failed\n"); + printf("%s verification failed\n", algo); else - printf("RSA verification succesful\n"); + printf("%s verification succesful\n", algo); finish: yaca_free(signature); @@ -219,7 +219,8 @@ int main() // TODO simple? - sign_verify_rsa(); + sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); + sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); sign_verify_hmac(); sign_verify_cmac(); -- 2.7.4 From 0a41580e6f4b9fa048450f697f7bca36e895f2b8 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 14:08:35 +0200 Subject: [PATCH 10/16] Use specific RSA/DSA export variants The reason is, that the output of a PEM is different in the case of PrivateKey variant and DSAPrivateKey and RSAPrivateKey variants. According to the manual they should behave the same way. They don't. They seem to be in a different ASN1 format. This change is to be consistent with the default behaviour of the command line tool. This problem does not seem to appear on DER keys, but just for consistency and to be safe do the same there. Change-Id: I6a765e831515e9aac0353595132a139aec7b38d2 --- src/key.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index 2406350..3327ba4 100644 --- a/src/key.c +++ b/src/key.c @@ -428,8 +428,12 @@ int export_evp(struct yaca_key_evp_s *evp_key, switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: + ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), + NULL, NULL, 0, NULL, NULL); + break; case YACA_KEY_TYPE_DSA_PRIV: - ret = PEM_write_bio_PrivateKey(mem, evp_key->evp, NULL, NULL, 0, NULL, NULL); + ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), + NULL, NULL, 0, NULL, NULL); break; case YACA_KEY_TYPE_RSA_PUB: @@ -457,8 +461,11 @@ int export_evp(struct yaca_key_evp_s *evp_key, switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: + ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); + break; + case YACA_KEY_TYPE_DSA_PRIV: - ret = i2d_PrivateKey_bio(mem, evp_key->evp); + ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); break; case YACA_KEY_TYPE_RSA_PUB: -- 2.7.4 From 92eb4e64e351bbdf04ad7049fc5f970b51a36d8a Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 15:50:58 +0200 Subject: [PATCH 11/16] Add support for importing public keys from X509 certificate Fix a bug with X509 not being freed and pkey not being freed in case of an error. Change-Id: I063f606b928c679c452347cc18db793fc066c509 --- src/key.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/key.c b/src/key.c index 3327ba4..db8b6c4 100644 --- a/src/key.c +++ b/src/key.c @@ -221,6 +221,7 @@ int import_evp(yaca_key_h *key, assert(data != NULL); assert(data_len != 0); + int ret; BIO *src = NULL; EVP_PKEY *pkey = NULL; bool private; @@ -257,6 +258,15 @@ int import_evp(yaca_key_h *key, pkey = PEM_read_bio_PUBKEY(src, NULL, NULL, NULL); private = false; } + + if (pkey == NULL) { + BIO_reset(src); + X509 *x509 = PEM_read_bio_X509(src, NULL, NULL, NULL); + if (x509 != NULL) + pkey = X509_get_pubkey(x509); + private = false; + X509_free(x509); + } } /* Possible DER */ else { @@ -292,21 +302,31 @@ int import_evp(yaca_key_h *key, break; default: - return YACA_ERROR_INVALID_ARGUMENT; + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free; } - if (type != key_type) - return YACA_ERROR_INVALID_ARGUMENT; + if (type != key_type) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free; + } nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); - if (nk == NULL) - return YACA_ERROR_OUT_OF_MEMORY; + if (nk == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto free; + } nk->evp = pkey; *key = (yaca_key_h)nk; (*key)->type = type; - return 0; + pkey = NULL; + ret = 0; + +free: + EVP_PKEY_free(pkey); + return ret; } int export_simple_raw(struct yaca_key_simple_s *simple_key, -- 2.7.4 From 95c02cc487f8c792d99eba6c9f4351fa3317844d Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 15:51:40 +0200 Subject: [PATCH 12/16] Example for X509 import Change-Id: I698b81ff87ca4f2579447a8085a2a2ba2f0cb3ee --- examples/key_import_export.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ examples/x509.crt | 21 +++++++++++++++++++++ examples/x509.key | 28 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 examples/x509.crt create mode 100644 examples/x509.key diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 6dc18e1..1c4db07 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -210,6 +210,42 @@ free: return ret; } +int key_import_x509(void) +{ + int ret; + char *pub = NULL; + size_t pub_len; + yaca_key_h rsa_pub_from_cert = YACA_KEY_NULL; + + ret = read_file("x509.crt", &pub, &pub_len); + if (ret != 0) { + printf("Make sure you copied a x509.crt from yaca_root/examples to your current directory\n"); + printf("You can also generate one with:\n"); + printf("openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout x509.key -out x509.crt\n"); + return ret; + } + + ret = yaca_key_import(&rsa_pub_from_cert, YACA_KEY_TYPE_RSA_PUB, pub, pub_len); + if (ret != 0) + goto free; + + yaca_free(pub); + pub = NULL; + + ret = yaca_key_export(rsa_pub_from_cert, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pub, &pub_len); + if (ret != 0) + goto free; + + printf("\n\t***** RSA X509 imported public key: *****\n%.*s", (int)pub_len, pub); + + ret = 0; + +free: + yaca_key_free(rsa_pub_from_cert); + yaca_free(pub); + return ret; +} + int main() { yaca_key_h sym = YACA_KEY_NULL; @@ -272,6 +308,15 @@ int main() else printf("\n\t************ DSA - failure ************\n\n"); + printf("\t***************************************\n"); + printf("\t**************** X509 *****************\n"); + printf("\t***************************************\n"); + ret = key_import_x509(); + if (ret == 0) + printf("\n\t*********** X509 - success ************\n\n"); + else + printf("\n\t*********** X509 - failure ************\n\n"); + free: yaca_key_free(dsa_pub); yaca_key_free(dsa_priv); diff --git a/examples/x509.crt b/examples/x509.crt new file mode 100644 index 0000000..f421e11 --- /dev/null +++ b/examples/x509.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIJAMmTp8b7IBZ4MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV +BAYTAlBMMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxEDAOBgNVBAoMB1NhbXN1bmcx +CzAJBgNVBAsMAlJEMRYwFAYDVQQDDA15YWNhLnRlc3Qua2V5MB4XDTE2MDUwOTE0 +MDUwM1oXDTE3MDUwOTE0MDUwM1owWzELMAkGA1UEBhMCUEwxFTATBgNVBAcMDERl +ZmF1bHQgQ2l0eTEQMA4GA1UECgwHU2Ftc3VuZzELMAkGA1UECwwCUkQxFjAUBgNV +BAMMDXlhY2EudGVzdC5rZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC7729iOIdGcnuTba8nq1G4HF8isCR/8K/vtclsoCjAxQph5ANa+/9gbIFdQmmn +MBhSOckl9Tl/a9g/2b/vbezo2qXAuaeOPNr/ZF6Z+h7yPJids7WmBAPphzHeIKQf +kr2KLRbFYIIGF4mC/JfNOBzh8ChcklxnUJu4W8bJPrPkr3zlcMqxpRCCXAqIUxh7 +lCDta7Uoip+VcibRqh8g7+eZmTu3GwWtZQCB9kq5BijfguxxDHAXyQ6g7gxOZpwA +BP9AXdB7K1KAoeBf0e/lUjC1eXkhvno9TJSp2Q7LEIJqEe/Khyj4FG4KrOu/ifpS +wpGP1ztzdMcY5UGwSbtEwMqvAgMBAAGjUDBOMB0GA1UdDgQWBBTtvbhve2aaeNIL +0eYjakjeEGMCsDAfBgNVHSMEGDAWgBTtvbhve2aaeNIL0eYjakjeEGMCsDAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj9LtBvK6P65J/1jEfSajvoIip +ZtpW38KbRkgencq9bFeNONMHGv5M7tEnWNdytCPunlh5DLEXMUORcWfXU73GCNHO +9So74rri+q8NKrllJWxWmbYoAo+zJ3xSJ0PKhU8SW6J+dfPvsg140bUXI+MbOGrr +ski88TRVnBOb3HBU1Vd+A2W7YKy9j2ykQH4NiIUPV01h3hguvMLcLzHZ6LN/BHnA +NQx/K/EVIHZxy1ez8vbbIuWW5MRj6SPeofyZC0QoxQGIT6sGDZSNDP6xIGVuKw4D +UpzPNfCvsWgNIaIFTTzLBZJYCwoexJYIO+NiaJxCV9l3swj2iUA3yeyNQZhI +-----END CERTIFICATE----- diff --git a/examples/x509.key b/examples/x509.key new file mode 100644 index 0000000..e2d8ae1 --- /dev/null +++ b/examples/x509.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7729iOIdGcnuT +ba8nq1G4HF8isCR/8K/vtclsoCjAxQph5ANa+/9gbIFdQmmnMBhSOckl9Tl/a9g/ +2b/vbezo2qXAuaeOPNr/ZF6Z+h7yPJids7WmBAPphzHeIKQfkr2KLRbFYIIGF4mC +/JfNOBzh8ChcklxnUJu4W8bJPrPkr3zlcMqxpRCCXAqIUxh7lCDta7Uoip+VcibR +qh8g7+eZmTu3GwWtZQCB9kq5BijfguxxDHAXyQ6g7gxOZpwABP9AXdB7K1KAoeBf +0e/lUjC1eXkhvno9TJSp2Q7LEIJqEe/Khyj4FG4KrOu/ifpSwpGP1ztzdMcY5UGw +SbtEwMqvAgMBAAECggEBAJhdhZM/O0U9Gb0sJt5lggpfTi4kWmMzsqAIZPZhXsjy +tvkoUCQavC/jqHoAlwHJ913qpY7VorkQqTETDA5Es9cRNWLr4dFquy5lpGD3rNE9 +mYn5oeKnzLgvOJnbItTKNkrpRVXeaWwg9wawXS4vORNgjoiGzM2iR62PEroj0Nss +mwua2xs92ZHTAMNH6PdJC9U4gqjmlAMofV7ZgpxJLzKsI4rbxcGk9NWrie5bmMu+ +SECwtFDqxHe7YJRjSOvz/HErbXg9qWsglU6PFCVUjQ2dLM4k78ORkR5hvpGYGc83 +DucbEGqOnQ37RACvgNX4/RGFMvVnJDx3FVoDMcz2NFECgYEA6jEiY5RZuUy7jIBR +t1RFTem0KUFco7YLxwHacrT66vEntc1REXeBYSMPeKav1R319jxVVD7iiF4w49Ol +4VxxgPBUhfHou/ZU5S5xLbWRrJG0jvUPUKNVebNCqbv1YXhzf6kRn1vE5j+MR9ge +YMMFG1Si3VXoUm5+IInj1b2mC5kCgYEAzW+YiRJpEbl0+2gNCcHTAhr2cA1t6mdL +9/JGkUhHqwGhMAByZr1QFJeOTLKR9cSNS1FYOJu6wUetnkYDvNgx7gnsiJ50TEof +poTZgtnFCxgGwcEFL23L0PPim5CEUMHRti4j+Wlb8FzTQvz5WvyOw79II4i6DRaL +JA4KN/5aNYcCgYEA4EAqYNY2UGR0lqZtGTKdpmyp8nM/JRh2EJrqtbotJvnC/6hZ +/3LCteQftXVPm7AzzRSa1K/etZwUDqSlC7Y8ja4UEarCI/JN+qLNB2r80hU3o0hv +4NR2TbHknKl531q6pjybvk/erGefiVAeTqOP6UrTJURU0VIyfi/rtckDDckCgYBQ +Lm0/mrLtmw/gjCUCmObtnG5xH5y172lENgh67dYjFXi/Dn2YQe1+jASbRNsZLITl +T7N6LLYAeCR4cOVGkK80NCVg0U+c8xVVXeazXqG8ib0hZF/MujLhtD7O7uHlzzA1 +xd5+mzOqJeDC9Y+xhn+GQSM700Kilxjpkp1Ea370AwKBgGQzCY1tbO48s8RKd/Nz +oKG6ctp9S9vYtinXwuCdw0iL2i671bUgMONoXDNGcVBsYsuXb2324BKpw/bQK+BP +8p3TlBB1szA/W0EeueJkTHCkQninGc9vzvc6VbfacqJnuz7Pv/v1CkMa/E+ILamd +0aJoZHwNLuCkrzbVG+t+5yAS +-----END PRIVATE KEY----- -- 2.7.4 From 50e899abcb077f15bd7e72bd0a0ce2d934fb76db Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:31:01 +0200 Subject: [PATCH 13/16] Prevent use of uninitialized variable in examples Change-Id: I79052b160cd3d009fe89652a33e0450ee1e516d3 --- examples/misc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/misc.c b/examples/misc.c index b3a8fdc..ef8c53c 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -54,7 +54,7 @@ int read_file(const char *path, char **data, size_t *data_len) int ret; char tmp[BUF_SIZE]; char *buf = NULL; - size_t buf_len; + size_t buf_len = 0; FILE *f; f = fopen(path, "r"); @@ -71,7 +71,6 @@ int read_file(const char *path, char **data, size_t *data_len) ret = -1; break; } - buf_len = 0; } else { char *new_buf = yaca_realloc(buf, buf_len + read); if (new_buf == NULL) { -- 2.7.4 From cd27fc8c0d7d36de901313c87efce3eee06e1c8b Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:26:03 +0200 Subject: [PATCH 14/16] Remove symbol names from @brief paragraph Symbol names are not necessary in @brief paragraph. The symbol names are produced anyway and there's no point in duplicating them. Change-Id: I5283771962966cf2ff5ffbf91499f0c2fe8e48cd --- api/yaca/crypto.h | 41 ++++++++++++++++++++--------------------- api/yaca/digest.h | 6 +++--- api/yaca/encrypt.h | 14 +++++++------- api/yaca/error.h | 9 ++++----- api/yaca/key.h | 19 +++++++++---------- api/yaca/seal.h | 12 ++++++------ api/yaca/sign.h | 12 ++++++------ api/yaca/simple.h | 6 +++--- 8 files changed, 58 insertions(+), 61 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 52c7a32..20b444a 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -40,12 +40,12 @@ extern "C" { */ /** - * @brief YACA_CTX_NULL NULL value for the crypto context. + * @brief NULL value for the crypto context. */ #define YACA_CTX_NULL ((yaca_ctx_h) NULL) /** - * @brief yaca_init Initializes the library. Must be called before any other crypto function. + * @brief Initializes the library. Must be called before any other crypto function. * * @return 0 on success, negative on error. * @see yaca_exit() @@ -53,14 +53,14 @@ extern "C" { int yaca_init(void); /** - * @brief yaca_exit Closes the library. Must be called before exiting the application. + * @brief Closes the library. Must be called before exiting the application. * * @see yaca_init() */ void yaca_exit(void); /** - * @brief yaca_malloc Allocates the memory. + * @brief Allocates the memory. * * @param[in] size Size of the allocation (bytes). * @@ -71,7 +71,7 @@ void yaca_exit(void); void *yaca_malloc(size_t size); /** - * @brief yaca_zalloc Allocates the zeroed memory. + * @brief Allocates the zeroed memory. * * @param[in] size Size of the allocation (bytes). * @@ -82,7 +82,7 @@ void *yaca_malloc(size_t size); void *yaca_zalloc(size_t size); /** - * @brief yaca_realloc Re-allocates the memory. + * @brief Re-allocates the memory. * * @param[in] addr Address of the memory to be reallocated. * @param[in] size Size of the new allocation (bytes). @@ -94,8 +94,8 @@ void *yaca_zalloc(size_t size); void *yaca_realloc(void *addr, size_t size); /** - * @brief yaca_free Frees the memory allocated by yaca_malloc(), yaca_zalloc(), - * yaca_realloc() or one of the cryptographic operations. + * @brief Frees the memory allocated by yaca_malloc(), yaca_zalloc(), + * yaca_realloc() or one of the cryptographic operations. * * @param[in] ptr Pointer to the memory to be freed. * @see yaca_malloc(), yaca_zalloc(), yaca_realloc() @@ -105,7 +105,7 @@ void *yaca_realloc(void *addr, size_t size); void yaca_free(void *ptr); /** - * @brief yaca_rand_bytes Generates random data. + * @brief Generates random data. * * @param[in,out] data Pointer to the memory to be randomized. * @param[in] data_len Length of the memory to be randomized. @@ -115,8 +115,8 @@ void yaca_free(void *ptr); int yaca_rand_bytes(char *data, size_t data_len); /** - * @brief yaca_ctx_set_param Sets the extended context parameters. - * Can only be called on an initialized context. + * @brief Sets the extended context parameters. Can only be called on an + * initialized context. * * @param[in,out] ctx Previously initialized crypto context. * @param[in] param Parameter to be set. @@ -132,8 +132,8 @@ int yaca_ctx_set_param(yaca_ctx_h ctx, size_t value_len); /** - * @brief yaca_ctx_get_param Returns the extended context parameters. - * Can only be called on an initialized context. + * @brief Returns the extended context parameters. Can only be called on an + * initialized context. * * @param[in] ctx Previously initialized crypto context. * @param[in] param Parameter to be read. @@ -149,9 +149,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, size_t *value_len); /** - * @brief yaca_ctx_free Destroys the crypto context. Must be called - * on all contexts that are no longer used. - * Passing YACA_CTX_NULL is allowed. + * @brief Destroys the crypto context. Must be called on all contexts that are + * no longer used. Passing YACA_CTX_NULL is allowed. * * @param[in,out] ctx Crypto context. * @see #yaca_ctx_h @@ -160,8 +159,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, void yaca_ctx_free(yaca_ctx_h ctx); /** - * @brief yaca_get_output_length Returns the output length for a given algorithm. - * Can only be called on an initialized context. + * @brief Returns the output length for a given algorithm. Can only be called + * on an initialized context. * * @param[in] ctx Previously initialized crypto context. * @param[in] input_len Length of the input data to be processed. @@ -173,17 +172,17 @@ void yaca_ctx_free(yaca_ctx_h ctx); int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); /** - * @brief yaca_get_digest_length Wrapper - returns the length of the digest (for a given context). + * @brief Wrapper - returns the length of the digest (for a given context). */ #define yaca_get_digest_length(ctxa) yaca_get_output_length((ctxa), 0) /** - * @brief yaca_get_sign_length Wrapper - returns the length of the signature (for a given context). + * @brief Wrapper - returns the length of the signature (for a given context). */ #define yaca_get_sign_length(ctxa) yaca_get_output_length((ctxa), 0) /** - * @brief yaca_get_block_length Wrapper - returns the length of the block (for a given context). + * @brief Wrapper - returns the length of the block (for a given context). */ #define yaca_get_block_length(ctxa) yaca_get_output_length((ctxa), 0) diff --git a/api/yaca/digest.h b/api/yaca/digest.h index dc49b92..0ea17d4 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -40,7 +40,7 @@ extern "C" { */ /** - * @brief yaca_digest_init Initializes a digest context. + * @brief Initializes a digest context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -51,7 +51,7 @@ extern "C" { int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); /** - * @brief yaca_digest_update Feeds the data into the message digest algorithm. + * @brief Feeds the data into the message digest algorithm. * * @param[in,out] ctx Context created by yaca_digest_init(). * @param[in] data Data from which the digest is to be calculated. @@ -63,7 +63,7 @@ int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); /** - * @brief yaca_digest_final Calculates the final digest. + * @brief Calculates the final digest. * * @param[in,out] ctx A valid digest context. * @param[out] digest Buffer for the message digest (must be allocated by client, diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index b62541d..23351cf 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -42,7 +42,7 @@ extern "C" { */ /** - * @brief yaca_encrypt_init Initializes an encryption context. + * @brief Initializes an encryption context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. @@ -60,7 +60,7 @@ int yaca_encrypt_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_encrypt_update Encrypts chunk of the data. + * @brief Encrypts chunk of the data. * * @param[in,out] ctx Context created by yaca_encrypt_init(). * @param[in] plain Plain text to be encrypted. @@ -79,7 +79,7 @@ int yaca_encrypt_update(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_encrypt_final Encrypts the final chunk of the data. + * @brief Encrypts the final chunk of the data. * * @param[in,out] ctx A valid encrypt context. * @param[out] cipher Final piece of the encrypted data (must be allocated by client, see @@ -94,7 +94,7 @@ int yaca_encrypt_final(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_decrypt_init Initializes an decryption context. + * @brief Initializes an decryption context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that was used to encrypt the data. @@ -112,7 +112,7 @@ int yaca_decrypt_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_decrypt_update Decrypts chunk of the data. + * @brief Decrypts chunk of the data. * * @param[in,out] ctx Context created by yaca_decrypt_init(). * @param[in] cipher Cipher text to be decrypted. @@ -131,7 +131,7 @@ int yaca_decrypt_update(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_decrypt_final Decrypts the final chunk of the data. + * @brief Decrypts the final chunk of the data. * * @param[in,out] ctx A valid decrypt context. * @param[out] plain Final piece of the decrypted data (must be allocated by client, see @@ -146,7 +146,7 @@ int yaca_decrypt_final(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_get_iv_bits Returns the recomended/default length of the IV for a given encryption configuration. + * @brief Returns the recomended/default length of the IV for a given encryption configuration. * * @param[in] algo Encryption algorithm. * @param[in] bcm Chain mode. diff --git a/api/yaca/error.h b/api/yaca/error.h index 944d8a3..15addf0 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -54,12 +54,11 @@ enum __yaca_error_code { typedef void (*yaca_debug_func)(const char*); /** - * @brief yaca_error_set_debug_func Sets a current thread debug callback that will be called each - * time an internal error occurs. A NULL terminated string with - * location and description of the error will be passed as an - * argument. + * @brief Sets a current thread debug callback that will be called each time an + * internal error occurs. A NULL terminated string with location and + * description of the error will be passed as an argument. * - * @param[in] fn Function to set as internal error callback. + * @param[in] fn Function to set as internal error callback. */ void yaca_error_set_debug_func(yaca_debug_func fn); diff --git a/api/yaca/key.h b/api/yaca/key.h index 0ffc8cf..f97d6df 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -44,7 +44,7 @@ extern "C" { // TODO: We need a way to import keys encrypted with hw (or other) keys. New function like yaca_key_load or sth?? /** - * @brief yaca_key_get_bits Get key's length (in bits). + * @brief Get key's length (in bits). * * @param[in] key Key which length we return. * @@ -53,7 +53,7 @@ extern "C" { int yaca_key_get_bits(const yaca_key_h key); /** - * @brief yaca_key_import Imports a key. + * @brief Imports a key. * * This function imports a key trying to match it to the key_type specified. * It should autodetect both, key format and file format. @@ -81,7 +81,7 @@ int yaca_key_import(yaca_key_h *key, size_t data_len); /** - * @brief yaca_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. + * @brief Exports a key to arbitrary format. Export may fail if key is HW-based. * * This function exports the key to an arbitrary key format and key file format. * @@ -113,7 +113,7 @@ int yaca_key_export(const yaca_key_h key, size_t *data_len); /** - * @brief yaca_key_gen Generates a secure key (or an initialization vector). + * @brief Generates a secure key (or an initialization vector). * * This function is used to generate symmetric and private asymmetric keys. * @@ -129,7 +129,7 @@ int yaca_key_gen(yaca_key_h *key, size_t key_bits); /** - * @brief yaca_key_extract_public Extracts public key from a private one. + * @brief Extracts public key from a private one. * * @param[in] prv_key Private key to extract the public one from. * @param[out] pub_key Extracted public key (must be freed with yaca_key_free()). @@ -140,8 +140,7 @@ int yaca_key_gen(yaca_key_h *key, int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** - * @brief yaca_key_free Frees the key created by the library. - * Passing YACA_KEY_NULL is allowed. + * @brief Frees the key created by the library. Passing YACA_KEY_NULL is allowed. * * @param key Key to be freed. * @see yaca_key_import(), yaca_key_export(), yaca_key_gen() @@ -161,7 +160,7 @@ void yaca_key_free(yaca_key_h key); */ /** - * @brief yaca_key_derive_dh Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. + * @brief Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. * * @param[in] prv_key Our private key. * @param[in] pub_key Peer public key. @@ -175,7 +174,7 @@ int yaca_key_derive_dh(const yaca_key_h prv_key, yaca_key_h *sym_key); /** - * @brief yaca_key_derive_kea Derives a key using KEA key exchange protocol. + * @brief Derives a key using KEA key exchange protocol. * * @param[in] prv_key Our DH private component. * @param[in] pub_key Peers' DH public component. @@ -195,7 +194,7 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, yaca_key_h *sym_key); /** - * @brief yaca_key_derive_pbkdf2 Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). + * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * * @param[in] password User password as a NULL-terminated string. * @param[in] salt Salt, should be non-zero. diff --git a/api/yaca/seal.h b/api/yaca/seal.h index a6897be..4786ebe 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -44,7 +44,7 @@ extern "C" { */ /** - * @brief yaca_seal_init Initializes an asymmetric encryption context. + * @brief Initializes an asymmetric encryption context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] pub_key Public key of the peer that will receive the encrypted data. @@ -66,7 +66,7 @@ int yaca_seal_init(yaca_ctx_h *ctx, yaca_key_h *iv); /** - * @brief yaca_seal_update Encrypts piece of the data. + * @brief Encrypts piece of the data. * * @param[in,out] ctx Context created by yaca_seal_init(). * @param[in] plain Plain text to be encrypted. @@ -85,7 +85,7 @@ int yaca_seal_update(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_seal_final Encrypts the final piece of the data. + * @brief Encrypts the final piece of the data. * * @param[in,out] ctx A valid seal context. * @param[out] cipher Final piece of the encrypted data (must be allocated by client, see @@ -100,7 +100,7 @@ int yaca_seal_final(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_open_init Initializes an asymmetric decryption context. + * @brief Initializes an asymmetric decryption context. * * @param[out] ctx Newly created context. Must be freed by yaca_ctx_free(). * @param[in] prv_key Private key, part of the pair that was used for the encryption. @@ -122,7 +122,7 @@ int yaca_open_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_open_update Decrypts piece of the data. + * @brief Decrypts piece of the data. * * @param[in,out] ctx Context created by yaca_open_init(). * @param[in] cipher Cipher text to be decrypted. @@ -141,7 +141,7 @@ int yaca_open_update(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_open_final Decrypts last chunk of sealed message. + * @brief Decrypts last chunk of sealed message. * * @param[in,out] ctx A valid open context. * @param[out] plain Final piece of the decrypted data (must be allocated by client, see diff --git a/api/yaca/sign.h b/api/yaca/sign.h index 91c47d1..a5feb21 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -41,7 +41,7 @@ extern "C" { */ /** - * @brief yaca_sign_init Initializes a signature context. + * @brief Initializes a signature context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -55,7 +55,7 @@ int yaca_sign_init(yaca_ctx_h *ctx, const yaca_key_h key); /** - * @brief yaca_sign_update Feeds the data into the digital signature algorithm. + * @brief Feeds the data into the digital signature algorithm. * * @param[in,out] ctx Context created by yaca_sign_init(). * @param[in] data Data to be signed. @@ -69,7 +69,7 @@ int yaca_sign_update(yaca_ctx_h ctx, size_t data_len); /** - * @brief yaca_sign_final Calculates the final signature. + * @brief Calculates the final signature. * * @param[in,out] ctx A valid sign context. * @param[out] mac Buffer for the MAC or the signature (must be allocated by client, see @@ -84,7 +84,7 @@ int yaca_sign_final(yaca_ctx_h ctx, size_t *mac_len); /** - * @brief yaca_verify_init Initializes a signature verification context. + * @brief Initializes a signature verification context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -98,7 +98,7 @@ int yaca_verify_init(yaca_ctx_h *ctx, const yaca_key_h key); /** - * @brief yaca_verify_update Feeds the data into the digital signature verification algorithm. + * @brief Feeds the data into the digital signature verification algorithm. * * @param[in,out] ctx Context created by yaca_verify_init(). * @param[in] data Data to be verified. @@ -112,7 +112,7 @@ int yaca_verify_update(yaca_ctx_h ctx, size_t data_len); /** - * @brief yaca_verify_final Performs the verification. + * @brief Performs the verification. * * @param[in,out] ctx A valid verify context. * @param[in] mac Input MAC or signature (returned by yaca_sign_final()). diff --git a/api/yaca/simple.h b/api/yaca/simple.h index 3075aac..42a7545 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -48,7 +48,7 @@ extern "C" { */ /** - * @brief yaca_digest_calc Calculate a digest of a buffer. + * @brief Calculate a digest of a buffer. * * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure). * @param[in] data Data from which the digest is to be calculated. @@ -67,7 +67,7 @@ int yaca_digest_calc(yaca_digest_algo_e algo, size_t *digest_len); /** - * @brief yaca_encrypt Encrypt data using a symmetric cipher. + * @brief Encrypt data using a symmetric cipher. * * @param[in] algo Encryption algorithm (select #YACA_ENC_AES if unsure). * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure). @@ -92,7 +92,7 @@ int yaca_encrypt(yaca_enc_algo_e algo, size_t *cipher_len); /** - * @brief yaca_decrypt Decrypta data using a symmetric cipher. + * @brief Decrypt data using a symmetric cipher. * * @param[in] algo Decryption algorithm that was used to encrypt the data. * @param[in] bcm Chaining mode that was used to encrypt the data. -- 2.7.4 From 9f6b51792eae7e4ae5712c9d8f7efca8c9184115 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:45:55 +0200 Subject: [PATCH 15/16] Add prefix to header guards to avoid conflicts. Change-Id: I1e96b8ca538d61da8d4ae34ab9ee632472e192ce --- api/yaca/crypto.h | 6 +++--- api/yaca/digest.h | 6 +++--- api/yaca/encrypt.h | 6 +++--- api/yaca/error.h | 6 +++--- api/yaca/key.h | 6 +++--- api/yaca/seal.h | 6 +++--- api/yaca/sign.h | 6 +++--- api/yaca/simple.h | 6 +++--- api/yaca/types.h | 6 +++--- src/internal.h | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 20b444a..205cce2 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef CRYPTO_H -#define CRYPTO_H +#ifndef YACA_CRYPTO_H +#define YACA_CRYPTO_H #include #include @@ -192,4 +192,4 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); } /* extern */ #endif -#endif /* CRYPTO_H */ +#endif /* YACA_CRYPTO_H */ diff --git a/api/yaca/digest.h b/api/yaca/digest.h index 0ea17d4..5e3aa0d 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef DIGEST_H -#define DIGEST_H +#ifndef YACA_DIGEST_H +#define YACA_DIGEST_H #include #include @@ -81,4 +81,4 @@ int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len); } /* extern */ #endif -#endif /* DIGEST_H */ +#endif /* YACA_DIGEST_H */ diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index 23351cf..7806e16 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef ENCRYPT_H -#define ENCRYPT_H +#ifndef YACA_ENCRYPT_H +#define YACA_ENCRYPT_H #include #include @@ -164,4 +164,4 @@ int yaca_get_iv_bits(yaca_enc_algo_e algo, } /* extern */ #endif -#endif /* ENCRYPT_H */ +#endif /* YACA_ENCRYPT_H */ diff --git a/api/yaca/error.h b/api/yaca/error.h index 15addf0..55656bd 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef ERROR_H -#define ERROR_H +#ifndef YACA_ERROR_H +#define YACA_ERROR_H #ifdef __cplusplus extern "C" { @@ -68,4 +68,4 @@ void yaca_error_set_debug_func(yaca_debug_func fn); } /* extern */ #endif -#endif /* ERROR_H */ +#endif /* YACA_ERROR_H */ diff --git a/api/yaca/key.h b/api/yaca/key.h index f97d6df..ce69f21 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef KEY_H -#define KEY_H +#ifndef YACA_KEY_H +#define YACA_KEY_H #include #include @@ -224,4 +224,4 @@ int yaca_key_derive_pbkdf2(const char *password, } /* extern */ #endif -#endif /* KEY_H */ +#endif /* YACA_KEY_H */ diff --git a/api/yaca/seal.h b/api/yaca/seal.h index 4786ebe..4f7b2fa 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SEAL_H -#define SEAL_H +#ifndef YACA_SEAL_H +#define YACA_SEAL_H #include #include @@ -161,4 +161,4 @@ int yaca_open_final(yaca_ctx_h ctx, } /* extern */ #endif -#endif /* SEAL_H */ +#endif /* YACA_SEAL_H */ diff --git a/api/yaca/sign.h b/api/yaca/sign.h index a5feb21..f018a31 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SIGN_H -#define SIGN_H +#ifndef YACA_SIGN_H +#define YACA_SIGN_H #include #include @@ -131,4 +131,4 @@ int yaca_verify_final(yaca_ctx_h ctx, } /* extern */ #endif -#endif /* SIGN_H */ +#endif /* YACA_SIGN_H */ diff --git a/api/yaca/simple.h b/api/yaca/simple.h index 42a7545..ec1e333 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SIMPLE_H -#define SIMPLE_H +#ifndef YACA_SIMPLE_H +#define YACA_SIMPLE_H #include #include @@ -124,4 +124,4 @@ int yaca_decrypt(yaca_enc_algo_e algo, } /* extern */ #endif -#endif /* SIMPLE_H */ +#endif /* YACA_SIMPLE_H */ diff --git a/api/yaca/types.h b/api/yaca/types.h index ea9b2bd..d069fc2 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef TYPES_H -#define TYPES_H +#ifndef YACA_TYPES_H +#define YACA_TYPES_H #ifdef __cplusplus extern "C" { @@ -289,4 +289,4 @@ typedef enum { } /* extern */ #endif -#endif /* TYPES_H */ +#endif /* YACA_TYPES_H */ diff --git a/src/internal.h b/src/internal.h index 119728f..5d1f49a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -21,8 +21,8 @@ * @brief Internal API */ -#ifndef INTERNAL_H -#define INTERNAL_H +#ifndef YACA_INTERNAL_H +#define YACA_INTERNAL_H #include #include @@ -103,4 +103,4 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key); void error_dump(const char *file, int line, const char *function, int code); #define ERROR_DUMP(code) error_dump(__FILE__, __LINE__, __func__, (code)) -#endif +#endif /* YACA_INTERNAL_H */ -- 2.7.4 From f27c652d044cee5cd386904ac9f70cd545b62833 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 9 May 2016 16:27:22 +0200 Subject: [PATCH 16/16] Generate/import/export DES key. Change-Id: Iac23685e9be18204c0d9a317bf4aa17e4539e556 --- api/yaca/types.h | 3 +-- src/key.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index d069fc2..5b8c6b6 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -101,9 +101,8 @@ typedef enum { YACA_KEY_CURVE_P256 = 256, /**< ECC: P-256 curve */ YACA_KEY_CURVE_P384 = 384, /**< ECC: SECP-384 curve */ YACA_KEY_UNSAFE_40BIT = 40, - YACA_KEY_UNSAFE_56BIT = 56, + YACA_KEY_UNSAFE_64BIT = 64, YACA_KEY_UNSAFE_80BIT = 80, - YACA_KEY_UNSAFE_112BIT = 112, YACA_KEY_UNSAFE_128BIT = 128, YACA_KEY_192BIT = 192, YACA_KEY_256BIT = 256, diff --git a/src/key.c b/src/key.c index db8b6c4..bb6bc32 100644 --- a/src/key.c +++ b/src/key.c @@ -23,8 +23,6 @@ #include #include -#include - #include #include #include @@ -34,6 +32,7 @@ #include #include #include +#include #include "internal.h" @@ -194,6 +193,17 @@ int import_simple(yaca_key_h *key, goto out; } + /* DES key length verification */ + if (key_type == YACA_KEY_TYPE_DES) { + size_t key_bits = key_data_len * 8; + if (key_bits != YACA_KEY_UNSAFE_64BIT && + key_bits != YACA_KEY_UNSAFE_128BIT && + key_bits != YACA_KEY_192BIT) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto out; + } + } + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len); if (nk == NULL) { ret = YACA_ERROR_OUT_OF_MEMORY; @@ -575,6 +585,54 @@ int gen_simple(struct yaca_key_simple_s **out, size_t key_bits) return 0; } +int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits) +{ + assert(out != NULL); + + if (key_bits != YACA_KEY_UNSAFE_64BIT && + key_bits != YACA_KEY_UNSAFE_128BIT && + key_bits != YACA_KEY_192BIT) + return YACA_ERROR_INVALID_ARGUMENT; + + int ret; + struct yaca_key_simple_s *nk; + size_t key_byte_len = key_bits / 8; + + if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + DES_cblock *des_key = (DES_cblock*)nk->d; + if (key_byte_len >= 8) { + ret = DES_random_key(des_key); + if (ret != 1) + goto free_nk; + } + if (key_byte_len >= 16) { + ret = DES_random_key(des_key + 1); + if (ret != 1) + goto free_nk; + } + if (key_byte_len >= 24) { + ret = DES_random_key(des_key + 2); + if (ret != 1) + goto free_nk; + } + + nk->bits = key_bits; + *out = nk; + return 0; + +free_nk: + yaca_free(nk); + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; +} + int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits) { assert(out != NULL); @@ -800,6 +858,7 @@ API int yaca_key_import(yaca_key_h *key, switch (key_type) { case YACA_KEY_TYPE_SYMMETRIC: + case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_IV: return import_simple(key, key_type, data, data_len); case YACA_KEY_TYPE_RSA_PUB: @@ -807,7 +866,6 @@ API int yaca_key_import(yaca_key_h *key, case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: return import_evp(key, key_type, data, data_len); - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PUB: @@ -878,6 +936,16 @@ API int yaca_key_gen(yaca_key_h *key, *key = (yaca_key_h)nk_simple; return 0; + case YACA_KEY_TYPE_DES: + ret = gen_simple_des(&nk_simple, key_bits); + if (ret != 0) + return ret; + + nk_simple->key.type = key_type; + + *key = (yaca_key_h)nk_simple; + return 0; + case YACA_KEY_TYPE_RSA_PRIV: ret = gen_evp_rsa(&nk_evp, key_bits); if (ret != 0) @@ -898,7 +966,6 @@ API int yaca_key_gen(yaca_key_h *key, *key = (yaca_key_h)nk_evp; return 0; - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PRIV: case YACA_KEY_TYPE_ECDH_PRIV: -- 2.7.4