Merge "Update GetPackageAppInfoN() API" into tizen_2.1
[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         const _AlgorithmIdentifierImpl* pOther = dynamic_cast< const _AlgorithmIdentifierImpl* >(&obj);
214
215         SysTryReturn(NID_SEC_CRYPTO, pOther != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
216
217         if (pOther == this)
218         {
219                 return true;
220         }
221
222         algorithm = pOther->GetAlgorithmObjectId();
223
224         if (algorithm == __algorithm)
225         {
226
227                 switch (_PkcsUtility::ConvertOidToEnum(algorithm))
228                 {
229                 case _OID_TYPE_DES_CBC:
230                 // fall through
231                 case _OID_TYPE_DES_CBC_EDE3:
232                 // fall through
233                 case _OID_TYPE_AES_128_CBC:
234                 // fall through
235                 case _OID_TYPE_AES_192_CBC:
236                 // fall through
237                 case _OID_TYPE_AES_256_CBC:
238                 {
239                         std::unique_ptr< InitialVector > pIvObj(dynamic_cast< InitialVector* >(pOther->GetParametersN()));
240                         SysTryReturn(NID_SEC_CRYPTO, pIvObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
241
242                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
243
244                         if (pIvObj->Equals(*(dynamic_cast< InitialVector* >(__pAlgoParams))))
245                         {
246                                 return true;
247                         }
248                         else
249                         {
250                                 return false;
251                         }
252                 }
253                 break;
254
255                 case _OID_TYPE_RC2_CBC:
256                 {
257                         std::unique_ptr< Rc2CbcParameters > pRcObj(dynamic_cast< Rc2CbcParameters* >(pOther->GetParametersN()));
258                         SysTryReturn(NID_SEC_CRYPTO, pRcObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
259
260                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
261
262                         if (pRcObj->Equals(*(dynamic_cast< Rc2CbcParameters* >(__pAlgoParams))))
263                         {
264                                 return true;
265                         }
266                         else
267                         {
268                                 return false;
269                         }
270
271                 }
272                 break;
273
274                 case _OID_TYPE_HMAC_SHA1:
275                 // fall through
276                 case _OID_TYPE_HMAC_SHA2_224:
277                 // fall through
278                 case _OID_TYPE_HMAC_SHA2_256:
279                 // fall through
280                 case _OID_TYPE_HMAC_SHA2_384:
281                 // fall through
282                 case _OID_TYPE_HMAC_SHA2_512:
283                 // fall through
284                 case _OID_TYPE_RSA_ENCRYPTION:
285                 {
286                         return true;
287                 }
288                 break;
289
290                 case _OID_TYPE_PBES2:
291                 {
292                         std::unique_ptr< Pkcs05PbEs2Parameters > pEncObj(dynamic_cast< Pkcs05PbEs2Parameters* >(pOther->GetParametersN()));
293                         SysTryReturn(NID_SEC_CRYPTO, pEncObj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
294
295                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
296
297                         if (pEncObj->GetKeyDerivationAlgorithm().Equals(((dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams))->GetKeyDerivationAlgorithm())))
298                         {
299                                 if (pEncObj->GetEncryptionScheme().Equals(((dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams))->GetEncryptionScheme())))
300                                 {
301                                         return true;
302
303                                 }
304                                 else
305                                 {
306                                         return false;
307                                 }
308
309                         }
310                         else
311                         {
312                                 return false;
313                         }
314                 }
315                 break;
316
317                 case _OID_TYPE_PBKDF2:
318                 {
319                         std::unique_ptr< Pkcs05PbKdf2Parameters > pKdf2Obj(dynamic_cast< Pkcs05PbKdf2Parameters* >(pOther->GetParametersN()));
320                         SysTryReturn(NID_SEC_CRYPTO, pKdf2Obj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
321
322                         SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
323
324                         if (pKdf2Obj->Equals(*((dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams)))))
325                         {
326                                 return true;
327                         }
328                         else
329                         {
330                                 return false;
331                         }
332                 }
333                 break;
334
335                 default:
336                         SetLastResult(E_INVALID_ARG);
337                         return false;
338
339                 }
340
341         }
342
343         return false;
344 }
345
346 int
347 _AlgorithmIdentifierImpl::GetHashCode(void) const
348 {
349         InitialVector* pIvObj = null;
350         Rc2CbcParameters* pRcObj = null;
351         Pkcs05PbEs2Parameters* pEncObj = null;
352         Pkcs05PbKdf2Parameters* pKdf2Obj = null;
353         int hashCode = 0;
354
355         switch (_PkcsUtility::ConvertOidToEnum(__algorithm))
356         {
357         case _OID_TYPE_DES_CBC:
358         // fall through
359         case _OID_TYPE_DES_CBC_EDE3:
360         // fall through
361         case _OID_TYPE_AES_128_CBC:
362         // fall through
363         case _OID_TYPE_AES_192_CBC:
364         // fall through
365         case _OID_TYPE_AES_256_CBC:
366         {
367                 pIvObj = dynamic_cast< InitialVector* >(__pAlgoParams);
368                 hashCode = __algorithm.GetHashCode() + pIvObj->GetHashCode();
369
370                 return hashCode;
371         }
372
373         case _OID_TYPE_RC2_CBC:
374         {
375                 pRcObj = dynamic_cast< Rc2CbcParameters* >(__pAlgoParams);
376                 hashCode = __algorithm.GetHashCode() + pRcObj->GetHashCode();
377
378                 return hashCode;
379         }
380
381         case _OID_TYPE_HMAC_SHA1:
382         // fall through
383         case _OID_TYPE_HMAC_SHA2_224:
384         // fall through
385         case _OID_TYPE_HMAC_SHA2_256:
386         // fall through
387         case _OID_TYPE_HMAC_SHA2_384:
388         // fall through
389         case _OID_TYPE_HMAC_SHA2_512:
390         // fall through
391         case _OID_TYPE_RSA_ENCRYPTION:
392         {
393                 return __algorithm.GetHashCode();
394         }
395
396         case _OID_TYPE_PBES2:
397         {
398                 pEncObj = dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams);
399
400                 hashCode = pEncObj->GetKeyDerivationAlgorithm().GetHashCode() + pEncObj->GetEncryptionScheme().GetHashCode();
401
402                 return hashCode;
403         }
404
405         case _OID_TYPE_PBKDF2:
406         {
407                 pKdf2Obj = dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams);
408
409                 hashCode = __algorithm.GetHashCode() + pKdf2Obj->GetHashCode();
410                 return hashCode;
411
412         }
413
414         default:
415                 return 0;
416
417         }
418
419         return 0;
420
421 }
422
423 _AlgorithmIdentifierImpl*
424 _AlgorithmIdentifierImpl::GetInstance(AlgorithmIdentifier& algorithmIdentifier)
425 {
426         return algorithmIdentifier.__pAlgorithmIdentifierImpl;
427 }
428
429 const _AlgorithmIdentifierImpl*
430 _AlgorithmIdentifierImpl::GetInstance(const AlgorithmIdentifier& algorithmIdentifier)
431 {
432         return algorithmIdentifier.__pAlgorithmIdentifierImpl;
433 }
434
435 } }}