Applied sizeof operator on fixed sized array to calculate size.
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertManager.cpp
index 25155f6..d2d97f5 100644 (file)
@@ -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 <FIoDirEnumerator.h>
 #include <FIoFileAttributes.h>
 #include <FIoFile.h>
+#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
 {