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