2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSecCert_X509CertificateStoreImpl.cpp
20 * @brief This is the implementation file for _X509CertificateStoreImpl class.
25 #include <unique_ptr.h>
26 #include <FBaseResult.h>
27 #include <FSecCertX509Certificate.h>
28 #include <FBaseSysLog.h>
29 #include <FBase_StringConverter.h>
30 #include <FSecCert_CertService.h>
31 #include <FSecCert_CertServiceProxy.h>
32 #include <FSecCert_X509CertificateStoreImpl.h>
34 using namespace Tizen::Base;
36 namespace Tizen { namespace Security { namespace Cert
39 static const int _MAX_CERT_BUFFER_SIZE = 2048;
41 _X509CertificateStoreImpl::_X509CertificateStoreImpl(void)
42 : __certType(static_cast< int >(_CERT_TYPE_NOT_BOUNDED))
43 , __certificateStoreCtx(0)
47 __pCertServiceProxy = _CertServiceProxy::GetInstance();
48 SysTryReturnVoidResult(NID_SEC_CERT, __pCertServiceProxy != null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate proxy instance.");
51 _X509CertificateStoreImpl::~_X509CertificateStoreImpl(void)
54 if (__certificateStoreCtx != 0)
56 __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
61 _X509CertificateStoreImpl::GetName(String& name) const
63 result r = __pCertServiceProxy->GetName();
66 name = L"CertServiceStore";
73 _X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
77 CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
82 __certType = _CERT_TYPE_ROOT_CA;
86 __certType = _CERT_TYPE_ROOT_DOMAIN1;
89 case TRUSTED_THIRD_PARTY_DOMAIN:
90 __certType = _CERT_TYPE_ROOT_DOMAIN3;
94 __certType = _CERT_TYPE_USER_CERT;
98 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
102 if (__certificateStoreCtx != 0)
104 __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
105 __certificateStoreCtx = 0;
108 return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count, __certificateStoreCtx);
112 _X509CertificateStoreImpl::GetCertificateCount(int& count) const
114 if (__certificateStoreCtx != 0)
116 return __pCertServiceProxy->GetCertificateCount(__certificateStoreCtx, count);
124 Tizen::Security::Cert::ICertificate*
125 _X509CertificateStoreImpl::GetNextCertificateN(void) const
127 result r = E_SUCCESS;
128 ByteBuffer certBuffer;
129 byte certBytes[_MAX_CERT_BUFFER_SIZE] = {0, };
130 int certLen = sizeof(certBytes);
134 SysTryReturn(NID_SEC_CERT, __certificateStoreCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call SetCertificateSelector() function.");
136 r = __pCertServiceProxy->GetNextCertificate(__certificateStoreCtx, certBytes, certLen);
137 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to get next root certificate.", GetErrorMessage(r));
139 r = certBuffer.Construct(certLen);
140 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
142 r = certBuffer.SetArray(certBytes, 0, certLen);
143 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM]An unexpected system error occurred.");
147 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
148 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
150 r = pCert->Construct(certBuffer);
151 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] X509Certificate instance is not constructed.");
153 return pCert.release();
158 _X509CertificateStoreImpl::Insert(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
160 result r = E_SUCCESS;
161 byte* pBuffer = null;
163 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
165 switch (certificateType)
168 certType = _CERT_TYPE_ROOT_CA;
171 case OPERATOR_DOMAIN:
172 certType = _CERT_TYPE_ROOT_DOMAIN1;
175 case TRUSTED_THIRD_PARTY_DOMAIN:
176 certType = _CERT_TYPE_ROOT_DOMAIN3;
180 certType = _CERT_TYPE_USER_CERT;
184 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
188 std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
189 SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
191 pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
192 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
194 bufferLen = pEncodedData->GetRemaining();
195 SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Length value is not positive.");
197 if (certType == _CERT_TYPE_USER_CERT)
199 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pBuffer), bufferLen, null, 0);
203 r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
206 if (r == E_FILE_ALREADY_EXIST)
210 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
212 r = UpdateCertStoreContext();
213 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
219 _X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password)
221 result r = E_SUCCESS;
222 std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
223 std::unique_ptr< char[] > pPassword(_StringConverter::CopyToCharArrayN(password));
225 SysTryReturnResult(NID_SEC_CERT, filePath.GetLength() > 0, E_INVALID_ARG, "Length of file path is not positive.");
226 SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "File path is invalid.");
228 //password can be null
229 r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get());
230 if (r == E_FILE_ALREADY_EXIST)
234 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
236 r = UpdateCertStoreContext();
237 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
243 _X509CertificateStoreImpl::Update(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& oldCert, const Tizen::Security::Cert::ICertificate& newCert)
245 result r = E_SUCCESS;
246 byte* pOldBuffer = null;
247 byte* pNewBuffer = null;
248 int oldBufferLen = 0;
249 int newBufferLen = 0;
250 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
252 switch (certificateType)
255 certType = _CERT_TYPE_ROOT_CA;
258 case OPERATOR_DOMAIN:
259 certType = _CERT_TYPE_ROOT_DOMAIN1;
262 case TRUSTED_THIRD_PARTY_DOMAIN:
263 certType = _CERT_TYPE_ROOT_DOMAIN3;
267 certType = _CERT_TYPE_USER_CERT;
271 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
275 std::unique_ptr< ByteBuffer > pOldEncodedData(oldCert.GetEncodedDataN());
276 SysTryReturnResult(NID_SEC_CERT, pOldEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on old input certificate.");
278 pOldBuffer = const_cast< byte* >(pOldEncodedData->GetPointer());
279 SysTryReturnResult(NID_SEC_CERT, pOldBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
281 oldBufferLen = pOldEncodedData->GetRemaining();
282 SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
284 pOldEncodedData.reset(null);
286 std::unique_ptr< ByteBuffer > pNewEncodedData(newCert.GetEncodedDataN());
287 SysTryReturnResult(NID_SEC_CERT, pNewEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on new input certificate.");
289 pNewBuffer = const_cast< byte* >(pNewEncodedData->GetPointer());
290 SysTryReturnResult(NID_SEC_CERT, pNewBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
292 newBufferLen = pNewEncodedData->GetRemaining();
293 SysTryReturnResult(NID_SEC_CERT, newBufferLen > 0, E_INVALID_ARG, "Input new certificate length is not positive.");
295 if (certType == _CERT_TYPE_USER_CERT)
297 CertificateHandle certHandle = 0;
300 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pOldBuffer), oldBufferLen, &certHandle);
301 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
303 r = _CertService::GetUserCertificateId(certHandle, certId);
305 _CertService::CloseCertificate(&certHandle);
306 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
308 r = __pCertServiceProxy->RemoveUserCaCertificateByCertId(certId);
309 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove/update user certificates from store.", GetErrorMessage(r));
311 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pNewBuffer), newBufferLen, null, 0);
312 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to install/update user certificates.", GetErrorMessage(r));
316 r = __pCertServiceProxy->UpdateCaCertificate(static_cast< int >(certType), pOldBuffer, oldBufferLen, pNewBuffer, newBufferLen);
317 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update certificate.", GetErrorMessage(r));
320 r = UpdateCertStoreContext();
321 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
328 _X509CertificateStoreImpl::Remove(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
330 result r = E_SUCCESS;
331 byte* pBuffer = null;
333 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
335 switch (certificateType)
338 certType = _CERT_TYPE_ROOT_CA;
341 case OPERATOR_DOMAIN:
342 certType = _CERT_TYPE_ROOT_DOMAIN1;
345 case TRUSTED_THIRD_PARTY_DOMAIN:
346 certType = _CERT_TYPE_ROOT_DOMAIN3;
350 certType = _CERT_TYPE_USER_CERT;
354 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
358 std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
359 SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
361 pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
362 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
364 bufferLen = pEncodedData->GetRemaining();
365 SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
367 if (certType == _CERT_TYPE_USER_CERT)
369 CertificateHandle certHandle = 0;
372 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pBuffer), bufferLen, &certHandle);
373 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
375 r = _CertService::GetUserCertificateId(certHandle, certId);
376 _CertService::CloseCertificate(&certHandle);
377 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
379 r = __pCertServiceProxy->RemoveUserCertificateByCertId(certId);
380 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
384 r = __pCertServiceProxy->RemoveCaCertificate(static_cast< int >(certType), pBuffer, bufferLen);
385 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
388 r = UpdateCertStoreContext();
389 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
394 _X509CertificateStoreImpl*
395 _X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
397 return x509CertificateStore.__pX509CertificateStoreImpl;
400 const _X509CertificateStoreImpl*
401 _X509CertificateStoreImpl::GetInstance(const X509CertificateStore& x509CertificateStore)
403 return x509CertificateStore.__pX509CertificateStoreImpl;
407 _X509CertificateStoreImpl::UpdateCertStoreContext(void)
409 result r = E_SUCCESS;
412 if (__certificateStoreCtx != 0)
414 __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
415 r = __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count, __certificateStoreCtx);
416 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
424 } } } // Tizen::Security::Cert