Simplify memory allocation in read_file
[platform/core/security/yaca.git] / src / key.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18
19 /**
20  * @file key.c
21  * @brief
22  */
23
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdint.h>
28 #include <stdbool.h>
29
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>
35
36 #include <yaca_crypto.h>
37 #include <yaca_error.h>
38 #include <yaca_key.h>
39
40 #include "internal.h"
41
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
44  */
45 int password_dummy_cb(char *buf, int size, int rwflag, void *u)
46 {
47         const char empty[] = "";
48
49         memcpy(buf, empty, sizeof(empty));
50
51         return sizeof(empty);
52 }
53
54 int base64_decode_length(const char *data, size_t data_len, size_t *len)
55 {
56         assert(data != NULL);
57         assert(data_len != 0);
58         assert(len != NULL);
59
60         size_t padded = 0;
61         size_t tmp_len = data_len;
62
63         if (data_len % 4 != 0)
64                 return YACA_ERROR_INVALID_ARGUMENT;
65
66         if (data[tmp_len - 1] == '=') {
67                 padded = 1;
68                 if (data[tmp_len - 2] == '=')
69                         padded = 2;
70         }
71
72         *len = data_len / 4 * 3 - padded;
73         return YACA_ERROR_NONE;
74 }
75
76 #define TMP_BUF_LEN 512
77
78 int base64_decode(const char *data, size_t data_len, BIO **output)
79 {
80         assert(data != NULL);
81         assert(data_len != 0);
82         assert(output != NULL);
83
84         int ret;
85         BIO *b64 = NULL;
86         BIO *src = NULL;
87         BIO *dst = NULL;
88         char tmpbuf[TMP_BUF_LEN];
89         size_t b64_len;
90         char *out;
91         long out_len;
92
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;
96
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)
100                 return ret;
101
102         b64 = BIO_new(BIO_f_base64());
103         if (b64 == NULL) {
104                 ret = YACA_ERROR_INTERNAL;
105                 ERROR_DUMP(ret);
106                 return ret;
107         }
108
109         src = BIO_new_mem_buf(data, data_len);
110         if (src == NULL) {
111                 ret = YACA_ERROR_INTERNAL;
112                 ERROR_DUMP(ret);
113                 goto exit;
114         }
115
116         BIO_push(b64, src);
117
118         dst = BIO_new(BIO_s_mem());
119         if (dst == NULL) {
120                 ret = YACA_ERROR_INTERNAL;
121                 ERROR_DUMP(ret);
122                 goto exit;
123         }
124
125         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
126
127         /* Try to decode */
128         for (;;) {
129                 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
130                 if (ret < 0) {
131                         ret = YACA_ERROR_INTERNAL;
132                         ERROR_DUMP(ret);
133                         goto exit;
134                 }
135
136                 if (ret == YACA_ERROR_NONE)
137                         break;
138
139                 if (BIO_write(dst, tmpbuf, ret) != ret) {
140                         ret = YACA_ERROR_INTERNAL;
141                         ERROR_DUMP(ret);
142                         goto exit;
143                 }
144         }
145
146         BIO_flush(dst);
147
148         /* Check wether the length of the decoded data is what we expected */
149         out_len = BIO_get_mem_data(dst, &out);
150         if (out_len < 0) {
151                 ret = YACA_ERROR_INTERNAL;
152                 ERROR_DUMP(ret);
153                 goto exit;
154         }
155         if ((size_t)out_len != b64_len) {
156                 ret = YACA_ERROR_INVALID_ARGUMENT;
157                 goto exit;
158         }
159
160         *output = dst;
161         dst = NULL;
162         ret = YACA_ERROR_NONE;
163
164 exit:
165         BIO_free_all(b64);
166         BIO_free_all(dst);
167
168         return ret;
169 }
170
171 int import_simple(yaca_key_h *key,
172                   yaca_key_type_e key_type,
173                   const char *data,
174                   size_t data_len)
175 {
176         assert(key != NULL);
177         assert(data != NULL);
178         assert(data_len != 0);
179
180         int ret;
181         BIO *decoded = NULL;
182         const char *key_data;
183         size_t key_data_len;
184         struct yaca_key_simple_s *nk = NULL;
185
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;
192                         ERROR_DUMP(ret);
193                         return ret;
194                 }
195                 key_data_len = len;
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;
199                 key_data = data;
200         } else {
201                 /* Some other, possibly unrecoverable error, give up */
202                 return ret;
203         }
204
205         /* key_bits has to fit in size_t */
206         if (key_data_len > SIZE_MAX / 8) {
207                 ret = YACA_ERROR_INVALID_ARGUMENT;
208                 goto exit;
209         }
210
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;
218                         goto exit;
219                 }
220         }
221
222         ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
223         if (ret != YACA_ERROR_NONE)
224                 goto exit;
225
226         memcpy(nk->d, key_data, key_data_len);
227         nk->bits = key_data_len * 8;
228         nk->key.type = key_type;
229
230         *key = (yaca_key_h)nk;
231         nk = NULL;
232         ret = YACA_ERROR_NONE;
233
234 exit:
235         BIO_free_all(decoded);
236
237         return ret;
238 }
239
240 bool check_import_wrong_pass()
241 {
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);
245
246         if (err == err_bad_password_1 || err == err_bad_password_2)
247                 return true;
248
249         return false;
250 }
251
252 int import_evp(yaca_key_h *key,
253                yaca_key_type_e key_type,
254                const char *password,
255                const char *data,
256                size_t data_len)
257 {
258         assert(key != NULL);
259         assert(password == NULL || password[0] != '\0');
260         assert(data != NULL);
261         assert(data_len != 0);
262
263         int ret;
264         BIO *src = NULL;
265         EVP_PKEY *pkey = NULL;
266         bool wrong_pass = false;
267         pem_password_cb *cb = NULL;
268         bool private;
269         yaca_key_type_e type;
270         struct yaca_key_evp_s *nk = NULL;
271
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.
275          */
276         if (data_len < 4)
277                 return YACA_ERROR_INVALID_ARGUMENT;
278
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;
282
283         src = BIO_new_mem_buf(data, data_len);
284         if (src == NULL) {
285                 ERROR_DUMP(YACA_ERROR_INTERNAL);
286                 return YACA_ERROR_INTERNAL;
287         }
288
289         /* Block the default OpenSSL password callback */
290         if (password == NULL)
291                 cb = password_dummy_cb;
292
293         /* Possible PEM */
294         if (strncmp("----", data, 4) == 0) {
295                 if (pkey == NULL && !wrong_pass) {
296                         BIO_reset(src);
297                         pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)password);
298                         if (check_import_wrong_pass())
299                                 wrong_pass = true;
300                         private = true;
301                         ERROR_CLEAR();
302                 }
303
304                 if (pkey == NULL && !wrong_pass) {
305                         BIO_reset(src);
306                         pkey = PEM_read_bio_PUBKEY(src, NULL, cb, (void*)password);
307                         if (check_import_wrong_pass())
308                                 wrong_pass = true;
309                         private = false;
310                         ERROR_CLEAR();
311                 }
312
313                 if (pkey == NULL && !wrong_pass) {
314                         BIO_reset(src);
315                         X509 *x509 = PEM_read_bio_X509(src, NULL, cb, (void*)password);
316                         if (check_import_wrong_pass())
317                                 wrong_pass = true;
318                         if (x509 != NULL)
319                                 pkey = X509_get_pubkey(x509);
320                         X509_free(x509);
321                         private = false;
322                         ERROR_CLEAR();
323                 }
324         }
325         /* Possible DER */
326         else {
327                 if (pkey == NULL && !wrong_pass) {
328                         BIO_reset(src);
329                         pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)password);
330                         if (check_import_wrong_pass())
331                                 wrong_pass = true;
332                         private = true;
333                         ERROR_CLEAR();
334                 }
335
336                 if (pkey == NULL && !wrong_pass) {
337                         BIO_reset(src);
338                         pkey = d2i_PrivateKey_bio(src, NULL);
339                         private = true;
340                         ERROR_CLEAR();
341                 }
342
343                 if (pkey == NULL && !wrong_pass) {
344                         BIO_reset(src);
345                         pkey = d2i_PUBKEY_bio(src, NULL);
346                         private = false;
347                         ERROR_CLEAR();
348                 }
349         }
350
351         BIO_free(src);
352
353         if (wrong_pass)
354                 return YACA_ERROR_PASSWORD_INVALID;
355
356         if (pkey == NULL)
357                 return YACA_ERROR_INVALID_ARGUMENT;
358
359         switch (EVP_PKEY_type(pkey->type)) {
360         case EVP_PKEY_RSA:
361                 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
362                 break;
363
364         case EVP_PKEY_DSA:
365                 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
366                 break;
367
368 //      case EVP_PKEY_EC:
369 //              type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
370 //              break;
371
372         default:
373                 ret = YACA_ERROR_INVALID_ARGUMENT;
374                 goto exit;
375         }
376
377         if (type != key_type) {
378                 ret = YACA_ERROR_INVALID_ARGUMENT;
379                 goto exit;
380         }
381
382         ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
383         if (ret != YACA_ERROR_NONE)
384                 goto exit;
385
386         nk->evp = pkey;
387         *key = (yaca_key_h)nk;
388         (*key)->type = type;
389
390         pkey = NULL;
391         ret = YACA_ERROR_NONE;
392
393 exit:
394         EVP_PKEY_free(pkey);
395
396         return ret;
397 }
398
399 int export_simple_raw(struct yaca_key_simple_s *simple_key,
400                       char **data,
401                       size_t *data_len)
402 {
403         int ret;
404         assert(simple_key != NULL);
405         assert(data != NULL);
406         assert(data_len != NULL);
407
408         size_t key_len = simple_key->bits / 8;
409
410         ret = yaca_malloc(key_len, (void**)data);
411         if (ret != YACA_ERROR_NONE)
412                 return ret;
413
414         memcpy(*data, simple_key->d, key_len);
415         *data_len = key_len;
416
417         return YACA_ERROR_NONE;
418 }
419
420 int export_simple_base64(struct yaca_key_simple_s *simple_key,
421                          char **data,
422                          size_t *data_len)
423 {
424         assert(simple_key != NULL);
425         assert(data != NULL);
426         assert(data_len != NULL);
427
428         int ret;
429         size_t key_len = simple_key->bits / 8;
430         BIO *b64;
431         BIO *mem;
432         char *bio_data;
433         long bio_data_len;
434
435         b64 = BIO_new(BIO_f_base64());
436         if (b64 == NULL) {
437                 ret = YACA_ERROR_INTERNAL;
438                 ERROR_DUMP(ret);
439                 return ret;
440         }
441
442         mem = BIO_new(BIO_s_mem());
443         if (mem == NULL) {
444                 ret = YACA_ERROR_INTERNAL;
445                 ERROR_DUMP(ret);
446                 goto exit;
447         }
448
449         BIO_push(b64, mem);
450         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
451
452         ret = BIO_write(b64, simple_key->d, key_len);
453         if (ret <= 0 || (unsigned)ret != key_len) {
454                 ret = YACA_ERROR_INTERNAL;
455                 ERROR_DUMP(ret);
456                 goto exit;
457         }
458
459         ret = BIO_flush(b64);
460         if (ret <= 0) {
461                 ret = YACA_ERROR_INTERNAL;
462                 ERROR_DUMP(ret);
463                 goto exit;
464         }
465
466         bio_data_len = BIO_get_mem_data(mem, &bio_data);
467         if (bio_data_len <= 0) {
468                 ret = YACA_ERROR_INTERNAL;
469                 ERROR_DUMP(ret);
470                 goto exit;
471         }
472
473         ret = yaca_malloc(bio_data_len, (void**)data);
474         if (ret != YACA_ERROR_NONE)
475                 goto exit;
476
477         memcpy(*data, bio_data, bio_data_len);
478         *data_len = bio_data_len;
479         ret = YACA_ERROR_NONE;
480
481 exit:
482         BIO_free_all(b64);
483
484         return ret;
485 }
486
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,
490                            BIO *mem)
491 {
492         assert(evp_key != NULL);
493         assert(password == NULL || password[0] != '\0');
494         assert(mem != NULL);
495
496         int ret;
497         const EVP_CIPHER *enc = NULL;
498
499         if (password != NULL)
500                 enc = EVP_aes_256_cbc();
501
502         switch (key_file_fmt) {
503
504         case YACA_KEY_FILE_FORMAT_PEM:
505                 switch (evp_key->key.type) {
506
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);
510                         break;
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);
514                         break;
515
516                 case YACA_KEY_TYPE_RSA_PUB:
517                 case YACA_KEY_TYPE_DSA_PUB:
518                         ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
519                         break;
520
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
526                 default:
527                         return YACA_ERROR_INVALID_ARGUMENT;
528                 }
529
530                 break;
531
532         case YACA_KEY_FILE_FORMAT_DER:
533                 switch (evp_key->key.type) {
534
535                 case YACA_KEY_TYPE_RSA_PRIV:
536                         ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
537                         break;
538
539                 case YACA_KEY_TYPE_DSA_PRIV:
540                         ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
541                         break;
542
543                 case YACA_KEY_TYPE_RSA_PUB:
544                 case YACA_KEY_TYPE_DSA_PUB:
545                         ret = i2d_PUBKEY_bio(mem, evp_key->evp);
546                         break;
547
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
553                 default:
554                         return YACA_ERROR_INVALID_ARGUMENT;
555                 }
556
557                 break;
558
559         default:
560                 return YACA_ERROR_INVALID_ARGUMENT;
561         }
562
563         if (ret <= 0) {
564                 ret = YACA_ERROR_INTERNAL;
565                 ERROR_DUMP(ret);
566                 return ret;
567         }
568
569         return YACA_ERROR_NONE;
570 }
571
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,
575                          BIO *mem)
576 {
577         assert(evp_key != NULL);
578         assert(password == NULL || password[0] != '\0');
579         assert(mem != NULL);
580
581         int ret;
582         int nid = -1;
583
584         if (password != NULL)
585                 nid = NID_pbeWithMD5AndDES_CBC;
586
587         switch (key_file_fmt) {
588
589         case YACA_KEY_FILE_FORMAT_PEM:
590                 switch (evp_key->key.type) {
591
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);
596                         break;
597 //              case YACA_KEY_TYPE_DH_PRIV:
598 //              case YACA_KEY_TYPE_EC_PRIV:
599 //                      TODO NOT_IMPLEMENTED
600                 default:
601                         /* Public keys are not supported by PKCS8 */
602                         return YACA_ERROR_INVALID_ARGUMENT;
603                 }
604
605                 break;
606
607         case YACA_KEY_FILE_FORMAT_DER:
608                 switch (evp_key->key.type) {
609
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);
614                         break;
615
616 //              case YACA_KEY_TYPE_DH_PRIV:
617 //              case YACA_KEY_TYPE_EC_PRIV:
618 //                      TODO NOT_IMPLEMENTED
619                 default:
620                         /* Public keys are not supported by PKCS8 */
621                         return YACA_ERROR_INVALID_ARGUMENT;
622                 }
623
624                 break;
625
626         default:
627                 return YACA_ERROR_INVALID_ARGUMENT;
628         }
629
630         if (ret <= 0) {
631                 ret = YACA_ERROR_INTERNAL;
632                 ERROR_DUMP(ret);
633                 return ret;
634         }
635
636         return YACA_ERROR_NONE;
637 }
638
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,
643                char **data,
644                size_t *data_len)
645 {
646         assert(evp_key != NULL);
647         assert(password == NULL || password[0] != '\0');
648         assert(data != NULL);
649         assert(data_len != NULL);
650
651         int ret = YACA_ERROR_NONE;
652         BIO *mem;
653         char *bio_data;
654         long bio_data_len;
655
656         mem = BIO_new(BIO_s_mem());
657         if (mem == NULL) {
658                 ret = YACA_ERROR_INTERNAL;
659                 ERROR_DUMP(ret);
660                 return ret;
661         }
662
663         switch (key_fmt) {
664         case YACA_KEY_FORMAT_DEFAULT:
665                 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
666                 break;
667         case YACA_KEY_FORMAT_PKCS8:
668                 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
669                 break;
670         default:
671                 ret = YACA_ERROR_INVALID_ARGUMENT;
672                 break;
673         }
674
675         if (ret != YACA_ERROR_NONE)
676                 goto exit;
677
678         ret = BIO_flush(mem);
679         if (ret <= 0) {
680                 ret = YACA_ERROR_INTERNAL;
681                 ERROR_DUMP(ret);
682                 goto exit;
683         }
684
685         bio_data_len = BIO_get_mem_data(mem, &bio_data);
686         if (bio_data_len <= 0) {
687                 ret = YACA_ERROR_INTERNAL;
688                 ERROR_DUMP(ret);
689                 goto exit;
690         }
691
692         ret = yaca_malloc(bio_data_len, (void**)data);
693         if (ret != YACA_ERROR_NONE)
694                 goto exit;
695
696         memcpy(*data, bio_data, bio_data_len);
697         *data_len = bio_data_len;
698         ret = YACA_ERROR_NONE;
699
700 exit:
701         BIO_free_all(mem);
702
703         return ret;
704 }
705
706 int gen_simple(struct yaca_key_simple_s **out, size_t key_bits)
707 {
708         assert(out != NULL);
709
710         int ret;
711         struct yaca_key_simple_s *nk;
712         size_t key_byte_len = key_bits / 8;
713
714         ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
715         if (ret != YACA_ERROR_NONE)
716                 return ret;
717
718         nk->bits = key_bits;
719
720         ret = yaca_rand_bytes(nk->d, key_byte_len);
721         if (ret != YACA_ERROR_NONE)
722                 return ret;
723
724         *out = nk;
725         return YACA_ERROR_NONE;
726 }
727
728 int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits)
729 {
730         assert(out != NULL);
731
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;
736
737         int ret;
738         struct yaca_key_simple_s *nk;
739         size_t key_byte_len = key_bits / 8;
740
741         ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
742         if (ret != YACA_ERROR_NONE)
743                 return ret;
744
745         DES_cblock *des_key = (DES_cblock*)nk->d;
746         if (key_byte_len >= 8) {
747                 ret = DES_random_key(des_key);
748                 if (ret != 1) {
749                         ret = YACA_ERROR_INTERNAL;
750                         ERROR_DUMP(ret);
751                         goto exit;
752                 }
753         }
754         if (key_byte_len >= 16) {
755                 ret = DES_random_key(des_key + 1);
756                 if (ret != 1) {
757                         ret = YACA_ERROR_INTERNAL;
758                         ERROR_DUMP(ret);
759                         goto exit;
760                 }
761         }
762         if (key_byte_len >= 24) {
763                 ret = DES_random_key(des_key + 2);
764                 if (ret != 1) {
765                         ret = YACA_ERROR_INTERNAL;
766                         ERROR_DUMP(ret);
767                         goto exit;
768                 }
769         }
770
771         nk->bits = key_bits;
772         *out = nk;
773         nk = NULL;
774         ret = YACA_ERROR_NONE;
775
776 exit:
777         yaca_free(nk);
778
779         return ret;
780 }
781
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)
784 {
785         assert(out != NULL);
786         assert(key_bits > 0);
787         assert(key_bits % 8 == 0);
788
789         int ret;
790         struct yaca_key_evp_s *nk;
791         EVP_PKEY_CTX *ctx;
792         EVP_PKEY *pkey = NULL;
793
794         ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
795         if (ret != YACA_ERROR_NONE)
796                 return ret;
797
798         ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
799         if (ctx == NULL) {
800                 ret = YACA_ERROR_INTERNAL;
801                 ERROR_DUMP(ret);
802                 goto exit;
803         }
804
805         ret = EVP_PKEY_keygen_init(ctx);
806         if (ret != 1) {
807                 ret = YACA_ERROR_INTERNAL;
808                 ERROR_DUMP(ret);
809                 goto exit;
810         }
811
812         ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits);
813         if (ret != 1) {
814                 ret = ERROR_HANDLE();
815                 goto exit;
816         }
817
818         ret = EVP_PKEY_keygen(ctx, &pkey);
819         if (ret != 1) {
820                 ret = YACA_ERROR_INTERNAL;
821                 ERROR_DUMP(ret);
822                 goto exit;
823         }
824
825         nk->evp = pkey;
826         pkey = NULL;
827         *out = nk;
828         nk = NULL;
829
830         ret = YACA_ERROR_NONE;
831
832 exit:
833         EVP_PKEY_CTX_free(ctx);
834         yaca_free(nk);
835
836         return ret;
837 }
838
839 int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits)
840 {
841         assert(out != NULL);
842         assert(key_bits > 0);
843         assert(key_bits % 8 == 0);
844
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;
849
850         int ret;
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;
856
857         ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
858         if (ret != YACA_ERROR_NONE)
859                 return ret;
860
861         pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
862         if (pctx == NULL) {
863                 ret = YACA_ERROR_INTERNAL;
864                 ERROR_DUMP(ret);
865                 goto exit;
866         }
867
868         ret = EVP_PKEY_paramgen_init(pctx);
869         if (ret != 1) {
870                 ret = YACA_ERROR_INTERNAL;
871                 ERROR_DUMP(ret);
872                 goto exit;
873         }
874
875         ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits);
876         if (ret != 1) {
877                 ret = ERROR_HANDLE();
878                 goto exit;
879         }
880
881         ret = EVP_PKEY_paramgen(pctx, &params);
882         if (ret != 1) {
883                 ret = YACA_ERROR_INTERNAL;
884                 ERROR_DUMP(ret);
885                 goto exit;
886         }
887
888         kctx = EVP_PKEY_CTX_new(params, NULL);
889         if (kctx == NULL) {
890                 ret = YACA_ERROR_INTERNAL;
891                 ERROR_DUMP(ret);
892                 goto exit;
893         }
894
895         ret = EVP_PKEY_keygen_init(kctx);
896         if (ret != 1) {
897                 ret = YACA_ERROR_INTERNAL;
898                 ERROR_DUMP(ret);
899                 goto exit;
900         }
901
902         ret = EVP_PKEY_keygen(kctx, &pkey);
903         if (ret != 1) {
904                 ret = YACA_ERROR_INTERNAL;
905                 ERROR_DUMP(ret);
906                 goto exit;
907         }
908
909         nk->evp = pkey;
910         pkey = NULL;
911         *out = nk;
912         nk = NULL;
913
914         ret = YACA_ERROR_NONE;
915
916 exit:
917         EVP_PKEY_CTX_free(kctx);
918         EVP_PKEY_free(params);
919         EVP_PKEY_CTX_free(pctx);
920         yaca_free(nk);
921
922         return ret;
923 }
924
925 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
926 {
927         struct yaca_key_simple_s *k;
928
929         if (key == YACA_KEY_NULL)
930                 return NULL;
931
932         switch (key->type) {
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;
937
938                 /* sanity check */
939                 assert(k->bits != 0);
940                 assert(k->bits % 8 == 0);
941                 assert(k->d != NULL);
942
943                 return k;
944         default:
945                 return NULL;
946         }
947 }
948
949 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
950 {
951         struct yaca_key_evp_s *k;
952
953         if (key == YACA_KEY_NULL)
954                 return NULL;
955
956         switch (key->type) {
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;
962
963                 /* sanity check */
964                 assert(k->evp != NULL);
965
966                 return k;
967         default:
968                 return NULL;
969         }
970 }
971
972 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
973 {
974         const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
975
976         if (lkey == NULL || key_type == NULL)
977                 return YACA_ERROR_INVALID_ARGUMENT;
978
979         *key_type = lkey->type;
980         return YACA_ERROR_NONE;
981 }
982
983 API int yaca_key_get_bits(const yaca_key_h key, size_t *key_bits)
984 {
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);
987
988         if (key_bits == NULL)
989                 return YACA_ERROR_INVALID_ARGUMENT;
990
991         if (simple_key != NULL) {
992                 *key_bits = simple_key->bits;
993                 return YACA_ERROR_NONE;
994         }
995
996         if (evp_key != NULL) {
997                 int ret;
998
999                 // TODO: handle ECC keys when they're implemented
1000                 ret = EVP_PKEY_bits(evp_key->evp);
1001                 if (ret <= 0) {
1002                         ret = YACA_ERROR_INTERNAL;
1003                         ERROR_DUMP(ret);
1004                         return ret;
1005                 }
1006
1007                 *key_bits = ret;
1008                 return YACA_ERROR_NONE;
1009         }
1010
1011         return YACA_ERROR_INVALID_ARGUMENT;
1012 }
1013
1014 API int yaca_key_import(yaca_key_type_e key_type,
1015                         const char *password,
1016                         const char *data,
1017                         size_t data_len,
1018                         yaca_key_h *key)
1019 {
1020         if (key == NULL || data == NULL || data_len == 0)
1021                 return YACA_ERROR_INVALID_ARGUMENT;
1022
1023         /* allow an empty password, OpenSSL returns an error with "" */
1024         if (password != NULL && password[0] == '\0')
1025                 password = NULL;
1026
1027         switch (key_type) {
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
1044         default:
1045                 return YACA_ERROR_INVALID_ARGUMENT;
1046         }
1047 }
1048
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,
1053                         char **data,
1054                         size_t *data_len)
1055 {
1056         struct yaca_key_simple_s *simple_key = key_get_simple(key);
1057         struct yaca_key_evp_s *evp_key = key_get_evp(key);
1058
1059         if (data == NULL || data_len == NULL)
1060                 return YACA_ERROR_INVALID_ARGUMENT;
1061
1062         /* allow an empty password, OpenSSL returns an error with "" */
1063         if (password != NULL && password[0] == '\0')
1064                 password = NULL;
1065
1066         if (password != NULL && simple_key != NULL)
1067                 return YACA_ERROR_INVALID_ARGUMENT;
1068
1069         if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1070             key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1071             simple_key != NULL)
1072                 return export_simple_raw(simple_key, data, data_len);
1073
1074         if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1075             key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1076             simple_key != NULL)
1077                 return export_simple_base64(simple_key, data, data_len);
1078
1079         if (evp_key != NULL)
1080                 return export_evp(evp_key, key_fmt, key_file_fmt,
1081                                   password, data, data_len);
1082
1083         return YACA_ERROR_INVALID_ARGUMENT;
1084 }
1085
1086 API int yaca_key_gen(yaca_key_type_e key_type,
1087                      size_t key_bits,
1088                      yaca_key_h *key)
1089 {
1090         int ret;
1091         struct yaca_key_simple_s *nk_simple = NULL;
1092         struct yaca_key_evp_s *nk_evp = NULL;
1093
1094         if (key == NULL || key_bits == 0 || key_bits % 8 != 0)
1095                 return YACA_ERROR_INVALID_ARGUMENT;
1096
1097         switch (key_type) {
1098         case YACA_KEY_TYPE_SYMMETRIC:
1099         case YACA_KEY_TYPE_IV:
1100                 ret = gen_simple(&nk_simple, key_bits);
1101                 break;
1102         case YACA_KEY_TYPE_DES:
1103                 ret = gen_simple_des(&nk_simple, key_bits);
1104                 break;
1105         case YACA_KEY_TYPE_RSA_PRIV:
1106                 ret = gen_evp_rsa(&nk_evp, key_bits);
1107                 break;
1108         case YACA_KEY_TYPE_DSA_PRIV:
1109                 ret = gen_evp_dsa(&nk_evp, key_bits);
1110                 break;
1111 //      case YACA_KEY_TYPE_DH_PRIV:
1112 //      case YACA_KEY_TYPE_EC_PRIV:
1113 //              TODO NOT_IMPLEMENTED
1114         default:
1115                 return YACA_ERROR_INVALID_ARGUMENT;
1116         }
1117
1118         if (ret != YACA_ERROR_NONE)
1119                 return ret;
1120
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;
1127         }
1128
1129         return YACA_ERROR_NONE;
1130
1131 }
1132
1133 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1134 {
1135         int ret;
1136         struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1137         struct yaca_key_evp_s *nk;
1138         BIO *mem = NULL;
1139         EVP_PKEY *pkey = NULL;
1140
1141         if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1142                 return YACA_ERROR_INVALID_ARGUMENT;
1143
1144         ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1145         if (ret != YACA_ERROR_NONE)
1146                 return ret;
1147
1148         mem = BIO_new(BIO_s_mem());
1149         if (mem == NULL) {
1150                 ret = YACA_ERROR_INTERNAL;
1151                 ERROR_DUMP(ret);
1152                 goto exit;
1153         }
1154
1155         ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1156         if (ret != 1) {
1157                 ret = YACA_ERROR_INTERNAL;
1158                 ERROR_DUMP(ret);
1159                 goto exit;
1160         }
1161
1162         pkey = d2i_PUBKEY_bio(mem, NULL);
1163         if (pkey == NULL) {
1164                 ret = YACA_ERROR_INTERNAL;
1165                 ERROR_DUMP(ret);
1166                 goto exit;
1167         }
1168
1169         BIO_free(mem);
1170         mem = NULL;
1171
1172         switch (prv_key->type) {
1173         case YACA_KEY_TYPE_RSA_PRIV:
1174                 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1175                 break;
1176         case YACA_KEY_TYPE_DSA_PRIV:
1177                 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1178                 break;
1179 //      case YACA_KEY_TYPE_EC_PRIV:
1180 //              nk->key.type = YACA_KEY_TYPE_EC_PUB;
1181 //              break;
1182         default:
1183                 ret = YACA_ERROR_INVALID_ARGUMENT;
1184                 goto exit;
1185         }
1186
1187         nk->evp = pkey;
1188         pkey = NULL;
1189         *pub_key = (yaca_key_h)nk;
1190         nk = NULL;
1191         ret = YACA_ERROR_NONE;
1192
1193 exit:
1194         EVP_PKEY_free(pkey);
1195         BIO_free(mem);
1196         yaca_free(nk);
1197
1198         return ret;
1199 }
1200
1201 API int yaca_key_free(yaca_key_h key)
1202 {
1203         struct yaca_key_simple_s *simple_key = key_get_simple(key);
1204         struct yaca_key_evp_s *evp_key = key_get_evp(key);
1205
1206         if (simple_key != NULL)
1207                 yaca_free(simple_key);
1208
1209         if (evp_key != NULL) {
1210                 EVP_PKEY_free(evp_key->evp);
1211                 yaca_free(evp_key);
1212         }
1213
1214         return YACA_ERROR_NONE;
1215 }
1216
1217 API int yaca_key_derive_pbkdf2(const char *password,
1218                                const char *salt,
1219                                size_t salt_len,
1220                                int iter,
1221                                yaca_digest_algo_e algo,
1222                                size_t key_bits,
1223                                yaca_key_h *key)
1224 {
1225         const EVP_MD *md;
1226         struct yaca_key_simple_s *nk;
1227         size_t key_byte_len = key_bits / 8;
1228         int ret;
1229
1230         if (password == NULL || salt == NULL || salt_len == 0 ||
1231             iter == 0 || key_bits == 0 || key == NULL)
1232                 return YACA_ERROR_INVALID_ARGUMENT;
1233
1234         if (key_bits % 8) /* Key length must be multiple of 8-bits */
1235                 return YACA_ERROR_INVALID_ARGUMENT;
1236
1237         ret = digest_get_algorithm(algo, &md);
1238         if (ret != YACA_ERROR_NONE)
1239                 return ret;
1240
1241         ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1242         if (ret != YACA_ERROR_NONE)
1243                 return ret;
1244
1245         nk->bits = key_bits;
1246         nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1247
1248         ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1249                                 salt_len, iter, md, key_byte_len,
1250                                 (unsigned char*)nk->d);
1251         if (ret != 1) {
1252                 ret = YACA_ERROR_INTERNAL;
1253                 ERROR_DUMP(ret);
1254                 goto exit;
1255         }
1256
1257         *key = (yaca_key_h)nk;
1258         nk = NULL;
1259         ret = YACA_ERROR_NONE;
1260 exit:
1261         yaca_free(nk);
1262
1263         return ret;
1264 }