2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FSecCert_CertManager.cpp
19 * @brief This file contains implementation of X509 Certificate and private key interface APIs.
22 #include <unique_ptr.h>
31 #include <openssl/sha.h>
32 #include <openssl/evp.h>
33 #include <openssl/pem.h>
34 #include <FBaseByteBuffer.h>
35 #include <FBaseResult.h>
36 #include <FSysSystemTime.h>
37 #include <FBaseSysLog.h>
38 #include <FIoDirectory.h>
39 #include <FIoDirEnumerator.h>
40 #include <FIoFileAttributes.h>
42 #include "FSecCertX509Certificate.h"
43 #include "FSecCert_CertManager.h"
44 #include "FSecCert_CertPrivateKeyInfo.h"
45 #include "FSecCert_CertDbManager.h"
46 #include "FSecCert_Base64.h"
47 #include "FSecCert_CertOidDef.h"
48 #include "FSecCert_CertFileStore.h"
50 using namespace Tizen::Base;
51 using namespace Tizen::System;
52 using namespace Tizen::Io;
58 void operator ()(byte* c)
65 namespace Tizen { namespace Security { namespace Cert
68 static const char* _CERT_BASE64_HEADER = "-----BEGIN CERTIFICATE-----";
69 static const char* _CERT_BASE64_TRAILER = "-----END CERTIFICATE-----";
72 _CertManager::CreateCrtFile(void)
80 byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, };
82 int certBufferLen = 0;
84 int certificateBase64Len = 0;
86 String dirName(_CERT_ROOT_CA_CERT_FILE_DIRECTORY);
87 String crtFileName(_CERT_MGR_CRT_FILE_PATH);
88 String tmpCrtFileName(_TEMP_CERT_MGR_CRT_FILE_PATH);
90 r = fileCrt.Construct(tmpCrtFileName, L"a+");
91 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Construct failed.", GetErrorMessage(r));
93 r = dir.Construct(dirName);
94 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct directory.", GetErrorMessage(r));
96 std::unique_ptr< DirEnumerator > pDirEnum(dir.ReadN());
97 SysTryReturn(NID_SEC_CERT, pDirEnum != null, GetLastResult(), GetLastResult(), "[%s] Failed to read directory.", GetErrorMessage(GetLastResult()));
99 while (pDirEnum->MoveNext() == E_SUCCESS)
103 DirEntry entry = pDirEnum->GetCurrentDirEntry();
105 fileName.Append(dirName);
106 fileName.Append(entry.GetName());
107 if ((entry.GetName() == "..") || (entry.GetName() == "."))
112 r = file.Construct(fileName, L"r");
113 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct file.", GetErrorMessage(r));
115 r = File::GetAttributes(fileName, attr);
116 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
118 fileSize = attr.GetFileSize();
119 SysTryCatch(NID_SEC_CERT, fileSize > 0, r = GetLastResult(), GetLastResult(), "[%s] Failed to get file size.", GetErrorMessage(r));
120 SysTryCatch(NID_SEC_CERT, fileSize < _MAX_CERTIFICATE_SIZE, r = GetLastResult(), GetLastResult(), "[%s] File size exceeds maximum specified length.", GetErrorMessage(r));
122 readCnt = file.Read(certBufData, fileSize);
123 certificateBase64Len = _Base64::GetEncodedSize(readCnt);
125 if (!IsFailed(r) && readCnt == fileSize)
130 pBio = BIO_new(BIO_s_mem());
131 SysTryCatch(NID_SEC_CERT, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
133 std::unique_ptr< unsigned char[] > pCertBuffer(new (std::nothrow) unsigned char[readCnt]);
134 SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
136 memcpy(static_cast< void* >(pCertBuffer.get()), certBufData, readCnt);
137 certBufferLen = readCnt;
139 const unsigned char* pTemp = pCertBuffer.get();
140 pCert = d2i_X509(null, &pTemp, certBufferLen);
141 SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed.");
143 readLength = PEM_write_bio_X509(pBio, pCert);
144 SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
146 readCnt = certificateBase64Len + (2 * _MAX_PEM_HEADER);
148 readLength = BIO_read(pBio, certBufData, readCnt);
149 SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
151 readCnt = readLength;
153 r = fileCrt.Write(certBufData, readLength);
154 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%] Failed to write certificate to file.", GetErrorMessage(r));
159 memset(certBufData, 0, _MAX_CERTIFICATE_SIZE);
163 Tizen::Io::File::Remove(crtFileName);
164 Tizen::Io::File::Move(tmpCrtFileName, crtFileName);
172 _CertManager::OpenContext(_CertContextType type, CertChainCtx* pHCertCtx)
174 SysTryReturnResult(NID_SEC_CERT, type > 0, E_INVALID_ARG, "Invalid input parameter.");
176 _CertChain* pCertChain = new (std::nothrow) _CertChain();
177 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
179 pCertChain->SetContextType(type);
180 *pHCertCtx = (CertChainCtx) pCertChain;
186 _CertManager::AddCertificate(CertChainCtx certCtx, byte* pCert, int certLen)
188 result r = E_SUCCESS;
189 byte* pDerCert = null;
190 int derCertBufferLength = 0;
191 _CertFormat certFormat = _CERT_UNKNOWN;
192 _CertEncodingType encodingType = _CERT_ENC_TYPE_UNKNOWN;
193 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
195 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
196 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
198 certFormat = _CertManager::GetEncodedCertBuffer(pCert, certLen, &pDerCert, &derCertBufferLength, &encodingType);
199 std::unique_ptr< byte, ByteDeleter > pDerCertBuffer(pDerCert);
202 SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Unsupported certificate format.");
203 SysTryReturnResult(NID_SEC_CERT, derCertBufferLength > 0, E_INVALID_ARG, "Invalid certificate length.");
204 SysTryReturnResult(NID_SEC_CERT, pDerCertBuffer != null, E_INVALID_ARG, "Input certificate buffer.");
206 r = pCertChain->AddCertificate(certFormat, static_cast< byte* >(pDerCertBuffer.get()), derCertBufferLength);
207 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "Failed to add certificate in chain context.");
213 _CertManager::VerifyChain(CertChainCtx certCtx, _CertDomainType* pDomain)
215 result r = E_SUCCESS;
216 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
218 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
220 r = pCertChain->VerifyCertChainWithDb();
221 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to verify certificate chain.", GetErrorMessage(r));
225 *pDomain = pCertChain->GetCertTypeByDomain();
232 _CertManager::VerifyCertificate(CertificateHandle certHandle, byte* pPublickey, int keyLen)
234 result r = E_SUCCESS;
236 SysTryReturnResult(NID_SEC_CERT, pPublickey != null, E_INVALID_ARG, "Initial parameters are invalid.");
237 SysTryReturnResult(NID_SEC_CERT, keyLen > 0, E_INVALID_ARG, "Initial parameters are invalid.");
238 SysTryReturnResult(NID_SEC_CERT, certHandle != 0, E_INVALID_ARG, "Initial parameters are invalid.");
240 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certHandle);
241 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
243 _CertFormat format = pTempCert->GetCertFormat();
245 if (format == _CERT_X509)
247 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
249 pCert->VerifySignature(pPublickey, keyLen);
250 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get signature.", GetErrorMessage(r));
255 SysLogException(NID_SEC_CERT, E_INVALID_CONTENT, "[E_INVALID_CONTENT]GetCertificateType: Unknown certificate format.");
263 _CertManager::GetChainDepth(CertChainCtx certCtx, int* pDepth)
265 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
266 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
267 *pDepth = pCertChain->GetCount();
272 _CertManager::GetNthCertificate(CertChainCtx certCtx, int nth, CertificateHandle* pCertHandle)
274 result r = E_SUCCESS;
275 _CertFormat format = _CERT_UNKNOWN;
276 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
277 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
279 r = pCertChain->MoveHead();
280 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move ahead in certificate chain.");
282 for (int index = 0; index < nth; index++)
284 r = pCertChain->MoveNext();
285 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
287 format = pCertChain->GetCertFormat();
288 if (format == _CERT_X509)
290 _X509Certificate* pCert = null;
291 pCert = pCertChain->GetCurrentCertificate();
292 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
294 pCert->SetContextCertificate(true);
295 *pCertHandle = (CertificateHandle) pCert;
302 _CertManager::GetCertBuffer(CertificateHandle certHandle, char** ppCertbuffer, int* pCertLen)
304 result r = E_SUCCESS;
307 _Certificate* pTempCert = null;
310 SysTryReturnResult(NID_SEC_CERT, certHandle != null, E_INVALID_ARG, "Initial params not set.");
312 pTempCert = reinterpret_cast< _Certificate* >(certHandle);
313 format = pTempCert->GetCertFormat();
314 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Initial params not set.");
316 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
318 r = pCert->GetCertBuffer(pBuf, bufSize);
319 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
321 *ppCertbuffer = new (std::nothrow) char[bufSize];
322 SysTryReturnResult(NID_SEC_CERT, *ppCertbuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
324 memcpy(*ppCertbuffer, pBuf, bufSize);
331 _CertManager::CloseContext(CertChainCtx certCtx)
333 _CertChain* pCertChain = static_cast< _CertChain* >(certCtx);
334 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameter not set.");
341 _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _CertFieldInfos* pCertInfo)
343 result r = E_SUCCESS;
344 _X509Certificate* pCert = static_cast< _X509Certificate* >(certHandle);
345 _X509TbsCert* pTbsCert = null;
346 byte* pSerial = null;
347 int publicKeyLen = 0;
348 int fingerPrintLen = 0;
351 char* pSigAlg = null;
353 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial params not set.");
354 SysTryReturnResult(NID_SEC_CERT, pCertInfo != null, E_INVALID_ARG, "Initial params not set.");
356 memset(pCertInfo, 0, sizeof(_CertFieldInfos));
358 pTbsCert = pCert->GetTbsCertInstance();
359 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
361 if (field & _CERT_FIELD_SERIAL)
363 pTbsCert->GetSerialNumber(pSerial, serialLen);
366 byte* pSerialNumber = null;
370 pSerialNumber = static_cast< byte* >(pSerial);
371 memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1);
372 for (index = 0; index < iterVal; index++)
374 snprintf(&pCertInfo->serialNo[index * 2], (_MAX_SERIAL_NUMBER_SIZE + 1), "%02X", pSerialNumber[index]);
378 if (field & _CERT_FIELD_SIGALGORITHM)
380 pSigAlg = pTbsCert->GetSignatureAlgoId();
383 int len = strlen(pSigAlg);
384 if (len <= _MAX_CERT_ALGORITHM_SIZE)
386 strncpy(pCertInfo->sigAlgorithm, pSigAlg, len);
390 memcpy(pCertInfo->sigAlgorithm, pSigAlg, _MAX_CERT_ALGORITHM_SIZE);
391 pCertInfo->sigAlgorithm[_MAX_CERT_ALGORITHM_SIZE] = '\0';
397 strcpy(pCertInfo->sigAlgorithm, "Unknown");
400 if (field & _CERT_FIELD_VALIDITY)
402 Tizen::Base::DateTime notBefore;
403 Tizen::Base::DateTime notAfter;
405 pTbsCert->GetAfterTimes(notAfter);
406 pTbsCert->GetBeforeTimes(notBefore);
408 memset(pCertInfo->validityFrom, 0, _MAX_CERT_VALIDITY_SIZE + 1);
409 memset(pCertInfo->validityTo, 0, _MAX_CERT_VALIDITY_SIZE + 1);
411 _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom);
413 _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo);
417 if (field & _CERT_FIELD_SUBJECT)
419 byte* pSubjectName = pTbsCert->GetSubjectName();
420 int subLen = strlen(reinterpret_cast< const char* >(pSubjectName));
421 memset(pCertInfo->subjectName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
422 if (subLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
424 strncpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName), subLen);
426 ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle);
429 if (field & _CERT_FIELD_ISSUER)
431 byte* pIssuerName = pTbsCert->GetIssuerName();
432 int issuerLen = strlen(reinterpret_cast< const char* >(pIssuerName));
433 memset(pCertInfo->issuerName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
434 if (issuerLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
436 strncpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName), issuerLen);
438 ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle);
441 if (field & _CERT_FIELD_FINGERPRINT)
443 byte* pX509Buff = null;
444 int x509BuffSize = 0;
446 memset(pCertInfo->fingerPrint, 0, _MAX_CERT_FINGERPRINT_SIZE + 1);
448 //As per OpenSSL APIs, it takes input as unsigned data types
449 pCert->GetCertBuffer(pX509Buff, x509BuffSize);
450 SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
452 std::unique_ptr< byte[] > pFingerPrint(new (std::nothrow) byte[SHA_DIGEST_LENGTH + 1]);
453 SysTryReturnResult(NID_SEC_CERT, pFingerPrint != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
455 memset(pFingerPrint.get(), 0, SHA_DIGEST_LENGTH + 1);
457 resValue = EVP_Digest(pX509Buff, x509BuffSize, pFingerPrint.get(), reinterpret_cast< unsigned int* >(&fingerPrintLen), EVP_sha1(), 0);
458 SysTryReturnResult(NID_SEC_CERT, resValue == 1, E_SYSTEM, "Failed to create digest hash.");
461 int maxValue = SHA_DIGEST_LENGTH;
462 for (index = 0; index < maxValue; index++)
464 snprintf(&pCertInfo->fingerPrint[index * 2], (_MAX_CERT_FINGERPRINT_SIZE + 1), "%02X", pFingerPrint[index]);
466 pCertInfo->fingerPrintLen = fingerPrintLen;
469 if (field & _CERT_FIELD_PUBLICKEY)
471 byte* pPublicKeyBuffer = null;
472 pTbsCert->GetPublicKeyInfoN(publicKeyLen, &pPublicKeyBuffer);
473 if (pPublicKeyBuffer != null)
475 std::unique_ptr< byte[] > pPublicKeyAuto(pPublicKeyBuffer);
476 int iterVal = publicKeyLen;
479 memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1);
480 for (index = 0; index < iterVal; index++)
482 snprintf(&pCertInfo->publicKey[index * 2], (_MAX_CERT_PUBLIC_KEY_SIZE + 1), "%02X", pPublicKeyBuffer[index]);
488 if (field & _CERT_FIELD_VERSION)
490 pCertInfo->certVersion = pTbsCert->GetVersion();
491 SysTryReturnResult(NID_SEC_CERT, pCertInfo->certVersion > 0, E_SYSTEM, "Failed to get version.");
494 if (field & _CERT_FIELD_TYPE)
496 char type[6] = "X.509";
497 memset(pCertInfo->certTypeFormat, 0, sizeof(pCertInfo->certTypeFormat));
498 strcpy(pCertInfo->certTypeFormat, type);
500 if (strcmp(pCertInfo->certTitle, pCertInfo->certSubTitle) == 0)
502 char selfSigned[12] = "Self-signed";
503 memset(pCertInfo->certSubTitle, 0, sizeof(pCertInfo->certSubTitle));
504 strcpy(pCertInfo->certSubTitle, selfSigned);
512 _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** pDerCertBuffer, int* pDerCertBufferLength, _CertEncodingType* encodingType)
514 result r = E_SUCCESS;
515 _CertFormat certFormat = _CERT_UNKNOWN;
517 X509* pOpensslX509Cert = null;
518 char* pBase64Header = null;
519 char* pBase64Trailer = null;
527 SysTryReturn(NID_SEC_CERT, pCertBuffer != null, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
528 SysTryReturn(NID_SEC_CERT, certBufferLen > 0, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
530 std::unique_ptr< _X509Certificate > pX509Cert(new (std::nothrow) _X509Certificate());
531 SysTryReturn(NID_SEC_CERT, pX509Cert != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
533 pBase64Header = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_HEADER);
534 pBase64Trailer = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_TRAILER);
536 if ((pBase64Header != null) && (pBase64Trailer != null) && (pBase64Trailer > pBase64Header))
538 pBio = BIO_new(BIO_s_mem());
539 SysTryReturn(NID_SEC_CERT, pBio != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
541 pemCertSize = (int(pBase64Trailer - pBase64Header) + strlen(_CERT_BASE64_TRAILER));
542 readCount = BIO_write(pBio, (const void*) pBase64Header, pemCertSize);
543 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
545 pOpensslX509Cert = PEM_read_bio_X509(pBio, NULL, 0, NULL);
546 SysTryCatch(NID_SEC_CERT, pOpensslX509Cert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate convention failed. readCount = %d Calculated length = %d pBase64Trailer = %s, pBase64Header = %s", readCount, pemCertSize, pBase64Trailer, pBase64Header);
548 decodedLen = i2d_X509(pOpensslX509Cert, pDerCertBuffer);
549 SysTryCatch(NID_SEC_CERT, decodedLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
551 *pDerCertBufferLength = decodedLen;
553 certFormat = _CERT_X509;
554 *encodingType = _CERT_ENC_TYPE_PEM;
556 else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS)
558 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufferLen)));
559 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
561 memcpy(pCertBuf.get(), pCertBuffer, certBufferLen);
562 certBufLen = certBufferLen;
564 *pDerCertBuffer = pCertBuf.release();
565 *pDerCertBufferLength = certBufLen;
567 certFormat = _CERT_X509;
568 *encodingType = _CERT_ENC_TYPE_BINARY;
572 certBufLen = _Base64::GetDecodedSize(certBufferLen);
573 SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
575 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufLen)));
576 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
578 memset(pCertBuf.get(), 0, certBufLen);
580 decodedLen = certBufLen;
581 readCount = _Base64::Decode(reinterpret_cast< char* >(pCertBuffer), certBufferLen, pCertBuf.get(), decodedLen);
582 SysTryReturn(NID_SEC_CERT, readCount > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Certificate decoding failed.");
584 *pDerCertBuffer = pCertBuf.release();
585 *pDerCertBufferLength = decodedLen;
587 certFormat = _CERT_X509;
588 *encodingType = _CERT_ENC_TYPE_BASE64;
591 SetLastResult(E_SUCCESS); //To clear the result of parsing certificate.
600 if (pOpensslX509Cert != null)
602 X509_free(pOpensslX509Cert);
609 _CertManager::GetPublicKey(CertificateHandle certificate, char* pBuffer, int* pBufLen)
611 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
612 _X509Certificate* pCert = null;
613 _X509TbsCert* pTbsCert = null;
617 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
618 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Invalid input parameter.");
620 _CertFormat format = pTempCert->GetCertFormat();
621 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
623 pCert = reinterpret_cast< _X509Certificate* >(certificate);
624 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input parameter.");
626 pTbsCert = pCert->GetTbsCertInstance();
627 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
629 pTbsCert->GetPublicKeyInfoN(pubKeyLen, &pPuKey);
630 SysTryReturnResult(NID_SEC_CERT, pPuKey != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
632 std::unique_ptr< byte[] > pPubKeyAuto(pPuKey);
634 memcpy(pBuffer, pPubKeyAuto.get(), pubKeyLen);
638 *pBufLen = pubKeyLen;
645 _CertManager::GetSignature(CertificateHandle certificate, char* pBuffer, int* pBufLen)
647 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
648 _X509Certificate* pCert = null;
649 byte* pSignature = null;
651 _CertSignature* pSig = null;
654 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
655 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
657 format = pTempCert->GetCertFormat();
658 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
659 pCert = reinterpret_cast< _X509Certificate* >(certificate);
661 pSig = pCert->GetSignInstance();
662 SysTryReturnResult(NID_SEC_CERT, pSig != null, E_SYSTEM, "Failed to get certificate signature.");
664 pSignature = pSig->GetSignatureInfo(signLength);
665 memcpy(pBuffer, pSignature, signLength);
669 *pBufLen = signLength;
675 _CertManager::GetVersion(CertificateHandle certificate)
677 _Certificate* pTempCert = null;
678 _X509Certificate* pCert = null;
679 _X509TbsCert* pTbsCert = null;
681 pTempCert = reinterpret_cast< _Certificate* >(certificate);
682 SysTryReturn(NID_SEC_CERT, pTempCert != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Initial parameter not set.");
684 _CertFormat format = pTempCert->GetCertFormat();
686 SysTryReturn(NID_SEC_CERT, format == _CERT_X509, -1, E_SYSTEM, "[E_SYSTEM] Unknown certificate format.");
687 pCert = reinterpret_cast< _X509Certificate* >(certificate);
689 pTbsCert = pCert->GetTbsCertInstance();
690 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
692 return pTbsCert->GetVersion();
696 _CertManager::GetValidity(CertificateHandle certificate, _CertValidityType* pValidity)
698 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
699 _X509Certificate* pCert = null;
700 _X509TbsCert* pTbsCert = null;
701 Tizen::Base::DateTime notBefore;
702 Tizen::Base::DateTime notAfter;
703 Tizen::Base::DateTime curTime;
705 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
707 _CertFormat format = pTempCert->GetCertFormat();
708 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Unknown certificate format.");
710 pCert = reinterpret_cast< _X509Certificate* >(certificate);
712 Tizen::System::SystemTime::GetCurrentTime(UTC_TIME, curTime);
714 pTbsCert = pCert->GetTbsCertInstance();
715 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
717 pTbsCert->GetBeforeTimes(notBefore);
718 pTbsCert->GetAfterTimes(notAfter);
719 if (curTime <= notAfter && curTime >= notBefore)
721 *pValidity = _CERT_VALIDITY_VALID;
723 else if (curTime < notBefore)
725 *pValidity = _CERT_VALIDITY_NOT_YET_VALID;
727 else if (curTime > notAfter)
729 *pValidity = _CERT_VALIDITY_EXPIRED;
736 _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCertType)
738 result r = E_SUCCESS;
739 char subjectName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
740 char issuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
741 int lenSubjectName = 0;
742 int lenIssuerName = 0;
743 _Certificate* pParentCert = reinterpret_cast< _Certificate* >(certHandle);
744 _X509Certificate* pCert = null;
745 _X509TbsCert* pTbsCert = null;
746 _CertDbManager* pCertDb = null;
748 SysTryReturnResult(NID_SEC_CERT, pParentCert != null, E_INVALID_ARG, "Initial parameter not set.");
751 _CertFormat format = pParentCert->GetCertFormat();
752 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
754 pCert = reinterpret_cast< _X509Certificate* >(certHandle);
755 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameter not set.");
757 pTbsCert = pCert->GetTbsCertInstance();
758 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
760 lenSubjectName = strlen(reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
761 lenIssuerName = strlen(reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
762 SysTryReturnResult(NID_SEC_CERT, lenSubjectName > 0, E_SYSTEM, "Subject length is not valid.");
763 SysTryReturnResult(NID_SEC_CERT, lenIssuerName > 0, E_SYSTEM, "Issuer length is not valid.");
765 strncpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()), lenSubjectName);
766 strncpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()), lenIssuerName);
768 pCertDb = _CertDbManager::GetInstance();
769 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
771 r = pCertDb->FindCertType(format, issuerName, subjectName, pCertType);
775 *pCertType = _CERT_TYPE_MAX;
783 _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1])
787 SysTryReturn(NID_SEC_CERT, subject[0] != '\0', E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
789 SysAssertf(strlen(subject) <= (size_t) _MAX_ISSUER_SUBJECT_NAME_SIZE, "The buffer size of source is too big.");
792 char* pPivotPtr = null;
793 char* pSavePtr = null;
794 char* pSubStr = null;
795 char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, };
797 strncpy(tempSubject, subject, strlen(subject + 1));
798 pPivotPtr = tempSubject;
799 for (;; pSubStr = null)
801 pSubStr = strtok_r(pPivotPtr, "/", &pSavePtr);
803 if (strncmp(pSubStr, _CERT_COMMON_NAME, strlen(_CERT_COMMON_NAME)) == 0)
805 pSubStr = pSubStr + strlen(_CERT_COMMON_NAME);
809 else if (strncmp(pSubStr, _CERT_ORG_NAME, strlen(_CERT_ORG_NAME)) == 0)
811 pSubStr = pSubStr + strlen(_CERT_ORG_NAME);
815 else if (strncmp(pSubStr, _CERT_ORG_UNIT_NAME, strlen(_CERT_ORG_UNIT_NAME)) == 0)
817 pSubStr = pSubStr + strlen(_CERT_ORG_UNIT_NAME);
821 else if (strncmp(pSubStr, _CERT_EMAIL_ADDRESS, strlen(_CERT_EMAIL_ADDRESS)) == 0)
823 pSubStr = pSubStr + strlen(_CERT_EMAIL_ADDRESS);
828 pPivotPtr = pSavePtr;
832 SysTryReturn(NID_SEC_CERT, done, E_PARSING_FAILED, E_SYSTEM, "[%s] Failed to parse Certificate title.", GetErrorMessage(E_PARSING_FAILED));
835 for (int index = 0; index < _MAX_ISSUER_SUBJECT_NAME_SIZE + 1; index++)
840 // copy title into out param
841 strncpy(title, pSubStr, strlen(pSubStr));
846 //User Certificate APIs
848 _CertManager::MakeParseAndVerifyCertChainBufferN(byte* pCertChainBuffer, int certChainLength, byte* pUserPrivateKeyBuffer, int userPrivateKeyLength, _CertChain** ppX509CertChain, _CertPrivateKeyInfo** ppX509PrivateKeyInfo)
850 result r = E_SUCCESS;
852 int currCertBufLen = 0;
853 int totCertCount = 0;
855 int countTotalCertificateChecked = 0;
856 int addedNumberCertificate = 0;
857 bool pubPriPair = false;
858 byte* pCertBuf = null;
859 byte* pCurrCertBuf = null;
860 _X509Certificate* pUserCert = null;
861 std::unique_ptr< _CertPrivateKeyInfo > pPKeyInfo(null);
863 pCertBuf = pCertChainBuffer;
864 bufSize = certChainLength;
866 SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_INVALID_ARG, "Invalid certificate chain buffer.");
867 SysTryReturnResult(NID_SEC_CERT, bufSize > 0, E_INVALID_ARG, "Invalid length of certificate chain buffer.");
869 // Process Private Key
870 if (pUserPrivateKeyBuffer != null && userPrivateKeyLength > 0)
872 pPKeyInfo = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pUserPrivateKeyBuffer, userPrivateKeyLength));
873 SysTryReturnResult(NID_SEC_CERT, pPKeyInfo != null, E_OUT_OF_MEMORY, "Failed allocate memory.");
877 while (dataOffset < bufSize)
879 pCurrCertBuf = pCertBuf + dataOffset;
880 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
882 dataOffset += currCertBufLen;
887 std::unique_ptr< _CertChain > pCertChain(new (std::nothrow) _CertChain());
888 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to parse and verify certificate chain.");
890 if (pPKeyInfo != null)
892 // Find Device/User Certificate
893 while (dataOffset < bufSize)
895 pCurrCertBuf = pCertBuf + dataOffset;
896 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
898 std::unique_ptr< _X509Certificate > pTmpCert(new (std::nothrow) _X509Certificate());
899 SysTryReturnResult(NID_SEC_CERT, pTmpCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
901 r = pTmpCert->Parse(pCurrCertBuf, currCertBufLen);
902 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse and verify certificate chain.");
904 r = _CertManager::CheckRsaPublicPrivateKeyPair(pTmpCert.get(), pPKeyInfo.get());
907 r = pCertChain->AddCertificate(pTmpCert.get());
908 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to parse and verify certificate chain.");
911 addedNumberCertificate++;
912 pUserCert = pTmpCert.release();
916 dataOffset += currCertBufLen;
919 SysTryReturnResult(NID_SEC_CERT, pubPriPair, E_INVALID_KEY, "Failed to parse and verify certificate chain.");
924 //As there is no private key present in chain, it is assumed that first certificate is user certificate
925 if (pUserCert == null)
927 pCurrCertBuf = pCertBuf + dataOffset;
928 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
930 std::unique_ptr< _X509Certificate > pUserCertAuto(new (std::nothrow) _X509Certificate());
931 SysTryReturnResult(NID_SEC_CERT, pUserCertAuto != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
933 r = pUserCertAuto->Parse(pCurrCertBuf, currCertBufLen);
934 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse first certificate in chain.");
936 r = pCertChain->AddCertificate(pUserCertAuto.get());
937 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add first certificate in chain. ");
939 addedNumberCertificate++;
940 pUserCert = pUserCertAuto.release();
944 while (totCertCount > addedNumberCertificate)
947 countTotalCertificateChecked++;
949 if (countTotalCertificateChecked > totCertCount)
954 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_INVALID_ARG, "Invalid certificate in chain. ");
956 while (dataOffset < bufSize)
958 std::unique_ptr< _X509Certificate > pCurrentCert(new (std::nothrow) _X509Certificate());
959 SysTryReturnResult(NID_SEC_CERT, pCurrentCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
961 pCurrCertBuf = pCertBuf + dataOffset;
962 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
964 r = pCurrentCert->Parse(pCurrCertBuf, currCertBufLen);
965 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse certificate in chain. ");
967 if (pUserCert->IsIssuer(pCurrentCert.get()))
969 r = pCertChain->AddCertificate(pCurrentCert.get());
970 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add certificate in chain. ");
972 pUserCert = pCurrentCert.release();
973 addedNumberCertificate++;
977 dataOffset += currCertBufLen;
981 //Here is the place where we verifying certificate chain before installation
982 r = pCertChain->VerifyCertChainWithDb();
983 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
985 *ppX509CertChain = pCertChain.release();
986 *ppX509PrivateKeyInfo = pPKeyInfo.release();
992 _CertManager::CheckRsaPublicPrivateKeyPair(_X509Certificate* pX509Certificate, _CertPrivateKeyInfo* pX509CertificatePrivateKey)
994 result r = E_SUCCESS;
996 EVP_PKEY* pPrivateKey = null;
997 int privateKeyLength = 0;
998 X509* pX509Cert = null;
999 const char* pSigalg = null;
1001 SysTryReturnResult(NID_SEC_CERT, pX509Certificate != null, E_INVALID_ARG, "Invalid input parameter. ");
1002 SysTryReturnResult(NID_SEC_CERT, pX509CertificatePrivateKey != null, E_INVALID_ARG, "Invalid input parameter.");
1004 pX509Cert = static_cast< X509* >(pX509Certificate->GetX509CertObject());
1005 SysTryReturnResult(NID_SEC_CERT, pX509Cert != null, E_SYSTEM, "Failed to parse certificate. ");
1008 pSigalg = OBJ_nid2ln(OBJ_obj2nid(pX509Cert->sig_alg->algorithm));
1009 SysTryReturnResult(NID_SEC_CERT, pSigalg != null, E_SYSTEM, "Unable to get certificate algorithm.");
1011 if (strstr(pSigalg, "WithRSA"))
1013 byte* pPriKey = null;
1015 pX509CertificatePrivateKey->GetPrivateKeyN(privateKeyLength, &pPriKey);
1016 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_SYSTEM, "Unable to get certificate private key.");
1018 std::unique_ptr< byte[] > pPriKeyBuf(pPriKey);
1020 pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, null, const_cast< const unsigned char** >(static_cast< unsigned char** >(&pPriKey)), privateKeyLength);
1021 if (pPrivateKey != null)
1023 retValue = X509_check_private_key(pX509Cert, pPrivateKey);
1025 EVP_PKEY_free(pPrivateKey);
1027 SysTryReturnResult(NID_SEC_CERT, retValue == 1, E_SYSTEM, "Private public key mismatch, this key does not belong to this certificate.");
1034 SysLog(NID_SEC_CERT, "Private key conversion failed.");
1042 SysLog(NID_SEC_CERT, "Unsupported Algorithm = %s", pSigalg);
1050 _CertManager::GetCertificateSubjectNameN(CertificateHandle certificateHandle, byte** ppSubjectName, int* pSubjectNameLength)
1054 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1055 _CertFormat format = pTempCert->GetCertFormat();
1057 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1059 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1060 pCert->GetIssuerBuffer(pBuf, len);
1062 *ppSubjectName = new (std::nothrow) byte[len];
1063 SysTryReturnResult(NID_SEC_CERT, *ppSubjectName != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
1065 memset(*ppSubjectName, 0, len);
1066 memcpy(*ppSubjectName, pBuf, len);
1067 *pSubjectNameLength = len;
1073 _CertManager::GetCertificateIssuerNameN(CertificateHandle certificateHandle, byte** ppIssuerName, int* pIssuerNameLength)
1075 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1076 _CertFormat format = pTempCert->GetCertFormat();
1080 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1082 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1083 pCert->GetSubjectNameBuffer(pBuf, len);
1085 *ppIssuerName = new (std::nothrow) byte[len];
1086 SysTryReturnResult(NID_SEC_CERT, *ppIssuerName != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1087 memset(*ppIssuerName, 0, len);
1088 memcpy(*ppIssuerName, pBuf, len);
1089 *pIssuerNameLength = len;
1095 _CertManager::OpenUserCertificateStore(int& totalCount)
1097 result r = E_SUCCESS;
1098 UserCertRecord certRecord = {0};
1099 _CertRootList* pHoldList = null;
1100 _CertFileStore fileStore;
1101 CertificateStoreCtx certificateStoreCtx = null;
1103 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1104 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1110 snprintf(condition, _MAX_TYPE_CONST_SIZE, "installed = '%s'", installedRecord);
1112 std::unique_ptr< _UserCertDbStore > pUserCertDbStore(new (std::nothrow) _UserCertDbStore());
1113 SysTryReturn(NID_SEC_CERT, pUserCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1115 r = pUserCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1116 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1118 std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1119 SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1121 std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1122 SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1124 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1125 pCertListFirstNode->pNext = null;
1127 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1128 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to set file handle.");
1130 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1131 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to read from file.");
1133 pCertListFirstNode->length = certLength;
1134 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1136 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1138 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1142 while ((pUserCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1144 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1145 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1147 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1148 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1150 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1151 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1153 pCertList->pNext = null;
1154 pCertList->length = certLength;
1155 pCertList->format = (_CertFormat) certRecord.certFormat;
1157 pHoldList->pNext = pCertList.release();
1158 pHoldList = pHoldList->pNext;
1163 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1165 return certificateStoreCtx;
1170 _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_TRUSTED_CA or _CERT_TYPE_ROOT_CA, ?
1172 result r = E_SUCCESS;
1173 CaCertRecord certRecord = {0};
1174 _CertRootList* pHoldList = null;
1175 _CertFileStore fileStore;
1176 CertificateStoreCtx certificateStoreCtx = null;
1178 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1179 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1185 SysTryReturn(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1186 SysTryReturn(NID_SEC_CERT, type < _CERT_TYPE_MAX, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1188 snprintf(condition, _MAX_TYPE_CONST_SIZE, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord);
1190 std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore());
1191 SysTryReturn(NID_SEC_CERT, pCaCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1193 r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1194 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1196 std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1197 SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1199 std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1200 SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1202 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1203 pCertListFirstNode->pNext = null;
1205 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1206 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1208 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1209 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1211 pCertListFirstNode->length = certLength;
1212 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1214 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1216 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1220 while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1222 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1223 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1225 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1226 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1227 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1228 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1230 pCertList->pNext = null;
1231 pCertList->length = certLength;
1232 pCertList->format = (_CertFormat) certRecord.certFormat;
1234 pHoldList->pNext = pCertList.release();
1235 pHoldList = pHoldList->pNext;
1240 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1242 return certificateStoreCtx;
1246 _CertManager::CheckRootCaIntegrity(void)
1248 result r = E_SUCCESS;
1249 CaCertRecord certRecord = {0};
1250 _CertFileStore fileStore;
1251 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1252 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1253 static const int _BUF_SIZE = 4096;
1254 static const int _FILE_NAME_LENGTH = 9; // 001.cert
1255 static const wchar_t _ROOT_CA_CERT_FILE_DIRECTORY[] = L"/opt/usr/share/certs/rootcert/";
1259 snprintf(condition, _MAX_TYPE_CONST_SIZE, "certType = %d and installed = '%s'", _CERT_TYPE_ROOT_CA, installedRecord);
1261 std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore());
1262 SysTryReturnResult(NID_SEC_CERT, pCaCertDbStore != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1264 r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1265 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1269 std::unique_ptr< File > pFile(null);
1270 std::unique_ptr< ByteBuffer > pBuffer(null);
1271 std::unique_ptr< X509Certificate > pCert(null);
1272 String tempPath(certRecord.fileName);
1273 String certPath(_ROOT_CA_CERT_FILE_DIRECTORY);
1274 ByteBuffer* pTempBuffer = null;
1275 wchar_t certFile[_FILE_NAME_LENGTH] = {0, };
1276 swprintf(certFile, _FILE_NAME_LENGTH, L"%03d.cert", certRecord.certId);
1277 certPath.Append(certFile);
1279 SysTryCatch(NID_SEC_CERT, certPath == tempPath, , E_SYSTEM, "[%s] The root CA certificate DB was damaged.", GetErrorMessage(E_SYSTEM));
1281 pFile.reset(new (std::nothrow) File());
1282 SysTryReturnResult(NID_SEC_CERT, pFile != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1284 r = pFile->Construct(certPath, "r");
1285 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1287 pBuffer.reset(new (std::nothrow) ByteBuffer());
1288 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1290 r = pBuffer->Construct(_BUF_SIZE);
1291 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1293 pTempBuffer = pBuffer.get();
1294 r = pFile->Read(*pTempBuffer);
1295 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1297 pTempBuffer->Flip();
1299 pCert.reset(new (std::nothrow) X509Certificate());
1300 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1302 r = pCert->Construct(*pTempBuffer);
1303 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1308 SysSecureLog(NID_SEC_CERT, "Remove broken certificate %d", certRecord.certId);
1310 r = pCaCertDbStore->RemoveCertificateById(certRecord.certId);
1311 SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
1313 r = File::Remove(certPath);
1314 SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
1316 while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS);
1322 enum _Asn1EncodingStyle
1324 _ASN1_ENCODING_TYPE_PRIMITIVE = 0x00,
1325 _ASN1_ENCODING_TYPE_CONSTRUCTED = 0x20,
1326 _ASN1_ENCODING_TYPE_UNKNOWN = 0xFF
1327 }; //_Asn1EncodingStyle
1330 static const int _CERT_ASN1_TAG_CHECK_BIT_ = 0x7F;
1331 static const int _CERT_ASN1_LENGTH_CHECK_BIT_ = 0x80;
1332 static const int _CERT_ASN1_ENCODING_TYPE_OFFSET_ = 0x20;
1335 _CertManager::GetBlockSize(byte* pBuf)
1339 int contentLength = 0;
1340 _Asn1EncodingStyle encodingType = _ASN1_ENCODING_TYPE_PRIMITIVE;
1344 SysTryReturn(NID_SEC_CERT, pBuf != null, retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1346 encodingType = (_Asn1EncodingStyle) (pBuf[0] & _CERT_ASN1_ENCODING_TYPE_OFFSET_);
1348 if (pBuf[1] > _CERT_ASN1_TAG_CHECK_BIT_)
1350 // Length is in indefinite form
1351 if (pBuf[1] == _CERT_ASN1_LENGTH_CHECK_BIT_)
1353 // STRICT: indefinite form cannot be used with Primitive encoding
1354 SysTryReturn(NID_SEC_CERT, encodingType != _ASN1_ENCODING_TYPE_PRIMITIVE, retVal, E_INVALID_CONTENT, "[E_INVALID_CONTENT] Encoding type is not valid.");
1355 //For the indefinite form, the length octets indicate that the contents octets are terminated by end-of-contents
1356 //octets (see 8.1.5), and shall consist of a single octet.
1358 contentLength = 2; //4
1360 // Length is in Long form
1365 //STRICT: Size cannot be seven "1" bits
1367 SysTryReturn(NID_SEC_CERT, !(((pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_) == _CERT_ASN1_TAG_CHECK_BIT_), retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1369 count = (pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_;
1371 for (lenpos = 2; lenpos < 2 + count; ++lenpos)
1373 length = (length << 8) | pBuf[lenpos];
1375 contentLength = lenpos;
1378 // Length is in short form
1385 length += contentLength;
1389 } } } //Tizen::Security::Cert