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 struct openssl_password_data {
43 bool password_requested;
47 int openssl_password_cb(char *buf, int size, UNUSED int rwflag, void *u)
49 struct openssl_password_data *cb_data = u;
51 if (cb_data->password == NULL)
54 size_t pass_len = strlen(cb_data->password);
56 if (pass_len > INT_MAX || (int)pass_len > size)
59 memcpy(buf, cb_data->password, pass_len);
60 cb_data->password_requested = true;
65 int openssl_password_cb_error(UNUSED char *buf, UNUSED int size, UNUSED int rwflag, UNUSED void *u)
70 int base64_decode_length(const char *data, size_t data_len, size_t *len)
73 assert(data_len != 0);
77 size_t tmp_len = data_len;
79 if (data_len % 4 != 0)
80 return YACA_ERROR_INVALID_PARAMETER;
82 if (data[tmp_len - 1] == '=') {
84 if (data[tmp_len - 2] == '=')
88 *len = data_len / 4 * 3 - padded;
89 return YACA_ERROR_NONE;
92 #define TMP_BUF_LEN 512
94 int base64_decode(const char *data, size_t data_len, BIO **output)
97 assert(data_len != 0);
98 assert(output != NULL);
104 char tmpbuf[TMP_BUF_LEN];
109 /* This is because of BIO_new_mem_buf() having its length param typed int */
110 if (data_len > INT_MAX)
111 return YACA_ERROR_INVALID_PARAMETER;
113 /* First phase of correctness checking, calculate expected output length */
114 ret = base64_decode_length(data, data_len, &b64_len);
115 if (ret != YACA_ERROR_NONE)
118 b64 = BIO_new(BIO_f_base64());
120 ret = YACA_ERROR_INTERNAL;
125 src = BIO_new_mem_buf(data, data_len);
127 ret = YACA_ERROR_INTERNAL;
134 dst = BIO_new(BIO_s_mem());
136 ret = YACA_ERROR_INTERNAL;
141 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
145 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
147 ret = YACA_ERROR_INTERNAL;
152 if (ret == YACA_ERROR_NONE)
155 if (BIO_write(dst, tmpbuf, ret) != ret) {
156 ret = YACA_ERROR_INTERNAL;
164 /* Check wether the length of the decoded data is what we expected */
165 out_len = BIO_get_mem_data(dst, &out);
167 ret = YACA_ERROR_INTERNAL;
171 if ((size_t)out_len != b64_len) {
172 ret = YACA_ERROR_INVALID_PARAMETER;
178 ret = YACA_ERROR_NONE;
187 int import_simple(yaca_key_h *key,
188 yaca_key_type_e key_type,
193 assert(data != NULL);
194 assert(data_len != 0);
198 const char *key_data;
200 struct yaca_key_simple_s *nk = NULL;
202 ret = base64_decode(data, data_len, &decoded);
203 if (ret == YACA_ERROR_NONE) {
204 /* Conversion successfull, get the BASE64 */
205 long len = BIO_get_mem_data(decoded, &key_data);
206 if (len <= 0 || key_data == NULL) {
207 ret = YACA_ERROR_INTERNAL;
212 } else if (ret == YACA_ERROR_INVALID_PARAMETER) {
213 /* This was not BASE64 or it was corrupted, treat as RAW */
214 key_data_len = data_len;
217 /* Some other, possibly unrecoverable error, give up */
221 /* key_bits has to fit in size_t */
222 if (key_data_len > SIZE_MAX / 8) {
223 ret = YACA_ERROR_INVALID_PARAMETER;
227 /* DES key length verification */
228 if (key_type == YACA_KEY_TYPE_DES) {
229 size_t key_bits = key_data_len * 8;
230 if (key_bits != YACA_KEY_LENGTH_UNSAFE_64BIT &&
231 key_bits != YACA_KEY_LENGTH_UNSAFE_128BIT &&
232 key_bits != YACA_KEY_LENGTH_192BIT) {
233 ret = YACA_ERROR_INVALID_PARAMETER;
238 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
239 if (ret != YACA_ERROR_NONE)
242 memcpy(nk->d, key_data, key_data_len);
243 nk->bits = key_data_len * 8;
244 nk->key.type = key_type;
246 *key = (yaca_key_h)nk;
248 ret = YACA_ERROR_NONE;
251 BIO_free_all(decoded);
256 int import_evp(yaca_key_h *key,
257 yaca_key_type_e key_type,
258 const char *password,
263 assert(password == NULL || password[0] != '\0');
264 assert(data != NULL);
265 assert(data_len != 0);
269 EVP_PKEY *pkey = NULL;
270 pem_password_cb *cb = openssl_password_cb;
271 struct openssl_password_data cb_data = {false, password};
273 bool password_supported;
274 yaca_key_type_e type;
275 struct yaca_key_evp_s *nk = NULL;
277 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
278 * to be minimum for DER, much more for PEM). This is just to make
279 * sure we have at least 4 bytes for strncmp() below.
282 return YACA_ERROR_INVALID_PARAMETER;
284 /* This is because of BIO_new_mem_buf() having its length param typed int */
285 if (data_len > INT_MAX)
286 return YACA_ERROR_INVALID_PARAMETER;
288 src = BIO_new_mem_buf(data, data_len);
290 ERROR_DUMP(YACA_ERROR_INTERNAL);
291 return YACA_ERROR_INTERNAL;
295 if (strncmp("----", data, 4) == 0) {
298 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data);
299 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
300 return YACA_ERROR_INVALID_PASSWORD;
302 password_supported = true;
307 pkey = PEM_read_bio_PUBKEY(src, NULL, openssl_password_cb_error, NULL);
310 password_supported = false;
315 X509 *x509 = PEM_read_bio_X509(src, NULL, openssl_password_cb_error, NULL);
317 pkey = X509_get_pubkey(x509);
322 password_supported = false;
329 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data);
330 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
331 return YACA_ERROR_INVALID_PASSWORD;
333 password_supported = true;
338 pkey = d2i_PrivateKey_bio(src, NULL);
341 password_supported = false;
346 pkey = d2i_PUBKEY_bio(src, NULL);
349 password_supported = false;
354 X509 *x509 = d2i_X509_bio(src, NULL);
356 pkey = X509_get_pubkey(x509);
361 password_supported = false;
368 return YACA_ERROR_INVALID_PARAMETER;
370 /* password was given, but it was not required to perform import */
371 if (password != NULL && !cb_data.password_requested) {
372 if (password_supported)
373 ret = YACA_ERROR_INVALID_PASSWORD;
375 ret = YACA_ERROR_INVALID_PARAMETER;
379 switch (EVP_PKEY_type(pkey->type)) {
381 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
385 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
389 // type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
393 ret = YACA_ERROR_INVALID_PARAMETER;
397 if (type != key_type) {
398 ret = YACA_ERROR_INVALID_PARAMETER;
402 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
403 if (ret != YACA_ERROR_NONE)
407 *key = (yaca_key_h)nk;
411 ret = YACA_ERROR_NONE;
419 int export_simple_raw(struct yaca_key_simple_s *simple_key,
424 assert(simple_key != NULL);
425 assert(data != NULL);
426 assert(data_len != NULL);
428 size_t key_len = simple_key->bits / 8;
432 ret = yaca_malloc(key_len, (void**)data);
433 if (ret != YACA_ERROR_NONE)
436 memcpy(*data, simple_key->d, key_len);
439 return YACA_ERROR_NONE;
442 int export_simple_base64(struct yaca_key_simple_s *simple_key,
446 assert(simple_key != NULL);
447 assert(data != NULL);
448 assert(data_len != NULL);
451 size_t key_len = simple_key->bits / 8;
457 b64 = BIO_new(BIO_f_base64());
459 ret = YACA_ERROR_INTERNAL;
464 mem = BIO_new(BIO_s_mem());
466 ret = YACA_ERROR_INTERNAL;
472 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
474 ret = BIO_write(b64, simple_key->d, key_len);
475 if (ret <= 0 || (unsigned)ret != key_len) {
476 ret = YACA_ERROR_INTERNAL;
481 ret = BIO_flush(b64);
483 ret = YACA_ERROR_INTERNAL;
488 bio_data_len = BIO_get_mem_data(mem, &bio_data);
489 if (bio_data_len <= 0) {
490 ret = YACA_ERROR_INTERNAL;
495 ret = yaca_malloc(bio_data_len, (void**)data);
496 if (ret != YACA_ERROR_NONE)
499 memcpy(*data, bio_data, bio_data_len);
500 *data_len = bio_data_len;
501 ret = YACA_ERROR_NONE;
509 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
510 yaca_key_file_format_e key_file_fmt,
511 const char *password,
514 assert(evp_key != NULL);
515 assert(password == NULL || password[0] != '\0');
519 const EVP_CIPHER *enc = NULL;
521 if (password != NULL)
522 enc = EVP_aes_256_cbc();
524 switch (key_file_fmt) {
526 case YACA_KEY_FILE_FORMAT_PEM:
527 switch (evp_key->key.type) {
529 case YACA_KEY_TYPE_RSA_PRIV:
530 ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
531 enc, NULL, 0, NULL, (void*)password);
533 case YACA_KEY_TYPE_DSA_PRIV:
534 ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
535 enc, NULL, 0, NULL, (void*)password);
538 case YACA_KEY_TYPE_RSA_PUB:
539 case YACA_KEY_TYPE_DSA_PUB:
540 if (password != NULL)
541 return YACA_ERROR_INVALID_PARAMETER;
542 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
545 // case YACA_KEY_TYPE_DH_PRIV:
546 // case YACA_KEY_TYPE_DH_PUB:
547 // case YACA_KEY_TYPE_EC_PRIV:
548 // case YACA_KEY_TYPE_EC_PUB:
549 // TODO NOT_IMPLEMENTED
551 return YACA_ERROR_INVALID_PARAMETER;
556 case YACA_KEY_FILE_FORMAT_DER:
557 switch (evp_key->key.type) {
559 case YACA_KEY_TYPE_RSA_PRIV:
560 if (password != NULL)
561 return YACA_ERROR_INVALID_PARAMETER;
562 ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
565 case YACA_KEY_TYPE_DSA_PRIV:
566 if (password != NULL)
567 return YACA_ERROR_INVALID_PARAMETER;
568 ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
571 case YACA_KEY_TYPE_RSA_PUB:
572 case YACA_KEY_TYPE_DSA_PUB:
573 if (password != NULL)
574 return YACA_ERROR_INVALID_PARAMETER;
575 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
578 // case YACA_KEY_TYPE_DH_PRIV:
579 // case YACA_KEY_TYPE_DH_PUB:
580 // case YACA_KEY_TYPE_EC_PRIV:
581 // case YACA_KEY_TYPE_EC_PUB:
582 // TODO NOT_IMPLEMENTED
584 return YACA_ERROR_INVALID_PARAMETER;
590 return YACA_ERROR_INVALID_PARAMETER;
594 ret = YACA_ERROR_INTERNAL;
599 return YACA_ERROR_NONE;
602 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
603 yaca_key_file_format_e key_file_fmt,
604 const char *password,
607 assert(evp_key != NULL);
608 assert(password == NULL || password[0] != '\0');
612 int nid = NID_pbeWithMD5AndDES_CBC;
614 /* PKCS8 export requires a password */
615 if (password == NULL)
616 return YACA_ERROR_INVALID_PARAMETER;
618 switch (key_file_fmt) {
620 case YACA_KEY_FILE_FORMAT_PEM:
621 switch (evp_key->key.type) {
623 case YACA_KEY_TYPE_RSA_PRIV:
624 case YACA_KEY_TYPE_DSA_PRIV:
625 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
626 NULL, 0, NULL, (void*)password);
628 // case YACA_KEY_TYPE_DH_PRIV:
629 // case YACA_KEY_TYPE_EC_PRIV:
630 // TODO NOT_IMPLEMENTED
632 /* Public keys are not supported by PKCS8 */
633 return YACA_ERROR_INVALID_PARAMETER;
638 case YACA_KEY_FILE_FORMAT_DER:
639 switch (evp_key->key.type) {
641 case YACA_KEY_TYPE_RSA_PRIV:
642 case YACA_KEY_TYPE_DSA_PRIV:
643 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
644 NULL, 0, NULL, (void*)password);
647 // case YACA_KEY_TYPE_DH_PRIV:
648 // case YACA_KEY_TYPE_EC_PRIV:
649 // TODO NOT_IMPLEMENTED
651 /* Public keys are not supported by PKCS8 */
652 return YACA_ERROR_INVALID_PARAMETER;
658 return YACA_ERROR_INVALID_PARAMETER;
662 ret = YACA_ERROR_INTERNAL;
667 return YACA_ERROR_NONE;
670 int export_evp(struct yaca_key_evp_s *evp_key,
671 yaca_key_format_e key_fmt,
672 yaca_key_file_format_e key_file_fmt,
673 const char *password,
677 assert(evp_key != NULL);
678 assert(password == NULL || password[0] != '\0');
679 assert(data != NULL);
680 assert(data_len != NULL);
682 int ret = YACA_ERROR_NONE;
687 mem = BIO_new(BIO_s_mem());
689 ret = YACA_ERROR_INTERNAL;
695 case YACA_KEY_FORMAT_DEFAULT:
696 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
698 case YACA_KEY_FORMAT_PKCS8:
699 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
702 ret = YACA_ERROR_INVALID_PARAMETER;
706 if (ret != YACA_ERROR_NONE)
709 ret = BIO_flush(mem);
711 ret = YACA_ERROR_INTERNAL;
716 bio_data_len = BIO_get_mem_data(mem, &bio_data);
717 if (bio_data_len <= 0) {
718 ret = YACA_ERROR_INTERNAL;
723 ret = yaca_malloc(bio_data_len, (void**)data);
724 if (ret != YACA_ERROR_NONE)
727 memcpy(*data, bio_data, bio_data_len);
728 *data_len = bio_data_len;
729 ret = YACA_ERROR_NONE;
737 int gen_simple(struct yaca_key_simple_s **out, size_t key_bits)
742 struct yaca_key_simple_s *nk;
743 size_t key_byte_len = key_bits / 8;
745 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
746 if (ret != YACA_ERROR_NONE)
751 ret = yaca_randomize_bytes(nk->d, key_byte_len);
752 if (ret != YACA_ERROR_NONE)
756 return YACA_ERROR_NONE;
759 int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits)
763 if (key_bits != YACA_KEY_LENGTH_UNSAFE_64BIT &&
764 key_bits != YACA_KEY_LENGTH_UNSAFE_128BIT &&
765 key_bits != YACA_KEY_LENGTH_192BIT)
766 return YACA_ERROR_INVALID_PARAMETER;
769 struct yaca_key_simple_s *nk;
770 size_t key_byte_len = key_bits / 8;
772 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
773 if (ret != YACA_ERROR_NONE)
776 DES_cblock *des_key = (DES_cblock*)nk->d;
777 if (key_byte_len >= 8) {
778 ret = DES_random_key(des_key);
780 ret = YACA_ERROR_INTERNAL;
785 if (key_byte_len >= 16) {
786 ret = DES_random_key(des_key + 1);
788 ret = YACA_ERROR_INTERNAL;
793 if (key_byte_len >= 24) {
794 ret = DES_random_key(des_key + 2);
796 ret = YACA_ERROR_INTERNAL;
805 ret = YACA_ERROR_NONE;
813 // TODO: consider merging gen_evp_*, they share awful lot of common code
814 int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits)
817 assert(key_bits > 0);
818 assert(key_bits % 8 == 0);
821 struct yaca_key_evp_s *nk;
823 EVP_PKEY *pkey = NULL;
825 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
826 if (ret != YACA_ERROR_NONE)
829 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
831 ret = YACA_ERROR_INTERNAL;
836 ret = EVP_PKEY_keygen_init(ctx);
838 ret = YACA_ERROR_INTERNAL;
843 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits);
845 ret = ERROR_HANDLE();
849 ret = EVP_PKEY_keygen(ctx, &pkey);
851 ret = YACA_ERROR_INTERNAL;
861 ret = YACA_ERROR_NONE;
864 EVP_PKEY_CTX_free(ctx);
870 int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits)
873 assert(key_bits > 0);
874 assert(key_bits % 8 == 0);
876 /* Openssl generates 512-bit key for key lengths smaller than 512. It also
877 * rounds key size to multiplication of 64. */
878 if (key_bits < 512 || key_bits % 64 != 0)
879 return YACA_ERROR_INVALID_PARAMETER;
882 struct yaca_key_evp_s *nk;
883 EVP_PKEY_CTX *pctx = NULL;
884 EVP_PKEY_CTX *kctx = NULL;
885 EVP_PKEY *pkey = NULL;
886 EVP_PKEY *params = NULL;
888 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
889 if (ret != YACA_ERROR_NONE)
892 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
894 ret = YACA_ERROR_INTERNAL;
899 ret = EVP_PKEY_paramgen_init(pctx);
901 ret = YACA_ERROR_INTERNAL;
906 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits);
908 ret = ERROR_HANDLE();
912 ret = EVP_PKEY_paramgen(pctx, ¶ms);
914 ret = YACA_ERROR_INTERNAL;
919 kctx = EVP_PKEY_CTX_new(params, NULL);
921 ret = YACA_ERROR_INTERNAL;
926 ret = EVP_PKEY_keygen_init(kctx);
928 ret = YACA_ERROR_INTERNAL;
933 ret = EVP_PKEY_keygen(kctx, &pkey);
935 ret = YACA_ERROR_INTERNAL;
945 ret = YACA_ERROR_NONE;
948 EVP_PKEY_CTX_free(kctx);
949 EVP_PKEY_free(params);
950 EVP_PKEY_CTX_free(pctx);
956 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
958 struct yaca_key_simple_s *k;
960 if (key == YACA_KEY_NULL)
964 case YACA_KEY_TYPE_SYMMETRIC:
965 case YACA_KEY_TYPE_DES:
966 case YACA_KEY_TYPE_IV:
967 k = (struct yaca_key_simple_s *)key;
970 assert(k->bits != 0);
971 assert(k->bits % 8 == 0);
972 assert(k->d != NULL);
980 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
982 struct yaca_key_evp_s *k;
984 if (key == YACA_KEY_NULL)
988 case YACA_KEY_TYPE_RSA_PUB:
989 case YACA_KEY_TYPE_RSA_PRIV:
990 case YACA_KEY_TYPE_DSA_PUB:
991 case YACA_KEY_TYPE_DSA_PRIV:
992 k = (struct yaca_key_evp_s *)key;
995 assert(k->evp != NULL);
1003 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
1005 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
1007 if (lkey == NULL || key_type == NULL)
1008 return YACA_ERROR_INVALID_PARAMETER;
1010 *key_type = lkey->type;
1011 return YACA_ERROR_NONE;
1014 API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len)
1016 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
1017 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
1019 if (key_bit_len == NULL)
1020 return YACA_ERROR_INVALID_PARAMETER;
1022 if (simple_key != NULL) {
1023 *key_bit_len = simple_key->bits;
1024 return YACA_ERROR_NONE;
1027 if (evp_key != NULL) {
1030 // TODO: handle ECC keys when they're implemented
1031 ret = EVP_PKEY_bits(evp_key->evp);
1033 ret = YACA_ERROR_INTERNAL;
1039 return YACA_ERROR_NONE;
1042 return YACA_ERROR_INVALID_PARAMETER;
1045 API int yaca_key_import(yaca_key_type_e key_type,
1046 const char *password,
1051 if (key == NULL || data == NULL || data_len == 0)
1052 return YACA_ERROR_INVALID_PARAMETER;
1054 /* allow an empty password, OpenSSL returns an error with "" */
1055 if (password != NULL && password[0] == '\0')
1059 case YACA_KEY_TYPE_SYMMETRIC:
1060 case YACA_KEY_TYPE_DES:
1061 case YACA_KEY_TYPE_IV:
1062 if (password != NULL)
1063 return YACA_ERROR_INVALID_PARAMETER;
1064 return import_simple(key, key_type, data, data_len);
1065 case YACA_KEY_TYPE_RSA_PUB:
1066 case YACA_KEY_TYPE_RSA_PRIV:
1067 case YACA_KEY_TYPE_DSA_PUB:
1068 case YACA_KEY_TYPE_DSA_PRIV:
1069 return import_evp(key, key_type, password, data, data_len);
1070 // case YACA_KEY_TYPE_DH_PUB:
1071 // case YACA_KEY_TYPE_DH_PRIV:
1072 // case YACA_KEY_TYPE_EC_PUB:
1073 // case YACA_KEY_TYPE_EC_PRIV:
1074 // TODO NOT_IMPLEMENTED
1076 return YACA_ERROR_INVALID_PARAMETER;
1080 API int yaca_key_export(const yaca_key_h key,
1081 yaca_key_format_e key_fmt,
1082 yaca_key_file_format_e key_file_fmt,
1083 const char *password,
1087 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1088 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1090 if (data == NULL || data_len == NULL)
1091 return YACA_ERROR_INVALID_PARAMETER;
1093 /* allow an empty password, OpenSSL returns an error with "" */
1094 if (password != NULL && password[0] == '\0')
1097 if (password != NULL && simple_key != NULL)
1098 return YACA_ERROR_INVALID_PARAMETER;
1100 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1101 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1103 return export_simple_raw(simple_key, data, data_len);
1105 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1106 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1108 return export_simple_base64(simple_key, data, data_len);
1110 if (evp_key != NULL)
1111 return export_evp(evp_key, key_fmt, key_file_fmt,
1112 password, data, data_len);
1114 return YACA_ERROR_INVALID_PARAMETER;
1117 API int yaca_key_generate(yaca_key_type_e key_type,
1122 struct yaca_key_simple_s *nk_simple = NULL;
1123 struct yaca_key_evp_s *nk_evp = NULL;
1125 if (key == NULL || key_bit_len == 0 || key_bit_len % 8 != 0)
1126 return YACA_ERROR_INVALID_PARAMETER;
1129 case YACA_KEY_TYPE_SYMMETRIC:
1130 case YACA_KEY_TYPE_IV:
1131 ret = gen_simple(&nk_simple, key_bit_len);
1133 case YACA_KEY_TYPE_DES:
1134 ret = gen_simple_des(&nk_simple, key_bit_len);
1136 case YACA_KEY_TYPE_RSA_PRIV:
1137 ret = gen_evp_rsa(&nk_evp, key_bit_len);
1139 case YACA_KEY_TYPE_DSA_PRIV:
1140 ret = gen_evp_dsa(&nk_evp, key_bit_len);
1142 // case YACA_KEY_TYPE_DH_PRIV:
1143 // case YACA_KEY_TYPE_EC_PRIV:
1144 // TODO NOT_IMPLEMENTED
1146 return YACA_ERROR_INVALID_PARAMETER;
1149 if (ret != YACA_ERROR_NONE)
1152 if (nk_simple != NULL) {
1153 nk_simple->key.type = key_type;
1154 *key = (yaca_key_h)nk_simple;
1155 } else if (nk_evp != NULL) {
1156 nk_evp->key.type = key_type;
1157 *key = (yaca_key_h)nk_evp;
1160 return YACA_ERROR_NONE;
1164 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1167 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1168 struct yaca_key_evp_s *nk;
1170 EVP_PKEY *pkey = NULL;
1172 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1173 return YACA_ERROR_INVALID_PARAMETER;
1175 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1176 if (ret != YACA_ERROR_NONE)
1179 mem = BIO_new(BIO_s_mem());
1181 ret = YACA_ERROR_INTERNAL;
1186 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1188 ret = YACA_ERROR_INTERNAL;
1193 pkey = d2i_PUBKEY_bio(mem, NULL);
1195 ret = YACA_ERROR_INTERNAL;
1203 switch (prv_key->type) {
1204 case YACA_KEY_TYPE_RSA_PRIV:
1205 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1207 case YACA_KEY_TYPE_DSA_PRIV:
1208 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1210 // case YACA_KEY_TYPE_EC_PRIV:
1211 // nk->key.type = YACA_KEY_TYPE_EC_PUB;
1214 ret = YACA_ERROR_INVALID_PARAMETER;
1220 *pub_key = (yaca_key_h)nk;
1222 ret = YACA_ERROR_NONE;
1225 EVP_PKEY_free(pkey);
1232 API void yaca_key_destroy(yaca_key_h key)
1234 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1235 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1237 if (simple_key != NULL)
1238 yaca_free(simple_key);
1240 if (evp_key != NULL) {
1241 EVP_PKEY_free(evp_key->evp);
1246 API int yaca_key_derive_pbkdf2(const char *password,
1250 yaca_digest_algorithm_e algo,
1255 struct yaca_key_simple_s *nk;
1256 size_t key_byte_len = key_bit_len / 8;
1259 if (password == NULL ||
1260 (salt == NULL && salt_len > 0) || (salt != NULL && salt_len == 0) ||
1261 iterations == 0 || key_bit_len == 0 || key == NULL)
1262 return YACA_ERROR_INVALID_PARAMETER;
1264 if (key_bit_len % 8) /* Key length must be multiple of 8-bits */
1265 return YACA_ERROR_INVALID_PARAMETER;
1267 if (iterations > INT_MAX) /* OpenSSL limitation */
1268 return YACA_ERROR_INVALID_PARAMETER;
1270 ret = digest_get_algorithm(algo, &md);
1271 if (ret != YACA_ERROR_NONE)
1274 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1275 if (ret != YACA_ERROR_NONE)
1278 nk->bits = key_bit_len;
1279 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1281 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1282 salt_len, iterations, md, key_byte_len,
1283 (unsigned char*)nk->d);
1285 ret = YACA_ERROR_INTERNAL;
1290 *key = (yaca_key_h)nk;
1292 ret = YACA_ERROR_NONE;