From d4b4854c415f0940edb3471f12e2a4b51da9d28d Mon Sep 17 00:00:00 2001 From: "so.yu" Date: Mon, 27 May 2013 10:32:48 +0900 Subject: [PATCH] Add RestoreRootCaIntegrity() method internally Change-Id: I3a3ae506e845e9d982f57fee27469c040ddde893 Signed-off-by: so.yu --- src/security/cert/FSecCert_CertManager.cpp | 78 ++++++++++++++++++++++ src/security/cert/FSecCert_CertManager.h | 1 + src/security/cert/FSecCert_CertServer.cpp | 8 +++ src/security/cert/FSecCert_CertServiceProxy.cpp | 17 +++++ .../cert/FSecCert_X509CertificateStoreImpl.cpp | 4 ++ src/security/inc/FSecCert_CertMgrMessages.h | 1 + src/security/inc/FSecCert_CertServer.h | 12 ++++ src/security/inc/FSecCert_CertServiceProxy.h | 13 ++++ 8 files changed, 134 insertions(+) diff --git a/src/security/cert/FSecCert_CertManager.cpp b/src/security/cert/FSecCert_CertManager.cpp index 6708aab..09a009f 100644 --- a/src/security/cert/FSecCert_CertManager.cpp +++ b/src/security/cert/FSecCert_CertManager.cpp @@ -39,6 +39,7 @@ #include #include #include +#include "FSecCertX509Certificate.h" #include "FSecCert_CertManager.h" #include "FSecCert_CertPrivateKeyInfo.h" #include "FSecCert_CertDbManager.h" @@ -1235,6 +1236,83 @@ _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_T return certificateStoreCtx; } +result +_CertManager::CheckRootCaIntegrity(void) +{ + result r = E_SUCCESS; + CaCertRecord certRecord = {0}; + _CertRootList* pHoldList = null; + _CertFileStore fileStore; + CertificateStoreCtx certificateStoreCtx = null; + char condition[_MAX_TYPE_CONST_SIZE] = {0}; + char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0"; + static const int _BUF_SIZE = 4096; + static const int _FILE_NAME_LENGTH = 9; // 001.cert + static const wchar_t _ROOT_CA_CERT_FILE_DIRECTORY[] = L"/opt/usr/share/certs/rootcert/"; + + ClearLastResult(); + + sprintf(condition, "certType = %d and installed = '%s'", _CERT_TYPE_ROOT_CA, installedRecord); + + std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore()); + SysTryReturnResult(NID_SEC_CERT, pCaCertDbStore != null, E_OUT_OF_MEMORY, "Failed to allocate memory."); + + r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord); + SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r)); + + while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS) + { + std::unique_ptr< File > pFile(null); + std::unique_ptr< ByteBuffer > pBuffer(null); + std::unique_ptr< X509Certificate > pCert(null); + String tempPath(certRecord.fileName); + String certPath(_ROOT_CA_CERT_FILE_DIRECTORY); + ByteBuffer* pTempBuffer = null; + wchar_t certFile[_FILE_NAME_LENGTH] = {0, }; + swprintf(certFile, _FILE_NAME_LENGTH, L"%03d.cert", certRecord.certId); + certPath.Append(certFile); + + SysTryCatch(NID_SEC_CERT, certPath == tempPath, , E_SYSTEM, "[%s] The root CA certificate DB was damaged.", GetErrorMessage(E_SYSTEM)); + + pFile.reset(new (std::nothrow) File()); + SysTryReturnResult(NID_SEC_CERT, pFile != null, E_OUT_OF_MEMORY, "Failed to allocate memory."); + + r = pFile->Construct(certPath, "r"); + SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); + + pBuffer.reset(new (std::nothrow) ByteBuffer()); + SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory."); + + r = pBuffer->Construct(_BUF_SIZE); + SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); + + pTempBuffer = pBuffer.get(); + r = pFile->Read(*pTempBuffer); + SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); + + pTempBuffer->Flip(); + + pCert.reset(new (std::nothrow) X509Certificate()); + SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory."); + + r = pCert->Construct(*pTempBuffer); + SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); + + continue; + + CATCH: + SysSecureLog(NID_SEC_CERT, "Remove broken certificate %d", certRecord.certId); + + r = pCaCertDbStore->RemoveCertificateById(certRecord.certId); + SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r)); + + r = File::Remove(certPath); + SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r)); + } + + return r; +} + enum _Asn1EncodingStyle { diff --git a/src/security/cert/FSecCert_CertManager.h b/src/security/cert/FSecCert_CertManager.h index b185689..cb7b2ad 100644 --- a/src/security/cert/FSecCert_CertManager.h +++ b/src/security/cert/FSecCert_CertManager.h @@ -85,6 +85,7 @@ public: static CertificateStoreCtx OpenRootCaStore(_CaCertType type, int& count); + static result CheckRootCaIntegrity(void); private: static result ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE]); diff --git a/src/security/cert/FSecCert_CertServer.cpp b/src/security/cert/FSecCert_CertServer.cpp index 9c687a5..0136d70 100644 --- a/src/security/cert/FSecCert_CertServer.cpp +++ b/src/security/cert/FSecCert_CertServer.cpp @@ -119,6 +119,14 @@ _CertServer::ReInitializeDb(void) return r; } +void +_CertServer::RestoreRootCaIntegrity(void) +{ + result r = E_SUCCESS; + r = _CertManager::CheckRootCaIntegrity(); + SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Failed to restore the Root CA certificate DB.", GetErrorMessage(r)); +} + result _CertServer::DropTables(void) { diff --git a/src/security/cert/FSecCert_CertServiceProxy.cpp b/src/security/cert/FSecCert_CertServiceProxy.cpp index d6fd7fc..72aed1d 100755 --- a/src/security/cert/FSecCert_CertServiceProxy.cpp +++ b/src/security/cert/FSecCert_CertServiceProxy.cpp @@ -548,4 +548,21 @@ _CertServiceProxy::GetUserCertFieldInfoByCertId(int certId, _CertFieldInfos* pCe return r; } + +void +_CertServiceProxy::RestoreRootCaIntegrity(void) +{ + result r = E_SUCCESS; + + ClearLastResult(); + + SysTryReturnVoidResult(NID_SEC_CERT, __pIpcClient != null, E_SYSTEM, "[%s] IPC instance is not constructed.", GetErrorMessage(E_SYSTEM)); + + std::unique_ptr< IPC::Message > pMessage(new (std::nothrow) CertServer_RestoreRootCaIntegrity()); + SysTryReturnVoidResult(NID_SEC_CERT, pMessage != null, E_OUT_OF_MEMORY, "[%s] Failed to allocate memory.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = __pIpcClient->SendRequest(pMessage.get()); + SysTryReturnVoidResult(NID_SEC_CERT, !IsFailed(r), r, "[%s] Failed to send message.", GetErrorMessage(r)); +} + } } } diff --git a/src/security/cert/FSecCert_X509CertificateStoreImpl.cpp b/src/security/cert/FSecCert_X509CertificateStoreImpl.cpp index 4bbb700..1df2b3b 100644 --- a/src/security/cert/FSecCert_X509CertificateStoreImpl.cpp +++ b/src/security/cert/FSecCert_X509CertificateStoreImpl.cpp @@ -76,6 +76,10 @@ _X509CertificateStoreImpl::_X509CertificateStoreImpl(void) __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) diff --git a/src/security/inc/FSecCert_CertMgrMessages.h b/src/security/inc/FSecCert_CertMgrMessages.h index e987c9f..da207ec 100755 --- a/src/security/inc/FSecCert_CertMgrMessages.h +++ b/src/security/inc/FSecCert_CertMgrMessages.h @@ -303,3 +303,4 @@ IPC_SYNC_MESSAGE_CONTROL1_1(CertServer_DeleteUserCertChainByCertId, int, result) IPC_SYNC_MESSAGE_CONTROL4_2(CertServer_GetUserCertChainByIssuerAndSubjectNameN, Tizen::Io::_IpcBuffer, int, Tizen::Io::_IpcBuffer, int, Tizen::Security::Cert::_CertificateListInfo, result); IPC_SYNC_MESSAGE_CONTROL2_2(CertServer_GetUserCertificateByCertIdN, int, int, Tizen::Security::Cert::_CertInfo, result); IPC_SYNC_MESSAGE_CONTROL1_2(CertServer_GetUserCertFieldInfoByCertId, int, Tizen::Security::Cert::_CertFieldInfos, result); +IPC_SYNC_MESSAGE_CONTROL0_0(CertServer_RestoreRootCaIntegrity); diff --git a/src/security/inc/FSecCert_CertServer.h b/src/security/inc/FSecCert_CertServer.h index e19632f..0242f94 100644 --- a/src/security/inc/FSecCert_CertServer.h +++ b/src/security/inc/FSecCert_CertServer.h @@ -81,6 +81,18 @@ public: static result ReInitializeDb(void); /** + * This function restores the root CA certificate DB. + * + * @since 2.2 + * @return An error code. + * @exception E_SUCCESS The method is successful. + * @exception E_SYSTEM A system error has occurred. + * - File operation error. + * - DB operation failed. + */ + static void RestoreRootCaIntegrity(void); + + /** * This function drops the tables and removes all certificate files from the storage. * * @since 2.1 diff --git a/src/security/inc/FSecCert_CertServiceProxy.h b/src/security/inc/FSecCert_CertServiceProxy.h index f442a2a..ebf9133 100755 --- a/src/security/inc/FSecCert_CertServiceProxy.h +++ b/src/security/inc/FSecCert_CertServiceProxy.h @@ -384,6 +384,19 @@ public: * - DB operation failed. */ result GetUserCertFieldInfoByCertId(int certId, _CertFieldInfos* pCertFieldInfos); + + /** + * This function restores the root CA certificate DB. + * + * @since 2.2 + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * - IPC operation failed. + * - File operation failed. + * - DB operation failed. + */ + void RestoreRootCaIntegrity(void); private: // This default constructor is intentionally declared as private to -- 2.7.4