2 // Open Service Platform
3 // Copyright (c) 2013 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 FSecPkcs_AlgorithmIdentifierImpl.cpp
20 * @brief This is the implementation file for _AlgorithmIdentifierImpl class.
22 * This header file contains the implementation of _AlgorithmIdentifierImpl class.
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>
42 #include "FSecPkcs_PkcsUtility.h"
43 #include "FSecPkcs_AlgorithmIdentifierImpl.h"
45 using namespace Tizen::Base;
47 namespace Tizen { namespace Security { namespace Pkcs
50 _AlgorithmIdentifierImpl::_AlgorithmIdentifierImpl(void)
55 _AlgorithmIdentifierImpl::~_AlgorithmIdentifierImpl(void)
61 _AlgorithmIdentifierImpl::Construct(const Tizen::Base::String& algorithm, const IAlgorithmParameters* pAlgoParams)
65 bool isParamSupported = false;
67 SysAssertf(__algorithm.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
69 SysTryReturnResult(NID_SEC_CRYPTO, algorithm.GetLength() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
71 __algorithm = algorithm;
72 oidValue = _PkcsUtility::ConvertOidToEnum(algorithm);
75 SysTryReturnResult(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "The object id of the input algorithm is not supported.");
80 if (pAlgoParams != null)
82 __pAlgoParams = pAlgoParams->CloneN();
83 SysTryReturnResult(NID_SEC_CRYPTO, __pAlgoParams != null, E_INVALID_ARG, "The specified input parameter is invalid.");
86 if (__pAlgoParams == null)
88 isParamSupported = _PkcsUtility::IsParameterSupported(algorithm);
89 SysTryReturnResult(NID_SEC_CRYPTO, !isParamSupported, E_INVALID_ARG, "The specified input parameter is invalid.");
96 _AlgorithmIdentifierImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
99 const byte* pBuffer = null;
102 X509_ALGOR* pAlgoObj = null;
103 Tizen::Base::String algoOid = null;
105 SysAssertf(__algorithm.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
107 pBuffer = encodedData.GetPointer();
108 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
110 bufferLen = encodedData.GetRemaining();
111 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
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.");
116 algoNid = OBJ_obj2nid(pAlgoObj->algorithm);
117 algoOid = _PkcsUtility::ConvertToOid(algoNid);
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.");
122 __algorithm = algoOid;
124 delete __pAlgoParams;
125 __pAlgoParams = null;
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.");
132 X509_ALGOR_free(pAlgoObj);
137 _AlgorithmIdentifierImpl::GetAlgorithmObjectId(void) const
143 IAlgorithmParameters*
144 _AlgorithmIdentifierImpl::GetParametersN(void) const
146 std::unique_ptr< IAlgorithmParameters > pAlgoParam;
148 //Return the Algorithm Parameter
151 if (__pAlgoParams != null)
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.");
156 return pAlgoParam.release();
166 _AlgorithmIdentifierImpl::GetEncodedDataN(void) const
168 result r = E_SUCCESS;
170 X509_ALGOR* pAlgoObj = null;
171 std::unique_ptr< ByteBuffer > pEncAlgoIdParam;
177 SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
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.");
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.");
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.");
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.");
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.");
194 pEncAlgoIdParam->Flip();
200 pEncAlgoIdParam.reset(null);
202 X509_ALGOR_free(pAlgoObj);
204 return pEncAlgoIdParam.release();
209 _AlgorithmIdentifierImpl::Equals(const Object& obj) const
211 Tizen::Base::String algorithm;
213 SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
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.");
223 algorithm = pOther->GetAlgorithmObjectId();
225 if (algorithm == __algorithm)
228 switch (_PkcsUtility::ConvertOidToEnum(algorithm))
230 case _OID_TYPE_DES_CBC:
232 case _OID_TYPE_DES_CBC_EDE3:
234 case _OID_TYPE_AES_128_CBC:
236 case _OID_TYPE_AES_192_CBC:
238 case _OID_TYPE_AES_256_CBC:
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.");
243 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
245 if (pIvObj->Equals(*(dynamic_cast< InitialVector* >(__pAlgoParams))))
256 case _OID_TYPE_RC2_CBC:
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.");
261 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
263 if (pRcObj->Equals(*(dynamic_cast< Rc2CbcParameters* >(__pAlgoParams))))
275 case _OID_TYPE_HMAC_SHA1:
277 case _OID_TYPE_HMAC_SHA2_224:
279 case _OID_TYPE_HMAC_SHA2_256:
281 case _OID_TYPE_HMAC_SHA2_384:
283 case _OID_TYPE_HMAC_SHA2_512:
285 case _OID_TYPE_RSA_ENCRYPTION:
291 case _OID_TYPE_PBES2:
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.");
296 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
298 SysTryReturn(NID_SEC_CRYPTO, dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams) != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
300 if (pEncObj->GetKeyDerivationAlgorithm().Equals(((dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams))->GetKeyDerivationAlgorithm())))
302 if (pEncObj->GetEncryptionScheme().Equals(((dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams))->GetEncryptionScheme())))
320 case _OID_TYPE_PBKDF2:
323 std::unique_ptr< Pkcs05PbKdf2Parameters > pKdf2Obj(dynamic_cast< Pkcs05PbKdf2Parameters* >(pOther->GetParametersN()));
324 SysTryReturn(NID_SEC_CRYPTO, pKdf2Obj, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
326 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
328 if (pKdf2Obj->Equals(*((dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams)))))
340 SetLastResult(E_INVALID_ARG);
351 _AlgorithmIdentifierImpl::GetHashCode(void) const
353 InitialVector* pIvObj = null;
354 Rc2CbcParameters* pRcObj = null;
355 Pkcs05PbEs2Parameters* pEncObj = null;
356 Pkcs05PbKdf2Parameters* pKdf2Obj = null;
359 SysAssertf(__algorithm.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
361 switch (_PkcsUtility::ConvertOidToEnum(__algorithm))
363 case _OID_TYPE_DES_CBC:
365 case _OID_TYPE_DES_CBC_EDE3:
367 case _OID_TYPE_AES_128_CBC:
369 case _OID_TYPE_AES_192_CBC:
371 case _OID_TYPE_AES_256_CBC:
373 pIvObj = dynamic_cast< InitialVector* >(__pAlgoParams);
374 SysTryReturn(NID_SEC_CRYPTO, pIvObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
376 hashCode = __algorithm.GetHashCode() + pIvObj->GetHashCode();
381 case _OID_TYPE_RC2_CBC:
383 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
385 pRcObj = dynamic_cast< Rc2CbcParameters* >(__pAlgoParams);
386 SysTryReturn(NID_SEC_CRYPTO, pRcObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
388 hashCode = __algorithm.GetHashCode() + pRcObj->GetHashCode();
393 case _OID_TYPE_HMAC_SHA1:
395 case _OID_TYPE_HMAC_SHA2_224:
397 case _OID_TYPE_HMAC_SHA2_256:
399 case _OID_TYPE_HMAC_SHA2_384:
401 case _OID_TYPE_HMAC_SHA2_512:
403 case _OID_TYPE_RSA_ENCRYPTION:
405 return __algorithm.GetHashCode();
408 case _OID_TYPE_PBES2:
410 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
412 pEncObj = dynamic_cast< Pkcs05PbEs2Parameters* >(__pAlgoParams);
413 SysTryReturn(NID_SEC_CRYPTO, pEncObj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
415 hashCode = pEncObj->GetKeyDerivationAlgorithm().GetHashCode() + pEncObj->GetEncryptionScheme().GetHashCode();
420 case _OID_TYPE_PBKDF2:
422 SysTryReturn(NID_SEC_CRYPTO, __pAlgoParams != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
424 pKdf2Obj = dynamic_cast< Pkcs05PbKdf2Parameters* >(__pAlgoParams);
425 SysTryReturn(NID_SEC_CRYPTO, pKdf2Obj != null, 0, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
427 hashCode = __algorithm.GetHashCode() + pKdf2Obj->GetHashCode();
441 _AlgorithmIdentifierImpl*
442 _AlgorithmIdentifierImpl::GetInstance(AlgorithmIdentifier& algorithmIdentifier)
444 return algorithmIdentifier.__pAlgorithmIdentifierImpl;
447 const _AlgorithmIdentifierImpl*
448 _AlgorithmIdentifierImpl::GetInstance(const AlgorithmIdentifier& algorithmIdentifier)
450 return algorithmIdentifier.__pAlgorithmIdentifierImpl;