+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// @file FSecCert_CertServer.cpp
+// @brief This file contains implementation of X509 Certificate Service APIs.
+//
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <error.h>
+#include <memory.h>
+#include <new>
+#include <sys/stat.h>
+#include <assert.h>
+#include <dirent.h>
+#include <openssl/rsa.h>
+#include <openssl/obj_mac.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <unique_ptr.h>
+#include <FBaseErrors.h>
+#include <FIoDirectory.h>
+#include <FIoDirEnumerator.h>
+#include <FIoFileAttributes.h>
+#include <FIoFile.h>
+#include <FBaseString.h>
+#include <FBaseByteBuffer.h>
+#include <FBaseResult.h>
+#include <FBaseSysLog.h>
+#include "FSec_CertServer.h"
+#include <FSecCert_CertService.h>
+#include <FSecCert_CertManager.h>
+#include <FSecCert_CertDbManager.h>
+#include <FSecCert_Base64.h>
+#include <FSecCert_CertFileStore.h>
+#include <FSecCert_CertOidDef.h>
+#include <FSecCert_Certificate.h>
+#include <FSecCert_Base64.h>
+
+
+using namespace Tizen::Io;
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Security { namespace Cert
+{
+
+const String _CERT_MGR_BASE_DIRECTORY = L"/opt/usr/share/certs/";
+const String _CERT_ROOT_CA_CERT_FILE_DIRECTORY = L"/opt/usr/share/certs/rootcert/";
+const String _CERT_USER_CERT_FILE_DIRECTORY = L"/opt/usr/share/certs/usercert/";
+const String _CERT_USER_PRIVKEY_FILE_DIRECTORY = L"/opt/usr/share/certs/usercert/key/";
+
+const String _CERT_ROOT_CA_CERT_TABLE = L"/opt/usr/dbspace/.security-rootcert.db";
+const String _CERT_USER_CERT_TABLE = L"/opt/usr/dbspace/.security-usercert.db";
+
+const String _CERT_MGR_CRT_FILE_PATH = _CERT_MGR_BASE_DIRECTORY + L"ca-certificate.crt";
+const String _TEMP_CERT_MGR_CRT_FILE_PATH = _CERT_MGR_BASE_DIRECTORY + L"tmp-ca-certificate.crt";
+
+const String _CERT_DOMAIN1_CERT_FILE_PATH = L"/opt/share/cert-svc/certs/sim/thirdparty/";
+const String _CERT_DOMAIN2_CERT_FILE_PATH = L"/opt/share/cert-svc/certs/sim/operator/";
+const String _CERT_SVC_DEFAULT_CERT_DIRECTORY = L"/opt/share/cert-svc/certs/ssl/";
+
+//Prefix definition for NAME Prefix
+const char* _CERT_COMMON_NAME = "CN=";
+const char* _CERT_ORG_UNIT_NAME = "OU=";
+const char* _CERT_ORG_NAME = "O=";
+const char* _CERT_LOCALITY_NAME = "L=";
+const char* _CERT_STATE_OR_PROVINCE_NAME = "S=";
+const char* _CERT_COUNTRY_NAME = "C=";
+const char* _CERT_EMAIL_ADDRESS = "emailAddress=";
+const char* _CERT_SERIAL_NUM = "SN=";
+const char* _CERT_GIVEN_NAME = "GN=";
+const char* _CERT_SUR_NAME = "SUN=";
+const char* _CERT_STATE_OF_PROVINCE = "ST=";
+const char* _CERT_DC = "_CERT_DC=";
+const char* _CERT_TK_ISSUER_NAME = "Test";
+
+result
+_CertServer::InitializeDb(void)
+{
+ result r = E_SUCCESS;
+ int certTrustTypes = 0;
+ int certCount = 0;
+
+ r = _CertServer::Initialize();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Cert Manager initialisation failed.");
+
+ certTrustTypes = static_cast< int >(_CERT_TRUST_SIM_ROOT_CA | _CERT_TRUST_SIM_DOMAIN);
+
+ _CertServer::RemoveCerts(certTrustTypes);
+
+ // Install Certificates
+ certTrustTypes = static_cast< int >(_CERT_TRUST_PHONE_ROOT_CA | _CERT_TRUST_PHONE_DOMAIN | _CERT_TRUST_OSP_ROOT_CA | _CERT_TRUST_SIM_DOMAIN | _CERT_TRUST_SIM_ROOT_CA);
+
+ r = _CertServer::InsertCerts(certTrustTypes, &certCount);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to install certificates.");
+
+ return r;
+}
+
+result
+_CertServer::Initialize(void)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ if (!pCertDb->IsCertificateTablesCreated())
+ {
+ r = pCertDb->CreateCertificateTables();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to create certificate table.");
+ }
+
+ return r;
+}
+
+result
+_CertServer::ReInitializeDb(void)
+{
+ result r = E_SUCCESS;
+ int certTrustTypes = 0;
+ int certCount = 0;
+
+ r = _CertServer::Initialize();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Db initialization failed.");
+
+ // Install Certificates
+ certTrustTypes = static_cast< int >(_CERT_TRUST_PHONE_ROOT_CA | _CERT_TRUST_PHONE_DOMAIN | _CERT_TRUST_OSP_ROOT_CA | _CERT_TRUST_SIM_DOMAIN | _CERT_TRUST_SIM_ROOT_CA);
+
+ r = _CertServer::InsertCerts(certTrustTypes, &certCount);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to install certificates.");
+
+ return r;
+}
+
+result
+_CertServer::DropTables(void)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ if (!pCertDb->IsCertificateTablesCreated())
+ {
+ r = pCertDb->RemoveCertificateTables();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate table.");
+ }
+
+ return r;
+}
+
+result
+_CertServer::ResetTables(void)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ if (!pCertDb->IsCertificateTablesCreated())
+ {
+ r = pCertDb->ResetCertificateTables();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate table.");
+ }
+
+ return r;
+}
+
+result
+_CertServer::MasterReset(void)
+{
+ _CertDbManager* pCertDb = null;
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ pCertDb->RemoveAllUserCertificate();
+
+ _CertServer::RemoveCert(_CERT_TYPE_ROOT_CA);
+ _CertServer::RemoveCert(_CERT_TYPE_ROOT_DOMAIN1);
+ _CertServer::RemoveCert(_CERT_TYPE_ROOT_DOMAIN2);
+ _CertServer::RemoveCert(_CERT_TYPE_ROOT_DOMAIN3);
+ _CertServer::RemoveCert(_CERT_TYPE_ROOT_CA_BY_USER);
+ _CertServer::RemoveCert(_CERT_TYPE_INTERMIDIATE_CA);
+ _CertServer::RemoveCert(_CERT_TYPE_USER_CERT);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_CRITICAL1);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_CRITICAL2);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_CRITICAL3);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_CRITICAL4);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_CRITICAL5);
+ _CertServer::RemoveCert(_CERT_TYPE_OSP_PRELOAD_APP);
+ _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN1);
+ _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN2);
+ _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN3);
+
+ return E_SUCCESS;
+}
+
+int
+_CertServer::InsertCert(_CaCertType type)
+{
+ result r = E_SUCCESS;
+ byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, };
+ long fileSize = 0;
+ int count = 0;
+ int readCnt = 0;
+ _CertFormat certFormat = _CERT_UNKNOWN;
+ Directory dir;
+ Directory rootCertdir;
+ FileAttributes attr;
+ String rootCertificatePath;
+
+ ClearLastResult();
+
+ SysTryReturn(NID_SEC_CERT, type >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
+
+ switch (type)
+ {
+ case _CERT_TYPE_ROOT_CA:
+
+ rootCertificatePath.Append(_CERT_SVC_DEFAULT_CERT_DIRECTORY);
+ break;
+
+ case _CERT_TYPE_DEV_ROOT_DOMAIN1:
+ rootCertificatePath.Append(_CERT_DOMAIN1_CERT_FILE_PATH);
+ break;
+
+ case _CERT_TYPE_DEV_ROOT_DOMAIN2:
+ rootCertificatePath.Append(_CERT_DOMAIN2_CERT_FILE_PATH);
+ break;
+
+ case _CERT_TYPE_OSP_CRITICAL1:
+ //fall through
+ case _CERT_TYPE_OSP_CRITICAL2:
+ //fall through
+ case _CERT_TYPE_OSP_PRELOAD_APP:
+ break;
+
+ default:
+ break;
+ }
+ certFormat = _CERT_X509;
+
+ if (rootCertificatePath.GetLength() <= 0)
+ {
+ SetLastResult(E_SUCCESS);
+ return 0;
+ }
+
+ // Open the directory
+ String dirName(rootCertificatePath);
+
+ r = dir.Construct(dirName);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), -1, r, "[%s] Failed to construct directory.", GetErrorMessage(r));
+
+ std::unique_ptr< DirEnumerator > pDirEnum(dir.ReadN());
+ SysTryReturn(NID_SEC_CRYPTO, pDirEnum != null, count, GetLastResult(), "[%s] Failed to get directory enumerator instance.", GetErrorMessage(GetLastResult()));
+
+ while (pDirEnum->MoveNext() == E_SUCCESS)
+ {
+ String fileName;
+ File file;
+
+ DirEntry entry = pDirEnum->GetCurrentDirEntry();
+
+ fileName.Append(dirName);
+ fileName.Append(entry.GetName());
+ if ((entry.GetName() == "..") || (entry.GetName() == "."))
+ {
+ continue;
+ }
+
+ r = file.Construct(fileName, L"r");
+ if (!IsFailed(r))
+ {
+ r = File::GetAttributes(fileName, attr);
+ if (!IsFailed(r))
+ {
+ fileSize = attr.GetFileSize();
+ if (fileSize > 0 && fileSize < _MAX_CERTIFICATE_SIZE)
+ {
+ readCnt = file.Read(certBufData, fileSize);
+ r = GetLastResult();
+ if (!IsFailed(r) && readCnt == fileSize)
+ {
+ _CertServer::InsertDefaultCaCertificate(type, certFormat, certBufData, readCnt);
+ count++;
+ fileSize = 0;
+ readCnt = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+result
+_CertServer::InsertCerts(int certTrustTypes, int* pCertCount)
+{
+ result r = E_SUCCESS;
+ int certCount = 0;
+ int certTotalCount = 0;
+
+ SysTryReturnResult(NID_SEC_CERT, certTrustTypes != _CERT_TRUST_NONE, E_INVALID_ARG, "Invalid certificate trust type.");
+ SysTryReturnResult(NID_SEC_CERT, certTrustTypes > 0, E_INVALID_ARG, "Invalid certificate trust type.");
+
+ if (certTrustTypes & _CERT_TRUST_OSP_ROOT_CA)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_PRELOAD_APP);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_CRITICAL2);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_CRITICAL1);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_CRITICAL3);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_CRITICAL4);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_OSP_CRITICAL5);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_PHONE_ROOT_CA)
+ {
+ //Install trusted by default certificates
+ certCount = _CertServer::InsertCert(_CERT_TYPE_TRUSTED_CA);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+
+ certCount = _CertServer::InsertCert(_CERT_TYPE_ROOT_CA);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_PHONE_DOMAIN)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_ROOT_DOMAIN1);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_ROOT_DOMAIN2);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_ROOT_DOMAIN3);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_SIM_DOMAIN)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN1);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN2);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN3);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_SIM_ROOT_CA)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_CA);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_DEV_ROOT_CA)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_CA);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+ if (certTrustTypes & _CERT_TRUST_DEV_DOMAIN)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN1);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN2);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_DEV_ROOT_DOMAIN3);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+
+ if (certTrustTypes & _CERT_TRUST_CSC_CA)
+ {
+ certCount = _CertServer::InsertCert(_CERT_TYPE_CSC_ROOT_CA);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_CSC_ROOT_DOMAIN1);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_CSC_ROOT_DOMAIN2);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ certCount = _CertServer::InsertCert(_CERT_TYPE_CSC_ROOT_DOMAIN3);
+ if (certCount == -1)
+ {
+ r = E_SYSTEM;
+ }
+ else
+ {
+ certTotalCount += certCount;
+ }
+ }
+
+ if (pCertCount != null)
+ {
+ *pCertCount = certTotalCount;
+ }
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertDefaultCaCertificate(_CaCertType type, _CertFormat format, byte* pCertBuf, int certLen)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_INVALID_ARG, "Invalid certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Invalid certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
+ SysTryReturnResult(NID_SEC_CERT, type < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->InsertDefaultCaCertificateFromBuffer(type, format, pCertBuf, certLen);
+ SysTryReturnResult(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), E_SYSTEM, "Failed to install default ca certiifcates.");
+
+ return r;
+}
+
+int
+_CertServer::InsertUserCaCertificatesToRootDb(void)
+{
+ result r = E_SUCCESS;
+ int certTrustTypes = 0;
+ int certCount = 0;
+
+ ClearLastResult();
+
+ certTrustTypes = static_cast< int >(_CERT_TRUST_DEV_ROOT_CA | _CERT_TRUST_DEV_DOMAIN);
+
+ _CertServer::RemoveCerts(certTrustTypes);
+
+ r = _CertServer::InsertCerts(certTrustTypes, &certCount);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), 0, E_SYSTEM, "[E_SYSTEM] Failed to install certificates.");
+
+ return certCount;
+}
+
+result
+_CertServer::InsertCertificateChainContext(CertChainCtx pCertCtx)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+ _CertChain* pCertChain = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertCtx != null, E_INVALID_ARG, "Invalid certificate chain context.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ pCertChain = reinterpret_cast< _CertChain* >(pCertCtx);
+
+ r = pCertDb->InsertCertChain(_CERT_X509, pCertChain);
+ SysTryReturn(NID_SEC_CERT, !(IsFailed(r) && (r != E_OBJ_ALREADY_EXIST) && (r != E_FILE_ALREADY_EXIST)), r, r, "[%s] Failed to install certificate chain.", GetErrorMessage(r));
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertCaCertificate(_CaCertType type, _CertFormat format, byte* pCertBuf, int certLen)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_INVALID_ARG, "Invalid certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Invalid certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
+ SysTryReturnResult(NID_SEC_CERT, type < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->InsertCaCertificateFromBuffer(type, format, pCertBuf, certLen);
+ SysTryReturnResult(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), E_SYSTEM, "Failed to install ca certificate from input buffer.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertUserCaCertificate(_CertFormat format, char* pCert, int certLen)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Invalid input certificate length.");
+
+ _CertDbManager* pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->InsertCaCertificateFromBuffer(_CERT_TYPE_ROOT_CA_BY_USER, format, reinterpret_cast< byte* >(pCert), certLen);
+ SysTryReturnResult(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), E_SYSTEM, "Failed to install certificate from input buffer.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertUserCaCertificate(byte* pFilePath)
+{
+ result r = E_SUCCESS;
+ _CertFormat certFormat = _CERT_X509;
+ _CertDomainType res;
+ CertChainCtx certCtx = null;
+ File file;
+ FileAttributes attr;
+ int certLen = 0;
+ int readCnt = 0;
+ long fileSize = 0;
+ String fileName(reinterpret_cast< char* >(pFilePath));
+
+ SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "Invalid file path.");
+
+ r = File::GetAttributes(fileName, attr);
+
+ fileSize = attr.GetFileSize();
+ SysTryReturn(NID_SEC_CERT, fileSize > 0, r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
+ SysTryReturn(NID_SEC_CERT, fileSize < _MAX_CERTIFICATE_SIZE, r, r, "[%s] File size exceeds maximum specified length.", GetErrorMessage(r));
+
+ r = file.Construct(fileName, L"r");
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct file.", GetErrorMessage(r));
+
+ std::unique_ptr< char[] > pCertBuf(new (std::nothrow) char[fileSize + 1]);
+ SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_OUT_OF_MEMORY, "Allocating new char array failed.");
+ memset(pCertBuf.get(), 0, (fileSize + 1));
+
+ readCnt = file.Read(pCertBuf.get(), fileSize);
+ r = GetLastResult();
+ SysTryReturn(NID_SEC_CERT, (readCnt == fileSize) || (!IsFailed(r)), r, r, "[%s] Failed to read file.", GetErrorMessage(r));
+
+ certLen = readCnt;
+
+ r = _CertService::OpenContext(_CERT_CONTEXT_CERT, &certCtx);
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] Unable to open certificate context.");
+
+ r = _CertService::AddCertificate(certCtx, reinterpret_cast< byte* >(pCertBuf.get()), certLen);
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] Unable to add certificate to context.");
+
+ r = _CertService::VerifyChain(certCtx, &res);
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] Unable to verify certificate chain context.");
+
+ r = _CertServer::InsertUserCaCertificate(certFormat, pCertBuf.get(), certLen);
+ SysTryCatch(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), r = E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] Unable to insert user ca certificate context.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+CATCH:
+
+ if (certCtx)
+ {
+ _CertService::CloseContext(certCtx);
+ }
+
+ return r;
+}
+
+result
+_CertServer::InsertUserCertChainPrivateKey(char* pCertChainBuffer, int certChainLength, char* pUserPrivateKey, int userPrivateKeyLength)
+{
+ result r = E_SUCCESS;
+ _CertChain* pCertTempChain = null;
+ _CertPrivateKeyInfo* pPrivateKeyTempInfo = null;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertChainBuffer != null, E_INVALID_ARG, "Failed to insert user certificate chain.");
+ SysTryReturnResult(NID_SEC_CERT, certChainLength > 0, E_INVALID_ARG, "Failed to insert user certificate chain.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = _CertManager::MakeParseAndVerifyCertChainBufferN(reinterpret_cast< byte* >(pCertChainBuffer), certChainLength, reinterpret_cast< byte* >(pUserPrivateKey), userPrivateKeyLength, &pCertTempChain, &pPrivateKeyTempInfo);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to parse and verify certificate chain buffer.", GetErrorMessage(r));
+
+ std::unique_ptr< _CertChain > pCertChain(pCertTempChain);
+ SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_SYSTEM, "Invalid certificate chain.");
+ pCertTempChain = null;
+
+ std::unique_ptr< _CertPrivateKeyInfo > pPrivateKeyInfo(pPrivateKeyTempInfo);
+ pPrivateKeyTempInfo = null;
+
+ r = pCertDb->InsertCertificateChain(_CERT_X509, pCertChain.get(), pPrivateKeyInfo.get());
+ SysTryReturn(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), r, r, "[%s] Failed to insert certificate chain.", GetErrorMessage(r));
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertCertificateChainWithPrivateKey(char* pCertChainPrivateKeyBuffer, int certChainPrivateKeyLength)
+{
+ result r = E_SUCCESS;
+ int privateKeyLen = 0;
+ int certChainLength = 0;
+ char* pCertChainBuffer = null;
+ _CertChain* pCertTempChain = null;
+ _CertDbManager* pCertDb = null;
+ _CertPrivateKeyInfo* pPrivateKeyTempInfo = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertChainPrivateKeyBuffer != null, E_INVALID_ARG, "Invalid private key buffer.");
+ SysTryReturnResult(NID_SEC_CERT, certChainPrivateKeyLength > 0, E_INVALID_ARG, "Invalid private key length.");
+
+ privateKeyLen = _CertManager::GetBlockSize(reinterpret_cast< byte* >(pCertChainPrivateKeyBuffer));
+ SysTryReturnResult(NID_SEC_CERT, privateKeyLen > 0, E_SYSTEM, "Failed to get private key length.");
+
+ pCertChainBuffer = pCertChainPrivateKeyBuffer + privateKeyLen;
+ certChainLength = certChainPrivateKeyLength - privateKeyLen;
+
+ SysTryReturnResult(NID_SEC_CERT, certChainLength > 0, E_INVALID_ARG, "Invalid private key length.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = _CertManager::MakeParseAndVerifyCertChainBufferN(reinterpret_cast< byte* >(pCertChainBuffer), certChainLength, reinterpret_cast< byte* >(pCertChainPrivateKeyBuffer), privateKeyLen, &pCertTempChain, &pPrivateKeyTempInfo);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to parse and verify certificate chain.", GetErrorMessage(r));
+
+ std::unique_ptr< _CertChain > pCertChain(pCertTempChain);
+ SysTryReturnResult(NID_SEC_CERT, pCertTempChain != null, E_SYSTEM, "Invalid certificate chain.");
+ pCertTempChain = null;
+
+ std::unique_ptr< _CertPrivateKeyInfo > pPrivateKeyInfo(pPrivateKeyTempInfo);
+ SysTryReturnResult(NID_SEC_CERT, pPrivateKeyTempInfo != null, E_SYSTEM, "Invalid private key info.");
+ pPrivateKeyTempInfo = null;
+
+ r = pCertDb->InsertCertificateChain(_CERT_X509, pCertChain.get(), pPrivateKeyInfo.get());
+ SysTryReturnResult(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), E_SYSTEM, "Failed to insert certificate chain");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::InsertPkcs12Content(char* pPkcs12FilePath, char* pPkcs12ImportPassword)
+{
+ result r = E_SUCCESS;
+ unsigned char* pTempPriKey = null;
+ unsigned char* pTempUserCertBuffer = null;
+ unsigned char* pTempCertBuffer = null;
+ std::unique_ptr< unsigned char[] > priKey;
+ std::unique_ptr< unsigned char[] > pCertChainBuffer;
+ std::unique_ptr< unsigned char > pCertBuffer;
+ std::unique_ptr< unsigned char > pUserCertBuffer;
+ int index = 0;
+ int curIndex = 0;
+ int priKeyLen = 0;
+ int userCertBufferLen = 0;
+ int certBufferLen = 0;
+ int certChainBufferLen = 0;
+ STACK_OF(X509)* pCaCertChain = null;
+ X509* pUserCert = null;
+ EVP_PKEY* pUserKey = null;
+ FILE* pFile = null;
+ PKCS12* pPkcs12Content = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pPkcs12FilePath != null, E_INVALID_ARG, "Invalid pkcs12 file path.");
+ SysTryReturnResult(NID_SEC_CERT, pPkcs12ImportPassword != null, E_INVALID_ARG, "Invalid pkcs12 password buffer.");
+
+ pFile = fopen(pPkcs12FilePath, "rb");
+ SysTryReturnResult(NID_SEC_CERT, pFile != null, E_SYSTEM, "Pkcs#12 file open failed.");
+
+ pPkcs12Content = d2i_PKCS12_fp(pFile, (PKCS12**) null);
+ SysTryCatch(NID_SEC_CERT, pPkcs12Content != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Pkcs 12 encoding failed.");
+
+ index = PKCS12_parse(pPkcs12Content, pPkcs12ImportPassword, &pUserKey, &pUserCert, &pCaCertChain);
+ SysTryCatch(NID_SEC_CERT, index != 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Pkcs 12 parsing failed.");
+
+ if (pUserKey != null)
+ {
+ priKeyLen = i2d_PrivateKey(pUserKey, &pTempPriKey);
+ priKey = std::unique_ptr< unsigned char[] >(pTempPriKey);
+ pTempPriKey = null;
+ }
+
+ userCertBufferLen = i2d_X509(pUserCert, &pTempUserCertBuffer);
+ pUserCertBuffer = std::unique_ptr< unsigned char >(pTempUserCertBuffer);
+ pTempUserCertBuffer = null;
+ certChainBufferLen = userCertBufferLen;
+
+ if (pCaCertChain && sk_num((_STACK*) pCaCertChain))
+ {
+ for (index = 0; index < sk_X509_num(pCaCertChain); index++)
+ {
+ certBufferLen = i2d_X509(sk_X509_value(pCaCertChain, index), &pTempCertBuffer);
+ certChainBufferLen = certChainBufferLen + certBufferLen;
+ pCertBuffer = std::unique_ptr< unsigned char >(pTempCertBuffer);
+ pTempCertBuffer = null;
+ certBufferLen = 0;
+ }
+
+ pCertChainBuffer = std::unique_ptr< unsigned char[] >(new (std::nothrow) unsigned char[certChainBufferLen]);
+ SysTryCatch(NID_SEC_CERT, pCertChainBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Allocating new char array failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+ memset(pCertChainBuffer.get(), 0, certChainBufferLen);
+ memcpy(pCertChainBuffer.get(), pUserCertBuffer.get(), userCertBufferLen);
+ curIndex = userCertBufferLen;
+
+ for (index = 0; index < sk_X509_num(pCaCertChain); index++)
+ {
+ certBufferLen = i2d_X509(sk_X509_value(pCaCertChain, index), &pTempCertBuffer);
+ pCertBuffer = std::unique_ptr< unsigned char >(pTempCertBuffer);
+ pTempCertBuffer = null;
+ memcpy((pCertChainBuffer.get() + curIndex), pCertBuffer.get(), certBufferLen);
+ curIndex = curIndex + certBufferLen;
+ certBufferLen = 0;
+ }
+ }
+ else
+ {
+ pCertChainBuffer = std::unique_ptr< unsigned char[] >(new (std::nothrow) unsigned char[certChainBufferLen]);
+ SysTryCatch(NID_SEC_CERT, pCertChainBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Allocating new char array failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+ memset(pCertChainBuffer.get(), 0, certChainBufferLen);
+ memcpy(pCertChainBuffer.get(), pUserCertBuffer.get(), userCertBufferLen);
+ }
+
+ r = InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pCertChainBuffer.get()), certChainBufferLen, reinterpret_cast< char* >(priKey.get()), priKeyLen);
+ SysTryCatch(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), , r, "[%s] Failed to insert user certificate chain.", GetErrorMessage(r));
+
+ r = _CertManager::CreateCrtFile();
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+CATCH:
+ fclose(pFile);
+ PKCS12_free(pPkcs12Content);
+ EVP_PKEY_free(pUserKey);
+ X509_free(pUserCert);
+ sk_X509_free(pCaCertChain);
+ return r;
+}
+
+result
+_CertServer::UpdateCaCertificate(_CaCertType type, char* pOldCert, int oldCertLen, char* pNewCert, int newCertLen) // if same certificate is in Db, replace the certificate using buffer2 and bufferLen2.
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+ _CertFormat certFormat = _CERT_UNKNOWN;
+ int derCertBufferLengthOld = 0;
+ int derCertBufferLengthNew = 0;
+ byte* pDerCertOld = null;
+ byte* pDerCertNew = null;
+ _CertEncodingType encodingType = _CERT_ENC_TYPE_UNKNOWN;
+
+ SysTryReturnResult(NID_SEC_CERT, pOldCert != null, E_INVALID_ARG, "Invalid old certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, oldCertLen > 0, E_INVALID_ARG, "Invalid old certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, pNewCert != null, E_INVALID_ARG, "Invalid new certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, newCertLen > 0, E_INVALID_ARG, "Invalid new certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
+ SysTryReturnResult(NID_SEC_CERT, type < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ certFormat = _CertManager::GetEncodedCertBuffer(reinterpret_cast< byte* >(pOldCert), oldCertLen, &pDerCertOld, &derCertBufferLengthOld, &encodingType);
+ SysTryReturnResult(NID_SEC_CERT, pDerCertOld != null, E_SYSTEM, "Invalid old certificate buffer.");
+
+ std::unique_ptr< byte[] > pDerCertBufferOld(pDerCertOld);
+ SysTryReturnResult(NID_SEC_CERT, pDerCertBufferOld != null, E_INVALID_ARG, "Invalid old certificate buffer.");
+
+ pDerCertOld = null;
+ SysTryReturnResult(NID_SEC_CERT, derCertBufferLengthOld > 0, E_SYSTEM, "Invalid old certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_SYSTEM, "Failed to find certificate format.");
+
+ certFormat = _CertManager::GetEncodedCertBuffer(reinterpret_cast< byte* >(pNewCert), newCertLen, &pDerCertNew, &derCertBufferLengthNew, &encodingType);
+ SysTryReturnResult(NID_SEC_CERT, pDerCertNew != null, E_SYSTEM, "Invalid new certificate buffer.");
+
+ std::unique_ptr< byte[] > pDerCertBufferNew(pDerCertNew);
+ SysTryReturnResult(NID_SEC_CERT, pDerCertBufferNew != null, E_SYSTEM, "Invalid new certificate buffer.");
+
+ pDerCertNew = null;
+
+ SysTryReturnResult(NID_SEC_CERT, derCertBufferLengthNew > 0, E_SYSTEM, "Invalid new certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_SYSTEM, "Failed to find certificate format.");
+
+ r = pCertDb->UpdateCaCertificateFromBuffer(type, certFormat, reinterpret_cast< byte* >(pDerCertBufferOld.get()), derCertBufferLengthOld, reinterpret_cast< byte* >(pDerCertBufferNew.get()), derCertBufferLengthNew);
+ if (r == E_DATA_NOT_FOUND)
+ {
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OBJ_NOT_FOUND, "Certificate not found in db.");
+ }
+
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "An unexpected system error occurred.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveUserCertChainByCertId(int certId)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid certificate id.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->RemoveCertificateChainByCertId(certId);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete user certificate chain.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveUserCaCertificateByCertId(int certId)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid certificate id.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->RemoveUserCaCertificateByCertId(certId);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete root ca certificate.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveCaCertificate(_CaCertType type, char* pBuffer, int bufLen) // if same certificate is in Db, remove the certificate.
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+ _CertFormat certFormat = _CERT_UNKNOWN;
+ byte* pDerCert = null;
+ int derCertBufferLength = 0;
+ _CertEncodingType encodingType = _CERT_ENC_TYPE_UNKNOWN;
+
+ SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input certificate buffer.");
+ SysTryReturnResult(NID_SEC_CERT, bufLen > 0, E_INVALID_ARG, "Invalid input certificate length.");
+
+ SysTryReturnResult(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
+ SysTryReturnResult(NID_SEC_CERT, type < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ certFormat = _CertManager::GetEncodedCertBuffer(reinterpret_cast< byte* >(pBuffer), bufLen, &pDerCert, &derCertBufferLength, &encodingType);
+ SysTryReturnResult(NID_SEC_CERT, pDerCert != null, E_SYSTEM, "Input certificate buffer.");
+
+ std::unique_ptr< byte[] > pDerCertBuffer(pDerCert);
+ SysTryReturnResult(NID_SEC_CERT, pDerCertBuffer != null, E_SYSTEM, "Invalid certificate buffer.");
+ pDerCert = null;
+
+ SysTryReturnResult(NID_SEC_CERT, derCertBufferLength > 0, E_SYSTEM, "Invalid certificate length.");
+ SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_SYSTEM, "Failed to find certificate format.");
+
+ r = pCertDb->RemoveCaCertificateFromBuffer(type, certFormat, reinterpret_cast< byte* >(pDerCertBuffer.get()), derCertBufferLength);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to remove Ca certificate.", GetErrorMessage(r));
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveCert(_CaCertType type)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
+ SysTryReturnResult(NID_SEC_CERT, type < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->RemoveCaCertificateByType(type);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete certificate of type %d", type);
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveCerts(int certTrustTypes)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_SEC_CERT, certTrustTypes >= 0, E_INVALID_ARG, "Invalid certificate trust type.");
+
+ if (certTrustTypes & _CERT_TRUST_SIM_DOMAIN)
+ {
+ r = _CertServer::RemoveCert(_CERT_TYPE_SIM_ROOT_DOMAIN1);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate for domain1.");
+
+ r = RemoveCert(_CERT_TYPE_SIM_ROOT_DOMAIN3);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate for domain3.");
+ }
+
+ if (certTrustTypes & _CERT_TRUST_DEV_ROOT_CA)
+ {
+ r = _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_CA);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove root ca certificate.");
+ }
+
+ if (certTrustTypes & _CERT_TRUST_DEV_DOMAIN)
+ {
+ r = _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN1);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate for domain1.");
+ r = _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN2);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate for domain2.");
+ r = _CertServer::RemoveCert(_CERT_TYPE_DEV_ROOT_DOMAIN3);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate for domain3.");
+ }
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::RemoveUserCaCertificatesFromRootDb(void)
+{
+ result r = E_SUCCESS;
+ int certTrustTypes = 0;
+
+ certTrustTypes = static_cast< int >(_CERT_TRUST_DEV_ROOT_CA | _CERT_TRUST_DEV_DOMAIN);
+
+ r = _CertServer::RemoveCerts(static_cast< _CaCertType >(certTrustTypes));
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to remove certificate.");
+
+ r = _CertManager::CreateCrtFile();
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create crt file.", GetErrorMessage(r));
+
+ return r;
+}
+
+result
+_CertServer::GetUserCertChainByIssuerAndSubjectNameN(char* pIssuerName, int issuerNameLength, char* pSubjectName, int subjectNameLength, _CertificateListInfo*& pUserCertListInfoTypesRef)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pIssuerName != null, E_INVALID_ARG, "Invalid certificate's issuer name.");
+ SysTryReturnResult(NID_SEC_CERT, issuerNameLength > 0, E_INVALID_ARG, "Invalid certificate's issuer name length.");
+ SysTryReturnResult(NID_SEC_CERT, issuerNameLength < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_INVALID_ARG, "Invalid certificate's issuer name length.");
+ SysTryReturnResult(NID_SEC_CERT, pSubjectName != null, E_INVALID_ARG, "Invalid certificate's subject name.");
+ SysTryReturnResult(NID_SEC_CERT, subjectNameLength > 0, E_INVALID_ARG, "Invalid certificate's subject name length.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->GetUserCertificateChain(pIssuerName, issuerNameLength, pSubjectName, subjectNameLength, _CERT_ENC_TYPE_BINARY, &pUserCertListInfoTypesRef);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to get user certificate chain.");
+
+ return r;
+}
+
+result
+_CertServer::GetUserCertificateByCertIdN(int certId, _CertEncodingType encodingType, _CertInfo*& pUserCertificateInfoRef)
+{
+ result r = E_SUCCESS;
+ _CertDbManager* pCertDb = null;
+
+ SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid input parameter.");
+
+ pCertDb = _CertDbManager::GetInstance();
+ SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
+
+ r = pCertDb->GetUserCertificateInfoByCertId(certId, encodingType, &pUserCertificateInfoRef);
+ SysTryReturn(NID_SEC_CERT, pCertDb != null, r, r, "[%s]Failed to get user certificate by input cert identifier: (%d).", GetErrorMessage(r), certId);
+
+ return r;
+}
+
+result
+_CertServer::GetUserCertFieldInfoByCertId(int certId, _CertFieldInfos* pCertFieldInfos)
+{
+ result r = E_SUCCESS;
+ _CertInfo* pCertInfo = null;
+ CertificateHandle certificateHandle = null;
+
+ SysTryReturnResult(NID_SEC_CERT, pCertFieldInfos != null, E_INVALID_ARG, "Invalid input parameter.");
+ SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid input parameter.");
+
+ r = GetUserCertificateByCertIdN(certId, _CERT_ENC_TYPE_BINARY, pCertInfo);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get user certificate.", GetErrorMessage(r));
+
+ memset(pCertFieldInfos, 0, sizeof(*pCertFieldInfos));
+
+ if (pCertInfo != null && pCertInfo->certLength != 0)
+ {
+ r = _CertService::OpenCertificate(reinterpret_cast< char* >(pCertInfo->certificate), pCertInfo->certLength, &certificateHandle);
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to open certificate.");
+
+ r = _CertService::GetCertInfo(certificateHandle, _CERT_FIELD_ALL, pCertFieldInfos);
+ SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate info.");
+
+ pCertFieldInfos[0].certType = _CERT_TYPE_USER_CERT;
+ pCertFieldInfos[0].certFileId = pCertInfo->certId;
+ _CertService::CloseCertificate(&certificateHandle);
+ }
+
+CATCH:
+ _CertService::FreeCertificateInfo(pCertInfo);
+ _CertService::CloseCertificate(&certificateHandle);
+ return r;
+
+}
+
+CertificateStoreCtx
+_CertServer::OpenCertificateStoreByType(_CaCertType type, int* pCount)
+{
+ CertificateStoreCtx retCtx;
+ int count = 0;
+
+ if (type == _CERT_TYPE_USER_CERT)
+ {
+ retCtx = _CertManager::OpenUserCertificateStore(count);
+ }
+ else
+ {
+ retCtx = _CertManager::OpenRootCaStore(type, count);
+ }
+
+ if (pCount != null)
+ {
+ *pCount = count;
+ }
+
+ return retCtx;
+}
+
+result
+_CertServer::CloseCertificateStore(CertificateStoreCtx certificateStoreCtx)
+{
+ _CertRootList* pTemp = null;
+
+ SysTryReturnResult(NID_SEC_CERT, certificateStoreCtx != null, E_INVALID_ARG, "Invalid input parameter.");
+
+ std::unique_ptr< _CertRootCaInfo > pRootCa(reinterpret_cast< _CertRootCaInfo* >(certificateStoreCtx));
+ SysTryReturnResult(NID_SEC_CERT, pRootCa->pRootList != null, E_INVALID_ARG, "Allocating new _CertRootCaInfo failed.");
+
+ while (pRootCa->pRootList != null)
+ {
+ pTemp = pRootCa->pRootList->pNext;
+ delete (pRootCa->pRootList);
+ pRootCa->pRootList = pTemp;
+ }
+ if (pRootCa->curPos)
+ {
+ pRootCa->curPos = 0;
+ }
+
+ return E_SUCCESS;
+}
+
+int
+_CertServer::GetCertificateCount(CertificateStoreCtx certificateStoreCtx)
+{
+ _CertRootCaInfo* pRootCa = null;
+ int count = 0;
+ _CertRootList* pTemp = null;
+
+ ClearLastResult();
+
+ if (certificateStoreCtx != null)
+ {
+ pRootCa = reinterpret_cast< _CertRootCaInfo* >(certificateStoreCtx);
+ if (pRootCa->pRootList != null)
+ {
+ pTemp = pRootCa->pRootList;
+ }
+ else
+ {
+ return 0;
+ }
+ while (pTemp != null)
+ {
+ count++;
+ pTemp = pTemp->pNext;
+ }
+ }
+
+ return count;
+}
+
+result
+_CertServer::GetNextCertificate(CertificateStoreCtx certificateStoreCtx, int& curPos, char* pBuffer, int* pBufferLen)
+{
+ _CertRootCaInfo* pRootCa = null;
+ _CertRootList* pTemp = null;
+ int count = 0;
+
+ SysTryReturnResult(NID_SEC_CERT, certificateStoreCtx != null, E_INVALID_ARG, "Invalid certificate store context.");
+ SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input buffer.");
+ SysTryReturnResult(NID_SEC_CERT, pBufferLen != null, E_INVALID_ARG, "Invalid input buffer length.");
+
+ pRootCa = reinterpret_cast< _CertRootCaInfo* >(certificateStoreCtx);
+ SysTryReturnResult(NID_SEC_CERT, pRootCa->pRootList != null, E_OBJ_NOT_FOUND, "Certificate list is empty.");
+
+ pTemp = pRootCa->pRootList;
+
+ while (count != curPos)
+ {
+ count++;
+ SysTryReturnResult(NID_SEC_CERT, pTemp->pNext != null, E_OBJ_NOT_FOUND, "Certificate index not found.");
+
+ pTemp = pTemp->pNext;
+ }
+
+ pRootCa->pCurrRootList = pTemp;
+ if (*pBufferLen > static_cast< int >(pRootCa->pCurrRootList->length))
+ {
+ memcpy(pBuffer, pRootCa->pCurrRootList->certificate, pRootCa->pCurrRootList->length);
+ *pBufferLen = pRootCa->pCurrRootList->length;
+ }
+ else
+ {
+ memcpy(pBuffer, pRootCa->pCurrRootList->certificate, *pBufferLen);
+ }
+
+ curPos++;
+
+ return E_SUCCESS;
+}
+
+} } } //Tizen::Security::Cert