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