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