X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsecurity%2Fcert%2FFSecCert_CertManager.cpp;h=d2d97f5bb63ba37749ae67f6590dd60731bc6754;hb=23e9bfa205cb5d90a34f53728baa5d4ec4fecb41;hp=25155f63c66f24f28548594b699873b356a708c5;hpb=90fa7aa7bcf38cf05b7095750cf6d7f0b678e4fd;p=platform%2Fframework%2Fnative%2Fappfw.git diff --git a/src/security/cert/FSecCert_CertManager.cpp b/src/security/cert/FSecCert_CertManager.cpp index 25155f6..d2d97f5 100644 --- a/src/security/cert/FSecCert_CertManager.cpp +++ b/src/security/cert/FSecCert_CertManager.cpp @@ -1,5 +1,4 @@ // -// Open Service Platform // Copyright (c) 2012 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the License); @@ -40,6 +39,7 @@ #include #include #include +#include "FSecCertX509Certificate.h" #include "FSecCert_CertManager.h" #include "FSecCert_CertPrivateKeyInfo.h" #include "FSecCert_CertDbManager.h" @@ -51,6 +51,17 @@ using namespace Tizen::Base; using namespace Tizen::System; using namespace Tizen::Io; +namespace +{ +struct ByteDeleter +{ + void operator ()(byte* c) + { + free(c); + } +}; +} + namespace Tizen { namespace Security { namespace Cert { @@ -67,7 +78,6 @@ _CertManager::CreateCrtFile(void) File fileCrt; FileAttributes attr; byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, }; - const unsigned char* pCertBuffer = null; long fileSize = 0; int certBufferLen = 0; int readLength = 0; @@ -120,13 +130,14 @@ _CertManager::CreateCrtFile(void) pBio = BIO_new(BIO_s_mem()); SysTryCatch(NID_SEC_CERT, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); - pCertBuffer = new (std::nothrow) unsigned char[readCnt]; + std::unique_ptr< unsigned char[] > pCertBuffer(new (std::nothrow) unsigned char[readCnt]); SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); - memcpy((void*) pCertBuffer, certBufData, readCnt); + memcpy(static_cast< void* >(pCertBuffer.get()), certBufData, readCnt); certBufferLen = readCnt; - pCert = d2i_X509(null, &pCertBuffer, certBufferLen); + const unsigned char* pTemp = pCertBuffer.get(); + pCert = d2i_X509(null, &pTemp, certBufferLen); SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed."); readLength = PEM_write_bio_X509(pBio, pCert); @@ -185,7 +196,7 @@ _CertManager::AddCertificate(CertChainCtx certCtx, byte* pCert, int certLen) SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameters are invalid."); certFormat = _CertManager::GetEncodedCertBuffer(pCert, certLen, &pDerCert, &derCertBufferLength, &encodingType); - std::unique_ptr< byte[] > pDerCertBuffer(pDerCert); + std::unique_ptr< byte, ByteDeleter > pDerCertBuffer(pDerCert); pDerCert = null; SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Unsupported certificate format."); @@ -342,6 +353,8 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial params not set."); SysTryReturnResult(NID_SEC_CERT, pCertInfo != null, E_INVALID_ARG, "Initial params not set."); + memset(pCertInfo, 0, sizeof(_CertFieldInfos)); + pTbsCert = pCert->GetTbsCertInstance(); SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance."); @@ -358,7 +371,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1); for (index = 0; index < iterVal; index++) { - sprintf(&pCertInfo->serialNo[index * 2], "%02X", pSerialNumber[index]); + snprintf(&pCertInfo->serialNo[index * 2], (_MAX_SERIAL_NUMBER_SIZE + 1), "%02X", pSerialNumber[index]); } } } @@ -370,7 +383,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C int len = strlen(pSigAlg); if (len <= _MAX_CERT_ALGORITHM_SIZE) { - strcpy(pCertInfo->sigAlgorithm, pSigAlg); + snprintf(pCertInfo->sigAlgorithm, sizeof(pCertInfo->sigAlgorithm), "%s", pSigAlg); } else { @@ -388,13 +401,17 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C { Tizen::Base::DateTime notBefore; Tizen::Base::DateTime notAfter; + pTbsCert->GetAfterTimes(notAfter); pTbsCert->GetBeforeTimes(notBefore); + memset(pCertInfo->validityFrom, 0, _MAX_CERT_VALIDITY_SIZE + 1); memset(pCertInfo->validityTo, 0, _MAX_CERT_VALIDITY_SIZE + 1); _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom); + _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo); + } if (field & _CERT_FIELD_SUBJECT) @@ -404,7 +421,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C memset(pCertInfo->subjectName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1); if (subLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1) { - strcpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName)); + snprintf(pCertInfo->subjectName, sizeof(pCertInfo->subjectName), "%s", reinterpret_cast< const char* >(pSubjectName)); } ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle); ClearLastResult(); @@ -416,7 +433,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C memset(pCertInfo->issuerName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1); if (issuerLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1) { - strcpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName)); + snprintf(pCertInfo->issuerName, sizeof(pCertInfo->issuerName), "%s", reinterpret_cast< const char* >(pIssuerName)); } ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle); ClearLastResult(); @@ -444,7 +461,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C int maxValue = SHA_DIGEST_LENGTH; for (index = 0; index < maxValue; index++) { - sprintf(&pCertInfo->fingerPrint[index * 2], "%02X", pFingerPrint[index]); + snprintf(&pCertInfo->fingerPrint[index * 2], (_MAX_CERT_FINGERPRINT_SIZE + 1), "%02X", pFingerPrint[index]); } pCertInfo->fingerPrintLen = fingerPrintLen; @@ -462,7 +479,7 @@ _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _C memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1); for (index = 0; index < iterVal; index++) { - sprintf(&pCertInfo->publicKey[index * 2], "%02X", pPublicKeyBuffer[index]); + snprintf(&pCertInfo->publicKey[index * 2], (_MAX_CERT_PUBLIC_KEY_SIZE + 1), "%02X", pPublicKeyBuffer[index]); } } @@ -538,7 +555,7 @@ _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** } else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS) { - std::unique_ptr< byte[] > pCertBuf(new (std::nothrow) byte[certBufferLen]); + std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufferLen))); SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); memcpy(pCertBuf.get(), pCertBuffer, certBufferLen); @@ -555,7 +572,7 @@ _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** certBufLen = _Base64::GetDecodedSize(certBufferLen); SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length."); - std::unique_ptr< byte[] > pCertBuf(new (std::nothrow) byte[certBufLen]); + std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufLen))); SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); memset(pCertBuf.get(), 0, certBufLen); @@ -745,8 +762,8 @@ _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCer SysTryReturnResult(NID_SEC_CERT, lenSubjectName > 0, E_SYSTEM, "Subject length is not valid."); SysTryReturnResult(NID_SEC_CERT, lenIssuerName > 0, E_SYSTEM, "Issuer length is not valid."); - strcpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName())); - strcpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())); + snprintf(subjectName, sizeof(subjectName), "%s", reinterpret_cast< const char* >(pTbsCert->GetSubjectName())); + snprintf(issuerName, sizeof(issuerName), "%s", reinterpret_cast< const char* >(pTbsCert->GetIssuerName())); pCertDb = _CertDbManager::GetInstance(); SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager."); @@ -777,7 +794,7 @@ _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], ch char* pSubStr = null; char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, }; - strncpy(tempSubject, subject, strlen(subject)); + snprintf(tempSubject, sizeof(tempSubject), "%s", subject); pPivotPtr = tempSubject; for (;; pSubStr = null) { @@ -1090,7 +1107,7 @@ _CertManager::OpenUserCertificateStore(int& totalCount) totalCount = 0; - sprintf(condition, "installed = '%s'", installedRecord); + snprintf(condition, sizeof(condition), "installed = '%s'", installedRecord); std::unique_ptr< _UserCertDbStore > pUserCertDbStore(new (std::nothrow) _UserCertDbStore()); SysTryReturn(NID_SEC_CERT, pUserCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); @@ -1168,7 +1185,7 @@ _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_T SysTryReturn(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type."); SysTryReturn(NID_SEC_CERT, type < _CERT_TYPE_MAX, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type."); - sprintf(condition, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord); + snprintf(condition, sizeof(condition), "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord); std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore()); SysTryReturn(NID_SEC_CERT, pCaCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory."); @@ -1225,6 +1242,82 @@ _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_T return certificateStoreCtx; } +result +_CertManager::CheckRootCaIntegrity(void) +{ + result r = E_SUCCESS; + CaCertRecord certRecord = {0}; + _CertFileStore fileStore; + 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(); + + snprintf(condition, sizeof(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)); + + do + { + 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)); + } + while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS); + + return E_SUCCESS; +} + enum _Asn1EncodingStyle {