353f52f6a31b5efccd3dd0c72efe4361d29b7617
[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         , __curPos(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         __pCertServiceProxy->CloseCertificateStore(__certType);
54 }
55
56 result
57 _X509CertificateStoreImpl::GetName(String& name) const
58 {
59         result r = __pCertServiceProxy->GetName();
60         if (!IsFailed(r))
61         {
62                 name = L"CertServiceStore";
63         }
64
65         return r;
66 }
67
68 result
69 _X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
70 {
71         int count = 0;
72
73         CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
74
75         __pCertServiceProxy->CloseCertificateStore(__certType);
76         __curPos = 0;
77
78         switch (certType)
79         {
80         case ROOT_CA:
81                 __certType = _CERT_TYPE_ROOT_CA;
82                 break;
83
84         case OPERATOR_DOMAIN:
85                 __certType = _CERT_TYPE_ROOT_DOMAIN1;
86                 break;
87
88         case TRUSTED_THIRD_PARTY_DOMAIN:
89                 __certType = _CERT_TYPE_ROOT_DOMAIN3;
90                 break;
91
92         case USER_CERT:
93                 __certType = _CERT_TYPE_USER_CERT;
94                 break;
95
96         default:
97                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
98                 break;
99         }
100
101         return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count);
102 }
103
104 result
105 _X509CertificateStoreImpl::GetCertificateCount(int& count)
106 {
107         return __pCertServiceProxy->GetCertificateCount(__certType, count);
108 }
109
110
111 Tizen::Security::Cert::ICertificate*
112 _X509CertificateStoreImpl::GetNextCertificateN(void)
113 {
114         result r = E_SUCCESS;
115         ByteBuffer certBuffer;
116         byte certBytes[_MAX_CERT_BUFFER_SIZE] = {0, };
117         int certLen = sizeof(certBytes);
118         int curPos = __curPos;
119
120         ClearLastResult();
121
122         r = __pCertServiceProxy->GetNextCertificate(__certType, curPos, certBytes, certLen);
123         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to get next root certificate.", GetErrorMessage(r));
124         __curPos = curPos;
125
126         r = certBuffer.Construct(certLen);
127         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
128
129         r = certBuffer.SetArray(certBytes, 0, certLen);
130         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM]An unexpected system error occurred.");
131
132         certBuffer.Flip();
133
134         std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
135         SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
136
137         r = pCert->Construct(certBuffer);
138         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] X509Certificate instance is not constructed.");
139
140         return pCert.release();
141 }
142
143
144 result
145 _X509CertificateStoreImpl::Insert(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
146 {
147         result r = E_SUCCESS;
148         byte* pBuffer = null;
149         int bufferLen = 0;
150         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
151
152         switch (certificateType)
153         {
154         case ROOT_CA:
155                 certType = _CERT_TYPE_ROOT_CA;
156                 break;
157
158         case OPERATOR_DOMAIN:
159                 certType = _CERT_TYPE_ROOT_DOMAIN1;
160                 break;
161
162         case TRUSTED_THIRD_PARTY_DOMAIN:
163                 certType = _CERT_TYPE_ROOT_DOMAIN3;
164                 break;
165
166         case USER_CERT:
167                 certType = _CERT_TYPE_USER_CERT;
168                 break;
169
170         default:
171                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
172                 break;
173         }
174
175         std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
176         SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
177
178         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
179         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
180
181         bufferLen = pEncodedData->GetRemaining();
182         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Length value is not positive.");
183
184         if (certType == _CERT_TYPE_USER_CERT)
185         {
186                 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pBuffer), bufferLen, null, 0);
187         }
188         else
189         {
190                 r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
191         }
192
193         if (r == E_FILE_ALREADY_EXIST)
194         {
195                 r = E_SUCCESS;
196         }
197         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
198
199         return r;
200 }
201
202 result
203 _X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password, bool checkPrivilege)
204 {
205         result r = E_SUCCESS;
206         std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
207         std::unique_ptr< char[] > pPassword(_StringConverter::CopyToCharArrayN(password));
208
209         SysTryReturnResult(NID_SEC_CERT, filePath.GetLength() > 0, E_INVALID_ARG, "Length of file path is not positive.");
210         SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "File path is invalid.");
211
212         //password can be null
213         r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get(), checkPrivilege);
214         if (r == E_FILE_ALREADY_EXIST)
215         {
216                 r = E_SUCCESS;
217         }
218         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
219
220         return r;
221 }
222
223
224 result
225 _X509CertificateStoreImpl::Update(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& oldCert, const Tizen::Security::Cert::ICertificate& newCert)
226 {
227         result r = E_SUCCESS;
228         byte* pOldBuffer = null;
229         byte* pNewBuffer = null;
230         int oldBufferLen = 0;
231         int newBufferLen = 0;
232         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
233
234         switch (certificateType)
235         {
236         case ROOT_CA:
237                 certType = _CERT_TYPE_ROOT_CA;
238                 break;
239
240         case OPERATOR_DOMAIN:
241                 certType = _CERT_TYPE_ROOT_DOMAIN1;
242                 break;
243
244         case TRUSTED_THIRD_PARTY_DOMAIN:
245                 certType = _CERT_TYPE_ROOT_DOMAIN3;
246                 break;
247
248         case USER_CERT:
249                 certType = _CERT_TYPE_USER_CERT;
250                 break;
251
252         default:
253                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
254                 break;
255         }
256
257         std::unique_ptr< ByteBuffer > pOldEncodedData(oldCert.GetEncodedDataN());
258         SysTryReturnResult(NID_SEC_CERT, pOldEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on old input certificate.");
259
260         pOldBuffer = const_cast< byte* >(pOldEncodedData->GetPointer());
261         SysTryReturnResult(NID_SEC_CERT, pOldBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
262
263         oldBufferLen = pOldEncodedData->GetRemaining();
264         SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
265
266         pOldEncodedData.reset(null);
267
268         std::unique_ptr< ByteBuffer > pNewEncodedData(newCert.GetEncodedDataN());
269         SysTryReturnResult(NID_SEC_CERT, pNewEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on new input certificate.");
270
271         pNewBuffer = const_cast< byte* >(pNewEncodedData->GetPointer());
272         SysTryReturnResult(NID_SEC_CERT, pNewBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
273
274         newBufferLen = pNewEncodedData->GetRemaining();
275         SysTryReturnResult(NID_SEC_CERT, newBufferLen > 0, E_INVALID_ARG, "Input new certificate length is not positive.");
276
277         if (certType == _CERT_TYPE_USER_CERT)
278         {
279                 CertificateHandle certHandle = 0;
280                 int certId = 0;
281
282                 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pOldBuffer), oldBufferLen, &certHandle);
283                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
284
285                 r = _CertService::GetUserCertificateId(certHandle, certId);
286
287                 _CertService::CloseCertificate(&certHandle);
288                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
289
290                 r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
291                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove/update user certificates from store.", GetErrorMessage(r));
292
293                 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pNewBuffer), newBufferLen, null, 0);
294                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to install/update user certificates.", GetErrorMessage(r));
295         }
296         else
297         {
298                 r = __pCertServiceProxy->UpdateCaCertificate(static_cast< int >(certType), pOldBuffer, oldBufferLen, pNewBuffer, newBufferLen);
299                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update certificate.", GetErrorMessage(r));
300         }
301
302         return r;
303 }
304
305
306 result
307 _X509CertificateStoreImpl::Remove(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
308 {
309         result r = E_SUCCESS;
310         byte* pBuffer = null;
311         int bufferLen = 0;
312         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
313
314         switch (certificateType)
315         {
316         case ROOT_CA:
317                 certType = _CERT_TYPE_ROOT_CA;
318                 break;
319
320         case OPERATOR_DOMAIN:
321                 certType = _CERT_TYPE_ROOT_DOMAIN1;
322                 break;
323
324         case TRUSTED_THIRD_PARTY_DOMAIN:
325                 certType = _CERT_TYPE_ROOT_DOMAIN3;
326                 break;
327
328         case USER_CERT:
329                 certType = _CERT_TYPE_USER_CERT;
330                 break;
331
332         default:
333                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
334                 break;
335         }
336
337         std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
338         SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
339
340         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
341         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
342
343         bufferLen = pEncodedData->GetRemaining();
344         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
345
346         if (certType == _CERT_TYPE_USER_CERT)
347         {
348                 CertificateHandle certHandle = 0;
349                 int certId = 0;
350
351                 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pBuffer), bufferLen, &certHandle);
352                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
353
354                 r = _CertService::GetUserCertificateId(certHandle, certId);
355
356                 _CertService::CloseCertificate(&certHandle);
357                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
358
359                 r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
360                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
361         }
362         else
363         {
364                 r = __pCertServiceProxy->RemoveCaCertificate(static_cast< int >(certType), pBuffer, bufferLen);
365                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
366         }
367
368         return r;
369 }
370
371 _X509CertificateStoreImpl*
372 _X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
373 {
374         return x509CertificateStore.__pX509CertificateStoreImpl;
375 }
376
377 const _X509CertificateStoreImpl*
378 _X509CertificateStoreImpl::GetInstance(const X509CertificateStore& x509CertificateStore)
379 {
380         return x509CertificateStore.__pX509CertificateStoreImpl;
381 }
382
383 int InsertPkcs12Content(const char* pPath, const char* pPassword)
384 {
385         result r = E_SUCCESS;
386         _X509CertificateStoreImpl store;
387         String filePath;
388         String password;
389
390         filePath.SetCapacity(strlen(pPath)+1);
391         password.SetCapacity(strlen(pPassword)+1);
392
393         filePath.Format(strlen(pPath)+1, L"%s", pPath);
394         password.Format(strlen(pPassword)+1, L"%s", pPassword);
395
396         r = store.InsertPkcs12(filePath, password, false);
397         SysTryReturn(NID_SEC_CERT, !IsFailed(r), -1, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
398
399         return 0;
400 }
401
402
403 } } }       // Tizen::Security::Cert