2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @author Jacek Migacz (j.migacz@samsung.com)
21 * @brief This is part of C-api proposition for cert-svc.
24 #include <sys/types.h>
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>
46 #include <dpl/log/log.h>
48 #include <cert-svc/cinstance.h>
49 #include <cert-svc/ccert.h>
50 #include <cert-svc/cpkcs12.h>
51 #include <cert-svc/cprimitives.h>
53 #include <vcore/Base64.h>
54 #include <vcore/Certificate.h>
55 #include <vcore/CertificateCollection.h>
56 #include <vcore/pkcs12.h>
58 #include <libxml/parser.h>
59 #include <libxml/tree.h>
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-----"
66 using namespace ValidationCore;
70 typedef std::unique_ptr<CERT_CONTEXT, std::function<int(CERT_CONTEXT*)> > ScopedCertCtx;
72 class CertSvcInstanceImpl {
75 : m_certificateCounter(0)
77 , m_stringListCounter(0)
80 ~CertSvcInstanceImpl(){
81 auto it = m_allocatedStringSet.begin();
82 for (; it != m_allocatedStringSet.end(); ++it)
87 m_certificateCounter = 0;
88 m_certificateMap.clear();
91 m_stringListCounter = 0;
92 m_stringListMap.clear();
94 auto it = m_allocatedStringSet.begin();
95 for (; it != m_allocatedStringSet.end(); ++it)
98 m_allocatedStringSet.clear();
101 inline size_t addCert(const CertificatePtr &cert) {
102 m_certificateMap[m_certificateCounter] = cert;
103 return m_certificateCounter++;
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);
113 inline int getCertFromList(
114 const CertSvcCertificateList &handler,
116 CertSvcCertificate *certificate)
118 auto iter = m_idListMap.find(handler.privateHandler);
119 if (iter == m_idListMap.end()) {
120 return CERTSVC_WRONG_ARGUMENT;
122 if (position >= iter->second.size()) {
123 return CERTSVC_WRONG_ARGUMENT;
125 certificate->privateInstance = handler.privateInstance;
126 certificate->privateHandler = (iter->second)[position];
127 return CERTSVC_SUCCESS;
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;
135 *len = (iter->second).size();
136 return CERTSVC_SUCCESS;
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);
145 inline void removeCertListAll(const CertSvcCertificateList &handler) {
146 auto iter = m_idListMap.find(handler.privateHandler);
147 if (iter == m_idListMap.end())
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())
155 m_certificateMap.erase(iterCert);
158 m_idListMap.erase(iter);
161 inline int isSignedBy(const CertSvcCertificate &child,
162 const CertSvcCertificate &parent,
165 auto citer = m_certificateMap.find(child.privateHandler);
166 if (citer == m_certificateMap.end()) {
167 return CERTSVC_WRONG_ARGUMENT;
169 auto piter = m_certificateMap.find(parent.privateHandler);
170 if (piter == m_certificateMap.end()) {
171 return CERTSVC_WRONG_ARGUMENT;
174 if (citer->second->isSignedBy(piter->second)) {
175 *status = CERTSVC_TRUE;
177 *status = CERTSVC_FALSE;
179 return CERTSVC_SUCCESS;
182 inline int getField(const CertSvcCertificate &cert,
183 CertSvcCertificateField field,
184 CertSvcString *buffer)
186 auto iter = m_certificateMap.find(cert.privateHandler);
187 if (iter == m_certificateMap.end()) {
188 return CERTSVC_WRONG_ARGUMENT;
191 auto certPtr = iter->second;
194 case CERTSVC_SUBJECT:
195 result = certPtr->getOneLine();
198 result = certPtr->getOneLine(Certificate::FIELD_ISSUER);
200 case CERTSVC_SUBJECT_COMMON_NAME:
201 result = certPtr->getCommonName();
203 case CERTSVC_SUBJECT_COUNTRY_NAME:
204 result = certPtr->getCountryName();
206 case CERTSVC_SUBJECT_STATE_NAME:
207 result = certPtr->getStateOrProvinceName();
209 case CERTSVC_SUBJECT_ORGANIZATION_NAME:
210 result = certPtr->getOrganizationName();
212 case CERTSVC_SUBJECT_ORGANIZATION_UNIT_NAME:
213 result = certPtr->getOrganizationalUnitName();
215 case CERTSVC_SUBJECT_EMAIL_ADDRESS:
216 result = certPtr->getEmailAddres();
218 case CERTSVC_ISSUER_COMMON_NAME:
219 result = certPtr->getCommonName(Certificate::FIELD_ISSUER);
221 case CERTSVC_ISSUER_STATE_NAME:
222 result = certPtr->getStateOrProvinceName(Certificate::FIELD_ISSUER);
224 case CERTSVC_ISSUER_ORGANIZATION_NAME:
225 result = certPtr->getOrganizationName(Certificate::FIELD_ISSUER);
227 case CERTSVC_ISSUER_ORGANIZATION_UNIT_NAME:
228 result = certPtr->getOrganizationalUnitName(Certificate::FIELD_ISSUER);
230 case CERTSVC_VERSION:
232 std::stringstream stream;
233 stream << (certPtr->getVersion()+1);
234 result = stream.str();
237 case CERTSVC_SERIAL_NUMBER:
238 result = certPtr->getSerialNumberString();
240 case CERTSVC_KEY_USAGE:
241 result = certPtr->getKeyUsageString();
244 result = certPtr->getPublicKeyString();
246 case CERTSVC_SIGNATURE_ALGORITHM:
247 result = certPtr->getSignatureAlgorithmString();
253 if (result.empty()) {
254 buffer->privateHandler = NULL;
255 buffer->privateLength = 0;
256 buffer->privateInstance = cert.privateInstance;
257 return CERTSVC_SUCCESS;
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;
268 strncpy(cstring, result.c_str(), result.size() + 1);
270 buffer->privateHandler = cstring;
271 buffer->privateLength = result.size();
272 buffer->privateInstance = cert.privateInstance;
274 m_allocatedStringSet.insert(cstring);
276 return CERTSVC_SUCCESS;
279 inline int getNotAfter(const CertSvcCertificate &cert,
282 auto iter = m_certificateMap.find(cert.privateHandler);
283 if (iter == m_certificateMap.end()) {
284 return CERTSVC_WRONG_ARGUMENT;
286 *time = iter->second->getNotAfter();
287 return CERTSVC_SUCCESS;
290 inline int getNotBefore(const CertSvcCertificate &cert,
293 auto iter = m_certificateMap.find(cert.privateHandler);
294 if (iter == m_certificateMap.end()) {
295 return CERTSVC_WRONG_ARGUMENT;
297 *time = iter->second->getNotBefore();
298 return CERTSVC_SUCCESS;
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;
306 if (iter->second->isRootCert()) {
307 *status = CERTSVC_TRUE;
309 *status = CERTSVC_FALSE;
311 return CERTSVC_SUCCESS;
314 inline int getStringFromList(
315 const CertSvcStringList &handler,
317 CertSvcString *buffer)
319 buffer->privateHandler = NULL;
320 buffer->privateLength = 0;
322 auto iter = m_stringListMap.find(handler.privateHandler);
323 if (iter == m_stringListMap.end()) {
324 return CERTSVC_WRONG_ARGUMENT;
326 if (position >= iter->second.size()) {
327 return CERTSVC_WRONG_ARGUMENT;
329 const std::string &data = iter->second.at(position);
330 size_t size = data.size();
331 char *cstring = new char[size + 1];
336 strncpy(cstring, data.c_str(), size + 1);
338 buffer->privateHandler = cstring;
339 buffer->privateLength = size;
340 buffer->privateInstance = handler.privateInstance;
342 m_allocatedStringSet.insert(cstring);
344 return CERTSVC_SUCCESS;
347 inline int getStringListLen(
348 const CertSvcStringList &handler,
351 auto iter = m_stringListMap.find(handler.privateHandler);
352 if (iter == m_stringListMap.end()) {
353 return CERTSVC_WRONG_ARGUMENT;
355 *size = iter->second.size();
356 return CERTSVC_SUCCESS;
359 inline void removeStringList(const CertSvcStringList &handler)
361 m_stringListMap.erase(m_stringListMap.find(handler.privateHandler));
364 inline void removeString(const CertSvcString &handler)
366 auto iter = m_allocatedStringSet.find(handler.privateHandler);
367 if (iter != m_allocatedStringSet.end()) {
369 m_allocatedStringSet.erase(iter);
373 inline int certificateSearch(
374 CertSvcInstance instance,
375 CertSvcCertificateField field,
377 CertSvcCertificateList *handler)
379 search_field fieldId = SEARCH_FIELD_END;
382 case CERTSVC_SUBJECT:
383 fieldId = SUBJECT_STR;
386 fieldId = ISSUER_STR;
388 case CERTSVC_SUBJECT_COMMON_NAME:
389 fieldId = SUBJECT_COMMONNAME;
392 LogError("Not implemented!");
393 return CERTSVC_WRONG_ARGUMENT;
396 ScopedCertCtx ctx(cert_svc_cert_context_init(),
397 cert_svc_cert_context_final);
399 if (ctx.get() == NULL) {
400 LogWarning("Error in cert_svc_cert_context_init.");
404 LogDebug("Match string : " << value);
405 int result = cert_svc_search_certificate(ctx.get(), fieldId, const_cast<char*>(value));
406 LogDebug("Search finished!");
408 if (CERT_SVC_ERR_NO_ERROR != result) {
409 LogWarning("Error during certificate search");
414 size_t listId = m_idListCounter++;
415 std::vector<size_t> &list = m_idListMap[listId];
416 handler->privateHandler = listId;
417 handler->privateInstance = instance;
419 cert_svc_filename_list *fileList = ctx.get()->fileNames;
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.");
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))
432 LogWarning("Error in cert_svc_load_file_to_context");
436 list.push_back(addCert(CertificatePtr(new Certificate(*(ctx2.get()->certBuf)))));
438 fileList = fileList->next;
440 return CERTSVC_SUCCESS;
443 inline int sortCollection(CertSvcCertificate *certificate_array, size_t size) {
445 return CERTSVC_WRONG_ARGUMENT;
448 for (size_t i = 1; i < size; ++i) {
449 if (certificate_array[i - 1].privateInstance.privatePtr
450 != certificate_array[i].privateInstance.privatePtr)
452 return CERTSVC_WRONG_ARGUMENT;
456 CertificateList certList;
457 std::map<Certificate*, size_t> translator;
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;
465 translator[cert->second.get()] = pos;
466 certList.push_back(cert->second);
469 CertificateCollection collection;
470 collection.load(certList);
472 if (!collection.sort()) {
476 auto chain = collection.getChain();
479 for (const auto &cert : collection.getChain())
480 certificate_array[i++].privateHandler = translator[cert.get()];
482 return CERTSVC_SUCCESS;
485 inline int getX509Copy(const CertSvcCertificate &certificate, X509** cert)
487 auto it = m_certificateMap.find(certificate.privateHandler);
488 if (it == m_certificateMap.end()) {
489 return CERTSVC_WRONG_ARGUMENT;
491 *cert = X509_dup(it->second->getX509());
492 return CERTSVC_SUCCESS;
495 inline int saveToFile(const CertSvcCertificate &certificate,
496 const char *location)
498 auto it = m_certificateMap.find(certificate.privateHandler);
499 if (it == m_certificateMap.end()) {
500 return CERTSVC_WRONG_ARGUMENT;
502 FILE *out = fopen(location, "w");
506 if (0 == i2d_X509_fp(out, it->second->getX509())) {
511 return CERTSVC_SUCCESS;
515 CertSvcCertificate certificate,
516 CertSvcString &message,
517 CertSvcString &signature,
518 const char *algorithm,
521 int result = CERTSVC_FAIL;
524 return CERTSVC_WRONG_ARGUMENT;
527 auto it = m_certificateMap.find(certificate.privateHandler);
528 if (it == m_certificateMap.end()) {
529 return CERTSVC_WRONG_ARGUMENT;
532 OpenSSL_add_all_digests();
535 EVP_MD_CTX* mdctx = NULL;
536 const EVP_MD * md = NULL;
537 X509 *cert = it->second->getX509();
538 EVP_PKEY *pkey = NULL;
544 pkey = X509_get_pubkey(cert);
550 if (algorithm == NULL) {
551 md = EVP_get_digestbyobj(cert->cert_info->signature->algorithm);
553 md = EVP_get_digestbyname(algorithm);
557 result = CERTSVC_INVALID_ALGORITHM;
561 mdctx = EVP_MD_CTX_create();
567 if (EVP_VerifyInit_ex(mdctx, md, NULL) != 1) {
571 if (EVP_VerifyUpdate(mdctx, message.privateHandler, message.privateLength) != 1) {
575 temp = EVP_VerifyFinal(mdctx,
576 reinterpret_cast<unsigned char*>(signature.privateHandler),
577 signature.privateLength,
581 *status = CERTSVC_INVALID_SIGNATURE;
582 result = CERTSVC_SUCCESS;
583 } else if (temp == 1) {
584 *status = CERTSVC_SUCCESS;
585 result = CERTSVC_SUCCESS;
590 EVP_MD_CTX_destroy(mdctx);
596 inline int base64Encode(
597 const CertSvcString &message,
598 CertSvcString *base64)
601 return CERTSVC_WRONG_ARGUMENT;
603 std::string info(message.privateHandler, message.privateLength);
609 char *ptr = new char[info.size()+1];
611 return CERTSVC_BAD_ALLOC;
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;
622 const CertSvcString &base64,
623 CertSvcString *message)
626 return CERTSVC_WRONG_ARGUMENT;
628 std::string info(base64.privateHandler, base64.privateLength);
632 if (!base.finalize()) {
636 char *ptr = new char[info.size()+1];
638 return CERTSVC_BAD_ALLOC;
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;
648 inline int stringNew(
649 CertSvcInstance &instance,
652 CertSvcString *output)
655 return CERTSVC_WRONG_ARGUMENT;
658 size_t allocSize = size;
660 if (allocSize == 0 || str[allocSize - 1] != 0)
663 char *ptr = new char[allocSize];
665 return CERTSVC_BAD_ALLOC;
667 memcpy(ptr, str, size);
668 ptr[allocSize - 1] = 0;
670 output->privateHandler = ptr;
671 output->privateLength = size;
672 output->privateInstance = instance;
674 m_allocatedStringSet.insert(ptr);
676 return CERTSVC_SUCCESS;
679 inline int certificateVerify(
680 CertSvcCertificate certificate,
681 const CertSvcCertificate *trusted,
683 const CertSvcCertificate *untrusted,
684 size_t untrustedSize,
688 if (!trusted || !status) {
689 return CERTSVC_WRONG_ARGUMENT;
691 auto iter = m_certificateMap.find(certificate.privateHandler);
692 if (iter == m_certificateMap.end()) {
693 return CERTSVC_WRONG_ARGUMENT;
696 X509 *cert = iter->second->getX509();
697 X509_STORE *store = X509_STORE_new();
698 STACK_OF(X509) *ustore = sk_X509_new_null();
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;
708 X509_STORE_add_cert(store, iter->second->getX509());
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;
719 if (sk_X509_push(ustore, iter->second->getX509()) == 0)
723 X509_STORE_CTX context;
724 X509_STORE_CTX_init(&context, store, cert, ustore);
725 int result = X509_verify_cert(&context);
727 if (result == 1 && checkCaFlag) { // check strictly
728 STACK_OF(X509) *resultChain = X509_STORE_CTX_get1_chain(&context);
729 X509* tmpCert = NULL;
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.
741 X509_STORE_CTX_cleanup(&context);
742 X509_STORE_free(store);
743 sk_X509_free(ustore);
746 *status = CERTSVC_SUCCESS;
748 *status = CERTSVC_FAIL;
750 return CERTSVC_SUCCESS;
753 int getVisibility(CertSvcCertificate certificate, CertSvcVisibility *visibility)
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*/
764 auto iter = m_certificateMap.find(certificate.privateHandler);
765 if (iter == m_certificateMap.end()) {
768 CertificatePtr certPtr = iter->second;
770 std::string fingerprint = Certificate::FingerprintToColonHex(certPtr->getFingerprint(Certificate::FINGERPRINT_SHA1));
773 xmlDocPtr doc = xmlParseFile(FINGERPRINT_LIST_PATH);
774 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL))
776 LogError("Failed to prase fingerprint_list.xml");
777 return CERTSVC_IO_ERROR;
780 xmlNodePtr curPtr = xmlFirstElementChild(xmlDocGetRootElement(doc));
783 LogError("Can not find root");
784 ret = CERTSVC_IO_ERROR;
788 while(curPtr != NULL)
790 xmlAttr* attr = curPtr->properties;
791 if(!attr->children || !attr->children->content)
793 LogError("Failed to get fingerprints from list");
798 xmlChar* strLevel = attr->children->content;
799 xmlNodePtr FpPtr = xmlFirstElementChild(curPtr);
802 LogError("Could not find fingerprint");
807 LogDebug("Retrieve level : " << strLevel);
810 xmlChar *content = xmlNodeGetContent(FpPtr);
811 if(xmlStrcmp(content, (xmlChar*)fingerprint.c_str()) == 0)
813 LogDebug("fingerprint : " << content << " are " << strLevel);
814 if(!xmlStrcmp(strLevel, xmlPathDomainPlatform))
816 *visibility = CERTSVC_VISIBILITY_PLATFORM;
817 ret = CERTSVC_SUCCESS;
820 else if(!xmlStrcmp(strLevel, xmlPathDomainPublic))
822 *visibility = CERTSVC_VISIBILITY_PUBLIC;
823 ret = CERTSVC_SUCCESS;
826 else if(!xmlStrcmp(strLevel, xmlPathDomainPartner))
828 *visibility = CERTSVC_VISIBILITY_PARTNER;
829 ret = CERTSVC_SUCCESS;
832 else if(!xmlStrcmp(strLevel, xmlPathDomainDeveloper))
834 *visibility = CERTSVC_VISIBILITY_DEVELOPER;
835 ret = CERTSVC_SUCCESS;
839 FpPtr = xmlNextElementSibling(FpPtr);
841 curPtr = xmlNextElementSibling(curPtr);
850 inline int pkcsNameIsUniqueInStore(
851 CertStoreType storeType,
852 CertSvcString pfxIdString,
855 return c_certsvc_pkcs12_alias_exists_in_store(storeType, pfxIdString.privateHandler, is_unique);
858 inline int getCertDetailFromStore(CertStoreType storeType,
863 return c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname.privateHandler, certBuffer, certSize);
866 inline int pkcsDeleteCertFromStore(
867 CertStoreType storeType,
871 return c_certsvc_pkcs12_delete_certificate_from_store(storeType, gname.privateHandler);
874 inline int pkcsHasPassword(
875 CertSvcString filepath,
878 return c_certsvc_pkcs12_has_password(filepath.privateHandler, has_password);
881 inline int pkcsImportToStore(
882 CertStoreType storeType,
885 CertSvcString pfxIdString)
887 return c_certsvc_pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
890 inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
894 return c_certsvc_pkcs12_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
897 inline int pkcsSetCertStatusToStore(CertStoreType storeType,
902 return c_certsvc_pkcs12_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
905 inline int pkcsGetCertStatusFromStore(
906 CertStoreType storeType,
910 return c_certsvc_pkcs12_get_certificate_status_from_store(storeType, gname.privateHandler, status);
913 inline int getCertFromStore(CertSvcInstance instance,
914 CertStoreType storeType,
916 CertSvcCertificate *certificate)
918 return certsvc_get_certificate(instance, storeType, gname, certificate);
921 inline int freePkcsIdListFromStore(
922 CertSvcStoreCertList** certList)
924 return c_certsvc_pkcs12_free_aliases_loaded_from_store(certList);
927 inline int getPkcsIdListFromStore(
928 CertStoreType storeType,
930 CertSvcStoreCertList** certList,
933 return c_certsvc_pkcs12_get_certificate_list_from_store(storeType, is_root_app, certList, length);
936 inline int getPkcsIdEndUserListFromStore(
937 CertStoreType storeType,
938 CertSvcStoreCertList** certList,
941 return c_certsvc_pkcs12_get_end_user_certificate_list_from_store(storeType, certList, length);
944 inline int getPkcsIdRootListFromStore(
945 CertStoreType storeType,
946 CertSvcStoreCertList** certList,
949 return c_certsvc_pkcs12_get_root_certificate_list_from_store(storeType, certList, length);
952 inline int getPkcsPrivateKeyFromStore(
953 CertStoreType storeType,
958 return c_certsvc_pkcs12_private_key_load_from_store(storeType, gname.privateHandler, certBuffer, certSize);
961 inline int getPkcsCertificateListFromStore(
962 CertSvcInstance &instance,
963 CertStoreType storeType,
964 CertSvcString &pfxIdString,
965 CertSvcCertificateList *handler)
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.");
975 std::vector<CertificatePtr> certPtrVector;
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.");
988 const char *header = strstr(certBuffer, START_CERT);
989 const char *headEnd = START_CERT;
990 const char *trailer = NULL;
991 const char *tailEnd = NULL;
993 // START_CERT not found. let's find START_TRUSTED.
994 header = strstr(certBuffer, START_TRUSTED);
995 headEnd = START_TRUSTED;
999 // START_something found. let's find END_CERT first.
1000 trailer = strstr(header, END_CERT);
1005 // END_CERT not found. let's find END_TRUSTED.
1006 trailer = strstr(header, END_TRUSTED);
1007 tailEnd = END_TRUSTED;
1011 LogError("Failed the get the certificate.");
1012 return CERTSVC_FAIL;
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)));
1024 c_certsvc_pkcs12_free_certificates(certs);
1026 std::vector<size_t> listId;
1027 for (const auto &cert : certPtrVector)
1028 listId.push_back(addCert(cert));
1030 size_t position = m_idListCounter++;
1031 m_idListMap[position] = listId;
1033 handler->privateInstance = instance;
1034 handler->privateHandler = position;
1039 inline bool checkValidStoreType(CertStoreType storeType)
1041 if (storeType >= VPN_STORE && storeType <= ALL_STORE)
1048 size_t m_certificateCounter;
1049 std::map<size_t, CertificatePtr> m_certificateMap;
1051 size_t m_idListCounter;
1052 std::map<size_t, std::vector<size_t> > m_idListMap;
1054 size_t m_stringListCounter;
1055 std::map<size_t, std::vector<std::string> > m_stringListMap;
1057 std::set<char *> m_allocatedStringSet;
1060 inline CertSvcInstanceImpl *impl(CertSvcInstance instance) {
1061 return static_cast<CertSvcInstanceImpl*>(instance.privatePtr);
1064 } // namespace anonymous
1066 int certsvc_instance_new(CertSvcInstance *instance) {
1067 static int init = 1;
1069 OpenSSL_add_ssl_algorithms();
1070 OpenSSL_add_all_digests();
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;
1081 return CERTSVC_FAIL;
1084 void certsvc_instance_reset(CertSvcInstance instance) {
1085 impl(instance)->reset();
1088 void certsvc_instance_free(CertSvcInstance instance) {
1089 delete impl(instance);
1092 int certsvc_certificate_new_from_file(
1093 CertSvcInstance instance,
1094 const char *location,
1095 CertSvcCertificate *certificate)
1098 ScopedCertCtx context(cert_svc_cert_context_init(),
1099 cert_svc_cert_context_final);
1101 int result = cert_svc_load_file_to_context(context.get(), location);
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;
1110 CertificatePtr cert(new Certificate(*(context->certBuf)));
1112 certificate->privateInstance = instance;
1113 certificate->privateHandler = impl(instance)->addCert(cert);
1115 return CERTSVC_SUCCESS;
1116 // TODO support for std exceptions
1117 } catch (std::bad_alloc &) {
1118 return CERTSVC_BAD_ALLOC;
1120 return CERTSVC_FAIL;
1123 int certsvc_certificate_new_from_memory(
1124 CertSvcInstance instance,
1125 const unsigned char *memory,
1127 CertSvcCertificateForm form,
1128 CertSvcCertificate *certificate)
1131 Certificate::FormType formType;
1132 std::string binary((char*)memory, len);
1134 if (CERTSVC_FORM_DER == form) {
1135 formType = Certificate::FORM_DER;
1137 formType = Certificate::FORM_BASE64;
1140 CertificatePtr cert(new Certificate(binary, formType));
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;
1148 return CERTSVC_FAIL;
1151 void certsvc_certificate_free(CertSvcCertificate certificate)
1153 if (certificate.privateHandler != 0)
1154 impl(certificate.privateInstance)->removeCert(certificate);
1157 int certsvc_certificate_save_file(
1158 CertSvcCertificate certificate,
1159 const char *location)
1161 return impl(certificate.privateInstance)->saveToFile(certificate, location);
1164 int certsvc_certificate_search(
1165 CertSvcInstance instance,
1166 CertSvcCertificateField field,
1168 CertSvcCertificateList *handler)
1171 return impl(instance)->certificateSearch(instance, field, value, handler);
1172 } catch (std::bad_alloc &) {
1173 return CERTSVC_BAD_ALLOC;
1175 return CERTSVC_FAIL;
1178 int certsvc_certificate_list_get_one(
1179 CertSvcCertificateList handler,
1181 CertSvcCertificate *certificate)
1183 return impl(handler.privateInstance)->
1184 getCertFromList(handler, position, certificate);
1187 int certsvc_certificate_list_get_length(
1188 CertSvcCertificateList handler,
1191 return impl(handler.privateInstance)->getCertListLen(handler, size);
1194 void certsvc_certificate_list_free(CertSvcCertificateList handler)
1196 impl(handler.privateInstance)->removeCertList(handler);
1199 void certsvc_certificate_list_all_free(CertSvcCertificateList handler)
1201 impl(handler.privateInstance)->removeCertListAll(handler);
1204 int certsvc_certificate_is_signed_by(
1205 CertSvcCertificate child,
1206 CertSvcCertificate parent,
1209 if (child.privateInstance.privatePtr == parent.privateInstance.privatePtr) {
1210 return impl(child.privateInstance)->isSignedBy(child, parent, status);
1212 return CERTSVC_WRONG_ARGUMENT;
1215 int certsvc_certificate_get_string_field(
1216 CertSvcCertificate certificate,
1217 CertSvcCertificateField field,
1218 CertSvcString *buffer)
1221 return impl(certificate.privateInstance)->getField(certificate, field, buffer);
1222 } catch (std::bad_alloc &) {
1223 return CERTSVC_BAD_ALLOC;
1225 return CERTSVC_FAIL;
1228 int certsvc_certificate_get_not_after(
1229 CertSvcCertificate certificate,
1233 return impl(certificate.privateInstance)->getNotAfter(certificate, result);
1235 return CERTSVC_FAIL;
1238 int certsvc_certificate_get_not_before(
1239 CertSvcCertificate certificate,
1243 return impl(certificate.privateInstance)->getNotBefore(certificate, result);
1245 return CERTSVC_FAIL;
1248 int certsvc_certificate_is_root_ca(CertSvcCertificate certificate, int *status)
1250 return impl(certificate.privateInstance)->isRootCA(certificate, status);
1253 int certsvc_string_list_get_one(
1254 CertSvcStringList handler,
1256 CertSvcString *buffer)
1259 return impl(handler.privateInstance)->getStringFromList(handler, position, buffer);
1260 } catch (std::bad_alloc &) {
1261 return CERTSVC_BAD_ALLOC;
1263 return CERTSVC_FAIL;
1266 int certsvc_string_list_get_length(
1267 CertSvcStringList handler,
1270 return impl(handler.privateInstance)->getStringListLen(handler, size);
1273 void certsvc_string_list_free(CertSvcStringList handler)
1275 if (handler.privateHandler != 0)
1277 impl(handler.privateInstance)->removeStringList(handler);
1278 handler.privateHandler = 0;
1282 void certsvc_string_free(CertSvcString string)
1284 if (string.privateHandler)
1285 impl(string.privateInstance)->removeString(string);
1288 void certsvc_string_to_cstring(
1289 CertSvcString string,
1290 const char **buffer,
1294 *buffer = string.privateHandler;
1297 *len = string.privateLength;
1301 int certsvc_certificate_chain_sort(
1302 CertSvcCertificate *certificate_array,
1306 if (!certificate_array) {
1307 return CERTSVC_WRONG_ARGUMENT;
1309 return impl(certificate_array[0].privateInstance)->
1310 sortCollection(certificate_array, size);
1311 } catch (std::bad_alloc &) {
1312 return CERTSVC_BAD_ALLOC;
1314 return CERTSVC_FAIL;
1317 int certsvc_certificate_dup_x509(CertSvcCertificate certificate, X509 **cert)
1320 return impl(certificate.privateInstance)->getX509Copy(certificate, cert);
1322 return CERTSVC_FAIL;
1325 void certsvc_certificate_free_x509(X509 *x509)
1331 void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey)
1333 EVP_PKEY_free(pkey);
1336 int certsvc_message_verify(
1337 CertSvcCertificate certificate,
1338 CertSvcString message,
1339 CertSvcString signature,
1340 const char *algorithm,
1344 return impl(certificate.privateInstance)->verify(
1351 return CERTSVC_FAIL;
1354 int certsvc_base64_encode(CertSvcString message, CertSvcString *base64)
1357 return impl(message.privateInstance)->base64Encode(message, base64);
1359 return CERTSVC_FAIL;
1362 int certsvc_base64_decode(CertSvcString base64, CertSvcString *message)
1365 return impl(base64.privateInstance)->base64Decode(base64, message);
1367 return CERTSVC_FAIL;
1370 int certsvc_string_new(
1371 CertSvcInstance instance,
1374 CertSvcString *output)
1377 return impl(instance)->stringNew(instance, url, size, output);
1379 return CERTSVC_FAIL;
1382 int certsvc_string_not_managed(
1383 CertSvcInstance instance,
1386 CertSvcString *output)
1389 return CERTSVC_WRONG_ARGUMENT;
1391 output->privateHandler = const_cast<char*>(url);
1392 output->privateLength = size;
1393 output->privateInstance = instance;
1394 return CERTSVC_SUCCESS;
1397 int certsvc_certificate_verify(
1398 CertSvcCertificate certificate,
1399 const CertSvcCertificate *trusted,
1401 const CertSvcCertificate *untrusted,
1402 size_t untrustedSize,
1406 return impl(certificate.privateInstance)->certificateVerify(
1415 return CERTSVC_FAIL;
1418 int certsvc_certificate_verify_with_caflag(
1419 CertSvcCertificate certificate,
1420 const CertSvcCertificate *trusted,
1422 const CertSvcCertificate *untrusted,
1423 size_t untrustedSize,
1427 return impl(certificate.privateInstance)->certificateVerify(
1436 return CERTSVC_FAIL;
1439 int certsvc_certificate_get_visibility(CertSvcCertificate certificate, CertSvcVisibility *visibility)
1442 return impl(certificate.privateInstance)->getVisibility(certificate, visibility);
1445 LogError("exception occur");
1447 return CERTSVC_FAIL;
1450 int certsvc_get_certificate(CertSvcInstance instance,
1451 CertStoreType storeType,
1453 CertSvcCertificate *certificate)
1455 int result = CERTSVC_SUCCESS;
1456 char* certBuffer = NULL;
1457 std::string fileName;
1459 FILE* fp_write = NULL;
1461 X509* x509Struct = NULL;
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.");
1470 pBio = BIO_new(BIO_s_mem());
1472 LogError("Failed to allocate memory.");
1473 result = CERTSVC_BAD_ALLOC;
1476 length = BIO_write(pBio, (const void*) certBuffer, length);
1478 LogError("Failed to load cert into bio.");
1479 result = CERTSVC_BAD_ALLOC;
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);
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;
1498 if (fwrite(certBuffer, sizeof(char), (size_t)length, fp_write) != (size_t)length) {
1499 LogError("Fail to write certificate.");
1500 result = CERTSVC_FAIL;
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.");
1510 unlink(fileName.c_str());
1512 result = CERTSVC_SUCCESS;
1513 } catch (std::bad_alloc &) {
1514 return CERTSVC_BAD_ALLOC;
1518 if (x509Struct) X509_free(x509Struct);
1519 if (pBio) BIO_free(pBio);
1523 int certsvc_pkcs12_check_alias_exists_in_store(CertSvcInstance instance,
1524 CertStoreType storeType,
1525 CertSvcString pfxIdString,
1528 if (pfxIdString.privateHandler == NULL || pfxIdString.privateLength<=0) {
1529 LogError("Invalid input parameter.");
1530 return CERTSVC_WRONG_ARGUMENT;
1534 if (!impl(instance)->checkValidStoreType(storeType)) {
1535 LogError("Invalid input parameter.");
1536 return CERTSVC_INVALID_STORE_TYPE;
1539 return impl(instance)->pkcsNameIsUniqueInStore(storeType, pfxIdString, is_unique);
1541 return CERTSVC_FAIL;
1544 int certsvc_pkcs12_free_certificate_list_loaded_from_store(CertSvcInstance instance,
1545 CertSvcStoreCertList **certList)
1547 if (certList == NULL || *certList == NULL) {
1548 LogError("Invalid input parameter.");
1549 return CERTSVC_WRONG_ARGUMENT;
1553 return impl(instance)->freePkcsIdListFromStore(certList);
1555 return CERTSVC_FAIL;
1558 int certsvc_pkcs12_get_certificate_list_from_store(CertSvcInstance instance,
1559 CertStoreType storeType,
1561 CertSvcStoreCertList **certList,
1564 if (certList == NULL || *certList != NULL) {
1565 LogError("Invalid input parameter.");
1566 return CERTSVC_WRONG_ARGUMENT;
1570 if (!impl(instance)->checkValidStoreType(storeType)) {
1571 LogError("Invalid input parameter.");
1572 return CERTSVC_INVALID_STORE_TYPE;
1575 return impl(instance)->getPkcsIdListFromStore(storeType, is_root_app, certList, length);
1578 return CERTSVC_FAIL;
1581 int certsvc_pkcs12_get_end_user_certificate_list_from_store(CertSvcInstance instance,
1582 CertStoreType storeType,
1583 CertSvcStoreCertList **certList,
1586 if (certList == NULL || *certList != NULL) {
1587 LogError("Invalid input parameter.");
1588 return CERTSVC_WRONG_ARGUMENT;
1592 if (!impl(instance)->checkValidStoreType(storeType)) {
1593 LogError("Invalid input parameter.");
1594 return CERTSVC_INVALID_STORE_TYPE;
1597 return impl(instance)->getPkcsIdEndUserListFromStore(storeType, certList, length);
1599 return CERTSVC_FAIL;
1602 int certsvc_pkcs12_get_root_certificate_list_from_store(CertSvcInstance instance,
1603 CertStoreType storeType,
1604 CertSvcStoreCertList **certList,
1607 if (certList == NULL || *certList != NULL) {
1608 LogError("Invalid input parameter.");
1609 return CERTSVC_WRONG_ARGUMENT;
1613 if (!impl(instance)->checkValidStoreType(storeType)) {
1614 LogError("Invalid input parameter.");
1615 return CERTSVC_INVALID_STORE_TYPE;
1618 return impl(instance)->getPkcsIdRootListFromStore(storeType, certList, length);
1620 return CERTSVC_FAIL;
1623 int certsvc_pkcs12_get_certificate_info_from_store(CertSvcInstance instance,
1624 CertStoreType storeType,
1625 CertSvcString gname,
1629 if (certBuffer == NULL || *certBuffer != NULL) {
1630 LogError("Invalid input parameter.");
1631 return CERTSVC_WRONG_ARGUMENT;
1635 if (!impl(instance)->checkValidStoreType(storeType)) {
1636 LogError("Invalid input parameter.");
1637 return CERTSVC_INVALID_STORE_TYPE;
1640 return impl(instance)->getCertDetailFromStore(storeType, gname, certBuffer, certSize);
1642 return CERTSVC_FAIL;
1645 int certsvc_pkcs12_delete_certificate_from_store(CertSvcInstance instance,
1646 CertStoreType storeType,
1647 CertSvcString gname)
1650 if (!impl(instance)->checkValidStoreType(storeType)) {
1651 LogError("Invalid input parameter.");
1652 return CERTSVC_INVALID_STORE_TYPE;
1654 return impl(instance)->pkcsDeleteCertFromStore(storeType, gname);
1656 return CERTSVC_FAIL;
1659 int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
1660 CertStoreType storeType,
1662 CertSvcString password,
1663 CertSvcString pfxIdString)
1666 if (path.privateHandler != NULL) {
1667 if (!impl(instance)->checkValidStoreType(storeType)) {
1668 LogError("Invalid input parameter.");
1669 return CERTSVC_INVALID_STORE_TYPE;
1671 return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
1674 return CERTSVC_FAIL;
1676 return CERTSVC_FAIL;
1679 int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
1680 CertStoreType storeType,
1681 CertSvcString gname,
1684 if (gname.privateHandler == NULL || gname.privateLength<=0) {
1685 LogError("Invalid input parameter.");
1686 return CERTSVC_WRONG_ARGUMENT;
1690 if (!impl(instance)->checkValidStoreType(storeType)) {
1691 LogError("Invalid input parameter.");
1692 return CERTSVC_INVALID_STORE_TYPE;
1694 return impl(instance)->pkcsGetAliasNameForCertInStore(storeType, gname, alias);
1696 return CERTSVC_FAIL;
1699 int certsvc_pkcs12_set_certificate_status_to_store(CertSvcInstance instance,
1700 CertStoreType storeType,
1702 CertSvcString gname,
1706 if (!impl(instance)->checkValidStoreType(storeType)) {
1707 LogError("Invalid input parameter.");
1708 return CERTSVC_INVALID_STORE_TYPE;
1710 return impl(instance)->pkcsSetCertStatusToStore(storeType, is_root_app, gname, status);
1712 return CERTSVC_FAIL;
1715 int certsvc_pkcs12_get_certificate_status_from_store(
1716 CertSvcInstance instance,
1717 CertStoreType storeType,
1718 CertSvcString gname,
1722 if (!impl(instance)->checkValidStoreType(storeType)) {
1723 LogError("Invalid input parameter.");
1724 return CERTSVC_INVALID_STORE_TYPE;
1726 return impl(instance)->pkcsGetCertStatusFromStore(storeType, gname, status);
1728 return CERTSVC_FAIL;
1731 int certsvc_pkcs12_get_certificate_from_store(CertSvcInstance instance,
1732 CertStoreType storeType,
1734 CertSvcCertificate *certificate)
1737 if (!impl(instance)->checkValidStoreType(storeType)) {
1738 LogError("Invalid input parameter.");
1739 return CERTSVC_INVALID_STORE_TYPE;
1741 return impl(instance)->getCertFromStore(instance, storeType, gname, certificate);
1743 return CERTSVC_FAIL;
1746 int certsvc_pkcs12_load_certificate_list_from_store(
1747 CertSvcInstance instance,
1748 CertStoreType storeType,
1749 CertSvcString pfxIdString,
1750 CertSvcCertificateList *certificateList)
1753 if (!impl(instance)->checkValidStoreType(storeType)) {
1754 LogError("Invalid input parameter.");
1755 return CERTSVC_INVALID_STORE_TYPE;
1757 return impl(instance)->getPkcsCertificateListFromStore(instance, storeType, pfxIdString, certificateList);
1759 return CERTSVC_FAIL;
1762 int certsvc_pkcs12_private_key_dup_from_store(
1763 CertSvcInstance instance,
1764 CertStoreType storeType,
1765 CertSvcString gname,
1770 if (!impl(instance)->checkValidStoreType(storeType)) {
1771 LogError("Invalid input parameter.");
1772 return CERTSVC_INVALID_STORE_TYPE;
1774 return impl(instance)->getPkcsPrivateKeyFromStore(storeType, gname, certBuffer, certSize);
1776 return CERTSVC_FAIL;
1779 int certsvc_pkcs12_dup_evp_pkey_from_store(
1780 CertSvcInstance instance,
1781 CertStoreType storeType,
1782 CertSvcString gname,
1785 char *buffer = NULL;
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");
1794 BIO *b = BIO_new(BIO_s_mem());
1795 if ((int)size != BIO_write(b, buffer, size)) {
1796 LogError("Error in BIO_write");
1798 certsvc_pkcs12_private_key_free(buffer);
1799 return CERTSVC_FAIL;
1802 certsvc_pkcs12_private_key_free(buffer);
1803 *pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
1806 return CERTSVC_SUCCESS;
1808 LogError("Result is null. Openssl REASON code is : " << ERR_GET_REASON(ERR_peek_last_error()));
1809 return CERTSVC_FAIL;
1812 int certsvc_pkcs12_has_password(
1813 CertSvcInstance instance,
1814 CertSvcString filepath,
1818 return impl(instance)->pkcsHasPassword(
1822 return CERTSVC_FAIL;
1825 void certsvc_pkcs12_private_key_free(char *buffer)