a093b21897ea49b4a21fb989106d2b1db5315516
[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 <glib-object.h>
38
39 #include <openssl/pem.h>
40 #include <openssl/ssl.h>
41 #include <openssl/x509v3.h>
42 #include <openssl/pkcs12.h>
43 #include <openssl/err.h>
44 #include <openssl/sha.h>
45 #include <openssl/evp.h>
46 #include <openssl/bio.h>
47
48 #include <dpl/foreach.h>
49 #include <dpl/log/log.h>
50
51 #include <cert-svc/cinstance.h>
52 #include <cert-svc/ccert.h>
53 #include <cert-svc/cpkcs12.h>
54 #include <cert-svc/cprimitives.h>
55
56 #include <vcore/Base64.h>
57 #include <vcore/Certificate.h>
58 #include <vcore/CertificateCollection.h>
59 #include <vcore/pkcs12.h>
60
61 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL 
62 #include <cert-svc/ccrl.h>
63 #include <cert-svc/cocsp.h>
64 #include <vcore/OCSP.h>
65 #include <vcore/CRL.h>
66 #include <vcore/CRLCacheInterface.h>
67 #endif
68
69 #include <libxml/parser.h>
70 #include <libxml/tree.h>
71
72 #define START_CERT      "-----BEGIN CERTIFICATE-----"
73 #define END_CERT        "-----END CERTIFICATE-----"
74 #define START_TRUSTED   "-----BEGIN TRUSTED CERTIFICATE-----"
75 #define END_TRUSTED     "-----END TRUSTED CERTIFICATE-----"
76
77 using namespace ValidationCore;
78
79 namespace {
80
81 typedef std::unique_ptr<CERT_CONTEXT, std::function<int(CERT_CONTEXT*)> > ScopedCertCtx;
82
83 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
84 class CRLCacheCAPI : public CRLCacheInterface {
85 public:
86     CRLCacheCAPI(
87         CertSvcCrlCacheWrite crlWrite,
88         CertSvcCrlCacheRead crlRead,
89         CertSvcCrlFree crlFree,
90         void *userParam)
91       : m_crlWrite(crlWrite)
92       , m_crlRead(crlRead)
93       , m_crlFree(crlFree)
94       , m_userParam(userParam)
95     {}
96
97     bool getCRLResponse(CRLCachedData *ptr){
98         if (!m_crlRead || !m_crlFree)
99             return false;
100
101         char *buffer;
102         int size;
103
104         bool result = m_crlRead(
105             ptr->distribution_point.c_str(),
106             &buffer,
107             &size,
108             &(ptr->next_update_time),
109             m_userParam);
110
111         if (result) {
112             ptr->crl_body.clear();
113             ptr->crl_body.append(buffer, size);
114             m_crlFree(buffer, m_userParam);
115         }
116
117         return result;
118     }
119     void setCRLResponse(CRLCachedData *ptr){
120         if (m_crlWrite) {
121             m_crlWrite(
122                 ptr->distribution_point.c_str(),
123                 ptr->crl_body.c_str(),
124                 ptr->crl_body.size(),
125                 ptr->next_update_time,
126                 m_userParam);
127         }
128     }
129
130 private:
131     CertSvcCrlCacheWrite m_crlWrite;
132     CertSvcCrlCacheRead m_crlRead;
133     CertSvcCrlFree m_crlFree;
134     void *m_userParam;
135 };
136 #endif
137
138 class CertSvcInstanceImpl {
139 public:
140     CertSvcInstanceImpl()
141       : m_certificateCounter(0)
142       , m_idListCounter(0)
143       , m_stringListCounter(0)
144 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
145       , m_crlWrite(NULL)
146       , m_crlRead(NULL)
147       , m_crlFree(NULL)
148 #endif
149     {}
150
151     ~CertSvcInstanceImpl(){
152         FOREACH(it, m_allocatedStringSet) {
153             delete[] *it;
154         }
155     }
156
157     inline void reset(){
158         m_certificateCounter = 0;
159         m_certificateMap.clear();
160         m_idListCounter = 0;
161         m_idListMap.clear();
162         m_stringListCounter = 0;
163         m_stringListMap.clear();
164
165         FOREACH(it, m_allocatedStringSet) {
166             delete[] *it;
167         }
168
169         m_allocatedStringSet.clear();
170     }
171
172     inline int addCert(const CertificatePtr &cert) {
173         m_certificateMap[m_certificateCounter] = cert;
174         return m_certificateCounter++;
175     }
176
177     inline void removeCert(const CertSvcCertificate &cert) {
178         auto iter = m_certificateMap.find(cert.privateHandler);
179         if (iter != m_certificateMap.end()) {
180             m_certificateMap.erase(iter);
181         }
182     }
183
184     inline int getCertFromList(
185         const CertSvcCertificateList &handler,
186         int position,
187         CertSvcCertificate *certificate)
188     {
189         auto iter = m_idListMap.find(handler.privateHandler);
190         if (iter == m_idListMap.end()) {
191             return CERTSVC_WRONG_ARGUMENT;
192         }
193         if (position >= static_cast<int>(iter->second.size())) {
194             return CERTSVC_WRONG_ARGUMENT;
195         }
196         certificate->privateInstance = handler.privateInstance;
197         certificate->privateHandler = (iter->second)[position];
198         return CERTSVC_SUCCESS;
199     }
200
201     inline int getCertListLen(const CertSvcCertificateList &handler, int *len) {
202         auto iter = m_idListMap.find(handler.privateHandler);
203         if (iter == m_idListMap.end() || !len) {
204             return CERTSVC_WRONG_ARGUMENT;
205         }
206         *len = (iter->second).size();
207         return CERTSVC_SUCCESS;
208     }
209
210     inline void removeCertList(const CertSvcCertificateList &handler) {
211         auto iter = m_idListMap.find(handler.privateHandler);
212         if (iter != m_idListMap.end())
213             m_idListMap.erase(iter);
214     }
215
216     inline int isSignedBy(const CertSvcCertificate &child,
217                           const CertSvcCertificate &parent,
218                           int *status)
219     {
220         auto citer = m_certificateMap.find(child.privateHandler);
221         if (citer == m_certificateMap.end()) {
222             return CERTSVC_WRONG_ARGUMENT;
223         }
224         auto piter = m_certificateMap.find(parent.privateHandler);
225         if (piter == m_certificateMap.end()) {
226             return CERTSVC_WRONG_ARGUMENT;
227         }
228
229         if (citer->second->isSignedBy(piter->second)) {
230             *status = CERTSVC_TRUE;
231         } else {
232             *status = CERTSVC_FALSE;
233         }
234         return CERTSVC_SUCCESS;
235     }
236
237     inline int getField(const CertSvcCertificate &cert,
238                         CertSvcCertificateField field,
239                         CertSvcString *buffer)
240     {
241         auto iter = m_certificateMap.find(cert.privateHandler);
242         if (iter == m_certificateMap.end()) {
243             return CERTSVC_WRONG_ARGUMENT;
244         }
245
246         auto certPtr = iter->second;
247         std::string result;
248         switch (field) {
249             case CERTSVC_SUBJECT:
250                 result = certPtr->getOneLine();
251                 break;
252             case CERTSVC_ISSUER:
253                 result = certPtr->getOneLine(Certificate::FIELD_ISSUER);
254                 break; 
255             case CERTSVC_SUBJECT_COMMON_NAME:
256                 result = certPtr->getCommonName();
257                 break;
258             case CERTSVC_SUBJECT_COUNTRY_NAME:
259                 result = certPtr->getCountryName();
260                 break;
261             case CERTSVC_SUBJECT_STATE_NAME:
262                 result = certPtr->getStateOrProvinceName();
263                 break;
264             case CERTSVC_SUBJECT_ORGANIZATION_NAME:
265                 result = certPtr->getOrganizationName();
266                 break;
267             case CERTSVC_SUBJECT_ORGANIZATION_UNIT_NAME:
268                 result = certPtr->getOrganizationalUnitName();
269                 break;
270             case CERTSVC_SUBJECT_EMAIL_ADDRESS:
271                 result = certPtr->getEmailAddres();
272                 break;
273             case CERTSVC_ISSUER_COMMON_NAME:
274                 result = certPtr->getCommonName(Certificate::FIELD_ISSUER);
275                 break;
276             case CERTSVC_ISSUER_STATE_NAME:
277                 result = certPtr->getStateOrProvinceName(Certificate::FIELD_ISSUER);
278                 break;
279             case CERTSVC_ISSUER_ORGANIZATION_NAME:
280                 result = certPtr->getOrganizationName(Certificate::FIELD_ISSUER);
281                 break;
282             case CERTSVC_ISSUER_ORGANIZATION_UNIT_NAME:
283                 result = certPtr->getOrganizationalUnitName(Certificate::FIELD_ISSUER);
284                 break;
285             case CERTSVC_VERSION:
286             {
287                 std::stringstream stream;
288                 stream << (certPtr->getVersion()+1);
289                 result = stream.str();
290                 break;
291             }
292             case CERTSVC_SERIAL_NUMBER:
293                 result = certPtr->getSerialNumberString();
294                 break;
295             case CERTSVC_KEY_USAGE:
296                 result = certPtr->getKeyUsageString();
297                 break;
298             case CERTSVC_KEY:
299                 result = certPtr->getPublicKeyString();
300                 break;
301             case CERTSVC_SIGNATURE_ALGORITHM:
302                 result = certPtr->getSignatureAlgorithmString();
303                 break;
304             default:
305                 break;
306         }
307
308         if (result.empty()) {
309             buffer->privateHandler = NULL;
310             buffer->privateLength = 0;
311             buffer->privateInstance = cert.privateInstance;
312             return CERTSVC_SUCCESS;
313         }
314
315         char *cstring = new char[result.size()+1];
316         if (cstring == NULL) {
317             buffer->privateHandler = NULL;
318             buffer->privateLength = 0;
319             buffer->privateInstance = cert.privateInstance;
320             return CERTSVC_BAD_ALLOC;
321         }
322
323         strncpy(cstring, result.c_str(), result.size()+1);
324
325         buffer->privateHandler = cstring;
326         buffer->privateLength = result.size();
327         buffer->privateInstance = cert.privateInstance;
328
329         m_allocatedStringSet.insert(cstring);
330
331         return CERTSVC_SUCCESS;
332     }
333
334     inline int getNotAfter(const CertSvcCertificate &cert,
335                            time_t *time)
336     {
337         auto iter = m_certificateMap.find(cert.privateHandler);
338         if (iter == m_certificateMap.end()) {
339             return CERTSVC_WRONG_ARGUMENT;
340         }
341         *time = iter->second->getNotAfter();
342         return CERTSVC_SUCCESS;
343     }
344
345     inline int getNotBefore(const CertSvcCertificate &cert,
346                             time_t *time)
347     {
348         auto iter = m_certificateMap.find(cert.privateHandler);
349         if (iter == m_certificateMap.end()) {
350             return CERTSVC_WRONG_ARGUMENT;
351         }
352         *time = iter->second->getNotBefore();
353         return CERTSVC_SUCCESS;
354     }
355
356     inline int isRootCA(const CertSvcCertificate &cert, int *status){
357         auto iter = m_certificateMap.find(cert.privateHandler);
358         if (iter == m_certificateMap.end()) {
359             return CERTSVC_WRONG_ARGUMENT;
360         }
361         if (iter->second->isRootCert()) {
362             *status = CERTSVC_TRUE;
363         } else {
364             *status = CERTSVC_FALSE;
365         }
366         return CERTSVC_SUCCESS;
367     }
368
369 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
370     inline int getCrl(const CertSvcCertificate &cert, CertSvcStringList *handler){
371         auto iter = m_certificateMap.find(cert.privateHandler);
372         if (iter == m_certificateMap.end()) {
373             return CERTSVC_WRONG_ARGUMENT;
374         }
375         int position = m_stringListCounter++;
376
377         std::list<std::string> temp = iter->second->getCrlUris();
378         std::copy(temp.begin(),
379                   temp.end(),
380                   back_inserter(m_stringListMap[position]));
381
382         handler->privateHandler = position;
383         handler->privateInstance = cert.privateInstance;
384
385         return CERTSVC_SUCCESS;
386     }
387 #endif
388
389     inline int getStringFromList(
390         const CertSvcStringList &handler,
391         int position,
392         CertSvcString *buffer)
393     {
394         buffer->privateHandler = NULL;
395         buffer->privateLength = 0;
396
397         auto iter = m_stringListMap.find(handler.privateHandler);
398         if (iter == m_stringListMap.end()) {
399             return CERTSVC_WRONG_ARGUMENT;
400         }
401         if (position >= (int)iter->second.size()) {
402             return CERTSVC_WRONG_ARGUMENT;
403         }
404         const std::string &data = iter->second.at(position);
405         int size = data.size();
406         char *cstring = new char[size+1];
407         if (!cstring) {
408             return CERTSVC_FAIL;
409         }
410
411         strncpy(cstring, data.c_str(), data.size()+1);
412
413         buffer->privateHandler = cstring;
414         buffer->privateLength = data.size();
415         buffer->privateInstance = handler.privateInstance;
416
417         m_allocatedStringSet.insert(cstring);
418
419         return CERTSVC_SUCCESS;
420     }
421
422     inline int getStringListLen(
423         const CertSvcStringList &handler,
424         int *size)
425     {
426         auto iter = m_stringListMap.find(handler.privateHandler);
427         if (iter == m_stringListMap.end()) {
428             return CERTSVC_WRONG_ARGUMENT;
429         }
430         *size = (int) iter->second.size();
431         return CERTSVC_SUCCESS;
432     }
433
434     inline void removeStringList(const CertSvcStringList &handler)
435     {
436         m_stringListMap.erase(m_stringListMap.find(handler.privateHandler));
437     }
438
439     inline void removeString(const CertSvcString &handler)
440     {
441         auto iter = m_allocatedStringSet.find(handler.privateHandler);
442         if (iter != m_allocatedStringSet.end()) {
443             delete[] *iter;
444             m_allocatedStringSet.erase(iter);
445         }
446     }
447
448     inline int certificateSearch(
449         CertSvcInstance instance,
450         CertSvcCertificateField field,
451         const char *value,
452         CertSvcCertificateList *handler)
453     {
454         int result;
455         search_field fieldId = SEARCH_FIELD_END;
456
457         switch(field){
458         case CERTSVC_SUBJECT:
459             fieldId = SUBJECT_STR;
460             break;
461         case CERTSVC_ISSUER:
462             fieldId = ISSUER_STR;
463             break;
464         case CERTSVC_SUBJECT_COMMON_NAME:
465             fieldId = SUBJECT_COMMONNAME;
466             break;
467         default:
468             LogError("Not implemented!");
469             return CERTSVC_WRONG_ARGUMENT;
470         }
471
472         ScopedCertCtx ctx(cert_svc_cert_context_init(),
473                           cert_svc_cert_context_final);
474
475         if (ctx.get() == NULL) {
476             LogWarning("Error in cert_svc_cert_context_init.");
477             return CERTSVC_FAIL;
478         }
479
480         LogDebug("Match string : " << value);
481         result = cert_svc_search_certificate(ctx.get(), fieldId, const_cast<char*>(value));
482         LogDebug("Search finished!");
483
484         if (CERT_SVC_ERR_NO_ERROR != result) {
485             LogWarning("Error during certificate search");
486             return CERTSVC_FAIL;
487         }
488
489         cert_svc_filename_list *fileList = ctx.get()->fileNames;
490
491         int listId = m_idListCounter++;
492         std::vector<int> &list = m_idListMap[listId];
493         handler->privateHandler = listId;
494         handler->privateInstance = instance;
495
496         for(;fileList != NULL; fileList = fileList->next) {
497             ScopedCertCtx ctx2(cert_svc_cert_context_init(),
498                                cert_svc_cert_context_final);
499             if (ctx2.get() == NULL) {
500                 LogWarning("Error in cert_svc_cert_context_init.");
501                 return CERTSVC_FAIL;
502             }
503
504             // TODO add read_certifcate_from_file function to Certificate.h
505             if (CERT_SVC_ERR_NO_ERROR !=
506                 cert_svc_load_file_to_context(ctx2.get(), fileList->filename))
507             {
508                 LogWarning("Error in cert_svc_load_file_to_context");
509                 return CERTSVC_FAIL;
510             }
511             int certId = addCert(CertificatePtr(new Certificate(*(ctx2.get()->certBuf))));
512             list.push_back(certId);
513         }
514         return CERTSVC_SUCCESS;
515     }
516
517     inline int sortCollection(CertSvcCertificate *certificate_array, int size) {
518         if (size < 2) {
519             return CERTSVC_WRONG_ARGUMENT;
520         }
521
522         for(int i=1; i<size; ++i) {
523             if (certificate_array[i-1].privateInstance.privatePtr
524                 != certificate_array[i].privateInstance.privatePtr)
525             {
526                 return CERTSVC_WRONG_ARGUMENT;
527             }
528         }
529
530         CertificateList certList;
531         std::map<Certificate*,int> translator;
532
533         for(int i=0; i<size; ++i) {
534             int pos = certificate_array[i].privateHandler;
535             auto cert = m_certificateMap.find(pos);
536             if (cert == m_certificateMap.end()) {
537                 return CERTSVC_WRONG_ARGUMENT;
538             }
539             translator[cert->second.get()] = pos;
540             certList.push_back(cert->second);
541         }
542
543         CertificateCollection collection;
544         collection.load(certList);
545
546         if (!collection.sort()) {
547             return CERTSVC_FAIL;
548         }
549
550         auto chain = collection.getChain();
551
552         int i=0;
553         for (auto iter = chain.begin(); iter != chain.end() && i<size; ++iter, ++i) {
554             certificate_array[i].privateHandler = translator[iter->get()];
555         }
556
557         return CERTSVC_SUCCESS;
558     }
559
560     inline int getX509Copy(const CertSvcCertificate &certificate, X509** cert)
561     {
562         auto it = m_certificateMap.find(certificate.privateHandler);
563         if (it == m_certificateMap.end()) {
564             return CERTSVC_WRONG_ARGUMENT;
565         }
566         *cert = X509_dup(it->second->getX509());
567         return CERTSVC_SUCCESS;
568     }
569
570     inline int saveToFile(const CertSvcCertificate &certificate,
571                           const char *location)
572     {
573         auto it = m_certificateMap.find(certificate.privateHandler);
574         if (it == m_certificateMap.end()) {
575             return CERTSVC_WRONG_ARGUMENT;
576         }
577         FILE *out;
578         if (NULL == (out = fopen(location, "w"))) {
579             return CERTSVC_FAIL;
580         }
581         if (0 == i2d_X509_fp(out, it->second->getX509())) {
582             fclose(out);
583             return CERTSVC_FAIL;
584         }
585         fclose(out);
586         return CERTSVC_SUCCESS;
587     }
588
589 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
590     inline int ocspCheck(const CertSvcCertificate *chain,
591                          int chain_size,
592                          const CertSvcCertificate *trusted,
593                          int trusted_size,
594                          const char *url,
595                          int *status)
596     {
597         auto instance = chain[0].privateInstance.privatePtr;
598
599         for(int i=1; i<chain_size; ++i) {
600             if (instance != chain[i].privateInstance.privatePtr)
601             {
602                 return CERTSVC_WRONG_ARGUMENT;
603             }
604         }
605         CertificateList chainList, trustedList;
606
607         for(int i=0; i<chain_size; ++i) {
608             auto cert = m_certificateMap.find(chain[i].privateHandler);
609             if (cert == m_certificateMap.end()) {
610                 return CERTSVC_WRONG_ARGUMENT;
611             }
612             chainList.push_back(cert->second);
613         }
614
615         for(int i=0; i<trusted_size; ++i) {
616             if (instance != trusted[i].privateInstance.privatePtr)
617             {
618                 return CERTSVC_WRONG_ARGUMENT;
619             }
620         }
621
622         for(int i=0; i<trusted_size; ++i) {
623             auto cert = m_certificateMap.find(trusted[i].privateHandler);
624             if (cert == m_certificateMap.end()) {
625                 return CERTSVC_WRONG_ARGUMENT;
626             }
627             trustedList.push_back(cert->second);
628         }
629
630         OCSP ocsp;
631 //        ocsp.setDigestAlgorithmForCertId(OCSP::SHA1);
632 //        ocsp.setDigestAlgorithmForRequest(OCSP::SHA1);
633         ocsp.setTrustedStore(trustedList);
634
635         if (url) {
636             ocsp.setUseDefaultResponder(true);
637             ocsp.setDefaultResponder(url);
638         }
639
640         CertificateCollection collection;
641         collection.load(chainList);
642         if (!collection.sort()) {
643             return CERTSVC_WRONG_ARGUMENT;
644         }
645
646         chainList = collection.getChain();
647
648         VerificationStatusSet statusSet = ocsp.validateCertificateList(chainList);
649
650         int ret = 0;
651         if (statusSet.contains(VERIFICATION_STATUS_GOOD)) {
652             ret |= CERTSVC_OCSP_GOOD;
653         }
654         if (statusSet.contains(VERIFICATION_STATUS_REVOKED)) {
655             ret |= CERTSVC_OCSP_REVOKED;
656         }
657         if (statusSet.contains(VERIFICATION_STATUS_UNKNOWN)) {
658             ret |= CERTSVC_OCSP_UNKNOWN;
659         }
660         if (statusSet.contains(VERIFICATION_STATUS_VERIFICATION_ERROR)) {
661             ret |= CERTSVC_OCSP_VERIFICATION_ERROR;
662         }
663         if (statusSet.contains(VERIFICATION_STATUS_NOT_SUPPORT)) {
664             ret |= CERTSVC_OCSP_NO_SUPPORT;
665         }
666         if (statusSet.contains(VERIFICATION_STATUS_CONNECTION_FAILED)) {
667             ret |= CERTSVC_OCSP_CONNECTION_FAILED;
668         }
669         if (statusSet.contains(VERIFICATION_STATUS_ERROR)) {
670             ret |= CERTSVC_OCSP_ERROR;
671         }
672
673         *status = ret;
674         return CERTSVC_SUCCESS;
675     }
676 #endif
677
678     inline int verify(
679         CertSvcCertificate certificate,
680         CertSvcString &message,
681         CertSvcString &signature,
682         const char *algorithm,
683         int *status)
684     {
685         int result = CERTSVC_FAIL;
686
687         if (!status) {
688             return CERTSVC_WRONG_ARGUMENT;
689         }
690
691         auto it = m_certificateMap.find(certificate.privateHandler);
692         if (it == m_certificateMap.end()) {
693             return CERTSVC_WRONG_ARGUMENT;
694         }
695
696         OpenSSL_add_all_digests();
697
698         int temp;
699         EVP_MD_CTX* mdctx = NULL;
700         const EVP_MD * md = NULL;
701         X509 *cert = it->second->getX509();
702         EVP_PKEY *pkey = NULL;
703
704         if (cert == NULL) {
705             goto err;
706         }
707
708         pkey = X509_get_pubkey(cert);
709
710         if (pkey == NULL) {
711             goto err;
712         }
713
714         if (algorithm == NULL) {
715             md = EVP_get_digestbyobj(cert->cert_info->signature->algorithm);
716         } else {
717             md = EVP_get_digestbyname(algorithm);
718         }
719
720         if (md == NULL) {
721             result = CERTSVC_INVALID_ALGORITHM;
722             goto err;
723         }
724
725         mdctx = EVP_MD_CTX_create();
726
727         if (mdctx == NULL) {
728             goto err;
729         }
730
731         if (EVP_VerifyInit_ex(mdctx, md, NULL) != 1) {
732             goto err;
733         }
734
735         if (EVP_VerifyUpdate(mdctx, message.privateHandler, message.privateLength) != 1) {
736             goto err;
737         }
738
739         temp = EVP_VerifyFinal(mdctx,
740             reinterpret_cast<unsigned char*>(signature.privateHandler),
741             signature.privateLength,
742             pkey);
743
744         if (temp == 0) {
745             *status = CERTSVC_INVALID_SIGNATURE;
746             result = CERTSVC_SUCCESS;
747         } else if (temp == 1) {
748             *status = CERTSVC_SUCCESS;
749             result = CERTSVC_SUCCESS;
750         }
751
752     err:
753         if (mdctx != NULL)
754             EVP_MD_CTX_destroy(mdctx);
755         if (pkey != NULL)
756             EVP_PKEY_free(pkey);
757         return result;
758     }
759
760     inline int base64Encode(
761         const CertSvcString &message,
762         CertSvcString *base64)
763     {
764         if (!base64) {
765             return CERTSVC_WRONG_ARGUMENT;
766         }
767         std::string info(message.privateHandler, message.privateLength);
768         Base64Encoder base;
769         base.reset();
770         base.append(info);
771         base.finalize();
772         info = base.get();
773         char *ptr = new char[info.size()+1];
774         if(ptr == NULL) {
775             return CERTSVC_BAD_ALLOC;
776         }
777         memcpy(ptr, info.c_str(), info.size()+1);
778         m_allocatedStringSet.insert(ptr);
779         base64->privateHandler = ptr;
780         base64->privateLength = info.size();
781         base64->privateInstance = message.privateInstance;
782         return CERTSVC_SUCCESS;
783     }
784
785     int base64Decode(
786         const CertSvcString &base64,
787         CertSvcString *message)
788     {
789         if (!message) {
790             return CERTSVC_WRONG_ARGUMENT;
791         }
792         std::string info(base64.privateHandler, base64.privateLength);
793         Base64Decoder base;
794         base.reset();
795         base.append(info);
796         if (!base.finalize()) {
797             return CERTSVC_FAIL;
798         }
799         info = base.get();
800         char *ptr = new char[info.size()+1];
801         if(ptr == NULL) {
802             return CERTSVC_BAD_ALLOC;
803         }
804         memcpy(ptr, info.c_str(), info.size()+1);
805         m_allocatedStringSet.insert(ptr);
806         message->privateHandler = ptr;
807         message->privateLength = info.size();
808         message->privateInstance = base64.privateInstance;
809         return CERTSVC_SUCCESS;
810     }
811
812     inline int stringNew(
813         CertSvcInstance &instance,
814         const char *str,
815         int size,
816         CertSvcString *output)
817     {
818         if (!output || size < 0) {
819             return CERTSVC_WRONG_ARGUMENT;
820         }
821
822         int allocSize = size;
823
824         if (allocSize == 0 || str[allocSize-1] != 0)
825             allocSize++;
826
827         char *ptr = new char[allocSize];
828         if(ptr == NULL) {
829             return CERTSVC_BAD_ALLOC;
830         }
831         memcpy(ptr, str, size);
832         ptr[allocSize-1] = 0;
833
834         output->privateHandler = ptr;
835         output->privateLength = size;
836         output->privateInstance = instance;
837
838         m_allocatedStringSet.insert(ptr);
839
840         return CERTSVC_SUCCESS;
841     }
842
843 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
844     inline void setCRLFunction(
845         CertSvcCrlCacheWrite writePtr,
846         CertSvcCrlCacheRead readPtr,
847         CertSvcCrlFree freePtr)
848     {
849         m_crlWrite = writePtr;
850         m_crlRead = readPtr;
851         m_crlFree = freePtr;
852     }
853
854     inline int crlCheck(
855         CertSvcCertificate certificate,
856         CertSvcCertificate *trustedStore,
857         int storeSize,
858         int force,
859         int *status,
860         void *userParam)
861     {
862         for(int i=1; i<storeSize; ++i) {
863             if (certificate.privateInstance.privatePtr
864                 != trustedStore[i].privateInstance.privatePtr)
865             {
866                 return CERTSVC_WRONG_ARGUMENT;
867             }
868         }
869
870         CRL crl(new CRLCacheCAPI(m_crlWrite, m_crlRead, m_crlFree, userParam));
871
872         for (int i=0; i<storeSize; ++i) {
873             auto iter = m_certificateMap.find(trustedStore[i].privateHandler);
874             if (iter == m_certificateMap.end()) {
875                 return CERTSVC_WRONG_ARGUMENT;
876             }
877             crl.addToStore(iter->second);
878         }
879
880         auto iter = m_certificateMap.find(certificate.privateHandler);
881         if (iter == m_certificateMap.end()) {
882             return CERTSVC_WRONG_ARGUMENT;
883         }
884         if (iter->second->getCrlUris().empty()) {
885             *status = CERTSVC_CRL_NO_SUPPORT;
886             return CERTSVC_SUCCESS;
887         }
888         crl.updateList(iter->second, force ? CRL::UPDATE_ON_DEMAND: CRL::UPDATE_ON_EXPIRED);
889         CRL::RevocationStatus st = crl.checkCertificate(iter->second);
890         *status = 0;
891
892         if (!st.isCRLValid) {
893             *status |= CERTSVC_CRL_VERIFICATION_ERROR;
894             return CERTSVC_SUCCESS;
895         }
896
897         if (st.isRevoked) {
898             *status |= CERTSVC_CRL_REVOKED;
899         } else {
900             *status |= CERTSVC_CRL_GOOD;
901         }
902
903         return CERTSVC_SUCCESS;
904     }
905 #endif
906
907     inline int certificateVerify(
908         CertSvcCertificate certificate,
909         CertSvcCertificate *trusted,
910         int trustedSize,
911         CertSvcCertificate *untrusted,
912         int untrustedSize,
913         int checkCaFlag,
914         int *status)
915     {
916         if (!trusted || !status) {
917             return CERTSVC_WRONG_ARGUMENT;
918         }
919         auto iter = m_certificateMap.find(certificate.privateHandler);
920         if (iter == m_certificateMap.end()) {
921             return CERTSVC_WRONG_ARGUMENT;
922         }
923
924         X509 *cert = iter->second->getX509();
925         X509_STORE *store = X509_STORE_new();
926         STACK_OF(X509) *ustore = sk_X509_new_null();
927
928         for (int i=0; i<trustedSize; ++i) {
929             auto iter = m_certificateMap.find(trusted[i].privateHandler);
930             if (iter == m_certificateMap.end()) {
931                 X509_STORE_free(store);
932                 sk_X509_free(ustore);
933                 return CERTSVC_WRONG_ARGUMENT;
934             }
935             X509_STORE_add_cert(store, iter->second->getX509());
936         }
937
938         for (int i=0; i<untrustedSize; ++i) {
939             auto iter = m_certificateMap.find(untrusted[i].privateHandler);
940             if (iter == m_certificateMap.end()) {
941                 X509_STORE_free(store);
942                 sk_X509_free(ustore);
943                 return CERTSVC_WRONG_ARGUMENT;
944             }
945             if (sk_X509_push(ustore, iter->second->getX509()) == 0)
946             {
947                 break;
948             }
949         }
950         X509_STORE_CTX context;
951         X509_STORE_CTX_init(&context, store, cert, ustore);
952         int result = X509_verify_cert(&context);
953
954         if(result == 1 && checkCaFlag) { // check strictly
955                 STACK_OF(X509) *resultChain = X509_STORE_CTX_get1_chain(&context);
956                 X509* tmpCert = NULL;
957                 int caFlagValidity;
958                 while((tmpCert = sk_X509_pop(resultChain))) {
959                         caFlagValidity = X509_check_ca(tmpCert);
960                         if(caFlagValidity != 1 && (tmpCert = sk_X509_pop(resultChain)) != NULL) { // the last one is not a CA.
961                                 result = 0;
962                                 break;
963                         }
964                 }
965         }
966
967         X509_STORE_CTX_cleanup(&context);
968         X509_STORE_free(store);
969         sk_X509_free(ustore);
970
971         if (result == 1) {
972             *status = CERTSVC_SUCCESS;
973         } else {
974             *status = CERTSVC_FAIL;
975         }
976         return CERTSVC_SUCCESS;
977     }
978
979     int getVisibility(CertSvcCertificate certificate, int* visibility)
980     {
981                 int ret = CERTSVC_FAIL;
982                 //xmlChar *xmlPathCertificateSet  = (xmlChar*) "CertificateSet"; /*unused variable*/
983                 //xmlChar *xmlPathCertificateDomain = (xmlChar*) "CertificateDomain";// name=\"tizen-platform\""; /*unused variable*/
984                 xmlChar *xmlPathDomainPlatform = (xmlChar*) "tizen-platform";
985                 xmlChar *xmlPathDomainPublic = (xmlChar*) "tizen-public";
986                 xmlChar *xmlPathDomainPartner = (xmlChar*) "tizen-partner";
987                 xmlChar *xmlPathDomainDeveloper = (xmlChar*) "tizen-developer";
988                 //xmlChar *xmlPathFingerPrintSHA1 = (xmlChar*) "FingerprintSHA1"; /*unused variable*/
989
990         auto iter = m_certificateMap.find(certificate.privateHandler);
991         if (iter == m_certificateMap.end()) {
992                         return CERTSVC_FAIL;
993         }
994         CertificatePtr certPtr = iter->second;
995
996                 std::string fingerprint = Certificate::FingerprintToColonHex(certPtr->getFingerprint(Certificate::FINGERPRINT_SHA1));
997
998                 /*   load file */
999                 xmlDocPtr doc = xmlParseFile(FINGERPRINT_LIST_PATH);
1000                 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL))
1001                 {
1002                         LogError("Failed to prase fingerprint_list.xml");
1003                         return CERTSVC_IO_ERROR;
1004                 }
1005
1006                 xmlNodePtr curPtr = xmlFirstElementChild(xmlDocGetRootElement(doc));
1007                 if(curPtr == NULL)
1008                 {
1009                         LogError("Can not find root");
1010                         ret = CERTSVC_IO_ERROR;
1011                         goto out;
1012                 }
1013
1014                 while(curPtr != NULL)
1015                 {
1016                         xmlAttr* attr = curPtr->properties;
1017                         if(!attr->children || !attr->children->content)
1018                         {
1019                                 LogError("Failed to get fingerprints from list");
1020                                 ret = CERTSVC_FAIL;
1021                                 goto out;
1022                         }
1023
1024                         xmlChar* strLevel = attr->children->content;
1025                         xmlNodePtr FpPtr = xmlFirstElementChild(curPtr);
1026                         if(FpPtr == NULL)
1027                         {
1028                                 LogError("Could not find fingerprint");
1029                                 ret = CERTSVC_FAIL;
1030                                 goto out;
1031                         }
1032
1033                         LogDebug("Retrieve level : " << strLevel);
1034                         while(FpPtr)
1035                         {
1036                                 xmlChar *content = xmlNodeGetContent(FpPtr);
1037                                 if(xmlStrcmp(content, (xmlChar*)fingerprint.c_str()) == 0)
1038                                 {
1039                                         LogDebug("fingerprint : " << content << " are " << strLevel);
1040                                         if(!xmlStrcmp(strLevel, xmlPathDomainPlatform))
1041                                         {
1042                                                 *visibility = CERTSVC_VISIBILITY_PLATFORM;
1043                                                 ret = CERTSVC_SUCCESS;
1044                                                 goto out;
1045                                         }
1046                                         else if(!xmlStrcmp(strLevel, xmlPathDomainPublic))
1047                                         {
1048                                                 *visibility = CERTSVC_VISIBILITY_PUBLIC;
1049                                                 ret = CERTSVC_SUCCESS;
1050                                                 goto out;
1051                                         }
1052                                         else if(!xmlStrcmp(strLevel, xmlPathDomainPartner))
1053                                         {
1054                                                 *visibility = CERTSVC_VISIBILITY_PARTNER;
1055                                                 ret = CERTSVC_SUCCESS;
1056                                                 goto out;
1057                                         }
1058                                         else if(!xmlStrcmp(strLevel, xmlPathDomainDeveloper))
1059                                         {
1060                                                 *visibility = CERTSVC_VISIBILITY_DEVELOPER;
1061                                                 ret = CERTSVC_SUCCESS;
1062                                                 goto out;
1063                                         }
1064                                 }
1065                                 FpPtr = xmlNextElementSibling(FpPtr);
1066                         }
1067                         curPtr = xmlNextElementSibling(curPtr);
1068                 }
1069                 xmlFreeDoc(doc);
1070                 return CERTSVC_FAIL;
1071 out:
1072                 xmlFreeDoc(doc);
1073                 return ret;
1074         }
1075
1076     inline int pkcsNameIsUnique(
1077         CertSvcString pfxIdString,
1078         int *is_unique)
1079     {
1080       gboolean exists;
1081       int result = c_certsvc_pkcs12_alias_exists(pfxIdString.privateHandler, &exists);
1082       *is_unique = !exists;
1083       return result;
1084     }
1085
1086     inline int pkcsImport(
1087         CertSvcString path,
1088         CertSvcString pass,
1089         CertSvcString pfxIdString)
1090     {
1091       return c_certsvc_pkcs12_import(path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
1092     }
1093
1094     inline int pkcsNameIsUniqueInStore(
1095         CertStoreType storeType,
1096         CertSvcString pfxIdString,
1097         int *is_unique)
1098     {
1099       int result = c_certsvc_pkcs12_alias_exists_in_store(storeType, pfxIdString.privateHandler, is_unique);
1100       return result;
1101     }
1102
1103     inline int getCertDetailFromStore(CertStoreType storeType,
1104         CertSvcString gname,
1105         char** certBuffer,
1106         size_t* certSize)
1107     {
1108         return c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname.privateHandler, certBuffer, certSize);
1109     }
1110
1111     inline int pkcsDeleteCertFromStore(
1112         CertStoreType storeType,
1113         CertSvcString gname
1114     )
1115     {
1116         return c_certsvc_pkcs12_delete_certificate_from_store(storeType, gname.privateHandler);
1117     }
1118
1119     inline int getPkcsIdList(
1120         CertSvcInstance &instance,
1121         CertSvcStringList *handler)
1122     {
1123       gchar **aliases;
1124       gsize i, naliases;
1125       std::vector<std::string> output;
1126       int result;
1127
1128       result = c_certsvc_pkcs12_aliases_load(&aliases, &naliases);
1129       if(result != CERTSVC_SUCCESS)
1130         return result;
1131       for(i = 0; i < naliases; i++)
1132         output.push_back(std::string(aliases[i]));
1133       c_certsvc_pkcs12_aliases_free(aliases);
1134
1135       int position = m_stringListCounter++;
1136       m_stringListMap[position] = output;
1137
1138       handler->privateHandler = position;
1139       handler->privateInstance = instance;
1140       return CERTSVC_SUCCESS;
1141     }
1142
1143     inline int pkcsHasPassword(
1144         CertSvcString filepath,
1145         int *has_password)
1146     {
1147       return c_certsvc_pkcs12_has_password(filepath.privateHandler, has_password);
1148     }
1149
1150     inline int getPkcsPrivateKey(
1151         CertSvcString pfxIdString,
1152         char **buffer,
1153         size_t *size)
1154     {
1155         return c_certsvc_pkcs12_private_key_load(pfxIdString.privateHandler, buffer, size);
1156     }
1157
1158     inline int getPkcsCertificateList(
1159         CertSvcInstance &instance,
1160         CertSvcString &pfxIdString,
1161         CertSvcCertificateList *handler)
1162     {
1163       gchar **certs;
1164       gsize i, ncerts;
1165       std::vector<CertificatePtr> certPtrVector;
1166       std::vector<int> listId;
1167       int result;
1168
1169       result = c_certsvc_pkcs12_load_certificates(pfxIdString.privateHandler, &certs, &ncerts);
1170       if(result != CERTSVC_SUCCESS)
1171         return result;
1172       for(i = 0; i < ncerts; i++) {
1173         ScopedCertCtx context(cert_svc_cert_context_init(), cert_svc_cert_context_final);
1174         if(cert_svc_load_file_to_context(context.get(), certs[i]) != CERT_SVC_ERR_NO_ERROR) {
1175           c_certsvc_pkcs12_free_certificates(certs);
1176           return CERTSVC_IO_ERROR;
1177         }
1178         else
1179           certPtrVector.push_back(CertificatePtr(new Certificate(*(context->certBuf))));
1180       }
1181       if(ncerts > 0)
1182           c_certsvc_pkcs12_free_certificates(certs);
1183
1184       FOREACH(it, certPtrVector) {
1185         listId.push_back(addCert(*it));
1186       }
1187
1188       int position = m_idListCounter++;
1189       m_idListMap[position] = listId;
1190
1191       handler->privateInstance = instance;
1192       handler->privateHandler = position;
1193
1194       return result;
1195     }
1196
1197     inline int pkcsDelete(CertSvcString pfxIdString)
1198     {
1199       return c_certsvc_pkcs12_delete(pfxIdString.privateHandler);
1200     }
1201
1202     inline int pkcsImportToStore(
1203         CertStoreType storeType,
1204         CertSvcString path,
1205         CertSvcString pass,
1206         CertSvcString pfxIdString)
1207     {
1208         return c_certsvc_pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
1209     }
1210
1211     inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
1212         CertSvcString gname,
1213         char **alias)
1214     {
1215         return c_certsvc_pkcs12_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
1216     }
1217
1218     inline int pkcsSetCertStatusToStore(CertStoreType storeType,
1219         int is_root_app,
1220         CertSvcString gname,
1221         CertStatus status)
1222     {
1223         return c_certsvc_pkcs12_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
1224     }
1225
1226     inline int pkcsGetCertStatusFromStore(
1227         CertStoreType storeType,
1228         CertSvcString gname,
1229         int *status)
1230     {
1231         return c_certsvc_pkcs12_get_certificate_status_from_store(storeType, gname.privateHandler, status);
1232     }
1233
1234     inline int getCertFromStore(CertSvcInstance instance,
1235         CertStoreType storeType,
1236         char *gname,
1237         CertSvcCertificate *certificate)
1238     {
1239             return certsvc_get_certificate(instance, storeType, gname, certificate);
1240     }
1241
1242     inline int freePkcsIdListFromStore(
1243         CertSvcStoreCertList** certList)
1244     {
1245         return c_certsvc_pkcs12_free_aliases_loaded_from_store(certList);
1246     }
1247
1248     inline int getPkcsIdListFromStore(
1249         CertStoreType storeType,
1250         int is_root_app,
1251         CertSvcStoreCertList** certList,
1252         int* length)
1253     {
1254         return c_certsvc_pkcs12_get_certificate_list_from_store(storeType, is_root_app, certList, length);
1255     }
1256
1257     inline int getPkcsIdEndUserListFromStore(
1258         CertStoreType storeType,
1259         CertSvcStoreCertList** certList,
1260         int* length)
1261     {
1262         return c_certsvc_pkcs12_get_end_user_certificate_list_from_store(storeType, certList, length);
1263     }
1264
1265     inline int getPkcsIdRootListFromStore(
1266         CertStoreType storeType,
1267         CertSvcStoreCertList** certList,
1268         int* length)
1269     {
1270         return c_certsvc_pkcs12_get_root_certificate_list_from_store(storeType, certList, length);
1271     }
1272
1273     inline int getPkcsPrivateKeyFromStore(
1274         CertStoreType storeType,
1275         CertSvcString gname,
1276         char **certBuffer,
1277         size_t *certSize)
1278     {
1279         return c_certsvc_pkcs12_private_key_load_from_store(storeType, gname.privateHandler, certBuffer, certSize);
1280     }
1281
1282     inline int getPkcsCertificateListFromStore(
1283         CertSvcInstance &instance,
1284         CertStoreType storeType,
1285         CertSvcString &pfxIdString,
1286         CertSvcCertificateList *handler)
1287     {
1288         char **certs;
1289         gsize i, ncerts;
1290         std::vector<CertificatePtr> certPtrVector;
1291         std::vector<int> listId;
1292         char *certBuffer = NULL;
1293         size_t certLength = 0;
1294         CertSvcString Alias;
1295         char* header = NULL;
1296         char* trailer = NULL;
1297         const char* headEnd = NULL;
1298         const char* tailEnd = NULL;
1299         int length = 0;
1300         int result;
1301
1302         result = c_certsvc_pkcs12_load_certificates_from_store(storeType, pfxIdString.privateHandler, &certs, &ncerts);
1303         if (result != CERTSVC_SUCCESS) {
1304             LogError("Unable to load certificates from store.");
1305             return result;
1306         }
1307
1308         for (i = 0; i < ncerts; i++) {
1309             Alias.privateHandler = certs[i];
1310             Alias.privateLength = strlen(certs[i]);
1311             result = certsvc_pkcs12_get_certificate_info_from_store(instance, storeType, Alias, &certBuffer, &certLength);
1312             if (result != CERTSVC_SUCCESS || !certBuffer) {
1313                 LogError("Failed to get certificate buffer.");
1314                 return CERTSVC_FAIL;
1315             }
1316
1317             header = strstr(certBuffer, START_CERT);
1318             headEnd = START_CERT;
1319             if (!header) {
1320                 // START_CERT not found. let's find START_TRUSTED.
1321                 header = strstr(certBuffer, START_TRUSTED);
1322                 headEnd = START_TRUSTED;
1323             }
1324
1325             if (header) {
1326                 // START_something found. let's find END_CERT first.
1327                 trailer = strstr(header, END_CERT);
1328                 tailEnd = END_CERT;
1329             }
1330
1331             if (!trailer) {
1332                 // END_CERT not found. let's find END_TRUSTED.
1333                 trailer = strstr(header, END_TRUSTED);
1334                 tailEnd = END_TRUSTED;
1335             }
1336
1337             if (!trailer) {
1338                 LogError("Failed the get the certificate.");
1339                 return CERTSVC_FAIL;
1340             }
1341
1342             length = ((1 + strlen(header)) - (strlen(headEnd) + strlen(tailEnd) + 1));
1343             std::string tmpBuffer(certBuffer);
1344             tmpBuffer = tmpBuffer.substr(strlen(headEnd),length);
1345             std::string binary(tmpBuffer.c_str(), length);
1346             Certificate::FormType formType = Certificate::FORM_BASE64;
1347             certPtrVector.push_back(CertificatePtr(new Certificate(binary, formType)));
1348             free(certBuffer);
1349             certBuffer = NULL;
1350         }
1351
1352         if (ncerts > 0)
1353             c_certsvc_pkcs12_free_certificates(certs);
1354
1355         FOREACH(it, certPtrVector) {
1356             listId.push_back(addCert(*it));
1357         }
1358
1359         int position = m_idListCounter++;
1360         m_idListMap[position] = listId;
1361
1362         handler->privateInstance = instance;
1363         handler->privateHandler = position;
1364
1365         return result;
1366     }
1367
1368     inline bool checkValidStoreType(CertStoreType storeType)
1369     {
1370         if (storeType >= VPN_STORE && storeType <= ALL_STORE)
1371             return true;
1372         else
1373             return false;
1374     }
1375
1376 private:
1377     int m_certificateCounter;
1378     std::map<int, CertificatePtr> m_certificateMap;
1379
1380     int m_idListCounter;
1381     std::map<int, std::vector<int> > m_idListMap;
1382
1383     int m_stringListCounter;
1384     std::map<int, std::vector<std::string> > m_stringListMap;
1385
1386     std::set<char *> m_allocatedStringSet;
1387         
1388 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
1389     CertSvcCrlCacheWrite m_crlWrite;
1390     CertSvcCrlCacheRead m_crlRead;
1391     CertSvcCrlFree m_crlFree;
1392 #endif
1393 };
1394
1395 inline CertSvcInstanceImpl *impl(CertSvcInstance instance) {
1396     return static_cast<CertSvcInstanceImpl*>(instance.privatePtr);
1397 }
1398
1399 } // namespace anonymous
1400
1401 int certsvc_instance_new(CertSvcInstance *instance) {
1402     static int init = 1;
1403     if (init) {
1404         SSL_library_init();     // required by message verification
1405         OpenSSL_add_all_digests();
1406         init = 0;
1407     }
1408     try {
1409         instance->privatePtr =
1410             reinterpret_cast<void*>(new CertSvcInstanceImpl);
1411         if (instance->privatePtr)
1412             return CERTSVC_SUCCESS;
1413     } catch (std::bad_alloc &) {
1414         return CERTSVC_BAD_ALLOC;
1415     } catch (...) {}
1416     return CERTSVC_FAIL;
1417 }
1418
1419 void certsvc_instance_reset(CertSvcInstance instance) {
1420     impl(instance)->reset();
1421 }
1422
1423 void certsvc_instance_free(CertSvcInstance instance) {
1424     delete impl(instance);
1425 }
1426
1427 int certsvc_certificate_new_from_file(
1428         CertSvcInstance instance,
1429         const char *location,
1430         CertSvcCertificate *certificate)
1431 {
1432     try {
1433         ScopedCertCtx context(cert_svc_cert_context_init(),
1434                               cert_svc_cert_context_final);
1435
1436         int result = cert_svc_load_file_to_context(context.get(), location);
1437
1438         switch(result) {
1439             case CERT_SVC_ERR_INVALID_PARAMETER: return CERTSVC_WRONG_ARGUMENT;
1440             case CERT_SVC_ERR_INVALID_OPERATION: return CERTSVC_FAIL;
1441             case CERT_SVC_ERR_MEMORY_ALLOCATION: return CERTSVC_BAD_ALLOC;
1442             default:;
1443         }
1444
1445         CertificatePtr cert(new Certificate(*(context->certBuf)));
1446
1447         certificate->privateInstance = instance;
1448         certificate->privateHandler = impl(instance)->addCert(cert);
1449
1450         return CERTSVC_SUCCESS;
1451     // TODO support for std exceptions
1452     } catch (std::bad_alloc &) {
1453         return CERTSVC_BAD_ALLOC;
1454     } catch (...) {}
1455     return CERTSVC_FAIL;
1456 }
1457
1458 int certsvc_certificate_new_from_memory(
1459         CertSvcInstance instance,
1460         const unsigned char *memory,
1461         int len,
1462         CertSvcCertificateForm form,
1463         CertSvcCertificate *certificate)
1464 {
1465     try {
1466         Certificate::FormType formType;
1467         std::string binary((char*)memory, len);
1468
1469         if (CERTSVC_FORM_DER == form) {
1470             formType = Certificate::FORM_DER;
1471         } else {
1472             formType = Certificate::FORM_BASE64;
1473         }
1474
1475         CertificatePtr cert(new Certificate(binary, formType));
1476
1477         certificate->privateInstance = instance;
1478         certificate->privateHandler = impl(instance)->addCert(cert);
1479         return CERTSVC_SUCCESS;
1480     } catch (std::bad_alloc &) {
1481         return CERTSVC_BAD_ALLOC;
1482     } catch (...) {}
1483     return CERTSVC_FAIL;
1484 }
1485
1486 void certsvc_certificate_free(CertSvcCertificate certificate)
1487 {
1488         if (certificate.privateHandler != 0)
1489                 impl(certificate.privateInstance)->removeCert(certificate);
1490 }
1491
1492 int certsvc_certificate_save_file(
1493         CertSvcCertificate certificate,
1494         const char *location)
1495 {
1496     return impl(certificate.privateInstance)->saveToFile(certificate, location);
1497 }
1498
1499 int certsvc_certificate_search(
1500         CertSvcInstance instance,
1501         CertSvcCertificateField field,
1502         const char *value,
1503         CertSvcCertificateList *handler)
1504 {
1505     try {
1506         return impl(instance)->certificateSearch(instance, field, value, handler);
1507     } catch (std::bad_alloc &) {
1508         return CERTSVC_BAD_ALLOC;
1509     } catch (...) {}
1510     return CERTSVC_FAIL;
1511 }
1512
1513 int certsvc_certificate_list_get_one(
1514         CertSvcCertificateList handler,
1515         int position,
1516         CertSvcCertificate *certificate)
1517 {
1518     return impl(handler.privateInstance)->
1519         getCertFromList(handler,position, certificate);
1520 }
1521
1522 int certsvc_certificate_list_get_length(
1523         CertSvcCertificateList handler,
1524         int *size)
1525 {
1526     return impl(handler.privateInstance)->getCertListLen(handler, size);
1527 }
1528
1529 void certsvc_certificate_list_free(CertSvcCertificateList handler)
1530 {
1531     impl(handler.privateInstance)->removeCertList(handler);
1532 }
1533
1534 int certsvc_certificate_is_signed_by(
1535         CertSvcCertificate child,
1536         CertSvcCertificate parent,
1537         int *status)
1538 {
1539     if (child.privateInstance.privatePtr == parent.privateInstance.privatePtr) {
1540         return impl(child.privateInstance)->isSignedBy(child, parent, status);
1541     }
1542     return CERTSVC_WRONG_ARGUMENT;
1543 }
1544
1545 int certsvc_certificate_get_string_field(
1546         CertSvcCertificate certificate,
1547         CertSvcCertificateField field,
1548         CertSvcString *buffer)
1549 {
1550     try {
1551         return impl(certificate.privateInstance)->getField(certificate, field, buffer);
1552     } catch (std::bad_alloc &) {
1553         return CERTSVC_BAD_ALLOC;
1554     } catch (...) {}
1555     return CERTSVC_FAIL;
1556 }
1557
1558 int certsvc_certificate_get_not_after(
1559         CertSvcCertificate certificate,
1560         time_t *result)
1561 {
1562     try {
1563         return impl(certificate.privateInstance)->getNotAfter(certificate, result);
1564     } catch(...) {}
1565     return CERTSVC_FAIL;
1566 }
1567
1568 int certsvc_certificate_get_not_before(
1569         CertSvcCertificate certificate,
1570         time_t *result)
1571 {
1572     try {
1573         return impl(certificate.privateInstance)->getNotBefore(certificate, result);
1574     } catch(...) {}
1575     return CERTSVC_FAIL;
1576 }
1577
1578 int certsvc_certificate_is_root_ca(CertSvcCertificate certificate, int *status)
1579 {
1580     return impl(certificate.privateInstance)->isRootCA(certificate, status);
1581 }
1582
1583 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
1584 int certsvc_certificate_get_crl_distribution_points(
1585         CertSvcCertificate certificate,
1586         CertSvcStringList *handler)
1587 {
1588     try {
1589         return impl(certificate.privateInstance)->getCrl(certificate, handler);
1590     } catch (...) {}
1591     return CERTSVC_FAIL;
1592 }
1593 #endif
1594
1595 int certsvc_string_list_get_one(
1596         CertSvcStringList handler,
1597         int position,
1598         CertSvcString *buffer)
1599 {
1600     try {
1601         return impl(handler.privateInstance)->getStringFromList(handler, position, buffer);
1602     } catch (std::bad_alloc &) {
1603         return CERTSVC_BAD_ALLOC;
1604     } catch (...) {}
1605     return CERTSVC_FAIL;
1606 }
1607
1608 int certsvc_string_list_get_length(
1609         CertSvcStringList handler,
1610         int *size)
1611 {
1612     return impl(handler.privateInstance)->getStringListLen(handler, size);
1613 }
1614
1615 void certsvc_string_list_free(CertSvcStringList handler)
1616 {
1617         if (handler.privateHandler != 0)
1618         {
1619                 impl(handler.privateInstance)->removeStringList(handler);
1620                 handler.privateHandler = 0;
1621         }
1622 }
1623
1624 void certsvc_string_free(CertSvcString string)
1625 {
1626         if (string.privateHandler)
1627                 impl(string.privateInstance)->removeString(string);
1628 }
1629
1630 void certsvc_string_to_cstring(
1631         CertSvcString string,
1632         const char **buffer,
1633         int *len)
1634 {
1635     if (buffer) {
1636         *buffer = string.privateHandler;
1637     }
1638     if (len) {
1639         *len = string.privateLength;
1640     }
1641 }
1642
1643 int certsvc_certificate_chain_sort(
1644         CertSvcCertificate *certificate_array,
1645         int size)
1646 {
1647     try {
1648         if (!certificate_array) {
1649             return CERTSVC_WRONG_ARGUMENT;
1650         }
1651         return impl(certificate_array[0].privateInstance)->
1652             sortCollection(certificate_array, size);
1653     } catch (std::bad_alloc &) {
1654         return CERTSVC_BAD_ALLOC;
1655     } catch (...) {}
1656     return CERTSVC_FAIL;
1657 }
1658
1659 int certsvc_certificate_dup_x509(CertSvcCertificate certificate, X509 **cert)
1660 {
1661     try {
1662         return impl(certificate.privateInstance)->getX509Copy(certificate, cert);
1663     } catch (...) {}
1664     return CERTSVC_FAIL;
1665 }
1666
1667 void certsvc_certificate_free_x509(X509 *x509)
1668 {
1669         if (x509)
1670                 X509_free(x509);
1671 }
1672
1673 int certsvc_pkcs12_dup_evp_pkey(
1674     CertSvcInstance instance,
1675     CertSvcString alias,
1676     EVP_PKEY** pkey)
1677 {
1678     char *buffer;
1679     size_t size;
1680
1681     int result = certsvc_pkcs12_private_key_dup(
1682         instance,
1683         alias,
1684         &buffer,
1685         &size);
1686
1687     if (result != CERTSVC_SUCCESS) {
1688         LogError("Error in certsvc_pkcs12_private_key_dup");
1689         return result;
1690     }
1691
1692     BIO *b = BIO_new(BIO_s_mem());
1693
1694     if ((int)size != BIO_write(b, buffer, size)) {
1695         LogError("Error in BIO_write");
1696         BIO_free_all(b);
1697         certsvc_pkcs12_private_key_free(buffer);
1698         return CERTSVC_FAIL;
1699     }
1700
1701     certsvc_pkcs12_private_key_free(buffer);
1702
1703     *pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
1704
1705     BIO_free_all(b);
1706
1707     if (*pkey) {
1708         return CERTSVC_SUCCESS;
1709     }
1710
1711     LogError("Result is null. Openssl REASON code is : " << ERR_GET_REASON(ERR_peek_last_error()));
1712
1713     return CERTSVC_FAIL;
1714 }
1715
1716 void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey)
1717 {
1718     EVP_PKEY_free(pkey);
1719 }
1720
1721 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
1722 int certsvc_ocsp_check(
1723     CertSvcCertificate *chain,
1724     int chain_size,
1725     CertSvcCertificate *trusted,
1726     int trusted_size,
1727     const char *url,
1728     int *status)
1729 {
1730     try {
1731         if (!chain || !trusted) {
1732             return CERTSVC_WRONG_ARGUMENT;
1733         }
1734         return impl(chain[0].privateInstance)->
1735             ocspCheck(chain,
1736                       chain_size,
1737                       trusted,
1738                       trusted_size,
1739                       url,
1740                       status);
1741     } catch (std::bad_alloc &) {
1742         return CERTSVC_BAD_ALLOC;
1743     } catch (...) {}
1744     return CERTSVC_FAIL;
1745 }
1746 #endif
1747
1748 int certsvc_message_verify(
1749     CertSvcCertificate certificate,
1750     CertSvcString message,
1751     CertSvcString signature,
1752     const char *algorithm,
1753     int *status)
1754 {
1755     try {
1756         return impl(certificate.privateInstance)->verify(
1757             certificate,
1758             message,
1759             signature,
1760             algorithm,
1761             status);
1762     } catch(...) {}
1763     return CERTSVC_FAIL;
1764 }
1765
1766 int certsvc_base64_encode(CertSvcString message, CertSvcString *base64)
1767 {
1768     try {
1769         return impl(message.privateInstance)->base64Encode(message, base64);
1770     } catch(...) {}
1771     return CERTSVC_FAIL;
1772 }
1773
1774 int certsvc_base64_decode(CertSvcString base64, CertSvcString *message)
1775 {
1776     try {
1777         return impl(base64.privateInstance)->base64Decode(base64, message);
1778     } catch(...) {}
1779     return CERTSVC_FAIL;
1780 }
1781
1782 int certsvc_string_new(
1783     CertSvcInstance instance,
1784     const char *url,
1785     int size,
1786     CertSvcString *output)
1787 {
1788     try {
1789         return impl(instance)->stringNew(instance, url, size, output);
1790     } catch (...) {}
1791     return CERTSVC_FAIL;
1792 }
1793
1794 int certsvc_string_not_managed(
1795     CertSvcInstance instance,
1796     const char *url,
1797     int size,
1798     CertSvcString *output)
1799 {
1800     if (!output) {
1801         return CERTSVC_WRONG_ARGUMENT;
1802     }
1803     output->privateHandler = const_cast<char*>(url);
1804     output->privateLength = size;
1805     output->privateInstance = instance;
1806     return CERTSVC_SUCCESS;
1807 }
1808
1809 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
1810 void certsvc_crl_cache_functions(
1811     CertSvcInstance instance,
1812     CertSvcCrlCacheWrite writePtr,
1813     CertSvcCrlCacheRead readPtr,
1814     CertSvcCrlFree freePtr)
1815 {
1816     impl(instance)->setCRLFunction(writePtr, readPtr, freePtr);
1817 }
1818
1819 int certsvc_crl_check(
1820     CertSvcCertificate certificate,
1821     CertSvcCertificate *trustedStore,
1822     int storeSize,
1823     int force,
1824     int *status,
1825     void *userParam)
1826 {
1827     try {
1828         return impl(certificate.privateInstance)->crlCheck(
1829             certificate,
1830             trustedStore,
1831             storeSize,
1832             force,
1833             status,
1834             userParam);
1835     } catch (...) {}
1836     return CERTSVC_FAIL;
1837 }
1838 #endif
1839
1840 int certsvc_certificate_verify(
1841     CertSvcCertificate certificate,
1842     CertSvcCertificate *trusted,
1843     int trustedSize,
1844     CertSvcCertificate *untrusted,
1845     int untrustedSize,
1846     int *status)
1847 {
1848     try {
1849         int check_caflag_false = 0;
1850         return impl(certificate.privateInstance)->certificateVerify(
1851             certificate,
1852             trusted,
1853             trustedSize,
1854             untrusted,
1855             untrustedSize,
1856             check_caflag_false,
1857             status);
1858     } catch (...) {}
1859     return CERTSVC_FAIL;
1860 }
1861
1862 int certsvc_certificate_verify_with_caflag(
1863     CertSvcCertificate certificate,
1864     CertSvcCertificate *trusted,
1865     int trustedSize,
1866     CertSvcCertificate *untrusted,
1867     int untrustedSize,
1868     int *status)
1869 {
1870     try {
1871         int check_caflag_true = 1;
1872         return impl(certificate.privateInstance)->certificateVerify(
1873             certificate,
1874             trusted,
1875             trustedSize,
1876             untrusted,
1877             untrustedSize,
1878             check_caflag_true,
1879             status);
1880     } catch (...) {}
1881     return CERTSVC_FAIL;
1882 }
1883
1884 int certsvc_certificate_get_visibility(CertSvcCertificate certificate, int* visibility)
1885 {
1886     try {
1887         return impl(certificate.privateInstance)->getVisibility(certificate, visibility);
1888     } catch (...)
1889         {
1890                 LogError("exception occur");
1891         }
1892     return CERTSVC_FAIL;
1893 }
1894
1895 int certsvc_pkcs12_alias_exists(CertSvcInstance instance,
1896     CertSvcString pfxIdString,
1897     int *is_unique)
1898 {
1899     try {
1900       return impl(instance)->pkcsNameIsUnique(pfxIdString, is_unique);
1901     } catch (...) {}
1902     return CERTSVC_FAIL;
1903 }
1904
1905 int certsvc_pkcs12_import_from_file(CertSvcInstance instance,
1906     CertSvcString path,
1907     CertSvcString password,
1908     CertSvcString pfxIdString)
1909 {
1910     try {
1911       return impl(instance)->pkcsImport(path, password, pfxIdString);
1912     } catch (...) {}
1913     return CERTSVC_FAIL;
1914 }
1915
1916 int certsvc_get_certificate(CertSvcInstance instance,
1917     CertStoreType storeType,
1918     char *gname,
1919     CertSvcCertificate *certificate)
1920 {
1921     int result = CERTSVC_SUCCESS;
1922     char* certBuffer = NULL;
1923     std::string fileName;
1924     size_t length = 0;
1925     FILE* fp_write = NULL;
1926     BIO* pBio = NULL;
1927     X509* x509Struct = NULL;
1928
1929     try {
1930         result = c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname, &certBuffer, &length);
1931         if (result != CERTSVC_SUCCESS) {
1932             LogError("Failed to get certificate buffer from store.");
1933             return result;
1934         }
1935
1936         pBio = BIO_new(BIO_s_mem());
1937         if (pBio == NULL) {
1938             LogError("Failed to allocate memory.");
1939             result = CERTSVC_BAD_ALLOC;
1940         }
1941
1942         length = BIO_write(pBio, (const void*) certBuffer, length);
1943         if (length < 1) {
1944             LogError("Failed to load cert into bio.");
1945             result = CERTSVC_BAD_ALLOC;
1946         }
1947
1948         x509Struct = PEM_read_bio_X509(pBio, NULL, 0, NULL);
1949         if (x509Struct != NULL) {
1950             CertificatePtr cert(new Certificate(x509Struct));
1951             certificate->privateInstance = instance;
1952             certificate->privateHandler = impl(instance)->addCert(cert);
1953             if (certBuffer!=NULL) free(certBuffer);
1954         }
1955         else {
1956             fileName.append(CERTSVC_PKCS12_STORAGE_DIR);
1957             fileName.append(gname);
1958             if (!(fp_write = fopen(fileName.c_str(), "w"))) {
1959                 LogError("Failed to open the file for writing, [" << fileName << "].");
1960                 result = CERTSVC_FAIL;
1961                 goto error;
1962             }
1963
1964             if (fwrite(certBuffer, sizeof(char), (size_t)length, fp_write) != (size_t)length) {
1965                 LogError("Fail to write certificate.");
1966                 result = CERTSVC_FAIL;
1967                 goto error;
1968             }
1969
1970             fclose(fp_write);
1971             result = certsvc_certificate_new_from_file(instance, fileName.c_str(), certificate);
1972             if (result != CERTSVC_SUCCESS) {
1973                 LogError("Failed to construct certificate from buffer.");
1974                 goto error;
1975             }
1976             unlink(fileName.c_str());
1977         }
1978         result = CERTSVC_SUCCESS;
1979     } catch (std::bad_alloc &) {
1980         return CERTSVC_BAD_ALLOC;
1981     } catch (...) {}
1982
1983 error:
1984     if (x509Struct) X509_free(x509Struct);
1985     if (pBio) BIO_free(pBio);
1986     return result;
1987 }
1988
1989 int certsvc_pkcs12_check_alias_exists_in_store(CertSvcInstance instance,
1990     CertStoreType storeType,
1991     CertSvcString pfxIdString,
1992     int *is_unique)
1993 {
1994     if (pfxIdString.privateHandler == NULL || pfxIdString.privateLength<=0) {
1995         LogError("Invalid input parameter.");
1996         return CERTSVC_WRONG_ARGUMENT;
1997     }
1998
1999     try {
2000         if (!impl(instance)->checkValidStoreType(storeType)) {
2001             LogError("Invalid input parameter.");
2002             return CERTSVC_INVALID_STORE_TYPE;
2003         }
2004
2005         return impl(instance)->pkcsNameIsUniqueInStore(storeType, pfxIdString, is_unique);
2006     } catch (...) {}
2007     return CERTSVC_FAIL;
2008 }
2009
2010 int certsvc_pkcs12_free_certificate_list_loaded_from_store(CertSvcInstance instance,
2011     CertSvcStoreCertList** certList)
2012 {
2013     if (*certList == NULL) {
2014         LogError("Invalid input parameter.");
2015         return CERTSVC_WRONG_ARGUMENT;
2016     }
2017
2018     try {
2019         return impl(instance)->freePkcsIdListFromStore(certList);
2020     } catch (...) {}
2021     return CERTSVC_FAIL;
2022 }
2023
2024 int certsvc_pkcs12_get_certificate_list_from_store(CertSvcInstance instance,
2025         CertStoreType storeType,
2026     int is_root_app,
2027         CertSvcStoreCertList** certList,
2028         int* length)
2029 {
2030     if (*certList != NULL) {
2031         LogError("Invalid input parameter.");
2032         return CERTSVC_WRONG_ARGUMENT;
2033     }
2034
2035     try {
2036         if (!impl(instance)->checkValidStoreType(storeType)) {
2037             LogError("Invalid input parameter.");
2038             return CERTSVC_INVALID_STORE_TYPE;
2039         }
2040
2041         return impl(instance)->getPkcsIdListFromStore(storeType, is_root_app, certList, length);
2042     } catch (...) {}
2043
2044     return CERTSVC_FAIL;
2045 }
2046
2047 int certsvc_pkcs12_get_end_user_certificate_list_from_store(CertSvcInstance instance,
2048         CertStoreType storeType,
2049         CertSvcStoreCertList** certList,
2050         int* length)
2051 {
2052     if (*certList != NULL) {
2053         LogError("Invalid input parameter.");
2054         return CERTSVC_WRONG_ARGUMENT;
2055     }
2056
2057     try {
2058         if (!impl(instance)->checkValidStoreType(storeType)) {
2059             LogError("Invalid input parameter.");
2060             return CERTSVC_INVALID_STORE_TYPE;
2061         }
2062
2063         return impl(instance)->getPkcsIdEndUserListFromStore(storeType, certList, length);
2064     } catch (...) {}
2065     return CERTSVC_FAIL;
2066 }
2067
2068 int certsvc_pkcs12_get_root_certificate_list_from_store(CertSvcInstance instance,
2069         CertStoreType storeType,
2070         CertSvcStoreCertList** certList,
2071         int* length)
2072 {
2073     if (*certList != NULL) {
2074         LogError("Invalid input parameter.");
2075         return CERTSVC_WRONG_ARGUMENT;
2076     }
2077
2078     try {
2079         if (!impl(instance)->checkValidStoreType(storeType)) {
2080             LogError("Invalid input parameter.");
2081             return CERTSVC_INVALID_STORE_TYPE;
2082         }
2083
2084         return impl(instance)->getPkcsIdRootListFromStore(storeType, certList, length);
2085     } catch (...) {}
2086     return CERTSVC_FAIL;
2087 }
2088
2089 int certsvc_pkcs12_get_certificate_info_from_store(CertSvcInstance instance,
2090     CertStoreType storeType,
2091     CertSvcString gname,
2092     char**  certBuffer,
2093     size_t* certSize)
2094 {
2095     if (*certBuffer != NULL) {
2096         LogError("Invalid input parameter.");
2097         return CERTSVC_WRONG_ARGUMENT;
2098     }
2099
2100     try {
2101         if (!impl(instance)->checkValidStoreType(storeType)) {
2102             LogError("Invalid input parameter.");
2103             return CERTSVC_INVALID_STORE_TYPE;
2104         }
2105
2106         return impl(instance)->getCertDetailFromStore(storeType, gname, certBuffer, certSize);
2107     } catch (...) {}
2108     return CERTSVC_FAIL;
2109 }
2110
2111 int certsvc_pkcs12_delete_certificate_from_store(CertSvcInstance instance,
2112     CertStoreType storeType,
2113     CertSvcString gname)
2114 {
2115      try {
2116          if (!impl(instance)->checkValidStoreType(storeType)) {
2117              LogError("Invalid input parameter.");
2118              return CERTSVC_INVALID_STORE_TYPE;
2119          }
2120          return impl(instance)->pkcsDeleteCertFromStore(storeType, gname);
2121      } catch (...) {}
2122      return CERTSVC_FAIL;
2123 }
2124
2125 int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
2126     CertStoreType storeType,
2127     CertSvcString path,
2128     CertSvcString password,
2129     CertSvcString pfxIdString)
2130 {
2131     try {
2132         if (path.privateHandler != NULL) {
2133         if (!impl(instance)->checkValidStoreType(storeType)) {
2134             LogError("Invalid input parameter.");
2135             return CERTSVC_INVALID_STORE_TYPE;
2136         }
2137         return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
2138     }
2139     else
2140         return CERTSVC_FAIL;
2141     } catch (...) {}
2142     return CERTSVC_FAIL;
2143 }
2144
2145 int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
2146     CertStoreType storeType,
2147     CertSvcString gname,
2148     char **alias)
2149 {
2150     if (gname.privateHandler == NULL || gname.privateLength<=0) {
2151         LogError("Invalid input parameter.");
2152         return CERTSVC_WRONG_ARGUMENT;
2153     }
2154
2155     try {
2156         if (!impl(instance)->checkValidStoreType(storeType)) {
2157             LogError("Invalid input parameter.");
2158             return CERTSVC_INVALID_STORE_TYPE;
2159         }
2160         return impl(instance)->pkcsGetAliasNameForCertInStore(storeType, gname, alias);
2161     } catch (...) {}
2162     return CERTSVC_FAIL;
2163 }
2164
2165 int certsvc_pkcs12_set_certificate_status_to_store(CertSvcInstance instance,
2166     CertStoreType storeType,
2167     int is_root_app,
2168     CertSvcString gname,
2169     CertStatus status)
2170 {
2171     try {
2172         if (!impl(instance)->checkValidStoreType(storeType)) {
2173             LogError("Invalid input parameter.");
2174             return CERTSVC_INVALID_STORE_TYPE;
2175         }
2176         return impl(instance)->pkcsSetCertStatusToStore(storeType, is_root_app, gname, status);
2177     } catch (...) {}
2178     return CERTSVC_FAIL;
2179 }
2180
2181 int certsvc_pkcs12_get_certificate_status_from_store(
2182     CertSvcInstance instance,
2183     CertStoreType storeType,
2184     CertSvcString gname,
2185     int *status)
2186 {
2187     try {
2188         if (!impl(instance)->checkValidStoreType(storeType)) {
2189             LogError("Invalid input parameter.");
2190             return CERTSVC_INVALID_STORE_TYPE;
2191         }
2192         return impl(instance)->pkcsGetCertStatusFromStore(storeType, gname, status);
2193     } catch (...) {}
2194     return CERTSVC_FAIL;
2195 }
2196
2197 int certsvc_pkcs12_get_certificate_from_store(CertSvcInstance instance,
2198     CertStoreType storeType,
2199     char *gname,
2200     CertSvcCertificate *certificate)
2201 {
2202     try {
2203         if (!impl(instance)->checkValidStoreType(storeType)) {
2204             LogError("Invalid input parameter.");
2205             return CERTSVC_INVALID_STORE_TYPE;
2206         }
2207         return impl(instance)->getCertFromStore(instance, storeType, gname, certificate);
2208     } catch (...) {}
2209     return CERTSVC_FAIL;
2210 }
2211
2212 int certsvc_pkcs12_load_certificate_list_from_store(
2213     CertSvcInstance instance,
2214     CertStoreType storeType,
2215     CertSvcString pfxIdString,
2216     CertSvcCertificateList *certificateList)
2217 {
2218     try {
2219         if (!impl(instance)->checkValidStoreType(storeType)) {
2220             LogError("Invalid input parameter.");
2221             return CERTSVC_INVALID_STORE_TYPE;
2222         }
2223         return impl(instance)->getPkcsCertificateListFromStore(instance, storeType, pfxIdString, certificateList);
2224     } catch (...) {}
2225     return CERTSVC_FAIL;
2226 }
2227
2228 int certsvc_pkcs12_private_key_dup_from_store(
2229     CertSvcInstance instance,
2230     CertStoreType storeType,
2231     CertSvcString gname,
2232     char **certBuffer,
2233     size_t *certSize)
2234 {
2235     try {
2236         if (!impl(instance)->checkValidStoreType(storeType)) {
2237             LogError("Invalid input parameter.");
2238             return CERTSVC_INVALID_STORE_TYPE;
2239         }
2240         return impl(instance)->getPkcsPrivateKeyFromStore(storeType, gname, certBuffer, certSize);
2241     } catch (...) {}
2242     return CERTSVC_FAIL;
2243 }
2244
2245 int certsvc_pkcs12_dup_evp_pkey_from_store(
2246     CertSvcInstance instance,
2247     CertStoreType storeType,
2248     CertSvcString gname,
2249     EVP_PKEY** pkey)
2250 {
2251     char *buffer = NULL;
2252     size_t size;
2253
2254     int result = certsvc_pkcs12_private_key_dup_from_store(instance, storeType, gname, &buffer, &size);
2255     if (result != CERTSVC_SUCCESS) {
2256         LogError("Error in certsvc_pkcs12_private_key_dup");
2257         return result;
2258     }
2259
2260     BIO *b = BIO_new(BIO_s_mem());
2261     if ((int)size != BIO_write(b, buffer, size)) {
2262          LogError("Error in BIO_write");
2263          BIO_free_all(b);
2264          certsvc_pkcs12_private_key_free(buffer);
2265          return CERTSVC_FAIL;
2266     }
2267
2268     certsvc_pkcs12_private_key_free(buffer);
2269     *pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
2270     BIO_free_all(b);
2271     if (*pkey)
2272         return CERTSVC_SUCCESS;
2273
2274     LogError("Result is null. Openssl REASON code is : " << ERR_GET_REASON(ERR_peek_last_error()));
2275     return CERTSVC_FAIL;
2276 }
2277
2278 int certsvc_pkcs12_get_id_list(
2279     CertSvcInstance instance,
2280     CertSvcStringList *pfxIdStringList)
2281 {
2282     try {
2283         return impl(instance)->getPkcsIdList(
2284             instance,
2285             pfxIdStringList);
2286     } catch (...) {}
2287     return CERTSVC_FAIL;
2288 }
2289
2290 int certsvc_pkcs12_has_password(
2291     CertSvcInstance instance,
2292     CertSvcString filepath,
2293     int *has_password)
2294 {
2295     try {
2296         return impl(instance)->pkcsHasPassword(
2297             filepath,
2298             has_password);
2299     } catch (...) {}
2300     return CERTSVC_FAIL;
2301 }
2302
2303 int certsvc_pkcs12_load_certificate_list(
2304     CertSvcInstance instance,
2305     CertSvcString pfxIdString,
2306     CertSvcCertificateList *certificateList)
2307 {
2308     try {
2309         return impl(instance)->getPkcsCertificateList(
2310             instance,
2311             pfxIdString,
2312             certificateList);
2313     } catch (...) {}
2314     return CERTSVC_FAIL;
2315 }
2316
2317 int certsvc_pkcs12_private_key_dup(
2318     CertSvcInstance instance,
2319     CertSvcString pfxIdString,
2320     char **buffer,
2321     size_t *size)
2322 {
2323     try {
2324         return impl(instance)->getPkcsPrivateKey(pfxIdString, buffer, size);
2325     } catch (...) {}
2326     return CERTSVC_FAIL;
2327 }
2328
2329 void certsvc_pkcs12_private_key_free(
2330     char *buffer)
2331 {
2332     free(buffer);
2333 }
2334
2335 int certsvc_pkcs12_delete(
2336     CertSvcInstance instance,
2337     CertSvcString pfxIdString)
2338 {
2339     try {
2340         return impl(instance)->pkcsDelete(pfxIdString);
2341     } catch (...) {}
2342     return CERTSVC_FAIL;
2343 }
2344