CKMC API: Add option to list aliases with information about password protection
[platform/core/security/key-manager.git] / src / manager / client-capi / ckmc-type.cpp
1 /*
2  *  Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  *
16  *
17  * @file        ckmc-type.cpp
18  * @author      Yuseok Jeon(yuseok.jeon@samsung.com)
19  * @version     1.0
20  * @brief       new and free methods for the struct of CAPI
21  */
22
23
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <ckm/ckm-type.h>
28 #include <ckmc/ckmc-type.h>
29 #include <ckmc/ckmc-error.h>
30 #include <ckmc-type-converter.h>
31 #include <client-common.h>
32 #include <protocols.h>
33 #include <openssl/x509v3.h>
34 #include <openssl/pkcs12.h>
35 #include <openssl/evp.h>
36 #include <openssl/pem.h>
37 #include <fstream>
38 #include <crypto-init.h>
39 #include <dpl/log/log.h>
40 #include <dpl/errno_string.h>
41
42 namespace {
43
44 const size_t DEFAULT_IV_LEN = 16;
45 const size_t DEFAULT_IV_LEN_BITS = 8 * DEFAULT_IV_LEN;
46 const size_t DEFAULT_KEY_LEN_BITS = 4096;
47
48 int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert)
49 {
50         if (xCert == NULL)
51                 return CKMC_ERROR_INVALID_FORMAT;
52
53         BIO *bcert = BIO_new(BIO_s_mem());
54
55         i2d_X509_bio(bcert, xCert);
56
57         CKM::RawBuffer output(8196);
58         int size = BIO_read(bcert, output.data(), output.size());
59         BIO_free_all(bcert);
60
61         if (size <= 0)
62                 return CKMC_ERROR_INVALID_FORMAT;
63
64         output.resize(size);
65
66         return ckmc_cert_new(output.data(), output.size(), CKMC_FORM_DER, cert);
67 }
68
69 void _ckmc_alias_info_free(ckmc_alias_info_s *info)
70 {
71         if (info == NULL)
72                 return;
73         free(info->alias);
74         free(info);
75 }
76
77 } // namespace anonymous
78
79 const char *const ckmc_label_name_separator    = CKM::ALIAS_SEPARATOR;
80 const char *const ckmc_owner_id_separator      = CKM::ALIAS_SEPARATOR;
81 const char *const ckmc_owner_id_system         = CKM::CLIENT_ID_SYSTEM;
82
83 KEY_MANAGER_CAPI
84 int ckmc_alias_new(const char *owner_id, const char *alias, char **full_alias)
85 {
86         if (owner_id == NULL || alias == NULL || full_alias == NULL)
87                 return CKMC_ERROR_INVALID_PARAMETER;
88
89         size_t len = strlen(owner_id) + strlen(alias) + strlen(ckmc_owner_id_separator);
90         char *_full_alias = static_cast<char *>(malloc(len + 1));
91
92         if (_full_alias == NULL)
93                 return CKMC_ERROR_OUT_OF_MEMORY;
94
95         strncpy(_full_alias, owner_id, len + 1);
96         strncat(_full_alias, ckmc_owner_id_separator, len - strlen(_full_alias));
97         strncat(_full_alias, alias, len - strlen(_full_alias));
98
99         *full_alias = _full_alias;
100
101         return CKMC_ERROR_NONE;
102 }
103
104 KEY_MANAGER_CAPI
105 int ckmc_key_new(unsigned char *raw_key, size_t key_size,
106                                  ckmc_key_type_e key_type, char *password, ckmc_key_s **ppkey)
107 {
108         ckmc_key_s *pkey;
109
110         if (raw_key == NULL || key_size == 0 || ppkey == NULL)
111                 return CKMC_ERROR_INVALID_PARAMETER;
112
113         pkey = static_cast<ckmc_key_s *>(malloc(sizeof(ckmc_key_s)));
114
115         if (pkey == NULL)
116                 return CKMC_ERROR_OUT_OF_MEMORY;
117
118         pkey->raw_key = reinterpret_cast<unsigned char *>(malloc(key_size));
119
120         if (pkey->raw_key == NULL) {
121                 free(pkey);
122                 return CKMC_ERROR_OUT_OF_MEMORY;
123         }
124
125         memcpy(pkey->raw_key, raw_key, key_size);
126
127         pkey->key_size = key_size;
128         pkey->key_type = key_type;
129
130         if (password != NULL) {
131                 pkey->password = strdup(password);
132                 if (pkey->password == NULL) {
133                         free(pkey->raw_key);
134                         free(pkey);
135                         return CKMC_ERROR_OUT_OF_MEMORY;
136                 }
137         } else {
138                 pkey->password = NULL;
139         }
140
141         *ppkey = pkey;
142
143         return CKMC_ERROR_NONE;
144 }
145
146 KEY_MANAGER_CAPI
147 void ckmc_key_free(ckmc_key_s *key)
148 {
149         if (key == NULL)
150                 return;
151
152         if (key->password != NULL)
153                 free(key->password);
154
155         if (key->raw_key != NULL) {
156                 memset(key->raw_key, 0, key->key_size);
157                 free(key->raw_key);
158         }
159
160         free(key);
161 }
162
163 KEY_MANAGER_CAPI
164 int ckmc_buffer_new(unsigned char *data, size_t size,
165                                         ckmc_raw_buffer_s **ppbuffer)
166 {
167         ckmc_raw_buffer_s *pbuff;
168
169         if (data == NULL || size == 0 || ppbuffer == NULL)
170                 return CKMC_ERROR_INVALID_PARAMETER;
171
172         pbuff = static_cast<ckmc_raw_buffer_s *>(malloc(sizeof(ckmc_raw_buffer_s)));
173
174         if (pbuff == NULL)
175                 return CKMC_ERROR_OUT_OF_MEMORY;
176
177         pbuff->data = reinterpret_cast<unsigned char *>(malloc(size));
178
179         if (pbuff->data == NULL) {
180                 free(pbuff);
181                 return CKMC_ERROR_OUT_OF_MEMORY;
182         }
183
184         memcpy(pbuff->data, data, size);
185
186         pbuff->size = size;
187         *ppbuffer = pbuff;
188
189         return CKMC_ERROR_NONE;
190 }
191
192 KEY_MANAGER_CAPI
193 void ckmc_buffer_free(ckmc_raw_buffer_s *buffer)
194 {
195         if (buffer == NULL)
196                 return;
197
198         if (buffer->data != NULL) {
199                 memset(buffer->data, 0, buffer->size);
200                 free(buffer->data);
201         }
202
203         free(buffer);
204 }
205
206 KEY_MANAGER_CAPI
207 int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size,
208                                   ckmc_data_format_e data_format, ckmc_cert_s **ppcert)
209 {
210         ckmc_cert_s *pcert;
211
212         if (raw_cert == NULL || cert_size == 0 || ppcert == NULL)
213                 return CKMC_ERROR_INVALID_PARAMETER;
214
215         pcert = static_cast<ckmc_cert_s *>(malloc(sizeof(ckmc_cert_s)));
216
217         if (pcert == NULL)
218                 return CKMC_ERROR_OUT_OF_MEMORY;
219
220         pcert->raw_cert = reinterpret_cast<unsigned char *>(malloc(cert_size));
221
222         if (pcert->raw_cert == NULL) {
223                 free(pcert);
224                 return CKMC_ERROR_OUT_OF_MEMORY;
225         }
226
227         memcpy(pcert->raw_cert, raw_cert, cert_size);
228
229         pcert->cert_size = cert_size;
230         pcert->data_format = data_format;
231
232         *ppcert = pcert;
233         return CKMC_ERROR_NONE;
234 }
235
236 KEY_MANAGER_CAPI
237 int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert)
238 {
239         CKM::initOpenSslOnce();
240
241         FILE *fp = fopen(file_path, "r");
242
243         if (fp == NULL)
244                 return CKMC_ERROR_FILE_ACCESS_DENIED;
245
246         X509 *pcert = NULL;
247
248         if (!(pcert = d2i_X509_fp(fp, NULL))) {
249                 if (-1 == fseek(fp, 0, SEEK_SET)) {
250                         LogError("fseek() failed: " <<  CKM::GetErrnoString(errno));
251                         fclose(fp);
252                         return CKMC_ERROR_UNKNOWN;
253                 }
254
255                 pcert = PEM_read_X509(fp, NULL, NULL, NULL);
256         }
257
258         fclose(fp);
259
260         if (pcert == NULL)
261                 return CKMC_ERROR_INVALID_FORMAT;
262
263         int ret = _ckmc_load_cert_from_x509(pcert, cert);
264
265         X509_free(pcert);
266
267         return ret;
268 }
269
270 KEY_MANAGER_CAPI
271 void ckmc_cert_free(ckmc_cert_s *cert)
272 {
273         if (cert == NULL)
274                 return;
275
276         if (cert->raw_cert != NULL) {
277                 memset(cert->raw_cert, 0, cert->cert_size);
278                 free(cert->raw_cert);
279         }
280
281         free(cert);
282 }
283
284 KEY_MANAGER_CAPI
285 int ckmc_pkcs12_new(ckmc_key_s *private_key, ckmc_cert_s *cert,
286                                         ckmc_cert_list_s *ca_cert_list, ckmc_pkcs12_s **pkcs12_bundle)
287 {
288         ckmc_pkcs12_s *pkcs12;
289
290         if (!pkcs12_bundle ||
291                         (private_key == NULL && cert == NULL && (ca_cert_list == NULL ||
292                                         ca_cert_list->cert == NULL)))
293                 return CKMC_ERROR_INVALID_PARAMETER;
294
295         pkcs12 = static_cast<ckmc_pkcs12_s *>(malloc(sizeof(ckmc_pkcs12_s)));
296
297         if (pkcs12 == NULL)
298                 return CKMC_ERROR_OUT_OF_MEMORY;
299
300         // ownership is transferred into pkcs12 - mentioned in the docs
301         pkcs12->priv_key = private_key;
302         pkcs12->cert = cert;
303         pkcs12->ca_chain = ca_cert_list;
304
305         *pkcs12_bundle = pkcs12;
306         return CKMC_ERROR_NONE;
307 }
308
309 KEY_MANAGER_CAPI
310 int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase,
311                                                            ckmc_key_s **private_key, ckmc_cert_s **ckmcert,
312                                                            ckmc_cert_list_s **ca_cert_list)
313 {
314         class Pkcs12Converter {
315         private:
316                 FILE *fp_in;
317                 PKCS12 *p12;
318                 EVP_PKEY *pkey;
319                 X509 *x509Cert;
320                 STACK_OF(X509) *ca;
321
322                 int ret;
323
324         public:
325                 ckmc_key_s *retPrivateKey;
326                 ckmc_cert_s *retCkmCert;
327                 ckmc_cert_list_s *retCaCertList;
328
329                 Pkcs12Converter()
330                 {
331                         fp_in = NULL;
332                         p12 = NULL;
333                         pkey = NULL;
334                         x509Cert = NULL;
335                         ca = NULL;
336                         ret = CKMC_ERROR_NONE;
337                         retPrivateKey = NULL;
338                         retCkmCert = NULL;
339                         retCaCertList = NULL;
340                 }
341
342                 ~Pkcs12Converter()
343                 {
344                         if (fp_in != NULL)
345                                 fclose(fp_in);
346
347                         if (p12 != NULL)
348                                 PKCS12_free(p12);
349
350                         if (x509Cert != NULL)
351                                 X509_free(x509Cert);
352
353                         if (pkey != NULL)
354                                 EVP_PKEY_free(pkey);
355
356                         if (ca != NULL)
357                                 sk_X509_pop_free(ca, X509_free);
358
359                         if (ret != CKMC_ERROR_NONE) {
360                                 if (retPrivateKey != NULL) {
361                                         ckmc_key_free(retPrivateKey);
362                                         retPrivateKey = NULL;
363                                 }
364
365                                 if (retCkmCert != NULL) {
366                                         ckmc_cert_free(retCkmCert);
367                                         retCkmCert = NULL;
368                                 }
369
370                                 if (retCaCertList != NULL) {
371                                         ckmc_cert_list_all_free(retCaCertList);
372                                         retCaCertList = NULL;
373                                 }
374                         }
375                 }
376
377                 int parsePkcs12(const char *filePath, const char *pass)
378                 {
379                         fp_in = NULL;
380
381                         if (!(fp_in = fopen(filePath, "rb")))
382                                 return CKMC_ERROR_FILE_ACCESS_DENIED;
383
384                         if (!(p12 = d2i_PKCS12_fp(fp_in, NULL)))
385                                 return CKMC_ERROR_INVALID_FORMAT;
386
387                         /* parse PKCS#12 certificate */
388                         if ((ret = PKCS12_parse(p12, pass, &pkey, &x509Cert, &ca)) != 1)
389                                 return CKMC_ERROR_INVALID_FORMAT;
390
391                         return CKMC_ERROR_NONE;
392                 }
393
394                 int toCkmCert()
395                 {
396                         if ((ret = _ckmc_load_cert_from_x509(x509Cert, &retCkmCert)) != CKMC_ERROR_NONE)
397                                 return ret;
398
399                         return CKMC_ERROR_NONE;
400                 }
401
402                 int toCkmKey()
403                 {
404                         BIO *bkey = BIO_new(BIO_s_mem());
405
406                         i2d_PrivateKey_bio(bkey, pkey);
407
408                         CKM::RawBuffer output(8196);
409                         int size = BIO_read(bkey, output.data(), output.size());
410                         BIO_free_all(bkey);
411
412                         if (size <= 0)
413                                 return CKMC_ERROR_INVALID_FORMAT;
414
415                         output.resize(size);
416
417                         int type = EVP_PKEY_type(pkey->type);
418                         ckmc_key_type_e key_type = CKMC_KEY_NONE;
419
420                         switch (type) {
421                         case EVP_PKEY_RSA :
422                                 key_type = CKMC_KEY_RSA_PRIVATE;
423                                 break;
424
425                         case EVP_PKEY_DSA :
426                                 key_type = CKMC_KEY_DSA_PRIVATE;
427                                 break;
428
429                         case EVP_PKEY_EC :
430                                 key_type = CKMC_KEY_ECDSA_PRIVATE;
431                                 break;
432                         }
433
434                         if (key_type == CKMC_KEY_NONE)
435                                 return CKMC_ERROR_INVALID_FORMAT;
436
437                         char *nullPassword = NULL;
438
439                         return ckmc_key_new(output.data(), size, key_type, nullPassword,
440                                                                 &retPrivateKey);
441                 }
442
443                 int toCaCkmCertList()
444                 {
445                         int tmpRet;
446                         X509 *popedCert = NULL;
447                         ckmc_cert_s *popedCkmCert = NULL;
448                         ckmc_cert_list_s *tmpCertList = NULL;
449
450                         while ((popedCert = sk_X509_pop(ca)) != NULL) {
451                                 tmpRet = _ckmc_load_cert_from_x509(popedCert, &popedCkmCert);
452                                 X509_free(popedCert);
453                                 if (tmpRet != CKMC_ERROR_NONE)
454                                         return CKMC_ERROR_OUT_OF_MEMORY;
455
456                                 if (tmpCertList == NULL) { // first
457                                         tmpRet = ckmc_cert_list_new(popedCkmCert, &tmpCertList);
458                                         retCaCertList = tmpCertList;
459                                 } else {
460                                         tmpRet = ckmc_cert_list_add(tmpCertList, popedCkmCert, &tmpCertList);
461                                 }
462
463                                 if (tmpRet != CKMC_ERROR_NONE) {
464                                         ckmc_cert_list_all_free(retCaCertList);
465                                         retCaCertList = NULL;
466                                         return tmpRet;
467                                 }
468                         }
469
470                         return CKMC_ERROR_NONE;
471                 }
472         };
473
474         LogWarning("DEPRECATION WARNING: " << __func__ << "() is deprecated and will be "
475                            "removed from next release. Use ckmc_pkcs12_load() instead.");
476
477         CKM::initOpenSslOnce();
478
479         int ret = CKMC_ERROR_NONE;
480
481         Pkcs12Converter converter;
482
483         if ((ret = converter.parsePkcs12(file_path, passphrase)) != CKMC_ERROR_NONE)
484                 return ret;
485
486         if ((ret = converter.toCkmCert()) != CKMC_ERROR_NONE)
487                 return ret;
488
489         if ((ret = converter.toCkmKey()) != CKMC_ERROR_NONE)
490                 return ret;
491
492         if ((ret = converter.toCaCkmCertList()) != CKMC_ERROR_NONE)
493                 return ret;
494
495         *private_key = converter.retPrivateKey;
496         *ckmcert = converter.retCkmCert;
497         *ca_cert_list = converter.retCaCertList;
498
499         return CKMC_ERROR_NONE;
500 }
501
502 KEY_MANAGER_CAPI
503 int ckmc_pkcs12_load(const char *file_path, const char *passphrase,
504                                          ckmc_pkcs12_s **pkcs12_bundle)
505 {
506         int ec;
507         ckmc_key_s *private_key = 0;
508         ckmc_cert_s *cert = 0;
509         ckmc_cert_list_s *ca_cert_list = 0;
510
511         if (!file_path || !pkcs12_bundle)
512                 return CKMC_ERROR_INVALID_PARAMETER;
513
514         ec = ckmc_load_from_pkcs12_file(file_path, passphrase, &private_key, &cert,
515                                                                         &ca_cert_list);
516
517         if (ec != CKMC_ERROR_NONE)
518                 return ec;
519
520         ec = ckmc_pkcs12_new(private_key, cert, ca_cert_list, pkcs12_bundle);
521
522         if (ec != CKMC_ERROR_NONE) {
523                 ckmc_key_free(private_key);
524                 ckmc_cert_free(cert);
525                 ckmc_cert_list_free(ca_cert_list);
526                 return ec;
527         }
528
529         return CKMC_ERROR_NONE;
530 }
531
532 KEY_MANAGER_CAPI
533 void ckmc_pkcs12_free(ckmc_pkcs12_s *pkcs12)
534 {
535         if (pkcs12 == NULL)
536                 return;
537
538         ckmc_key_free(pkcs12->priv_key);
539         ckmc_cert_free(pkcs12->cert);
540         ckmc_cert_list_all_free(pkcs12->ca_chain);
541         free(pkcs12);
542 }
543
544 KEY_MANAGER_CAPI
545 int ckmc_alias_list_new(char *alias, ckmc_alias_list_s **ppalias_list)
546 {
547         ckmc_alias_list_s *previous = NULL;
548         return ckmc_alias_list_add(previous, alias, ppalias_list);
549 }
550
551 KEY_MANAGER_CAPI
552 int ckmc_alias_list_add(ckmc_alias_list_s *previous, char *alias,
553                                                 ckmc_alias_list_s **pplast)
554 {
555         ckmc_alias_list_s *plist;
556
557         if (alias == NULL || pplast == NULL)
558                 return CKMC_ERROR_INVALID_PARAMETER;
559
560         plist = static_cast<ckmc_alias_list_s *>(malloc(sizeof(ckmc_alias_list_s)));
561
562         if (plist == NULL)
563                 return CKMC_ERROR_OUT_OF_MEMORY;
564
565         plist->alias = alias;
566         plist->next = NULL;
567
568         if (previous != NULL)
569                 previous->next = plist;
570
571         *pplast = plist;
572
573         return CKMC_ERROR_NONE;
574 }
575
576 KEY_MANAGER_CAPI
577 void ckmc_alias_list_free(ckmc_alias_list_s *first)
578 {
579         ckmc_alias_list_s *next = first;
580
581         while (next) {
582                 ckmc_alias_list_s *current = next;
583                 next = current->next;
584                 free(current);
585         }
586 }
587
588 KEY_MANAGER_CAPI
589 void ckmc_alias_list_all_free(ckmc_alias_list_s *first)
590 {
591         ckmc_alias_list_s *next = first;
592
593         while (next) {
594                 ckmc_alias_list_s *current = next;
595                 next = current->next;
596                 free(current->alias);
597                 free(current);
598         }
599 }
600
601 KEY_MANAGER_CAPI
602 int ckmc_alias_info_get_alias(const ckmc_alias_info_s* info, char** alias)
603 {
604         if (info == NULL || alias == NULL)
605                 return CKMC_ERROR_INVALID_PARAMETER;
606
607         *alias = info->alias;
608         return CKMC_ERROR_NONE;
609 }
610
611 KEY_MANAGER_CAPI
612 int ckmc_alias_info_is_password_protected(const ckmc_alias_info_s* info, bool* is_password_protected)
613 {
614         if (info == NULL || is_password_protected == NULL)
615                 return CKMC_ERROR_INVALID_PARAMETER;
616
617         *is_password_protected = info->is_password_protected;
618         return CKMC_ERROR_NONE;
619 }
620
621
622 KEY_MANAGER_CAPI
623 void ckmc_alias_info_list_all_free(ckmc_alias_info_list_s *first)
624 {
625         ckmc_alias_info_list_s *next = first;
626
627         while (next) {
628                 ckmc_alias_info_list_s *current = next;
629                 next = current->next;
630                 _ckmc_alias_info_free(current->info);
631                 free(current);
632         }
633 }
634
635 KEY_MANAGER_CAPI
636 int ckmc_cert_list_new(ckmc_cert_s *cert, ckmc_cert_list_s **ppalias_list)
637 {
638         ckmc_cert_list_s *previous = NULL;
639         return ckmc_cert_list_add(previous, cert, ppalias_list);
640 }
641
642 KEY_MANAGER_CAPI
643 int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert,
644                                                 ckmc_cert_list_s **pplast)
645 {
646         ckmc_cert_list_s *plist;
647
648         if (cert == NULL || pplast == NULL)
649                 return CKMC_ERROR_INVALID_PARAMETER;
650
651         plist = static_cast<ckmc_cert_list_s *>(malloc(sizeof(ckmc_cert_list_s)));
652
653         if (plist == NULL)
654                 return CKMC_ERROR_OUT_OF_MEMORY;
655
656         plist->cert = cert;
657         plist->next = NULL;
658
659         if (previous != NULL)
660                 previous->next = plist;
661
662         *pplast = plist;
663
664         return CKMC_ERROR_NONE;
665 }
666
667 KEY_MANAGER_CAPI
668 void ckmc_cert_list_free(ckmc_cert_list_s *first)
669 {
670         ckmc_cert_list_s *next = first;
671
672         while (next) {
673                 ckmc_cert_list_s *current = next;
674                 next = current->next;
675                 free(current);
676         }
677 }
678
679 KEY_MANAGER_CAPI
680 void ckmc_cert_list_all_free(ckmc_cert_list_s *first)
681 {
682         ckmc_cert_list_s *next = first;
683
684         while (next) {
685                 ckmc_cert_list_s *current = next;
686                 next = current->next;
687                 ckmc_cert_free(current->cert);
688                 free(current);
689         }
690 }
691
692 KEY_MANAGER_CAPI
693 int ckmc_param_list_new(ckmc_param_list_h *pparams)
694 {
695         if (!pparams)
696                 return CKMC_ERROR_INVALID_PARAMETER;
697
698         *pparams = reinterpret_cast<ckmc_param_list_h>(new(std::nothrow)(
699                                    CKM::CryptoAlgorithm));
700
701         if (!*pparams)
702                 return CKMC_ERROR_OUT_OF_MEMORY;
703
704         return CKMC_ERROR_NONE;
705 }
706
707 KEY_MANAGER_CAPI
708 int ckmc_param_list_set_integer(ckmc_param_list_h params,
709                                                                 ckmc_param_name_e name,
710                                                                 uint64_t value)
711 {
712         if (!params)
713                 return CKMC_ERROR_INVALID_PARAMETER;
714
715         CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params);
716         bool ret = algo->setParam(static_cast<CKM::ParamName>(name), value);
717         return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER);
718 }
719
720 KEY_MANAGER_CAPI
721 int ckmc_param_list_set_buffer(ckmc_param_list_h params,
722                                                            ckmc_param_name_e name,
723                                                            const ckmc_raw_buffer_s *buffer)
724 {
725         if (!params || !buffer || !buffer->data || buffer->size == 0)
726                 return CKMC_ERROR_INVALID_PARAMETER;
727
728         CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params);
729         CKM::RawBuffer b(buffer->data, buffer->data + buffer->size);
730         bool ret =  algo->setParam(static_cast<CKM::ParamName>(name), b);
731         return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER);
732 }
733
734 KEY_MANAGER_CAPI
735 int ckmc_param_list_get_integer(ckmc_param_list_h params,
736                                                                 ckmc_param_name_e name,
737                                                                 uint64_t *pvalue)
738 {
739         if (!params || !pvalue)
740                 return CKMC_ERROR_INVALID_PARAMETER;
741
742         const CKM::CryptoAlgorithm *algo =
743                 reinterpret_cast<const CKM::CryptoAlgorithm *>(params);
744
745         if (!algo->getParam(static_cast<CKM::ParamName>(name), *pvalue))
746                 return CKMC_ERROR_INVALID_PARAMETER;
747
748         return CKMC_ERROR_NONE;
749 }
750
751 KEY_MANAGER_CAPI
752 int ckmc_param_list_get_buffer(ckmc_param_list_h params,
753                                                            ckmc_param_name_e name,
754                                                            ckmc_raw_buffer_s **ppbuffer)
755 {
756         if (!params || !ppbuffer || *ppbuffer)
757                 return CKMC_ERROR_INVALID_PARAMETER;
758
759         const CKM::CryptoAlgorithm *algo =
760                 reinterpret_cast<const CKM::CryptoAlgorithm *>(params);
761         CKM::RawBuffer value;
762
763         if (!algo->getParam(static_cast<CKM::ParamName>(name), value))
764                 return CKMC_ERROR_INVALID_PARAMETER;
765
766         return ckmc_buffer_new(value.data(), value.size(), ppbuffer);
767 }
768
769 KEY_MANAGER_CAPI
770 void ckmc_param_list_free(ckmc_param_list_h params)
771 {
772         CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params);
773         delete algo;
774 }
775
776 KEY_MANAGER_CAPI
777 int ckmc_generate_new_params(ckmc_algo_type_e type, ckmc_param_list_h *pparams)
778 {
779         if (!pparams)
780                 return CKMC_ERROR_INVALID_PARAMETER;
781
782         ckmc_param_list_h params = NULL;
783         int ret = ckmc_param_list_new(&params);
784
785         if (ret != CKMC_ERROR_NONE)
786                 return ret;
787
788         switch (type) {
789         case CKMC_ALGO_AES_CTR:
790                 ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ED_CTR_LEN,
791                                                                                   DEFAULT_IV_LEN_BITS);
792                 break;
793
794         case CKMC_ALGO_AES_CBC:
795         case CKMC_ALGO_AES_GCM:
796         case CKMC_ALGO_AES_CFB:
797         case CKMC_ALGO_RSA_OAEP:
798                 // no iv by default
799                 break;
800
801         default:
802                 ret = CKMC_ERROR_INVALID_PARAMETER;
803                 break;
804         }
805
806         if (ret != CKMC_ERROR_NONE) {
807                 ckmc_param_list_free(params);
808                 return ret;
809         }
810
811         ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ALGO_TYPE, type);
812
813         if (ret != CKMC_ERROR_NONE) {
814                 ckmc_param_list_free(params);
815                 return ret;
816         }
817
818         *pparams = params;
819
820         return CKMC_ERROR_NONE;
821 }