//
-// Open Service Platform
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the License);
#include <FSecCertX509Certificate.h>
#include <FBaseSysLog.h>
#include <FBase_StringConverter.h>
+#include <FSec_AccessController.h>
+#include <FSec_AccessControlTypes.h>
+#include <FSecCert_CertServer.h>
#include <FSecCert_CertService.h>
#include <FSecCert_CertServiceProxy.h>
#include <FSecCert_X509CertificateStoreImpl.h>
static const int _MAX_CERT_BUFFER_SIZE = 2048;
+int
+GetIndexFromCertType(int certType)
+{
+ int index = 0;
+ switch (certType)
+ {
+ case _CERT_TYPE_ROOT_CA:
+ index = 0;
+ break;
+
+ case _CERT_TYPE_ROOT_DOMAIN1:
+ index = 1;
+ break;
+
+ case _CERT_TYPE_ROOT_DOMAIN3:
+ index = 2;
+ break;
+
+ default:
+ SysTryReturn(NID_SEC_CERT, false, -1, E_INVALID_ARG, "[%s] Invalid certificate type.", GetErrorMessage(E_INVALID_ARG));
+ break;
+ }
+
+ return index;
+}
+
_X509CertificateStoreImpl::_X509CertificateStoreImpl(void)
: __certType(static_cast< int >(_CERT_TYPE_NOT_BOUNDED))
- , __certificateStoreCtx(0)
+ , __curPos(0)
{
ClearLastResult();
+ memset(__context, 0, sizeof(__context));
+
__pCertServiceProxy = _CertServiceProxy::GetInstance();
SysTryReturnVoidResult(NID_SEC_CERT, __pCertServiceProxy != null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate proxy instance.");
+
+ // restore root CA cert DB
+ __pCertServiceProxy->RestoreRootCaIntegrity();
+ ClearLastResult();
}
_X509CertificateStoreImpl::~_X509CertificateStoreImpl(void)
{
-
- if (__certificateStoreCtx != 0)
+ if ((__certType > _CERT_TYPE_NOT_BOUNDED) && (__certType < _CERT_TYPE_MAX))
{
- __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
+ __pCertServiceProxy->CloseCertificateStore(__certType);
}
}
result
_X509CertificateStoreImpl::GetName(String& name) const
{
- result r = __pCertServiceProxy->GetName();
- if (!IsFailed(r))
- {
- name = L"CertServiceStore";
- }
-
- return r;
+ name = L"CertServiceStore";
+ return E_SUCCESS;
}
result
_X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
{
+ result r = E_SUCCESS;
+
+ int prevIndex = GetIndexFromCertType(__certType);
+ if (__certType == _CERT_TYPE_USER_CERT)
+ {
+ r = __pCertServiceProxy->CloseCertificateStore(__certType);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to close certificate store.");
+ }
+ else if (prevIndex > -1 && __context[prevIndex] != 0)
+ {
+ r = _CertServer::CloseCertificateStore(reinterpret_cast< CertificateStoreCtx >(__context[prevIndex]));
+ __context[prevIndex] = 0;
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to close certificate store.");
+ }
+
int count = 0;
+ __curPos = 0;
CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
-
switch (certType)
{
case ROOT_CA:
case USER_CERT:
__certType = _CERT_TYPE_USER_CERT;
- break;
+ return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count);
default:
SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
break;
}
- if (__certificateStoreCtx != 0)
+ CertificateStoreCtx certList = null;
+ int index = GetIndexFromCertType(__certType);
+
+ if (__context[index] == 0)
{
- __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
- __certificateStoreCtx = 0;
+ certList = _CertServer::OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), &count);
+ r = GetLastResult();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to open certificate store.");
+ __context[index] = reinterpret_cast< int >(certList);
}
- return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count, __certificateStoreCtx);
+ return E_SUCCESS;
}
result
-_X509CertificateStoreImpl::GetCertificateCount(int& count) const
+_X509CertificateStoreImpl::GetCertificateCount(int& count)
{
- if (__certificateStoreCtx != 0)
+ result r = E_SUCCESS;
+
+ if (__certType == _CERT_TYPE_USER_CERT)
{
- return __pCertServiceProxy->GetCertificateCount(__certificateStoreCtx, count);
+ r = __pCertServiceProxy->GetCertificateCount(__certType, count);
}
+ else
+ {
+ r = _AccessController::CheckUserPrivilege(_PRV_CERTIFICATE_READ);
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_PRIVILEGE_DENIED, "The application does not have the privilege to call this method.");
- count = 0;
- return E_SUCCESS;
-}
+ int index = GetIndexFromCertType(__certType);
+ SysTryReturnResult(NID_SEC_CERT, index > -1, E_SYSTEM, "Failed to open certificate store.");
+ count = _CertServer::GetCertificateCount(reinterpret_cast< CertificateStoreCtx >(__context[index]));
+ }
+ return r;
+}
Tizen::Security::Cert::ICertificate*
-_X509CertificateStoreImpl::GetNextCertificateN(void) const
+_X509CertificateStoreImpl::GetNextCertificateN(void)
{
result r = E_SUCCESS;
ByteBuffer certBuffer;
byte certBytes[_MAX_CERT_BUFFER_SIZE] = {0, };
int certLen = sizeof(certBytes);
+ int curPos = __curPos;
ClearLastResult();
- SysTryReturn(NID_SEC_CERT, __certificateStoreCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call SetCertificateSelector() function.");
+ if (__certType == _CERT_TYPE_USER_CERT)
+ {
+ r = __pCertServiceProxy->GetNextCertificate(__certType, curPos, certBytes, certLen);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to get next root certificate.", GetErrorMessage(r));
+ }
+ else
+ {
+ r = _AccessController::CheckUserPrivilege(_PRV_CERTIFICATE_READ);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_PRIVILEGE_DENIED, "The application does not have the privilege to call this method.");
+
+ _CertRootCaInfo* pRootCa = null;
+ _CertRootList* pTemp = null;
+ int count = 0;
+
+ int index = GetIndexFromCertType(__certType);
+ SysTryReturnResult(NID_SEC_CERT, index > -1, null, "Failed to open certificate store.");
+
+ CertificateStoreCtx certificateStoreCtx = reinterpret_cast< CertificateStoreCtx >(__context[index]);
+ SysTryReturn(NID_SEC_CERT, certificateStoreCtx != null, null, E_INVALID_ARG, "Invalid certificate store context.");
+
+ pRootCa = reinterpret_cast< _CertRootCaInfo* >(certificateStoreCtx);
+ SysTryReturn(NID_SEC_CERT, pRootCa->pRootList != null, null, E_OBJ_NOT_FOUND, "Certificate list is empty.");
+
+ pTemp = pRootCa->pRootList;
+
+ while (count != curPos)
+ {
+ count++;
+ SysTryReturn(NID_SEC_CERT, pTemp->pNext != null, null, E_OBJ_NOT_FOUND, "Certificate index not found.");
- r = __pCertServiceProxy->GetNextCertificate(__certificateStoreCtx, certBytes, certLen);
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to get next root certificate.", GetErrorMessage(r));
+ pTemp = pTemp->pNext;
+ }
+
+ pRootCa->pCurrRootList = pTemp;
+ if (certLen > static_cast< int >(pRootCa->pCurrRootList->length))
+ {
+ memcpy(certBytes, pRootCa->pCurrRootList->certificate, pRootCa->pCurrRootList->length);
+ certLen = pRootCa->pCurrRootList->length;
+ }
+ else
+ {
+ memcpy(certBytes, pRootCa->pCurrRootList->certificate, certLen);
+ }
+
+ curPos++;
+ }
+
+ __curPos = curPos;
r = certBuffer.Construct(certLen);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
else
{
r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
+
+ UpdateCertStoreContext(certType);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update cert store.", GetErrorMessage(r));
}
if (r == E_FILE_ALREADY_EXIST)
}
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
- r = UpdateCertStoreContext();
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
-
return r;
}
result
-_X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password)
+_X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password, bool checkPrivilege)
{
result r = E_SUCCESS;
std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "File path is invalid.");
//password can be null
- r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get());
+ r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get(), checkPrivilege);
if (r == E_FILE_ALREADY_EXIST)
{
r = E_SUCCESS;
}
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
-
- r = UpdateCertStoreContext();
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
+
return r;
}
oldBufferLen = pOldEncodedData->GetRemaining();
SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
- pOldEncodedData.reset(null);
-
std::unique_ptr< ByteBuffer > pNewEncodedData(newCert.GetEncodedDataN());
SysTryReturnResult(NID_SEC_CERT, pNewEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on new input certificate.");
_CertService::CloseCertificate(&certHandle);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
- r = __pCertServiceProxy->RemoveUserCaCertificateByCertId(certId);
+ r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove/update user certificates from store.", GetErrorMessage(r));
r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pNewBuffer), newBufferLen, null, 0);
{
r = __pCertServiceProxy->UpdateCaCertificate(static_cast< int >(certType), pOldBuffer, oldBufferLen, pNewBuffer, newBufferLen);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update certificate.", GetErrorMessage(r));
- }
- r = UpdateCertStoreContext();
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
+ UpdateCertStoreContext(certType);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update cert store.", GetErrorMessage(r));
+ }
return r;
}
result r = E_SUCCESS;
byte* pBuffer = null;
int bufferLen = 0;
+
_CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
switch (certificateType)
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
r = _CertService::GetUserCertificateId(certHandle, certId);
+
_CertService::CloseCertificate(&certHandle);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
- r = __pCertServiceProxy->RemoveUserCertificateByCertId(certId);
+ r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
}
else
{
r = __pCertServiceProxy->RemoveCaCertificate(static_cast< int >(certType), pBuffer, bufferLen);
SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
+
+ UpdateCertStoreContext(certType);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update cert store.", GetErrorMessage(r));
}
-
- r = UpdateCertStoreContext();
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
return r;
+}
+
+result
+_X509CertificateStoreImpl::UpdateCertStoreContext(int type)
+{
+ result r = E_SUCCESS;
+ CertificateStoreCtx certList = null;
+ int index = GetIndexFromCertType(type);
+
+ int count = 0;
+
+ if (index > -1 && type == __certType)
+ {
+ if (__context[index] != 0)
+ {
+ r = _CertServer::CloseCertificateStore(reinterpret_cast< CertificateStoreCtx >(__context[index]));
+ TryReturnResult(!IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
+ }
+ certList = _CertServer::OpenCertificateStoreByType(static_cast< _CaCertType >(type), &count);
+ r = GetLastResult();
+ SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to open certificate store.");
+ __context[index] = reinterpret_cast< int >(certList);
+ }
+
+ return r;
}
+
_X509CertificateStoreImpl*
_X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
{
return x509CertificateStore.__pX509CertificateStoreImpl;
}
-result
-_X509CertificateStoreImpl::UpdateCertStoreContext(void)
+int
+InsertPkcs12Content(const char* pPath, const char* pPassword)
{
result r = E_SUCCESS;
- int count =0;
+ _X509CertificateStoreImpl store;
+ String filePath;
+ String password;
- if (__certificateStoreCtx != 0)
- {
- __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
- r = __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count, __certificateStoreCtx);
- SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
- }
+ filePath.SetCapacity(strlen(pPath) + 1);
+ password.SetCapacity(strlen(pPassword) + 1);
- return r;
-}
+ filePath.Format(strlen(pPath) + 1, L"%s", pPath);
+ password.Format(strlen(pPassword) + 1, L"%s", pPassword);
+ r = store.InsertPkcs12(filePath, password, false);
+ SysTryReturn(NID_SEC_CERT, !IsFailed(r), -1, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
+
+ return 0;
+}
-} } } // Tizen::Security::Cert
+} } } // Tizen::Security::Cert