Fix prevent issues in FSecurity
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_AlgorithmIdentifierImpl.cpp
1 ///
2 // Open Service Platform
3 // Copyright (c) 2013 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                FSecPkcs_AlgorithmIdentifierImpl.cpp
20  * @brief               This is the implementation file for _AlgorithmIdentifierImpl class.
21  *
22  * This header file contains the implementation of _AlgorithmIdentifierImpl class.
23  *
24  */
25
26 #include <new>
27 #include <openssl/x509.h>
28 #include <openssl/objects.h>
29 #include <openssl/obj_mac.h>
30 #include <openssl/evp.h>
31 #include <unique_ptr.h>
32 #include <FBaseByteBuffer.h>
33 #include <FBaseResult.h>
34 #include <FBaseSysLog.h>
35 #include <FSecPkcsIAlgorithmParameters.h>
36 #include <FSecPkcsInitialVector.h>
37 #include <FSecPkcsPkcs05PbMacParameters.h>
38 #include <FSecPkcsPkcs05PbEs2Parameters.h>
39 #include <FSecPkcsPkcs05PbKdf2Parameters.h>
40 #include <FSecPkcsRc2CbcParameters.h>
41
42 #include "FSecPkcs_PkcsUtility.h"
43 #include "FSecPkcs_AlgorithmIdentifierImpl.h"
44
45 using namespace Tizen::Base;
46
47 namespace Tizen { namespace Security { namespace Pkcs
48 {
49
50 _AlgorithmIdentifierImpl::_AlgorithmIdentifierImpl(void)
51         : __pAlgoParams(null)
52 {
53
54 }
55 _AlgorithmIdentifierImpl::~_AlgorithmIdentifierImpl(void)
56 {
57         delete __pAlgoParams;
58 }
59
60 result
61 _AlgorithmIdentifierImpl::Construct(const Tizen::Base::String& algorithm, const IAlgorithmParameters* pAlgoParams)
62 {
63         result r = E_SUCCESS;
64         _OidType oidValue;
65         bool isParamSupported = false;
66
67         SysAssertf(__algorithm.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
68
69         SysTryReturnResult(NID_SEC_CRYPTO, algorithm.GetLength() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
70
71         __algorithm = algorithm;
72         oidValue = _PkcsUtility::ConvertOidToEnum(algorithm);
73
74         r = GetLastResult();
75         SysTryReturnResult(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "The object id of the input algorithm is not supported.");
76
77         delete __pAlgoParams;
78         __pAlgoParams = null;
79
80         if (pAlgoParams != null)
81         {
82                 __pAlgoParams = pAlgoParams->CloneN();
83                 SysTryReturnResult(NID_SEC_CRYPTO, __pAlgoParams != null, E_INVALID_ARG, "The specified input parameter is invalid.");
84         }
85
86         if (__pAlgoParams == null)
87         {
88                 isParamSupported = _PkcsUtility::IsParameterSupported(algorithm);
89                 SysTryReturnResult(NID_SEC_CRYPTO, !isParamSupported, E_INVALID_ARG, "The specified input parameter is invalid.");
90         }
91
92         return r;
93 }
94
95 result
96 _AlgorithmIdentifierImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
97 {
98         result r = E_SUCCESS;
99         const byte* pBuffer = null;
100         int bufferLen = 0;
101         int algoNid = 0;
102         X509_ALGOR* pAlgoObj = null;
103         Tizen::Base::String algoOid = null;
104
105         SysAssertf(__algorithm.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
106
107         pBuffer = encodedData.GetPointer();
108         SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
109
110         bufferLen = encodedData.GetRemaining();
111         SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
112
113         pAlgoObj = d2i_X509_ALGOR(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
114         SysTryReturnResult(NID_SEC_CRYPTO, pAlgoObj != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
115
116         algoNid = OBJ_obj2nid(pAlgoObj->algorithm);
117         algoOid = _PkcsUtility::ConvertToOid(algoNid);
118
119         r = GetLastResult();
120         SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The object id of the algorithm identifier is not supported.");
121
122         __algorithm = algoOid;
123
124         delete __pAlgoParams;
125         __pAlgoParams = null;
126
127         __pAlgoParams = _PkcsUtility::GernerateParametersFromOidN(__algorithm, pAlgoObj);
128         SysTryCatch(NID_SEC_CRYPTO, __pAlgoParams != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
129
130 CATCH:
131
132         X509_ALGOR_free(pAlgoObj);
133         return r;
134 }
135
136 String
137 _AlgorithmIdentifierImpl::GetAlgorithmObjectId(void) const
138 {
139         ClearLastResult();
140         return __algorithm;
141 }
142
143 IAlgorithmParameters*
144 _AlgorithmIdentifierImpl::GetParametersN(void) const
145 {
146         std::unique_ptr< IAlgorithmParameters > pAlgoParam;
147
148         //Return the Algorithm Parameter
149         ClearLastResult();
150
151         if (__pAlgoParams != null)
152         {
153                 pAlgoParam = std::unique_ptr< IAlgorithmParameters >(__pAlgoParams->CloneN());
154                 SysTryReturn(NID_SEC_CRYPTO, pAlgoParam != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
155
156                 return pAlgoParam.release();
157         }
158         else
159         {
160                 return null;
161         }
162
163 }
164
165 ByteBuffer*
166 _AlgorithmIdentifierImpl::GetEncodedDataN(void) const
167 {
168         result r = E_SUCCESS;
169         byte* pOut = null;
170         X509_ALGOR* pAlgoObj = null;
171         std::unique_ptr< ByteBuffer > pEncAlgoIdParam;
172         int value = 0;
173
174
175         ClearLastResult();
176
177         SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
178
179         pAlgoObj = _PkcsUtility::GenerateAlgorithmIdentifierStructureN(__algorithm, __pAlgoParams);
180         SysTryReturn(NID_SEC_CRYPTO, pAlgoObj != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
181
182         value = i2d_X509_ALGOR(pAlgoObj, &pOut);
183         SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
184
185         pEncAlgoIdParam = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
186         SysTryCatch(NID_SEC_CRYPTO, pEncAlgoIdParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
187
188         r = pEncAlgoIdParam->Construct(value);
189         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
190
191         r = pEncAlgoIdParam->SetArray(pOut, 0, value);
192         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
193
194         pEncAlgoIdParam->Flip();
195
196 CATCH:
197
198         if (IsFailed(r))
199         {
200                 pEncAlgoIdParam.reset(null);
201         }
202         X509_ALGOR_free(pAlgoObj);
203         SetLastResult(r);
204         return pEncAlgoIdParam.release();
205
206 }
207
208 bool
209 _AlgorithmIdentifierImpl::Equals(const Object& obj) const
210 {
211         Tizen::Base::String algorithm;
212
213         SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
214
215         const _AlgorithmIdentifierImpl* pOther = dynamic_cast< const _AlgorithmIdentifierImpl* >(&obj);
216         SysTryReturn(NID_SEC_CRYPTO, pOther != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
217
218         if (pOther == this)
219         {
220                 return true;
221         }
222
223         algorithm = pOther->GetAlgorithmObjectId();
224
225         if (algorithm == __algorithm)
226         {
227
228                 switch (_PkcsUtility::ConvertOidToEnum(algorithm))
229                 {
230                 case _OID_TYPE_DES_CBC:
231                 // fall through
232                 case _OID_TYPE_DES_CBC_EDE3:
233                 // fall through
234                 case _OID_TYPE_AES_128_CBC:
235                 // fall through
236                 case _OID_TYPE_AES_192_CBC:
237                 // fall through
238                 case _OID_TYPE_AES_256_CBC:
239                 {
240                         std::unique_ptr< InitialVector > pIvObj(dynamic_cast< InitialVector* >(pOther->GetParametersN()));
241                         SysTryReturn(NID_SEC_CRYPTO, pIvObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
242
243                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
244
245                         if (pIvObj->Equals(*(dynamic_cast< InitialVector* >(__pAlgoParams))))
246                         {
247                                 return true;
248                         }
249                         else
250                         {
251                                 return false;
252                         }
253                 }
254                 break;
255
256                 case _OID_TYPE_RC2_CBC:
257                 {
258                         std::unique_ptr< Rc2CbcParameters > pRcObj(dynamic_cast< Rc2CbcParameters* >(pOther->GetParametersN()));
259                         SysTryReturn(NID_SEC_CRYPTO, pRcObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
260
261                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
262
263                         if (pRcObj->Equals(*(dynamic_cast< Rc2CbcParameters* >(__pAlgoParams))))
264                         {
265                                 return true;
266                         }
267                         else
268                         {
269                                 return false;
270                         }
271
272                 }
273                 break;
274
275                 case _OID_TYPE_HMAC_SHA1:
276                 // fall through
277                 case _OID_TYPE_HMAC_SHA2_224:
278                 // fall through
279                 case _OID_TYPE_HMAC_SHA2_256:
280                 // fall through
281                 case _OID_TYPE_HMAC_SHA2_384:
282                 // fall through
283                 case _OID_TYPE_HMAC_SHA2_512:
284                 // fall through
285                 case _OID_TYPE_RSA_ENCRYPTION:
286                 {
287                         return true;
288                 }
289                 break;
290
291                 case _OID_TYPE_PBES2:
292                 {
293                         std::unique_ptr< Pkcs05PbEs2Parameters > pEncObj(dynamic_cast< Pkcs05PbEs2Parameters* >(pOther->GetParametersN()));
294                         SysTryReturn(NID_SEC_CRYPTO, pEncObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
295
296                         Pkcs05PbEs2Parameters* pPkcs05PbEs2Params = dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams);
297                         SysTryReturn(NID_SEC_CRYPTO, pPkcs05PbEs2Params != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
298
299                         if (pEncObj->GetKeyDerivationAlgorithm().Equals(pPkcs05PbEs2Params->GetKeyDerivationAlgorithm()))
300                         {
301                                 if (pEncObj->GetEncryptionScheme().Equals(pPkcs05PbEs2Params->GetEncryptionScheme()))
302                                 {
303                                         return true;
304
305                                 }
306                                 else
307                                 {
308                                         return false;
309                                 }
310
311                         }
312                         else
313                         {
314                                 return false;
315                         }
316                 }
317                 break;
318
319                 case _OID_TYPE_PBKDF2:
320                 {
321
322                         std::unique_ptr< Pkcs05PbKdf2Parameters > pKdf2Obj(dynamic_cast< Pkcs05PbKdf2Parameters* >(pOther->GetParametersN()));
323                         SysTryReturn(NID_SEC_CRYPTO, pKdf2Obj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
324
325                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
326
327                         if (pKdf2Obj->Equals(*((dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams)))))
328                         {
329                                 return true;
330                         }
331                         else
332                         {
333                                 return false;
334                         }
335                 }
336                 break;
337
338                 default:
339                         SetLastResult(E_INVALID_ARG);
340                         return false;
341
342                 }
343
344         }
345
346         return false;
347 }
348
349 int
350 _AlgorithmIdentifierImpl::GetHashCode(void) const
351 {
352         InitialVector* pIvObj = null;
353         Rc2CbcParameters* pRcObj = null;
354         Pkcs05PbEs2Parameters* pEncObj = null;
355         Pkcs05PbKdf2Parameters* pKdf2Obj = null;
356         int hashCode = 0;
357
358         SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
359
360         switch (_PkcsUtility::ConvertOidToEnum(__algorithm))
361         {
362         case _OID_TYPE_DES_CBC:
363         // fall through
364         case _OID_TYPE_DES_CBC_EDE3:
365         // fall through
366         case _OID_TYPE_AES_128_CBC:
367         // fall through
368         case _OID_TYPE_AES_192_CBC:
369         // fall through
370         case _OID_TYPE_AES_256_CBC:
371         {
372                 pIvObj = dynamic_cast< InitialVector* >(__pAlgoParams);
373                 SysTryReturn(NID_SEC_CRYPTO, pIvObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
374
375                 hashCode = __algorithm.GetHashCode() + pIvObj->GetHashCode();
376
377                 return hashCode;
378         }
379
380         case _OID_TYPE_RC2_CBC:
381         {
382                 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
383
384                 pRcObj = dynamic_cast< Rc2CbcParameters* >(__pAlgoParams);
385                 SysTryReturn(NID_SEC_CRYPTO, pRcObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
386
387                 hashCode = __algorithm.GetHashCode() + pRcObj->GetHashCode();
388
389                 return hashCode;
390         }
391
392         case _OID_TYPE_HMAC_SHA1:
393         // fall through
394         case _OID_TYPE_HMAC_SHA2_224:
395         // fall through
396         case _OID_TYPE_HMAC_SHA2_256:
397         // fall through
398         case _OID_TYPE_HMAC_SHA2_384:
399         // fall through
400         case _OID_TYPE_HMAC_SHA2_512:
401         // fall through
402         case _OID_TYPE_RSA_ENCRYPTION:
403         {
404                 return __algorithm.GetHashCode();
405         }
406
407         case _OID_TYPE_PBES2:
408         {
409                 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
410
411                 pEncObj = dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams);
412                 SysTryReturn(NID_SEC_CRYPTO, pEncObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
413
414                 hashCode = pEncObj->GetKeyDerivationAlgorithm().GetHashCode() + pEncObj->GetEncryptionScheme().GetHashCode();
415
416                 return hashCode;
417         }
418
419         case _OID_TYPE_PBKDF2:
420         {
421                 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
422
423                 pKdf2Obj = dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams);
424                 SysTryReturn(NID_SEC_CRYPTO, pKdf2Obj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
425
426                 hashCode = __algorithm.GetHashCode() + pKdf2Obj->GetHashCode();
427                 return hashCode;
428
429         }
430
431         default:
432                 return 0;
433
434         }
435
436         return 0;
437
438 }
439
440 _AlgorithmIdentifierImpl*
441 _AlgorithmIdentifierImpl::GetInstance(AlgorithmIdentifier& algorithmIdentifier)
442 {
443         return algorithmIdentifier.__pAlgorithmIdentifierImpl;
444 }
445
446 const _AlgorithmIdentifierImpl*
447 _AlgorithmIdentifierImpl::GetInstance(const AlgorithmIdentifier& algorithmIdentifier)
448 {
449         return algorithmIdentifier.__pAlgorithmIdentifierImpl;
450 }
451
452 } }}