2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
30 #include <openssl/evp.h>
31 #include <openssl/rsa.h>
32 #include <openssl/bio.h>
33 #include <openssl/pem.h>
34 #include <openssl/des.h>
36 #include <yaca_crypto.h>
37 #include <yaca_error.h>
42 /* This callback only exists to block the default OpenSSL one and
43 * allow us to check for a proper error code when the key is encrypted
45 int password_dummy_cb(char *buf, int size, int rwflag, void *u)
47 const char empty[] = "";
49 memcpy(buf, empty, sizeof(empty));
54 int base64_decode_length(const char *data, size_t data_len, size_t *len)
57 assert(data_len != 0);
61 size_t tmp_len = data_len;
63 if (data_len % 4 != 0)
64 return YACA_ERROR_INVALID_ARGUMENT;
66 if (data[tmp_len - 1] == '=') {
68 if (data[tmp_len - 2] == '=')
72 *len = data_len / 4 * 3 - padded;
73 return YACA_ERROR_NONE;
76 #define TMP_BUF_LEN 512
78 int base64_decode(const char *data, size_t data_len, BIO **output)
81 assert(data_len != 0);
82 assert(output != NULL);
88 char tmpbuf[TMP_BUF_LEN];
93 /* This is because of BIO_new_mem_buf() having its length param typed int */
94 if (data_len > INT_MAX)
95 return YACA_ERROR_INVALID_ARGUMENT;
97 /* First phase of correctness checking, calculate expected output length */
98 ret = base64_decode_length(data, data_len, &b64_len);
99 if (ret != YACA_ERROR_NONE)
102 b64 = BIO_new(BIO_f_base64());
104 ret = YACA_ERROR_INTERNAL;
109 src = BIO_new_mem_buf(data, data_len);
111 ret = YACA_ERROR_INTERNAL;
118 dst = BIO_new(BIO_s_mem());
120 ret = YACA_ERROR_INTERNAL;
125 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
129 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
131 ret = YACA_ERROR_INTERNAL;
136 if (ret == YACA_ERROR_NONE)
139 if (BIO_write(dst, tmpbuf, ret) != ret) {
140 ret = YACA_ERROR_INTERNAL;
148 /* Check wether the length of the decoded data is what we expected */
149 out_len = BIO_get_mem_data(dst, &out);
151 ret = YACA_ERROR_INTERNAL;
155 if ((size_t)out_len != b64_len) {
156 ret = YACA_ERROR_INVALID_ARGUMENT;
162 ret = YACA_ERROR_NONE;
171 int import_simple(yaca_key_h *key,
172 yaca_key_type_e key_type,
177 assert(data != NULL);
178 assert(data_len != 0);
182 const char *key_data;
184 struct yaca_key_simple_s *nk = NULL;
186 ret = base64_decode(data, data_len, &decoded);
187 if (ret == YACA_ERROR_NONE) {
188 /* Conversion successfull, get the BASE64 */
189 long len = BIO_get_mem_data(decoded, &key_data);
190 if (len <= 0 || key_data == NULL) {
191 ret = YACA_ERROR_INTERNAL;
196 } else if (ret == YACA_ERROR_INVALID_ARGUMENT) {
197 /* This was not BASE64 or it was corrupted, treat as RAW */
198 key_data_len = data_len;
201 /* Some other, possibly unrecoverable error, give up */
205 /* key_bits has to fit in size_t */
206 if (key_data_len > SIZE_MAX / 8) {
207 ret = YACA_ERROR_INVALID_ARGUMENT;
211 /* DES key length verification */
212 if (key_type == YACA_KEY_TYPE_DES) {
213 size_t key_bits = key_data_len * 8;
214 if (key_bits != YACA_KEY_UNSAFE_64BIT &&
215 key_bits != YACA_KEY_UNSAFE_128BIT &&
216 key_bits != YACA_KEY_192BIT) {
217 ret = YACA_ERROR_INVALID_ARGUMENT;
222 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
223 if (ret != YACA_ERROR_NONE)
226 memcpy(nk->d, key_data, key_data_len);
227 nk->bits = key_data_len * 8;
228 nk->key.type = key_type;
230 *key = (yaca_key_h)nk;
232 ret = YACA_ERROR_NONE;
235 BIO_free_all(decoded);
240 bool check_import_wrong_pass()
242 unsigned long err = ERR_peek_error();
243 unsigned long err_bad_password_1 = ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
244 unsigned long err_bad_password_2 = ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
246 if (err == err_bad_password_1 || err == err_bad_password_2)
252 int import_evp(yaca_key_h *key,
253 yaca_key_type_e key_type,
254 const char *password,
259 assert(password == NULL || password[0] != '\0');
260 assert(data != NULL);
261 assert(data_len != 0);
265 EVP_PKEY *pkey = NULL;
266 bool wrong_pass = false;
267 pem_password_cb *cb = NULL;
269 yaca_key_type_e type;
270 struct yaca_key_evp_s *nk = NULL;
272 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
273 * to be minimum for DER, much more for PEM). This is just to make
274 * sure we have at least 4 bytes for strncmp() below.
277 return YACA_ERROR_INVALID_ARGUMENT;
279 /* This is because of BIO_new_mem_buf() having its length param typed int */
280 if (data_len > INT_MAX)
281 return YACA_ERROR_INVALID_ARGUMENT;
283 src = BIO_new_mem_buf(data, data_len);
285 ERROR_DUMP(YACA_ERROR_INTERNAL);
286 return YACA_ERROR_INTERNAL;
289 /* Block the default OpenSSL password callback */
290 if (password == NULL)
291 cb = password_dummy_cb;
294 if (strncmp("----", data, 4) == 0) {
295 if (pkey == NULL && !wrong_pass) {
297 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)password);
298 if (check_import_wrong_pass())
304 if (pkey == NULL && !wrong_pass) {
306 pkey = PEM_read_bio_PUBKEY(src, NULL, cb, (void*)password);
307 if (check_import_wrong_pass())
313 if (pkey == NULL && !wrong_pass) {
315 X509 *x509 = PEM_read_bio_X509(src, NULL, cb, (void*)password);
316 if (check_import_wrong_pass())
319 pkey = X509_get_pubkey(x509);
327 if (pkey == NULL && !wrong_pass) {
329 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)password);
330 if (check_import_wrong_pass())
336 if (pkey == NULL && !wrong_pass) {
338 pkey = d2i_PrivateKey_bio(src, NULL);
343 if (pkey == NULL && !wrong_pass) {
345 pkey = d2i_PUBKEY_bio(src, NULL);
354 return YACA_ERROR_PASSWORD_INVALID;
357 return YACA_ERROR_INVALID_ARGUMENT;
359 switch (EVP_PKEY_type(pkey->type)) {
361 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
365 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
369 // type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
373 ret = YACA_ERROR_INVALID_ARGUMENT;
377 if (type != key_type) {
378 ret = YACA_ERROR_INVALID_ARGUMENT;
382 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
383 if (ret != YACA_ERROR_NONE)
387 *key = (yaca_key_h)nk;
391 ret = YACA_ERROR_NONE;
399 int export_simple_raw(struct yaca_key_simple_s *simple_key,
404 assert(simple_key != NULL);
405 assert(data != NULL);
406 assert(data_len != NULL);
408 size_t key_len = simple_key->bits / 8;
410 ret = yaca_malloc(key_len, (void**)data);
411 if (ret != YACA_ERROR_NONE)
414 memcpy(*data, simple_key->d, key_len);
417 return YACA_ERROR_NONE;
420 int export_simple_base64(struct yaca_key_simple_s *simple_key,
424 assert(simple_key != NULL);
425 assert(data != NULL);
426 assert(data_len != NULL);
429 size_t key_len = simple_key->bits / 8;
435 b64 = BIO_new(BIO_f_base64());
437 ret = YACA_ERROR_INTERNAL;
442 mem = BIO_new(BIO_s_mem());
444 ret = YACA_ERROR_INTERNAL;
450 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
452 ret = BIO_write(b64, simple_key->d, key_len);
453 if (ret <= 0 || (unsigned)ret != key_len) {
454 ret = YACA_ERROR_INTERNAL;
459 ret = BIO_flush(b64);
461 ret = YACA_ERROR_INTERNAL;
466 bio_data_len = BIO_get_mem_data(mem, &bio_data);
467 if (bio_data_len <= 0) {
468 ret = YACA_ERROR_INTERNAL;
473 ret = yaca_malloc(bio_data_len, (void**)data);
474 if (ret != YACA_ERROR_NONE)
477 memcpy(*data, bio_data, bio_data_len);
478 *data_len = bio_data_len;
479 ret = YACA_ERROR_NONE;
487 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
488 yaca_key_file_fmt_e key_file_fmt,
489 const char *password,
492 assert(evp_key != NULL);
493 assert(password == NULL || password[0] != '\0');
497 const EVP_CIPHER *enc = NULL;
499 if (password != NULL)
500 enc = EVP_aes_256_cbc();
502 switch (key_file_fmt) {
504 case YACA_KEY_FILE_FORMAT_PEM:
505 switch (evp_key->key.type) {
507 case YACA_KEY_TYPE_RSA_PRIV:
508 ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
509 enc, NULL, 0, NULL, (void*)password);
511 case YACA_KEY_TYPE_DSA_PRIV:
512 ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
513 enc, NULL, 0, NULL, (void*)password);
516 case YACA_KEY_TYPE_RSA_PUB:
517 case YACA_KEY_TYPE_DSA_PUB:
518 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
521 // case YACA_KEY_TYPE_DH_PRIV:
522 // case YACA_KEY_TYPE_DH_PUB:
523 // case YACA_KEY_TYPE_EC_PRIV:
524 // case YACA_KEY_TYPE_EC_PUB:
525 // TODO NOT_IMPLEMENTED
527 return YACA_ERROR_INVALID_ARGUMENT;
532 case YACA_KEY_FILE_FORMAT_DER:
533 switch (evp_key->key.type) {
535 case YACA_KEY_TYPE_RSA_PRIV:
536 ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
539 case YACA_KEY_TYPE_DSA_PRIV:
540 ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
543 case YACA_KEY_TYPE_RSA_PUB:
544 case YACA_KEY_TYPE_DSA_PUB:
545 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
548 // case YACA_KEY_TYPE_DH_PRIV:
549 // case YACA_KEY_TYPE_DH_PUB:
550 // case YACA_KEY_TYPE_EC_PRIV:
551 // case YACA_KEY_TYPE_EC_PUB:
552 // TODO NOT_IMPLEMENTED
554 return YACA_ERROR_INVALID_ARGUMENT;
560 return YACA_ERROR_INVALID_ARGUMENT;
564 ret = YACA_ERROR_INTERNAL;
569 return YACA_ERROR_NONE;
572 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
573 yaca_key_file_fmt_e key_file_fmt,
574 const char *password,
577 assert(evp_key != NULL);
578 assert(password == NULL || password[0] != '\0');
584 if (password != NULL)
585 nid = NID_pbeWithMD5AndDES_CBC;
587 switch (key_file_fmt) {
589 case YACA_KEY_FILE_FORMAT_PEM:
590 switch (evp_key->key.type) {
592 case YACA_KEY_TYPE_RSA_PRIV:
593 case YACA_KEY_TYPE_DSA_PRIV:
594 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
595 NULL, 0, NULL, (void*)password);
597 // case YACA_KEY_TYPE_DH_PRIV:
598 // case YACA_KEY_TYPE_EC_PRIV:
599 // TODO NOT_IMPLEMENTED
601 /* Public keys are not supported by PKCS8 */
602 return YACA_ERROR_INVALID_ARGUMENT;
607 case YACA_KEY_FILE_FORMAT_DER:
608 switch (evp_key->key.type) {
610 case YACA_KEY_TYPE_RSA_PRIV:
611 case YACA_KEY_TYPE_DSA_PRIV:
612 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
613 NULL, 0, NULL, (void*)password);
616 // case YACA_KEY_TYPE_DH_PRIV:
617 // case YACA_KEY_TYPE_EC_PRIV:
618 // TODO NOT_IMPLEMENTED
620 /* Public keys are not supported by PKCS8 */
621 return YACA_ERROR_INVALID_ARGUMENT;
627 return YACA_ERROR_INVALID_ARGUMENT;
631 ret = YACA_ERROR_INTERNAL;
636 return YACA_ERROR_NONE;
639 int export_evp(struct yaca_key_evp_s *evp_key,
640 yaca_key_fmt_e key_fmt,
641 yaca_key_file_fmt_e key_file_fmt,
642 const char *password,
646 assert(evp_key != NULL);
647 assert(password == NULL || password[0] != '\0');
648 assert(data != NULL);
649 assert(data_len != NULL);
651 int ret = YACA_ERROR_NONE;
656 mem = BIO_new(BIO_s_mem());
658 ret = YACA_ERROR_INTERNAL;
664 case YACA_KEY_FORMAT_DEFAULT:
665 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
667 case YACA_KEY_FORMAT_PKCS8:
668 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
671 ret = YACA_ERROR_INVALID_ARGUMENT;
675 if (ret != YACA_ERROR_NONE)
678 ret = BIO_flush(mem);
680 ret = YACA_ERROR_INTERNAL;
685 bio_data_len = BIO_get_mem_data(mem, &bio_data);
686 if (bio_data_len <= 0) {
687 ret = YACA_ERROR_INTERNAL;
692 ret = yaca_malloc(bio_data_len, (void**)data);
693 if (ret != YACA_ERROR_NONE)
696 memcpy(*data, bio_data, bio_data_len);
697 *data_len = bio_data_len;
698 ret = YACA_ERROR_NONE;
706 int gen_simple(struct yaca_key_simple_s **out, size_t key_bits)
711 struct yaca_key_simple_s *nk;
712 size_t key_byte_len = key_bits / 8;
714 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
715 if (ret != YACA_ERROR_NONE)
720 ret = yaca_rand_bytes(nk->d, key_byte_len);
721 if (ret != YACA_ERROR_NONE)
725 return YACA_ERROR_NONE;
728 int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits)
732 if (key_bits != YACA_KEY_UNSAFE_64BIT &&
733 key_bits != YACA_KEY_UNSAFE_128BIT &&
734 key_bits != YACA_KEY_192BIT)
735 return YACA_ERROR_INVALID_ARGUMENT;
738 struct yaca_key_simple_s *nk;
739 size_t key_byte_len = key_bits / 8;
741 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
742 if (ret != YACA_ERROR_NONE)
745 DES_cblock *des_key = (DES_cblock*)nk->d;
746 if (key_byte_len >= 8) {
747 ret = DES_random_key(des_key);
749 ret = YACA_ERROR_INTERNAL;
754 if (key_byte_len >= 16) {
755 ret = DES_random_key(des_key + 1);
757 ret = YACA_ERROR_INTERNAL;
762 if (key_byte_len >= 24) {
763 ret = DES_random_key(des_key + 2);
765 ret = YACA_ERROR_INTERNAL;
774 ret = YACA_ERROR_NONE;
782 // TODO: consider merging gen_evp_*, they share awful lot of common code
783 int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits)
786 assert(key_bits > 0);
787 assert(key_bits % 8 == 0);
790 struct yaca_key_evp_s *nk;
792 EVP_PKEY *pkey = NULL;
794 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
795 if (ret != YACA_ERROR_NONE)
798 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
800 ret = YACA_ERROR_INTERNAL;
805 ret = EVP_PKEY_keygen_init(ctx);
807 ret = YACA_ERROR_INTERNAL;
812 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits);
814 ret = ERROR_HANDLE();
818 ret = EVP_PKEY_keygen(ctx, &pkey);
820 ret = YACA_ERROR_INTERNAL;
830 ret = YACA_ERROR_NONE;
833 EVP_PKEY_CTX_free(ctx);
839 int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits)
842 assert(key_bits > 0);
843 assert(key_bits % 8 == 0);
845 /* Openssl generates 512-bit key for key lengths smaller than 512. It also
846 * rounds key size to multiplication of 64. */
847 if(key_bits < 512 || key_bits % 64 != 0)
848 return YACA_ERROR_INVALID_ARGUMENT;
851 struct yaca_key_evp_s *nk;
852 EVP_PKEY_CTX *pctx = NULL;
853 EVP_PKEY_CTX *kctx = NULL;
854 EVP_PKEY *pkey = NULL;
855 EVP_PKEY *params = NULL;
857 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
858 if (ret != YACA_ERROR_NONE)
861 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
863 ret = YACA_ERROR_INTERNAL;
868 ret = EVP_PKEY_paramgen_init(pctx);
870 ret = YACA_ERROR_INTERNAL;
875 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits);
877 ret = ERROR_HANDLE();
881 ret = EVP_PKEY_paramgen(pctx, ¶ms);
883 ret = YACA_ERROR_INTERNAL;
888 kctx = EVP_PKEY_CTX_new(params, NULL);
890 ret = YACA_ERROR_INTERNAL;
895 ret = EVP_PKEY_keygen_init(kctx);
897 ret = YACA_ERROR_INTERNAL;
902 ret = EVP_PKEY_keygen(kctx, &pkey);
904 ret = YACA_ERROR_INTERNAL;
914 ret = YACA_ERROR_NONE;
917 EVP_PKEY_CTX_free(kctx);
918 EVP_PKEY_free(params);
919 EVP_PKEY_CTX_free(pctx);
925 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
927 struct yaca_key_simple_s *k;
929 if (key == YACA_KEY_NULL)
933 case YACA_KEY_TYPE_SYMMETRIC:
934 case YACA_KEY_TYPE_DES:
935 case YACA_KEY_TYPE_IV:
936 k = (struct yaca_key_simple_s *)key;
939 assert(k->bits != 0);
940 assert(k->bits % 8 == 0);
941 assert(k->d != NULL);
949 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
951 struct yaca_key_evp_s *k;
953 if (key == YACA_KEY_NULL)
957 case YACA_KEY_TYPE_RSA_PUB:
958 case YACA_KEY_TYPE_RSA_PRIV:
959 case YACA_KEY_TYPE_DSA_PUB:
960 case YACA_KEY_TYPE_DSA_PRIV:
961 k = (struct yaca_key_evp_s *)key;
964 assert(k->evp != NULL);
972 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
974 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
976 if (lkey == NULL || key_type == NULL)
977 return YACA_ERROR_INVALID_ARGUMENT;
979 *key_type = lkey->type;
980 return YACA_ERROR_NONE;
983 API int yaca_key_get_bits(const yaca_key_h key, size_t *key_bits)
985 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
986 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
988 if (key_bits == NULL)
989 return YACA_ERROR_INVALID_ARGUMENT;
991 if (simple_key != NULL) {
992 *key_bits = simple_key->bits;
993 return YACA_ERROR_NONE;
996 if (evp_key != NULL) {
999 // TODO: handle ECC keys when they're implemented
1000 ret = EVP_PKEY_bits(evp_key->evp);
1002 ret = YACA_ERROR_INTERNAL;
1008 return YACA_ERROR_NONE;
1011 return YACA_ERROR_INVALID_ARGUMENT;
1014 API int yaca_key_import(yaca_key_type_e key_type,
1015 const char *password,
1020 if (key == NULL || data == NULL || data_len == 0)
1021 return YACA_ERROR_INVALID_ARGUMENT;
1023 /* allow an empty password, OpenSSL returns an error with "" */
1024 if (password != NULL && password[0] == '\0')
1028 case YACA_KEY_TYPE_SYMMETRIC:
1029 case YACA_KEY_TYPE_DES:
1030 case YACA_KEY_TYPE_IV:
1031 if (password != NULL)
1032 return YACA_ERROR_INVALID_ARGUMENT;
1033 return import_simple(key, key_type, data, data_len);
1034 case YACA_KEY_TYPE_RSA_PUB:
1035 case YACA_KEY_TYPE_RSA_PRIV:
1036 case YACA_KEY_TYPE_DSA_PUB:
1037 case YACA_KEY_TYPE_DSA_PRIV:
1038 return import_evp(key, key_type, password, data, data_len);
1039 // case YACA_KEY_TYPE_DH_PUB:
1040 // case YACA_KEY_TYPE_DH_PRIV:
1041 // case YACA_KEY_TYPE_EC_PUB:
1042 // case YACA_KEY_TYPE_EC_PRIV:
1043 // TODO NOT_IMPLEMENTED
1045 return YACA_ERROR_INVALID_ARGUMENT;
1049 API int yaca_key_export(const yaca_key_h key,
1050 yaca_key_fmt_e key_fmt,
1051 yaca_key_file_fmt_e key_file_fmt,
1052 const char *password,
1056 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1057 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1059 if (data == NULL || data_len == NULL)
1060 return YACA_ERROR_INVALID_ARGUMENT;
1062 /* allow an empty password, OpenSSL returns an error with "" */
1063 if (password != NULL && password[0] == '\0')
1066 if (password != NULL && simple_key != NULL)
1067 return YACA_ERROR_INVALID_ARGUMENT;
1069 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1070 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1072 return export_simple_raw(simple_key, data, data_len);
1074 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1075 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1077 return export_simple_base64(simple_key, data, data_len);
1079 if (evp_key != NULL)
1080 return export_evp(evp_key, key_fmt, key_file_fmt,
1081 password, data, data_len);
1083 return YACA_ERROR_INVALID_ARGUMENT;
1086 API int yaca_key_gen(yaca_key_type_e key_type,
1091 struct yaca_key_simple_s *nk_simple = NULL;
1092 struct yaca_key_evp_s *nk_evp = NULL;
1094 if (key == NULL || key_bits == 0 || key_bits % 8 != 0)
1095 return YACA_ERROR_INVALID_ARGUMENT;
1098 case YACA_KEY_TYPE_SYMMETRIC:
1099 case YACA_KEY_TYPE_IV:
1100 ret = gen_simple(&nk_simple, key_bits);
1102 case YACA_KEY_TYPE_DES:
1103 ret = gen_simple_des(&nk_simple, key_bits);
1105 case YACA_KEY_TYPE_RSA_PRIV:
1106 ret = gen_evp_rsa(&nk_evp, key_bits);
1108 case YACA_KEY_TYPE_DSA_PRIV:
1109 ret = gen_evp_dsa(&nk_evp, key_bits);
1111 // case YACA_KEY_TYPE_DH_PRIV:
1112 // case YACA_KEY_TYPE_EC_PRIV:
1113 // TODO NOT_IMPLEMENTED
1115 return YACA_ERROR_INVALID_ARGUMENT;
1118 if (ret != YACA_ERROR_NONE)
1121 if (nk_simple != NULL) {
1122 nk_simple->key.type = key_type;
1123 *key = (yaca_key_h)nk_simple;
1124 } else if (nk_evp != NULL) {
1125 nk_evp->key.type = key_type;
1126 *key = (yaca_key_h)nk_evp;
1129 return YACA_ERROR_NONE;
1133 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1136 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1137 struct yaca_key_evp_s *nk;
1139 EVP_PKEY *pkey = NULL;
1141 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1142 return YACA_ERROR_INVALID_ARGUMENT;
1144 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1145 if (ret != YACA_ERROR_NONE)
1148 mem = BIO_new(BIO_s_mem());
1150 ret = YACA_ERROR_INTERNAL;
1155 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1157 ret = YACA_ERROR_INTERNAL;
1162 pkey = d2i_PUBKEY_bio(mem, NULL);
1164 ret = YACA_ERROR_INTERNAL;
1172 switch (prv_key->type) {
1173 case YACA_KEY_TYPE_RSA_PRIV:
1174 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1176 case YACA_KEY_TYPE_DSA_PRIV:
1177 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1179 // case YACA_KEY_TYPE_EC_PRIV:
1180 // nk->key.type = YACA_KEY_TYPE_EC_PUB;
1183 ret = YACA_ERROR_INVALID_ARGUMENT;
1189 *pub_key = (yaca_key_h)nk;
1191 ret = YACA_ERROR_NONE;
1194 EVP_PKEY_free(pkey);
1201 API int yaca_key_free(yaca_key_h key)
1203 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1204 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1206 if (simple_key != NULL)
1207 yaca_free(simple_key);
1209 if (evp_key != NULL) {
1210 EVP_PKEY_free(evp_key->evp);
1214 return YACA_ERROR_NONE;
1217 API int yaca_key_derive_pbkdf2(const char *password,
1221 yaca_digest_algo_e algo,
1226 struct yaca_key_simple_s *nk;
1227 size_t key_byte_len = key_bits / 8;
1230 if (password == NULL || salt == NULL || salt_len == 0 ||
1231 iter == 0 || key_bits == 0 || key == NULL)
1232 return YACA_ERROR_INVALID_ARGUMENT;
1234 if (key_bits % 8) /* Key length must be multiple of 8-bits */
1235 return YACA_ERROR_INVALID_ARGUMENT;
1237 ret = digest_get_algorithm(algo, &md);
1238 if (ret != YACA_ERROR_NONE)
1241 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1242 if (ret != YACA_ERROR_NONE)
1245 nk->bits = key_bits;
1246 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1248 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1249 salt_len, iter, md, key_byte_len,
1250 (unsigned char*)nk->d);
1252 ret = YACA_ERROR_INTERNAL;
1257 *key = (yaca_key_h)nk;
1259 ret = YACA_ERROR_NONE;