Refactor SignatureValidator and reduce interface headers
[platform/core/security/cert-svc.git] / vcore / src / vcore / api.cpp
1 /**
2  * Copyright (c) 2015 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        api.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @author      Jacek Migacz (j.migacz@samsung.com)
20  * @version     1.0
21  * @brief       This is part of C-api proposition for cert-svc.
22  */
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <errno.h>
28
29 #include <algorithm>
30 #include <fstream>
31 #include <map>
32 #include <memory>
33 #include <set>
34 #include <string>
35 #include <vector>
36
37 #include <openssl/pem.h>
38 #include <openssl/ssl.h>
39 #include <openssl/x509v3.h>
40 #include <openssl/pkcs12.h>
41 #include <openssl/err.h>
42 #include <openssl/sha.h>
43 #include <openssl/evp.h>
44 #include <openssl/bio.h>
45
46 #include <dpl/foreach.h>
47 #include <dpl/log/log.h>
48
49 #include <cert-svc/cinstance.h>
50 #include <cert-svc/ccert.h>
51 #include <cert-svc/cpkcs12.h>
52 #include <cert-svc/cprimitives.h>
53
54 #include <vcore/Base64.h>
55 #include <vcore/Certificate.h>
56 #include <vcore/CertificateCollection.h>
57 #include <vcore/pkcs12.h>
58
59 #include <libxml/parser.h>
60 #include <libxml/tree.h>
61
62 #define START_CERT      "-----BEGIN CERTIFICATE-----"
63 #define END_CERT        "-----END CERTIFICATE-----"
64 #define START_TRUSTED   "-----BEGIN TRUSTED CERTIFICATE-----"
65 #define END_TRUSTED     "-----END TRUSTED CERTIFICATE-----"
66
67 using namespace ValidationCore;
68
69 namespace {
70
71 typedef std::unique_ptr<CERT_CONTEXT, std::function<int(CERT_CONTEXT*)> > ScopedCertCtx;
72
73 class CertSvcInstanceImpl {
74 public:
75     CertSvcInstanceImpl()
76       : m_certificateCounter(0)
77       , m_idListCounter(0)
78       , m_stringListCounter(0)
79     {}
80
81     ~CertSvcInstanceImpl(){
82         FOREACH(it, m_allocatedStringSet) {
83             delete[] *it;
84         }
85     }
86
87     inline void reset(){
88         m_certificateCounter = 0;
89         m_certificateMap.clear();
90         m_idListCounter = 0;
91         m_idListMap.clear();
92         m_stringListCounter = 0;
93         m_stringListMap.clear();
94
95         FOREACH(it, m_allocatedStringSet) {
96             delete[] *it;
97         }
98
99         m_allocatedStringSet.clear();
100     }
101
102     inline size_t addCert(const CertificatePtr &cert) {
103         m_certificateMap[m_certificateCounter] = cert;
104         return m_certificateCounter++;
105     }
106
107     inline void removeCert(const CertSvcCertificate &cert) {
108         auto iter = m_certificateMap.find(cert.privateHandler);
109         if (iter != m_certificateMap.end()) {
110             m_certificateMap.erase(iter);
111         }
112     }
113
114     inline int getCertFromList(
115         const CertSvcCertificateList &handler,
116         size_t position,
117         CertSvcCertificate *certificate)
118     {
119         auto iter = m_idListMap.find(handler.privateHandler);
120         if (iter == m_idListMap.end()) {
121             return CERTSVC_WRONG_ARGUMENT;
122         }
123         if (position >= iter->second.size()) {
124             return CERTSVC_WRONG_ARGUMENT;
125         }
126         certificate->privateInstance = handler.privateInstance;
127         certificate->privateHandler = (iter->second)[position];
128         return CERTSVC_SUCCESS;
129     }
130
131     inline int getCertListLen(const CertSvcCertificateList &handler, size_t *len) {
132         auto iter = m_idListMap.find(handler.privateHandler);
133         if (iter == m_idListMap.end() || !len) {
134             return CERTSVC_WRONG_ARGUMENT;
135         }
136         *len = (iter->second).size();
137         return CERTSVC_SUCCESS;
138     }
139
140     inline void removeCertList(const CertSvcCertificateList &handler) {
141         auto iter = m_idListMap.find(handler.privateHandler);
142         if (iter != m_idListMap.end())
143             m_idListMap.erase(iter);
144     }
145
146     inline void removeCertListAll(const CertSvcCertificateList &handler) {
147         auto iter = m_idListMap.find(handler.privateHandler);
148         if (iter == m_idListMap.end())
149             return;
150
151         for (size_t pos = 0; pos < iter->second.size(); ++pos) {
152             auto iterCert = m_certificateMap.find((iter->second)[pos]);
153             if (iterCert == m_certificateMap.end())
154                 return;
155
156             m_certificateMap.erase(iterCert);
157         }
158
159         m_idListMap.erase(iter);
160     }
161
162     inline int isSignedBy(const CertSvcCertificate &child,
163                           const CertSvcCertificate &parent,
164                           int *status)
165     {
166         auto citer = m_certificateMap.find(child.privateHandler);
167         if (citer == m_certificateMap.end()) {
168             return CERTSVC_WRONG_ARGUMENT;
169         }
170         auto piter = m_certificateMap.find(parent.privateHandler);
171         if (piter == m_certificateMap.end()) {
172             return CERTSVC_WRONG_ARGUMENT;
173         }
174
175         if (citer->second->isSignedBy(piter->second)) {
176             *status = CERTSVC_TRUE;
177         } else {
178             *status = CERTSVC_FALSE;
179         }
180         return CERTSVC_SUCCESS;
181     }
182
183     inline int getField(const CertSvcCertificate &cert,
184                         CertSvcCertificateField field,
185                         CertSvcString *buffer)
186     {
187         auto iter = m_certificateMap.find(cert.privateHandler);
188         if (iter == m_certificateMap.end()) {
189             return CERTSVC_WRONG_ARGUMENT;
190         }
191
192         auto certPtr = iter->second;
193         std::string result;
194         switch (field) {
195             case CERTSVC_SUBJECT:
196                 result = certPtr->getOneLine();
197                 break;
198             case CERTSVC_ISSUER:
199                 result = certPtr->getOneLine(Certificate::FIELD_ISSUER);
200                 break; 
201             case CERTSVC_SUBJECT_COMMON_NAME:
202                 result = certPtr->getCommonName();
203                 break;
204             case CERTSVC_SUBJECT_COUNTRY_NAME:
205                 result = certPtr->getCountryName();
206                 break;
207             case CERTSVC_SUBJECT_STATE_NAME:
208                 result = certPtr->getStateOrProvinceName();
209                 break;
210             case CERTSVC_SUBJECT_ORGANIZATION_NAME:
211                 result = certPtr->getOrganizationName();
212                 break;
213             case CERTSVC_SUBJECT_ORGANIZATION_UNIT_NAME:
214                 result = certPtr->getOrganizationalUnitName();
215                 break;
216             case CERTSVC_SUBJECT_EMAIL_ADDRESS:
217                 result = certPtr->getEmailAddres();
218                 break;
219             case CERTSVC_ISSUER_COMMON_NAME:
220                 result = certPtr->getCommonName(Certificate::FIELD_ISSUER);
221                 break;
222             case CERTSVC_ISSUER_STATE_NAME:
223                 result = certPtr->getStateOrProvinceName(Certificate::FIELD_ISSUER);
224                 break;
225             case CERTSVC_ISSUER_ORGANIZATION_NAME:
226                 result = certPtr->getOrganizationName(Certificate::FIELD_ISSUER);
227                 break;
228             case CERTSVC_ISSUER_ORGANIZATION_UNIT_NAME:
229                 result = certPtr->getOrganizationalUnitName(Certificate::FIELD_ISSUER);
230                 break;
231             case CERTSVC_VERSION:
232             {
233                 std::stringstream stream;
234                 stream << (certPtr->getVersion()+1);
235                 result = stream.str();
236                 break;
237             }
238             case CERTSVC_SERIAL_NUMBER:
239                 result = certPtr->getSerialNumberString();
240                 break;
241             case CERTSVC_KEY_USAGE:
242                 result = certPtr->getKeyUsageString();
243                 break;
244             case CERTSVC_KEY:
245                 result = certPtr->getPublicKeyString();
246                 break;
247             case CERTSVC_SIGNATURE_ALGORITHM:
248                 result = certPtr->getSignatureAlgorithmString();
249                 break;
250             default:
251                 break;
252         }
253
254         if (result.empty()) {
255             buffer->privateHandler = NULL;
256             buffer->privateLength = 0;
257             buffer->privateInstance = cert.privateInstance;
258             return CERTSVC_SUCCESS;
259         }
260
261         char *cstring = new char[result.size() + 1];
262         if (cstring == NULL) {
263             buffer->privateHandler = NULL;
264             buffer->privateLength = 0;
265             buffer->privateInstance = cert.privateInstance;
266             return CERTSVC_BAD_ALLOC;
267         }
268
269         strncpy(cstring, result.c_str(), result.size() + 1);
270
271         buffer->privateHandler = cstring;
272         buffer->privateLength = result.size();
273         buffer->privateInstance = cert.privateInstance;
274
275         m_allocatedStringSet.insert(cstring);
276
277         return CERTSVC_SUCCESS;
278     }
279
280     inline int getNotAfter(const CertSvcCertificate &cert,
281                            time_t *time)
282     {
283         auto iter = m_certificateMap.find(cert.privateHandler);
284         if (iter == m_certificateMap.end()) {
285             return CERTSVC_WRONG_ARGUMENT;
286         }
287         *time = iter->second->getNotAfter();
288         return CERTSVC_SUCCESS;
289     }
290
291     inline int getNotBefore(const CertSvcCertificate &cert,
292                             time_t *time)
293     {
294         auto iter = m_certificateMap.find(cert.privateHandler);
295         if (iter == m_certificateMap.end()) {
296             return CERTSVC_WRONG_ARGUMENT;
297         }
298         *time = iter->second->getNotBefore();
299         return CERTSVC_SUCCESS;
300     }
301
302     inline int isRootCA(const CertSvcCertificate &cert, int *status){
303         auto iter = m_certificateMap.find(cert.privateHandler);
304         if (iter == m_certificateMap.end()) {
305             return CERTSVC_WRONG_ARGUMENT;
306         }
307         if (iter->second->isRootCert()) {
308             *status = CERTSVC_TRUE;
309         } else {
310             *status = CERTSVC_FALSE;
311         }
312         return CERTSVC_SUCCESS;
313     }
314
315     inline int getStringFromList(
316         const CertSvcStringList &handler,
317         size_t position,
318         CertSvcString *buffer)
319     {
320         buffer->privateHandler = NULL;
321         buffer->privateLength = 0;
322
323         auto iter = m_stringListMap.find(handler.privateHandler);
324         if (iter == m_stringListMap.end()) {
325             return CERTSVC_WRONG_ARGUMENT;
326         }
327         if (position >= iter->second.size()) {
328             return CERTSVC_WRONG_ARGUMENT;
329         }
330         const std::string &data = iter->second.at(position);
331         size_t size = data.size();
332         char *cstring = new char[size + 1];
333         if (!cstring) {
334             return CERTSVC_FAIL;
335         }
336
337         strncpy(cstring, data.c_str(), size + 1);
338
339         buffer->privateHandler = cstring;
340         buffer->privateLength = size;
341         buffer->privateInstance = handler.privateInstance;
342
343         m_allocatedStringSet.insert(cstring);
344
345         return CERTSVC_SUCCESS;
346     }
347
348     inline int getStringListLen(
349         const CertSvcStringList &handler,
350         size_t *size)
351     {
352         auto iter = m_stringListMap.find(handler.privateHandler);
353         if (iter == m_stringListMap.end()) {
354             return CERTSVC_WRONG_ARGUMENT;
355         }
356         *size = iter->second.size();
357         return CERTSVC_SUCCESS;
358     }
359
360     inline void removeStringList(const CertSvcStringList &handler)
361     {
362         m_stringListMap.erase(m_stringListMap.find(handler.privateHandler));
363     }
364
365     inline void removeString(const CertSvcString &handler)
366     {
367         auto iter = m_allocatedStringSet.find(handler.privateHandler);
368         if (iter != m_allocatedStringSet.end()) {
369             delete[] *iter;
370             m_allocatedStringSet.erase(iter);
371         }
372     }
373
374     inline int certificateSearch(
375         CertSvcInstance instance,
376         CertSvcCertificateField field,
377         const char *value,
378         CertSvcCertificateList *handler)
379     {
380         search_field fieldId = SEARCH_FIELD_END;
381
382         switch (field) {
383         case CERTSVC_SUBJECT:
384             fieldId = SUBJECT_STR;
385             break;
386         case CERTSVC_ISSUER:
387             fieldId = ISSUER_STR;
388             break;
389         case CERTSVC_SUBJECT_COMMON_NAME:
390             fieldId = SUBJECT_COMMONNAME;
391             break;
392         default:
393             LogError("Not implemented!");
394             return CERTSVC_WRONG_ARGUMENT;
395         }
396
397         ScopedCertCtx ctx(cert_svc_cert_context_init(),
398                           cert_svc_cert_context_final);
399
400         if (ctx.get() == NULL) {
401             LogWarning("Error in cert_svc_cert_context_init.");
402             return CERTSVC_FAIL;
403         }
404
405         LogDebug("Match string : " << value);
406         int result = cert_svc_search_certificate(ctx.get(), fieldId, const_cast<char*>(value));
407         LogDebug("Search finished!");
408
409         if (CERT_SVC_ERR_NO_ERROR != result) {
410             LogWarning("Error during certificate search");
411             return CERTSVC_FAIL;
412         }
413
414
415         size_t listId = m_idListCounter++;
416         std::vector<size_t> &list = m_idListMap[listId];
417         handler->privateHandler = listId;
418         handler->privateInstance = instance;
419
420         cert_svc_filename_list *fileList = ctx.get()->fileNames;
421         while (fileList) {
422             ScopedCertCtx ctx2(cert_svc_cert_context_init(),
423                                cert_svc_cert_context_final);
424             if (ctx2.get() == NULL) {
425                 LogWarning("Error in cert_svc_cert_context_init.");
426                 return CERTSVC_FAIL;
427             }
428
429             // TODO add read_certifcate_from_file function to Certificate.h
430             if (CERT_SVC_ERR_NO_ERROR !=
431                 cert_svc_load_file_to_context(ctx2.get(), fileList->filename))
432             {
433                 LogWarning("Error in cert_svc_load_file_to_context");
434                 return CERTSVC_FAIL;
435             }
436
437             list.push_back(addCert(CertificatePtr(new Certificate(*(ctx2.get()->certBuf)))));
438
439             fileList = fileList->next;
440         }
441         return CERTSVC_SUCCESS;
442     }
443
444     inline int sortCollection(CertSvcCertificate *certificate_array, size_t size) {
445         if (size < 2) {
446             return CERTSVC_WRONG_ARGUMENT;
447         }
448
449         for (size_t i = 1; i < size; ++i) {
450             if (certificate_array[i - 1].privateInstance.privatePtr
451                 != certificate_array[i].privateInstance.privatePtr)
452             {
453                 return CERTSVC_WRONG_ARGUMENT;
454             }
455         }
456
457         CertificateList certList;
458         std::map<Certificate*, size_t> translator;
459
460         for (size_t i = 0; i < size; ++i) {
461             size_t pos = certificate_array[i].privateHandler;
462             auto cert = m_certificateMap.find(pos);
463             if (cert == m_certificateMap.end()) {
464                 return CERTSVC_WRONG_ARGUMENT;
465             }
466             translator[cert->second.get()] = pos;
467             certList.push_back(cert->second);
468         }
469
470         CertificateCollection collection;
471         collection.load(certList);
472
473         if (!collection.sort()) {
474             return CERTSVC_FAIL;
475         }
476
477         auto chain = collection.getChain();
478
479         size_t i = 0;
480         for (const auto &cert : collection.getChain())
481             certificate_array[i++].privateHandler = translator[cert.get()];
482
483         return CERTSVC_SUCCESS;
484     }
485
486     inline int getX509Copy(const CertSvcCertificate &certificate, X509** cert)
487     {
488         auto it = m_certificateMap.find(certificate.privateHandler);
489         if (it == m_certificateMap.end()) {
490             return CERTSVC_WRONG_ARGUMENT;
491         }
492         *cert = X509_dup(it->second->getX509());
493         return CERTSVC_SUCCESS;
494     }
495
496     inline int saveToFile(const CertSvcCertificate &certificate,
497                           const char *location)
498     {
499         auto it = m_certificateMap.find(certificate.privateHandler);
500         if (it == m_certificateMap.end()) {
501             return CERTSVC_WRONG_ARGUMENT;
502         }
503         FILE *out = fopen(location, "w");
504         if (out == NULL) {
505             return CERTSVC_FAIL;
506         }
507         if (0 == i2d_X509_fp(out, it->second->getX509())) {
508             fclose(out);
509             return CERTSVC_FAIL;
510         }
511         fclose(out);
512         return CERTSVC_SUCCESS;
513     }
514
515     inline int verify(
516         CertSvcCertificate certificate,
517         CertSvcString &message,
518         CertSvcString &signature,
519         const char *algorithm,
520         int *status)
521     {
522         int result = CERTSVC_FAIL;
523
524         if (!status) {
525             return CERTSVC_WRONG_ARGUMENT;
526         }
527
528         auto it = m_certificateMap.find(certificate.privateHandler);
529         if (it == m_certificateMap.end()) {
530             return CERTSVC_WRONG_ARGUMENT;
531         }
532
533         OpenSSL_add_all_digests();
534
535         int temp;
536         EVP_MD_CTX* mdctx = NULL;
537         const EVP_MD * md = NULL;
538         X509 *cert = it->second->getX509();
539         EVP_PKEY *pkey = NULL;
540
541         if (cert == NULL) {
542             goto err;
543         }
544
545         pkey = X509_get_pubkey(cert);
546
547         if (pkey == NULL) {
548             goto err;
549         }
550
551         if (algorithm == NULL) {
552             md = EVP_get_digestbyobj(cert->cert_info->signature->algorithm);
553         } else {
554             md = EVP_get_digestbyname(algorithm);
555         }
556
557         if (md == NULL) {
558             result = CERTSVC_INVALID_ALGORITHM;
559             goto err;
560         }
561
562         mdctx = EVP_MD_CTX_create();
563
564         if (mdctx == NULL) {
565             goto err;
566         }
567
568         if (EVP_VerifyInit_ex(mdctx, md, NULL) != 1) {
569             goto err;
570         }
571
572         if (EVP_VerifyUpdate(mdctx, message.privateHandler, message.privateLength) != 1) {
573             goto err;
574         }
575
576         temp = EVP_VerifyFinal(mdctx,
577             reinterpret_cast<unsigned char*>(signature.privateHandler),
578             signature.privateLength,
579             pkey);
580
581         if (temp == 0) {
582             *status = CERTSVC_INVALID_SIGNATURE;
583             result = CERTSVC_SUCCESS;
584         } else if (temp == 1) {
585             *status = CERTSVC_SUCCESS;
586             result = CERTSVC_SUCCESS;
587         }
588
589     err:
590         if (mdctx != NULL)
591             EVP_MD_CTX_destroy(mdctx);
592         if (pkey != NULL)
593             EVP_PKEY_free(pkey);
594         return result;
595     }
596
597     inline int base64Encode(
598         const CertSvcString &message,
599         CertSvcString *base64)
600     {
601         if (!base64) {
602             return CERTSVC_WRONG_ARGUMENT;
603         }
604         std::string info(message.privateHandler, message.privateLength);
605         Base64Encoder base;
606         base.reset();
607         base.append(info);
608         base.finalize();
609         info = base.get();
610         char *ptr = new char[info.size()+1];
611         if(ptr == NULL) {
612             return CERTSVC_BAD_ALLOC;
613         }
614         memcpy(ptr, info.c_str(), info.size()+1);
615         m_allocatedStringSet.insert(ptr);
616         base64->privateHandler = ptr;
617         base64->privateLength = info.size();
618         base64->privateInstance = message.privateInstance;
619         return CERTSVC_SUCCESS;
620     }
621
622     int base64Decode(
623         const CertSvcString &base64,
624         CertSvcString *message)
625     {
626         if (!message) {
627             return CERTSVC_WRONG_ARGUMENT;
628         }
629         std::string info(base64.privateHandler, base64.privateLength);
630         Base64Decoder base;
631         base.reset();
632         base.append(info);
633         if (!base.finalize()) {
634             return CERTSVC_FAIL;
635         }
636         info = base.get();
637         char *ptr = new char[info.size()+1];
638         if(ptr == NULL) {
639             return CERTSVC_BAD_ALLOC;
640         }
641         memcpy(ptr, info.c_str(), info.size()+1);
642         m_allocatedStringSet.insert(ptr);
643         message->privateHandler = ptr;
644         message->privateLength = info.size();
645         message->privateInstance = base64.privateInstance;
646         return CERTSVC_SUCCESS;
647     }
648
649     inline int stringNew(
650         CertSvcInstance &instance,
651         const char *str,
652         size_t size,
653         CertSvcString *output)
654     {
655         if (!output) {
656             return CERTSVC_WRONG_ARGUMENT;
657         }
658
659         size_t allocSize = size;
660
661         if (allocSize == 0 || str[allocSize - 1] != 0)
662             allocSize++;
663
664         char *ptr = new char[allocSize];
665         if (ptr == NULL)
666             return CERTSVC_BAD_ALLOC;
667
668         memcpy(ptr, str, size);
669         ptr[allocSize - 1] = 0;
670
671         output->privateHandler = ptr;
672         output->privateLength = size;
673         output->privateInstance = instance;
674
675         m_allocatedStringSet.insert(ptr);
676
677         return CERTSVC_SUCCESS;
678     }
679
680     inline int certificateVerify(
681         CertSvcCertificate certificate,
682         const CertSvcCertificate *trusted,
683         size_t trustedSize,
684         const CertSvcCertificate *untrusted,
685         size_t untrustedSize,
686         int checkCaFlag,
687         int *status)
688     {
689         if (!trusted || !status) {
690             return CERTSVC_WRONG_ARGUMENT;
691         }
692         auto iter = m_certificateMap.find(certificate.privateHandler);
693         if (iter == m_certificateMap.end()) {
694             return CERTSVC_WRONG_ARGUMENT;
695         }
696
697         X509 *cert = iter->second->getX509();
698         X509_STORE *store = X509_STORE_new();
699         STACK_OF(X509) *ustore = sk_X509_new_null();
700
701         for (size_t i = 0; i < trustedSize; ++i) {
702             auto iter = m_certificateMap.find(trusted[i].privateHandler);
703             if (iter == m_certificateMap.end()) {
704                 X509_STORE_free(store);
705                 sk_X509_free(ustore);
706                 return CERTSVC_WRONG_ARGUMENT;
707             }
708
709             X509_STORE_add_cert(store, iter->second->getX509());
710         }
711
712         for (size_t i = 0; i < untrustedSize; ++i) {
713             auto iter = m_certificateMap.find(untrusted[i].privateHandler);
714             if (iter == m_certificateMap.end()) {
715                 X509_STORE_free(store);
716                 sk_X509_free(ustore);
717                 return CERTSVC_WRONG_ARGUMENT;
718             }
719
720             if (sk_X509_push(ustore, iter->second->getX509()) == 0)
721                 break;
722         }
723
724         X509_STORE_CTX context;
725         X509_STORE_CTX_init(&context, store, cert, ustore);
726         int result = X509_verify_cert(&context);
727
728         if (result == 1 && checkCaFlag) { // check strictly
729                 STACK_OF(X509) *resultChain = X509_STORE_CTX_get1_chain(&context);
730                 X509* tmpCert = NULL;
731                 int caFlagValidity;
732             while ((tmpCert = sk_X509_pop(resultChain))) {
733                         caFlagValidity = X509_check_ca(tmpCert);
734                 if (caFlagValidity != 1 && (tmpCert = sk_X509_pop(resultChain)) != NULL) {
735                     // the last one is not a CA.
736                                 result = 0;
737                                 break;
738                         }
739                 }
740         }
741
742         X509_STORE_CTX_cleanup(&context);
743         X509_STORE_free(store);
744         sk_X509_free(ustore);
745
746         if (result == 1) {
747             *status = CERTSVC_SUCCESS;
748         } else {
749             *status = CERTSVC_FAIL;
750         }
751         return CERTSVC_SUCCESS;
752     }
753
754     int getVisibility(CertSvcCertificate certificate, CertSvcVisibility *visibility)
755     {
756                 int ret = CERTSVC_FAIL;
757                 //xmlChar *xmlPathCertificateSet  = (xmlChar*) "CertificateSet"; /*unused variable*/
758                 //xmlChar *xmlPathCertificateDomain = (xmlChar*) "CertificateDomain";// name=\"tizen-platform\""; /*unused variable*/
759                 xmlChar *xmlPathDomainPlatform = (xmlChar*) "tizen-platform";
760                 xmlChar *xmlPathDomainPublic = (xmlChar*) "tizen-public";
761                 xmlChar *xmlPathDomainPartner = (xmlChar*) "tizen-partner";
762                 xmlChar *xmlPathDomainDeveloper = (xmlChar*) "tizen-developer";
763                 //xmlChar *xmlPathFingerPrintSHA1 = (xmlChar*) "FingerprintSHA1"; /*unused variable*/
764
765         auto iter = m_certificateMap.find(certificate.privateHandler);
766         if (iter == m_certificateMap.end()) {
767                         return CERTSVC_FAIL;
768         }
769         CertificatePtr certPtr = iter->second;
770
771                 std::string fingerprint = Certificate::FingerprintToColonHex(certPtr->getFingerprint(Certificate::FINGERPRINT_SHA1));
772
773                 /*   load file */
774                 xmlDocPtr doc = xmlParseFile(FINGERPRINT_LIST_PATH);
775                 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL))
776                 {
777                         LogError("Failed to prase fingerprint_list.xml");
778                         return CERTSVC_IO_ERROR;
779                 }
780
781                 xmlNodePtr curPtr = xmlFirstElementChild(xmlDocGetRootElement(doc));
782                 if(curPtr == NULL)
783                 {
784                         LogError("Can not find root");
785                         ret = CERTSVC_IO_ERROR;
786                         goto out;
787                 }
788
789                 while(curPtr != NULL)
790                 {
791                         xmlAttr* attr = curPtr->properties;
792                         if(!attr->children || !attr->children->content)
793                         {
794                                 LogError("Failed to get fingerprints from list");
795                                 ret = CERTSVC_FAIL;
796                                 goto out;
797                         }
798
799                         xmlChar* strLevel = attr->children->content;
800                         xmlNodePtr FpPtr = xmlFirstElementChild(curPtr);
801                         if(FpPtr == NULL)
802                         {
803                                 LogError("Could not find fingerprint");
804                                 ret = CERTSVC_FAIL;
805                                 goto out;
806                         }
807
808                         LogDebug("Retrieve level : " << strLevel);
809                         while(FpPtr)
810                         {
811                                 xmlChar *content = xmlNodeGetContent(FpPtr);
812                                 if(xmlStrcmp(content, (xmlChar*)fingerprint.c_str()) == 0)
813                                 {
814                                         LogDebug("fingerprint : " << content << " are " << strLevel);
815                                         if(!xmlStrcmp(strLevel, xmlPathDomainPlatform))
816                                         {
817                                                 *visibility = CERTSVC_VISIBILITY_PLATFORM;
818                                                 ret = CERTSVC_SUCCESS;
819                                                 goto out;
820                                         }
821                                         else if(!xmlStrcmp(strLevel, xmlPathDomainPublic))
822                                         {
823                                                 *visibility = CERTSVC_VISIBILITY_PUBLIC;
824                                                 ret = CERTSVC_SUCCESS;
825                                                 goto out;
826                                         }
827                                         else if(!xmlStrcmp(strLevel, xmlPathDomainPartner))
828                                         {
829                                                 *visibility = CERTSVC_VISIBILITY_PARTNER;
830                                                 ret = CERTSVC_SUCCESS;
831                                                 goto out;
832                                         }
833                                         else if(!xmlStrcmp(strLevel, xmlPathDomainDeveloper))
834                                         {
835                                                 *visibility = CERTSVC_VISIBILITY_DEVELOPER;
836                                                 ret = CERTSVC_SUCCESS;
837                                                 goto out;
838                                         }
839                                 }
840                                 FpPtr = xmlNextElementSibling(FpPtr);
841                         }
842                         curPtr = xmlNextElementSibling(curPtr);
843                 }
844                 xmlFreeDoc(doc);
845                 return CERTSVC_FAIL;
846 out:
847                 xmlFreeDoc(doc);
848                 return ret;
849         }
850
851     inline int pkcsNameIsUniqueInStore(
852         CertStoreType storeType,
853         CertSvcString pfxIdString,
854         int *is_unique)
855     {
856         return c_certsvc_pkcs12_alias_exists_in_store(storeType, pfxIdString.privateHandler, is_unique);
857     }
858
859     inline int getCertDetailFromStore(CertStoreType storeType,
860         CertSvcString gname,
861         char **certBuffer,
862         size_t *certSize)
863     {
864         return c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname.privateHandler, certBuffer, certSize);
865     }
866
867     inline int pkcsDeleteCertFromStore(
868         CertStoreType storeType,
869         CertSvcString gname
870     )
871     {
872         return c_certsvc_pkcs12_delete_certificate_from_store(storeType, gname.privateHandler);
873     }
874
875     inline int pkcsHasPassword(
876         CertSvcString filepath,
877         int *has_password)
878     {
879         return c_certsvc_pkcs12_has_password(filepath.privateHandler, has_password);
880     }
881
882     inline int pkcsImportToStore(
883         CertStoreType storeType,
884         CertSvcString path,
885         CertSvcString pass,
886         CertSvcString pfxIdString)
887     {
888         return c_certsvc_pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
889     }
890
891     inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
892         CertSvcString gname,
893         char **alias)
894     {
895         return c_certsvc_pkcs12_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
896     }
897
898     inline int pkcsSetCertStatusToStore(CertStoreType storeType,
899         int is_root_app,
900         CertSvcString gname,
901         CertStatus status)
902     {
903         return c_certsvc_pkcs12_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
904     }
905
906     inline int pkcsGetCertStatusFromStore(
907         CertStoreType storeType,
908         CertSvcString gname,
909         CertStatus *status)
910     {
911         return c_certsvc_pkcs12_get_certificate_status_from_store(storeType, gname.privateHandler, status);
912     }
913
914     inline int getCertFromStore(CertSvcInstance instance,
915         CertStoreType storeType,
916         const char *gname,
917         CertSvcCertificate *certificate)
918     {
919             return certsvc_get_certificate(instance, storeType, gname, certificate);
920     }
921
922     inline int freePkcsIdListFromStore(
923         CertSvcStoreCertList** certList)
924     {
925         return c_certsvc_pkcs12_free_aliases_loaded_from_store(certList);
926     }
927
928     inline int getPkcsIdListFromStore(
929         CertStoreType storeType,
930         int is_root_app,
931         CertSvcStoreCertList** certList,
932         size_t *length)
933     {
934         return c_certsvc_pkcs12_get_certificate_list_from_store(storeType, is_root_app, certList, length);
935     }
936
937     inline int getPkcsIdEndUserListFromStore(
938         CertStoreType storeType,
939         CertSvcStoreCertList** certList,
940         size_t *length)
941     {
942         return c_certsvc_pkcs12_get_end_user_certificate_list_from_store(storeType, certList, length);
943     }
944
945     inline int getPkcsIdRootListFromStore(
946         CertStoreType storeType,
947         CertSvcStoreCertList** certList,
948         size_t *length)
949     {
950         return c_certsvc_pkcs12_get_root_certificate_list_from_store(storeType, certList, length);
951     }
952
953     inline int getPkcsPrivateKeyFromStore(
954         CertStoreType storeType,
955         CertSvcString gname,
956         char **certBuffer,
957         size_t *certSize)
958     {
959         return c_certsvc_pkcs12_private_key_load_from_store(storeType, gname.privateHandler, certBuffer, certSize);
960     }
961
962     inline int getPkcsCertificateListFromStore(
963         CertSvcInstance &instance,
964         CertStoreType storeType,
965         CertSvcString &pfxIdString,
966         CertSvcCertificateList *handler)
967     {
968         char **certs = NULL;
969         size_t ncerts = 0;
970         int result = c_certsvc_pkcs12_load_certificates_from_store(storeType, pfxIdString.privateHandler, &certs, &ncerts);
971         if (result != CERTSVC_SUCCESS) {
972             LogError("Unable to load certificates from store.");
973             return result;
974         }
975
976                 std::vector<CertificatePtr> certPtrVector;
977         CertSvcString Alias;
978         for (size_t i = 0; i < ncerts; i++) {
979             Alias.privateHandler = certs[i];
980             Alias.privateLength = strlen(certs[i]);
981             char *certBuffer = NULL;
982             size_t certLength = 0;
983             result = certsvc_pkcs12_get_certificate_info_from_store(instance, storeType, Alias, &certBuffer, &certLength);
984             if (result != CERTSVC_SUCCESS || !certBuffer) {
985                 LogError("Failed to get certificate buffer.");
986                 return CERTSVC_FAIL;
987             }
988
989             const char *header = strstr(certBuffer, START_CERT);
990             const char *headEnd = START_CERT;
991             const char *trailer = NULL;
992             const char *tailEnd = NULL;
993             if (!header) {
994                 // START_CERT not found. let's find START_TRUSTED.
995                 header = strstr(certBuffer, START_TRUSTED);
996                 headEnd = START_TRUSTED;
997             }
998
999             if (header) {
1000                 // START_something found. let's find END_CERT first.
1001                 trailer = strstr(header, END_CERT);
1002                 tailEnd = END_CERT;
1003             }
1004
1005             if (!trailer) {
1006                 // END_CERT not found. let's find END_TRUSTED.
1007                 trailer = strstr(header, END_TRUSTED);
1008                 tailEnd = END_TRUSTED;
1009             }
1010
1011             if (!trailer) {
1012                 LogError("Failed the get the certificate.");
1013                 return CERTSVC_FAIL;
1014             }
1015
1016             size_t length = ((1 + strlen(header)) - (strlen(headEnd) + strlen(tailEnd) + 1));
1017             std::string tmpBuffer(certBuffer);
1018             tmpBuffer = tmpBuffer.substr(strlen(headEnd), length);
1019             std::string binary(tmpBuffer.c_str(), length);
1020             certPtrVector.push_back(CertificatePtr(new Certificate(binary, Certificate::FORM_BASE64)));
1021             free(certBuffer);
1022         }
1023
1024         if (ncerts > 0)
1025             c_certsvc_pkcs12_free_certificates(certs);
1026
1027         std::vector<size_t> listId;
1028         for (const auto &cert : certPtrVector)
1029             listId.push_back(addCert(cert));
1030
1031         size_t position = m_idListCounter++;
1032         m_idListMap[position] = listId;
1033
1034         handler->privateInstance = instance;
1035         handler->privateHandler = position;
1036
1037         return result;
1038     }
1039
1040     inline bool checkValidStoreType(CertStoreType storeType)
1041     {
1042         if (storeType >= VPN_STORE && storeType <= ALL_STORE)
1043             return true;
1044         else
1045             return false;
1046     }
1047
1048 private:
1049     size_t m_certificateCounter;
1050     std::map<size_t, CertificatePtr> m_certificateMap;
1051
1052     size_t m_idListCounter;
1053     std::map<size_t, std::vector<size_t> > m_idListMap;
1054
1055     size_t m_stringListCounter;
1056     std::map<size_t, std::vector<std::string> > m_stringListMap;
1057
1058     std::set<char *> m_allocatedStringSet;
1059 };
1060
1061 inline CertSvcInstanceImpl *impl(CertSvcInstance instance) {
1062     return static_cast<CertSvcInstanceImpl*>(instance.privatePtr);
1063 }
1064
1065 } // namespace anonymous
1066
1067 int certsvc_instance_new(CertSvcInstance *instance) {
1068     static int init = 1;
1069     if (init) {
1070         OpenSSL_add_ssl_algorithms();
1071         OpenSSL_add_all_digests();
1072         init = 0;
1073     }
1074     try {
1075         instance->privatePtr =
1076             reinterpret_cast<void*>(new CertSvcInstanceImpl);
1077         if (instance->privatePtr)
1078             return CERTSVC_SUCCESS;
1079     } catch (std::bad_alloc &) {
1080         return CERTSVC_BAD_ALLOC;
1081     } catch (...) {}
1082     return CERTSVC_FAIL;
1083 }
1084
1085 void certsvc_instance_reset(CertSvcInstance instance) {
1086     impl(instance)->reset();
1087 }
1088
1089 void certsvc_instance_free(CertSvcInstance instance) {
1090     delete impl(instance);
1091 }
1092
1093 int certsvc_certificate_new_from_file(
1094         CertSvcInstance instance,
1095         const char *location,
1096         CertSvcCertificate *certificate)
1097 {
1098     try {
1099         ScopedCertCtx context(cert_svc_cert_context_init(),
1100                               cert_svc_cert_context_final);
1101
1102         int result = cert_svc_load_file_to_context(context.get(), location);
1103
1104         switch(result) {
1105             case CERT_SVC_ERR_INVALID_PARAMETER: return CERTSVC_WRONG_ARGUMENT;
1106             case CERT_SVC_ERR_INVALID_OPERATION: return CERTSVC_FAIL;
1107             case CERT_SVC_ERR_MEMORY_ALLOCATION: return CERTSVC_BAD_ALLOC;
1108             default:;
1109         }
1110
1111         CertificatePtr cert(new Certificate(*(context->certBuf)));
1112
1113         certificate->privateInstance = instance;
1114         certificate->privateHandler = impl(instance)->addCert(cert);
1115
1116         return CERTSVC_SUCCESS;
1117     // TODO support for std exceptions
1118     } catch (std::bad_alloc &) {
1119         return CERTSVC_BAD_ALLOC;
1120     } catch (...) {}
1121     return CERTSVC_FAIL;
1122 }
1123
1124 int certsvc_certificate_new_from_memory(
1125         CertSvcInstance instance,
1126         const unsigned char *memory,
1127         size_t len,
1128         CertSvcCertificateForm form,
1129         CertSvcCertificate *certificate)
1130 {
1131     try {
1132         Certificate::FormType formType;
1133         std::string binary((char*)memory, len);
1134
1135         if (CERTSVC_FORM_DER == form) {
1136             formType = Certificate::FORM_DER;
1137         } else {
1138             formType = Certificate::FORM_BASE64;
1139         }
1140
1141         CertificatePtr cert(new Certificate(binary, formType));
1142
1143         certificate->privateInstance = instance;
1144         certificate->privateHandler = impl(instance)->addCert(cert);
1145         return CERTSVC_SUCCESS;
1146     } catch (std::bad_alloc &) {
1147         return CERTSVC_BAD_ALLOC;
1148     } catch (...) {}
1149     return CERTSVC_FAIL;
1150 }
1151
1152 void certsvc_certificate_free(CertSvcCertificate certificate)
1153 {
1154         if (certificate.privateHandler != 0)
1155                 impl(certificate.privateInstance)->removeCert(certificate);
1156 }
1157
1158 int certsvc_certificate_save_file(
1159         CertSvcCertificate certificate,
1160         const char *location)
1161 {
1162     return impl(certificate.privateInstance)->saveToFile(certificate, location);
1163 }
1164
1165 int certsvc_certificate_search(
1166         CertSvcInstance instance,
1167         CertSvcCertificateField field,
1168         const char *value,
1169         CertSvcCertificateList *handler)
1170 {
1171     try {
1172         return impl(instance)->certificateSearch(instance, field, value, handler);
1173     } catch (std::bad_alloc &) {
1174         return CERTSVC_BAD_ALLOC;
1175     } catch (...) {}
1176     return CERTSVC_FAIL;
1177 }
1178
1179 int certsvc_certificate_list_get_one(
1180         CertSvcCertificateList handler,
1181         size_t position,
1182         CertSvcCertificate *certificate)
1183 {
1184     return impl(handler.privateInstance)->
1185         getCertFromList(handler, position, certificate);
1186 }
1187
1188 int certsvc_certificate_list_get_length(
1189         CertSvcCertificateList handler,
1190         size_t *size)
1191 {
1192     return impl(handler.privateInstance)->getCertListLen(handler, size);
1193 }
1194
1195 void certsvc_certificate_list_free(CertSvcCertificateList handler)
1196 {
1197     impl(handler.privateInstance)->removeCertList(handler);
1198 }
1199
1200 void certsvc_certificate_list_all_free(CertSvcCertificateList handler)
1201 {
1202     impl(handler.privateInstance)->removeCertListAll(handler);
1203 }
1204
1205 int certsvc_certificate_is_signed_by(
1206         CertSvcCertificate child,
1207         CertSvcCertificate parent,
1208         int *status)
1209 {
1210     if (child.privateInstance.privatePtr == parent.privateInstance.privatePtr) {
1211         return impl(child.privateInstance)->isSignedBy(child, parent, status);
1212     }
1213     return CERTSVC_WRONG_ARGUMENT;
1214 }
1215
1216 int certsvc_certificate_get_string_field(
1217         CertSvcCertificate certificate,
1218         CertSvcCertificateField field,
1219         CertSvcString *buffer)
1220 {
1221     try {
1222         return impl(certificate.privateInstance)->getField(certificate, field, buffer);
1223     } catch (std::bad_alloc &) {
1224         return CERTSVC_BAD_ALLOC;
1225     } catch (...) {}
1226     return CERTSVC_FAIL;
1227 }
1228
1229 int certsvc_certificate_get_not_after(
1230         CertSvcCertificate certificate,
1231         time_t *result)
1232 {
1233     try {
1234         return impl(certificate.privateInstance)->getNotAfter(certificate, result);
1235     } catch(...) {}
1236     return CERTSVC_FAIL;
1237 }
1238
1239 int certsvc_certificate_get_not_before(
1240         CertSvcCertificate certificate,
1241         time_t *result)
1242 {
1243     try {
1244         return impl(certificate.privateInstance)->getNotBefore(certificate, result);
1245     } catch(...) {}
1246     return CERTSVC_FAIL;
1247 }
1248
1249 int certsvc_certificate_is_root_ca(CertSvcCertificate certificate, int *status)
1250 {
1251     return impl(certificate.privateInstance)->isRootCA(certificate, status);
1252 }
1253
1254 int certsvc_string_list_get_one(
1255         CertSvcStringList handler,
1256         size_t position,
1257         CertSvcString *buffer)
1258 {
1259     try {
1260         return impl(handler.privateInstance)->getStringFromList(handler, position, buffer);
1261     } catch (std::bad_alloc &) {
1262         return CERTSVC_BAD_ALLOC;
1263     } catch (...) {}
1264     return CERTSVC_FAIL;
1265 }
1266
1267 int certsvc_string_list_get_length(
1268         CertSvcStringList handler,
1269         size_t *size)
1270 {
1271     return impl(handler.privateInstance)->getStringListLen(handler, size);
1272 }
1273
1274 void certsvc_string_list_free(CertSvcStringList handler)
1275 {
1276         if (handler.privateHandler != 0)
1277         {
1278                 impl(handler.privateInstance)->removeStringList(handler);
1279                 handler.privateHandler = 0;
1280         }
1281 }
1282
1283 void certsvc_string_free(CertSvcString string)
1284 {
1285         if (string.privateHandler)
1286                 impl(string.privateInstance)->removeString(string);
1287 }
1288
1289 void certsvc_string_to_cstring(
1290         CertSvcString string,
1291         const char **buffer,
1292         size_t *len)
1293 {
1294     if (buffer) {
1295         *buffer = string.privateHandler;
1296     }
1297     if (len) {
1298         *len = string.privateLength;
1299     }
1300 }
1301
1302 int certsvc_certificate_chain_sort(
1303         CertSvcCertificate *certificate_array,
1304         size_t size)
1305 {
1306     try {
1307         if (!certificate_array) {
1308             return CERTSVC_WRONG_ARGUMENT;
1309         }
1310         return impl(certificate_array[0].privateInstance)->
1311             sortCollection(certificate_array, size);
1312     } catch (std::bad_alloc &) {
1313         return CERTSVC_BAD_ALLOC;
1314     } catch (...) {}
1315     return CERTSVC_FAIL;
1316 }
1317
1318 int certsvc_certificate_dup_x509(CertSvcCertificate certificate, X509 **cert)
1319 {
1320     try {
1321         return impl(certificate.privateInstance)->getX509Copy(certificate, cert);
1322     } catch (...) {}
1323     return CERTSVC_FAIL;
1324 }
1325
1326 void certsvc_certificate_free_x509(X509 *x509)
1327 {
1328         if (x509)
1329                 X509_free(x509);
1330 }
1331
1332 void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey)
1333 {
1334     EVP_PKEY_free(pkey);
1335 }
1336
1337 int certsvc_message_verify(
1338     CertSvcCertificate certificate,
1339     CertSvcString message,
1340     CertSvcString signature,
1341     const char *algorithm,
1342     int *status)
1343 {
1344     try {
1345         return impl(certificate.privateInstance)->verify(
1346             certificate,
1347             message,
1348             signature,
1349             algorithm,
1350             status);
1351     } catch(...) {}
1352     return CERTSVC_FAIL;
1353 }
1354
1355 int certsvc_base64_encode(CertSvcString message, CertSvcString *base64)
1356 {
1357     try {
1358         return impl(message.privateInstance)->base64Encode(message, base64);
1359     } catch(...) {}
1360     return CERTSVC_FAIL;
1361 }
1362
1363 int certsvc_base64_decode(CertSvcString base64, CertSvcString *message)
1364 {
1365     try {
1366         return impl(base64.privateInstance)->base64Decode(base64, message);
1367     } catch(...) {}
1368     return CERTSVC_FAIL;
1369 }
1370
1371 int certsvc_string_new(
1372     CertSvcInstance instance,
1373     const char *url,
1374     size_t size,
1375     CertSvcString *output)
1376 {
1377     try {
1378         return impl(instance)->stringNew(instance, url, size, output);
1379     } catch (...) {}
1380     return CERTSVC_FAIL;
1381 }
1382
1383 int certsvc_string_not_managed(
1384     CertSvcInstance instance,
1385     const char *url,
1386     size_t size,
1387     CertSvcString *output)
1388 {
1389     if (!output) {
1390         return CERTSVC_WRONG_ARGUMENT;
1391     }
1392     output->privateHandler = const_cast<char*>(url);
1393     output->privateLength = size;
1394     output->privateInstance = instance;
1395     return CERTSVC_SUCCESS;
1396 }
1397
1398 int certsvc_certificate_verify(
1399     CertSvcCertificate certificate,
1400     const CertSvcCertificate *trusted,
1401     size_t trustedSize,
1402     const CertSvcCertificate *untrusted,
1403     size_t untrustedSize,
1404     int *status)
1405 {
1406     try {
1407         return impl(certificate.privateInstance)->certificateVerify(
1408             certificate,
1409             trusted,
1410             trustedSize,
1411             untrusted,
1412             untrustedSize,
1413             0,
1414             status);
1415     } catch (...) {}
1416     return CERTSVC_FAIL;
1417 }
1418
1419 int certsvc_certificate_verify_with_caflag(
1420     CertSvcCertificate certificate,
1421     const CertSvcCertificate *trusted,
1422     size_t trustedSize,
1423     const CertSvcCertificate *untrusted,
1424     size_t untrustedSize,
1425     int *status)
1426 {
1427     try {
1428         return impl(certificate.privateInstance)->certificateVerify(
1429             certificate,
1430             trusted,
1431             trustedSize,
1432             untrusted,
1433             untrustedSize,
1434             1,
1435             status);
1436     } catch (...) {}
1437     return CERTSVC_FAIL;
1438 }
1439
1440 int certsvc_certificate_get_visibility(CertSvcCertificate certificate, CertSvcVisibility *visibility)
1441 {
1442     try {
1443         return impl(certificate.privateInstance)->getVisibility(certificate, visibility);
1444     } catch (...)
1445         {
1446                 LogError("exception occur");
1447         }
1448     return CERTSVC_FAIL;
1449 }
1450
1451 int certsvc_get_certificate(CertSvcInstance instance,
1452     CertStoreType storeType,
1453     const char *gname,
1454     CertSvcCertificate *certificate)
1455 {
1456     int result = CERTSVC_SUCCESS;
1457     char* certBuffer = NULL;
1458     std::string fileName;
1459     size_t length = 0;
1460     FILE* fp_write = NULL;
1461     BIO* pBio = NULL;
1462     X509* x509Struct = NULL;
1463
1464     try {
1465         result = c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname, &certBuffer, &length);
1466         if (result != CERTSVC_SUCCESS) {
1467             LogError("Failed to get certificate buffer from store.");
1468             return result;
1469         }
1470
1471         pBio = BIO_new(BIO_s_mem());
1472         if (pBio == NULL) {
1473             LogError("Failed to allocate memory.");
1474             result = CERTSVC_BAD_ALLOC;
1475         }
1476
1477         length = BIO_write(pBio, (const void*) certBuffer, length);
1478         if (length < 1) {
1479             LogError("Failed to load cert into bio.");
1480             result = CERTSVC_BAD_ALLOC;
1481         }
1482
1483         x509Struct = PEM_read_bio_X509(pBio, NULL, 0, NULL);
1484         if (x509Struct != NULL) {
1485             CertificatePtr cert(new Certificate(x509Struct));
1486             certificate->privateInstance = instance;
1487             certificate->privateHandler = impl(instance)->addCert(cert);
1488             if (certBuffer!=NULL) free(certBuffer);
1489         }
1490         else {
1491             fileName.append(CERTSVC_PKCS12_STORAGE_DIR);
1492             fileName.append(gname);
1493             if (!(fp_write = fopen(fileName.c_str(), "w"))) {
1494                 LogError("Failed to open the file for writing, [" << fileName << "].");
1495                 result = CERTSVC_FAIL;
1496                 goto error;
1497             }
1498
1499             if (fwrite(certBuffer, sizeof(char), (size_t)length, fp_write) != (size_t)length) {
1500                 LogError("Fail to write certificate.");
1501                 result = CERTSVC_FAIL;
1502                 goto error;
1503             }
1504
1505             fclose(fp_write);
1506             result = certsvc_certificate_new_from_file(instance, fileName.c_str(), certificate);
1507             if (result != CERTSVC_SUCCESS) {
1508                 LogError("Failed to construct certificate from buffer.");
1509                 goto error;
1510             }
1511             unlink(fileName.c_str());
1512         }
1513         result = CERTSVC_SUCCESS;
1514     } catch (std::bad_alloc &) {
1515         return CERTSVC_BAD_ALLOC;
1516     } catch (...) {}
1517
1518 error:
1519     if (x509Struct) X509_free(x509Struct);
1520     if (pBio) BIO_free(pBio);
1521     return result;
1522 }
1523
1524 int certsvc_pkcs12_check_alias_exists_in_store(CertSvcInstance instance,
1525     CertStoreType storeType,
1526     CertSvcString pfxIdString,
1527     int *is_unique)
1528 {
1529     if (pfxIdString.privateHandler == NULL || pfxIdString.privateLength<=0) {
1530         LogError("Invalid input parameter.");
1531         return CERTSVC_WRONG_ARGUMENT;
1532     }
1533
1534     try {
1535         if (!impl(instance)->checkValidStoreType(storeType)) {
1536             LogError("Invalid input parameter.");
1537             return CERTSVC_INVALID_STORE_TYPE;
1538         }
1539
1540         return impl(instance)->pkcsNameIsUniqueInStore(storeType, pfxIdString, is_unique);
1541     } catch (...) {}
1542     return CERTSVC_FAIL;
1543 }
1544
1545 int certsvc_pkcs12_free_certificate_list_loaded_from_store(CertSvcInstance instance,
1546     CertSvcStoreCertList **certList)
1547 {
1548     if (certList == NULL || *certList == NULL) {
1549         LogError("Invalid input parameter.");
1550         return CERTSVC_WRONG_ARGUMENT;
1551     }
1552
1553     try {
1554         return impl(instance)->freePkcsIdListFromStore(certList);
1555     } catch (...) {}
1556     return CERTSVC_FAIL;
1557 }
1558
1559 int certsvc_pkcs12_get_certificate_list_from_store(CertSvcInstance instance,
1560         CertStoreType storeType,
1561     int is_root_app,
1562         CertSvcStoreCertList **certList,
1563         size_t *length)
1564 {
1565     if (certList == NULL || *certList != NULL) {
1566         LogError("Invalid input parameter.");
1567         return CERTSVC_WRONG_ARGUMENT;
1568     }
1569
1570     try {
1571         if (!impl(instance)->checkValidStoreType(storeType)) {
1572             LogError("Invalid input parameter.");
1573             return CERTSVC_INVALID_STORE_TYPE;
1574         }
1575
1576         return impl(instance)->getPkcsIdListFromStore(storeType, is_root_app, certList, length);
1577     } catch (...) {}
1578
1579     return CERTSVC_FAIL;
1580 }
1581
1582 int certsvc_pkcs12_get_end_user_certificate_list_from_store(CertSvcInstance instance,
1583         CertStoreType storeType,
1584         CertSvcStoreCertList **certList,
1585         size_t *length)
1586 {
1587     if (certList == NULL || *certList != NULL) {
1588         LogError("Invalid input parameter.");
1589         return CERTSVC_WRONG_ARGUMENT;
1590     }
1591
1592     try {
1593         if (!impl(instance)->checkValidStoreType(storeType)) {
1594             LogError("Invalid input parameter.");
1595             return CERTSVC_INVALID_STORE_TYPE;
1596         }
1597
1598         return impl(instance)->getPkcsIdEndUserListFromStore(storeType, certList, length);
1599     } catch (...) {}
1600     return CERTSVC_FAIL;
1601 }
1602
1603 int certsvc_pkcs12_get_root_certificate_list_from_store(CertSvcInstance instance,
1604         CertStoreType storeType,
1605         CertSvcStoreCertList **certList,
1606         size_t *length)
1607 {
1608     if (certList == NULL || *certList != NULL) {
1609         LogError("Invalid input parameter.");
1610         return CERTSVC_WRONG_ARGUMENT;
1611     }
1612
1613     try {
1614         if (!impl(instance)->checkValidStoreType(storeType)) {
1615             LogError("Invalid input parameter.");
1616             return CERTSVC_INVALID_STORE_TYPE;
1617         }
1618
1619         return impl(instance)->getPkcsIdRootListFromStore(storeType, certList, length);
1620     } catch (...) {}
1621     return CERTSVC_FAIL;
1622 }
1623
1624 int certsvc_pkcs12_get_certificate_info_from_store(CertSvcInstance instance,
1625     CertStoreType storeType,
1626     CertSvcString gname,
1627     char **certBuffer,
1628     size_t *certSize)
1629 {
1630     if (certBuffer == NULL || *certBuffer != NULL) {
1631         LogError("Invalid input parameter.");
1632         return CERTSVC_WRONG_ARGUMENT;
1633     }
1634
1635     try {
1636         if (!impl(instance)->checkValidStoreType(storeType)) {
1637             LogError("Invalid input parameter.");
1638             return CERTSVC_INVALID_STORE_TYPE;
1639         }
1640
1641         return impl(instance)->getCertDetailFromStore(storeType, gname, certBuffer, certSize);
1642     } catch (...) {}
1643     return CERTSVC_FAIL;
1644 }
1645
1646 int certsvc_pkcs12_delete_certificate_from_store(CertSvcInstance instance,
1647     CertStoreType storeType,
1648     CertSvcString gname)
1649 {
1650      try {
1651          if (!impl(instance)->checkValidStoreType(storeType)) {
1652              LogError("Invalid input parameter.");
1653              return CERTSVC_INVALID_STORE_TYPE;
1654          }
1655          return impl(instance)->pkcsDeleteCertFromStore(storeType, gname);
1656      } catch (...) {}
1657      return CERTSVC_FAIL;
1658 }
1659
1660 int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
1661     CertStoreType storeType,
1662     CertSvcString path,
1663     CertSvcString password,
1664     CertSvcString pfxIdString)
1665 {
1666     try {
1667         if (path.privateHandler != NULL) {
1668         if (!impl(instance)->checkValidStoreType(storeType)) {
1669             LogError("Invalid input parameter.");
1670             return CERTSVC_INVALID_STORE_TYPE;
1671         }
1672         return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
1673     }
1674     else
1675         return CERTSVC_FAIL;
1676     } catch (...) {}
1677     return CERTSVC_FAIL;
1678 }
1679
1680 int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
1681     CertStoreType storeType,
1682     CertSvcString gname,
1683     char **alias)
1684 {
1685     if (gname.privateHandler == NULL || gname.privateLength<=0) {
1686         LogError("Invalid input parameter.");
1687         return CERTSVC_WRONG_ARGUMENT;
1688     }
1689
1690     try {
1691         if (!impl(instance)->checkValidStoreType(storeType)) {
1692             LogError("Invalid input parameter.");
1693             return CERTSVC_INVALID_STORE_TYPE;
1694         }
1695         return impl(instance)->pkcsGetAliasNameForCertInStore(storeType, gname, alias);
1696     } catch (...) {}
1697     return CERTSVC_FAIL;
1698 }
1699
1700 int certsvc_pkcs12_set_certificate_status_to_store(CertSvcInstance instance,
1701     CertStoreType storeType,
1702     int is_root_app,
1703     CertSvcString gname,
1704     CertStatus status)
1705 {
1706     try {
1707         if (!impl(instance)->checkValidStoreType(storeType)) {
1708             LogError("Invalid input parameter.");
1709             return CERTSVC_INVALID_STORE_TYPE;
1710         }
1711         return impl(instance)->pkcsSetCertStatusToStore(storeType, is_root_app, gname, status);
1712     } catch (...) {}
1713     return CERTSVC_FAIL;
1714 }
1715
1716 int certsvc_pkcs12_get_certificate_status_from_store(
1717     CertSvcInstance instance,
1718     CertStoreType storeType,
1719     CertSvcString gname,
1720     CertStatus *status)
1721 {
1722     try {
1723         if (!impl(instance)->checkValidStoreType(storeType)) {
1724             LogError("Invalid input parameter.");
1725             return CERTSVC_INVALID_STORE_TYPE;
1726         }
1727         return impl(instance)->pkcsGetCertStatusFromStore(storeType, gname, status);
1728     } catch (...) {}
1729     return CERTSVC_FAIL;
1730 }
1731
1732 int certsvc_pkcs12_get_certificate_from_store(CertSvcInstance instance,
1733     CertStoreType storeType,
1734     const char *gname,
1735     CertSvcCertificate *certificate)
1736 {
1737     try {
1738         if (!impl(instance)->checkValidStoreType(storeType)) {
1739             LogError("Invalid input parameter.");
1740             return CERTSVC_INVALID_STORE_TYPE;
1741         }
1742         return impl(instance)->getCertFromStore(instance, storeType, gname, certificate);
1743     } catch (...) {}
1744     return CERTSVC_FAIL;
1745 }
1746
1747 int certsvc_pkcs12_load_certificate_list_from_store(
1748     CertSvcInstance instance,
1749     CertStoreType storeType,
1750     CertSvcString pfxIdString,
1751     CertSvcCertificateList *certificateList)
1752 {
1753     try {
1754         if (!impl(instance)->checkValidStoreType(storeType)) {
1755             LogError("Invalid input parameter.");
1756             return CERTSVC_INVALID_STORE_TYPE;
1757         }
1758         return impl(instance)->getPkcsCertificateListFromStore(instance, storeType, pfxIdString, certificateList);
1759     } catch (...) {}
1760     return CERTSVC_FAIL;
1761 }
1762
1763 int certsvc_pkcs12_private_key_dup_from_store(
1764     CertSvcInstance instance,
1765     CertStoreType storeType,
1766     CertSvcString gname,
1767     char **certBuffer,
1768     size_t *certSize)
1769 {
1770     try {
1771         if (!impl(instance)->checkValidStoreType(storeType)) {
1772             LogError("Invalid input parameter.");
1773             return CERTSVC_INVALID_STORE_TYPE;
1774         }
1775         return impl(instance)->getPkcsPrivateKeyFromStore(storeType, gname, certBuffer, certSize);
1776     } catch (...) {}
1777     return CERTSVC_FAIL;
1778 }
1779
1780 int certsvc_pkcs12_dup_evp_pkey_from_store(
1781     CertSvcInstance instance,
1782     CertStoreType storeType,
1783     CertSvcString gname,
1784     EVP_PKEY** pkey)
1785 {
1786     char *buffer = NULL;
1787     size_t size;
1788
1789     int result = certsvc_pkcs12_private_key_dup_from_store(instance, storeType, gname, &buffer, &size);
1790     if (result != CERTSVC_SUCCESS) {
1791         LogError("Error in certsvc_pkcs12_private_key_dup");
1792         return result;
1793     }
1794
1795     BIO *b = BIO_new(BIO_s_mem());
1796     if ((int)size != BIO_write(b, buffer, size)) {
1797          LogError("Error in BIO_write");
1798          BIO_free_all(b);
1799          certsvc_pkcs12_private_key_free(buffer);
1800          return CERTSVC_FAIL;
1801     }
1802
1803     certsvc_pkcs12_private_key_free(buffer);
1804     *pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
1805     BIO_free_all(b);
1806     if (*pkey)
1807         return CERTSVC_SUCCESS;
1808
1809     LogError("Result is null. Openssl REASON code is : " << ERR_GET_REASON(ERR_peek_last_error()));
1810     return CERTSVC_FAIL;
1811 }
1812
1813 int certsvc_pkcs12_has_password(
1814     CertSvcInstance instance,
1815     CertSvcString filepath,
1816     int *has_password)
1817 {
1818     try {
1819         return impl(instance)->pkcsHasPassword(
1820             filepath,
1821             has_password);
1822     } catch (...) {}
1823     return CERTSVC_FAIL;
1824 }
1825
1826 void certsvc_pkcs12_private_key_free(char *buffer)
1827 {
1828     free(buffer);
1829 }
1830