sync with tizen_2.0
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_X509CertificateStoreImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file                FSecCert_X509CertificateStoreImpl.cpp
20  * @brief               This is the implementation file for _X509CertificateStoreImpl class.
21  */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <new>
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>
33
34 using namespace Tizen::Base;
35
36 namespace Tizen { namespace Security { namespace Cert
37 {
38
39 static const int _MAX_CERT_BUFFER_SIZE = 2048;
40
41 _X509CertificateStoreImpl::_X509CertificateStoreImpl(void)
42         : __certType(static_cast< int >(_CERT_TYPE_NOT_BOUNDED))
43         , __certificateStoreCtx(0)
44 {
45         ClearLastResult();
46
47         __pCertServiceProxy = _CertServiceProxy::GetInstance();
48         SysTryReturnVoidResult(NID_SEC_CERT, __pCertServiceProxy != null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate proxy instance.");
49 }
50
51 _X509CertificateStoreImpl::~_X509CertificateStoreImpl(void)
52 {
53
54         if (__certificateStoreCtx != 0)
55         {
56                 __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
57         }
58 }
59
60 result
61 _X509CertificateStoreImpl::GetName(String& name) const
62 {
63         result r = __pCertServiceProxy->GetName();
64         if (!IsFailed(r))
65         {
66                 name = L"CertServiceStore";
67         }
68
69         return r;
70 }
71
72 result
73 _X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
74 {
75         int count = 0;
76
77         CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
78
79         switch (certType)
80         {
81         case ROOT_CA:
82                 __certType = _CERT_TYPE_ROOT_CA;
83                 break;
84
85         case OPERATOR_DOMAIN:
86                 __certType = _CERT_TYPE_ROOT_DOMAIN1;
87                 break;
88
89         case TRUSTED_THIRD_PARTY_DOMAIN:
90                 __certType = _CERT_TYPE_ROOT_DOMAIN3;
91                 break;
92
93         case USER_CERT:
94                 __certType = _CERT_TYPE_USER_CERT;
95                 break;
96
97         default:
98                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
99                 break;
100         }
101
102         if (__certificateStoreCtx != 0)
103         {
104                 __pCertServiceProxy->CloseCertificateStore(__certificateStoreCtx);
105                 __certificateStoreCtx = 0;
106         }
107
108         return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count, __certificateStoreCtx);
109 }
110
111 result
112 _X509CertificateStoreImpl::GetCertificateCount(int& count) const
113 {
114         if (__certificateStoreCtx != 0)
115         {
116                 return __pCertServiceProxy->GetCertificateCount(__certificateStoreCtx, count);
117         }
118
119         count = 0;
120         return E_SUCCESS;
121 }
122
123
124 Tizen::Security::Cert::ICertificate*
125 _X509CertificateStoreImpl::GetNextCertificateN(void) const
126 {
127         result r = E_SUCCESS;
128         ByteBuffer certBuffer;
129         byte certBytes[_MAX_CERT_BUFFER_SIZE] = {0, };
130         int certLen = sizeof(certBytes);
131
132         ClearLastResult();
133
134         SysTryReturn(NID_SEC_CERT, __certificateStoreCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call SetCertificateSelector() function.");
135
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));
138
139         r = certBuffer.Construct(certLen);
140         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
141
142         r = certBuffer.SetArray(certBytes, 0, certLen);
143         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM]An unexpected system error occurred.");
144
145         certBuffer.Flip();
146
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.");
149
150         r = pCert->Construct(certBuffer);
151         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] X509Certificate instance is not constructed.");
152
153         return pCert.release();
154 }
155
156
157 result
158 _X509CertificateStoreImpl::Insert(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
159 {
160         result r = E_SUCCESS;
161         byte* pBuffer = null;
162         int bufferLen = 0;
163         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
164
165         switch (certificateType)
166         {
167         case ROOT_CA:
168                 certType = _CERT_TYPE_ROOT_CA;
169                 break;
170
171         case OPERATOR_DOMAIN:
172                 certType = _CERT_TYPE_ROOT_DOMAIN1;
173                 break;
174
175         case TRUSTED_THIRD_PARTY_DOMAIN:
176                 certType = _CERT_TYPE_ROOT_DOMAIN3;
177                 break;
178
179         case USER_CERT:
180                 certType = _CERT_TYPE_USER_CERT;
181                 break;
182
183         default:
184                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
185                 break;
186         }
187
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.");
190
191         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
192         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
193
194         bufferLen = pEncodedData->GetRemaining();
195         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Length value is not positive.");
196
197         if (certType == _CERT_TYPE_USER_CERT)
198         {
199                 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pBuffer), bufferLen, null, 0);
200         }
201         else
202         {
203                 r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
204         }
205
206         if (r == E_FILE_ALREADY_EXIST)
207         {
208                 r = E_SUCCESS;
209         }
210         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
211
212         r = UpdateCertStoreContext();
213         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
214         
215         return r;
216 }
217
218 result
219 _X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password)
220 {
221         result r = E_SUCCESS;
222         std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
223         std::unique_ptr< char[] > pPassword(_StringConverter::CopyToCharArrayN(password));
224
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.");
227
228         //password can be null
229         r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get());
230         if (r == E_FILE_ALREADY_EXIST)
231         {
232                 r = E_SUCCESS;
233         }
234         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
235         
236         r = UpdateCertStoreContext();
237         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
238         return r;
239 }
240
241
242 result
243 _X509CertificateStoreImpl::Update(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& oldCert, const Tizen::Security::Cert::ICertificate& newCert)
244 {
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;
251
252         switch (certificateType)
253         {
254         case ROOT_CA:
255                 certType = _CERT_TYPE_ROOT_CA;
256                 break;
257
258         case OPERATOR_DOMAIN:
259                 certType = _CERT_TYPE_ROOT_DOMAIN1;
260                 break;
261
262         case TRUSTED_THIRD_PARTY_DOMAIN:
263                 certType = _CERT_TYPE_ROOT_DOMAIN3;
264                 break;
265
266         case USER_CERT:
267                 certType = _CERT_TYPE_USER_CERT;
268                 break;
269
270         default:
271                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
272                 break;
273         }
274
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.");
277
278         pOldBuffer = const_cast< byte* >(pOldEncodedData->GetPointer());
279         SysTryReturnResult(NID_SEC_CERT, pOldBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
280
281         oldBufferLen = pOldEncodedData->GetRemaining();
282         SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
283
284         pOldEncodedData.reset(null);
285
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.");
288
289         pNewBuffer = const_cast< byte* >(pNewEncodedData->GetPointer());
290         SysTryReturnResult(NID_SEC_CERT, pNewBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
291
292         newBufferLen = pNewEncodedData->GetRemaining();
293         SysTryReturnResult(NID_SEC_CERT, newBufferLen > 0, E_INVALID_ARG, "Input new certificate length is not positive.");
294
295         if (certType == _CERT_TYPE_USER_CERT)
296         {
297                 CertificateHandle certHandle = 0;
298                 int certId = 0;
299
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));
302
303                 r = _CertService::GetUserCertificateId(certHandle, certId);
304
305                 _CertService::CloseCertificate(&certHandle);
306                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
307
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));
310
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));
313         }
314         else
315         {
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));
318         }
319
320         r = UpdateCertStoreContext();
321         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
322
323         return r;
324 }
325
326
327 result
328 _X509CertificateStoreImpl::Remove(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
329 {
330         result r = E_SUCCESS;
331         byte* pBuffer = null;
332         int bufferLen = 0;
333         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
334
335         switch (certificateType)
336         {
337         case ROOT_CA:
338                 certType = _CERT_TYPE_ROOT_CA;
339                 break;
340
341         case OPERATOR_DOMAIN:
342                 certType = _CERT_TYPE_ROOT_DOMAIN1;
343                 break;
344
345         case TRUSTED_THIRD_PARTY_DOMAIN:
346                 certType = _CERT_TYPE_ROOT_DOMAIN3;
347                 break;
348
349         case USER_CERT:
350                 certType = _CERT_TYPE_USER_CERT;
351                 break;
352
353         default:
354                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
355                 break;
356         }
357
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.");
360
361         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
362         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
363
364         bufferLen = pEncodedData->GetRemaining();
365         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
366
367         if (certType == _CERT_TYPE_USER_CERT)
368         {
369                 CertificateHandle certHandle = 0;
370                 int certId = 0;
371
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));
374
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));
378
379                 r = __pCertServiceProxy->RemoveUserCertificateByCertId(certId);
380                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
381         }
382         else
383         {
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));
386         }
387         
388         r = UpdateCertStoreContext();
389         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to open certificate store context.", GetErrorMessage(r));
390
391         return r;
392
393 }
394 _X509CertificateStoreImpl*
395 _X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
396 {
397         return x509CertificateStore.__pX509CertificateStoreImpl;
398 }
399
400 const _X509CertificateStoreImpl*
401 _X509CertificateStoreImpl::GetInstance(const X509CertificateStore& x509CertificateStore)
402 {
403         return x509CertificateStore.__pX509CertificateStoreImpl;
404 }
405
406 result
407 _X509CertificateStoreImpl::UpdateCertStoreContext(void)
408 {
409         result r = E_SUCCESS;
410         int count =0;
411
412         if (__certificateStoreCtx != 0)
413         {
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));
417         }
418
419         return r;
420 }
421
422
423
424 } } }       // Tizen::Security::Cert