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_Pkcs05PbEs2ParametersImpl.cpp
20 * @brief This is the implementation file for _Pkcs05PbEs2ParametersImpl class.
22 * This header file contains the implementation of _Pkcs05PbEs2ParametersImpl class.
26 #include <openssl/evp.h>
27 #include <openssl/crypto.h>
28 #include <openssl/x509.h>
29 #include <openssl/hmac.h>
30 #include <openssl/bn.h>
31 #include <openssl/objects.h>
32 #include <openssl/obj_mac.h>
33 #include <unique_ptr.h>
34 #include <FBaseByteBuffer.h>
35 #include <FBaseResult.h>
36 #include <FBaseSysLog.h>
38 #include <FSecPkcsRc2CbcParameters.h>
39 #include <FSecPkcsInitialVector.h>
40 #include <FSecPkcsIAlgorithmParameters.h>
41 #include <FSecPkcsTypes.h>
42 #include <FSecPkcsAlgorithmIdentifier.h>
43 #include <FSecPkcsPkcs05PbKdf2Parameters.h>
44 #include <FSecPkcsPkcs05PbEs2Parameters.h>
45 #include "FSecPkcs_PkcsUtility.h"
46 #include "FSecPkcs_Pkcs05PbEs2ParametersImpl.h"
48 using namespace Tizen::Base;
50 namespace Tizen { namespace Security { namespace Pkcs
53 _Pkcs05PbEs2ParametersImpl::_Pkcs05PbEs2ParametersImpl(void)
60 _Pkcs05PbEs2ParametersImpl::~_Pkcs05PbEs2ParametersImpl(void)
66 _Pkcs05PbEs2ParametersImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
69 ASN1_TYPE* pParam = null;
70 PBE2PARAM* pPbes2 = null;
73 Tizen::Base::String encOid = null;
74 std::unique_ptr< Pkcs05PbKdf2Parameters > pKdf2Parameters;
75 std::unique_ptr< IAlgorithmParameters > pEncParam;
76 const byte* pBuffer = null;
78 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
79 SysAssertf(__encryptionScheme.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
81 pBuffer = encodedData.GetPointer();
82 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
84 bufferLen = encodedData.GetRemaining();
85 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
87 pPbes2 = d2i_PBE2PARAM(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
88 SysTryReturnResult(NID_SEC_CRYPTO, pPbes2 != null, E_INVALID_ARG, "The specified input parameter is invalid.");
90 SysTryCatch(NID_SEC_CRYPTO, OBJ_obj2nid(pPbes2->keyfunc->algorithm) == NID_id_pbkdf2, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
92 pKdf2Parameters = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(_PkcsUtility::GernerateParametersFromOidN(OID_PBKDF2, pPbes2->keyfunc)));
93 SysTryCatch(NID_SEC_CRYPTO, pKdf2Parameters, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
95 r = __keyDerivationFunction.Construct(OID_PBKDF2, pKdf2Parameters.get());
96 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
98 pParam = pPbes2->encryption->parameter;
99 SysTryCatch(NID_SEC_CRYPTO, pParam != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
101 nidEncAlgo = OBJ_obj2nid(pPbes2->encryption->algorithm);
102 encOid = _PkcsUtility::ConvertToOid(nidEncAlgo);
105 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
107 pEncParam = std::unique_ptr< IAlgorithmParameters >(_PkcsUtility::GernerateParametersFromOidN(encOid, pPbes2->encryption));
108 SysTryCatch(NID_SEC_CRYPTO, pEncParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
110 r = __encryptionScheme.Construct(encOid, pEncParam.get());
111 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Failed to construct algorithm identifier.", GetErrorMessage(r));
115 PBE2PARAM_free(pPbes2);
121 _Pkcs05PbEs2ParametersImpl::Construct(const AlgorithmIdentifier& keyDerivationFunction, const AlgorithmIdentifier& encryptionScheme)
123 result r = E_SUCCESS;
125 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
126 SysAssertf(__encryptionScheme.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
128 std::unique_ptr< IAlgorithmParameters > pkdfParam(keyDerivationFunction.GetParametersN());
130 SysTryReturn(NID_SEC_CRYPTO, pkdfParam != null, r, r, "[%s] Failed to get the parameters.", GetErrorMessage(r));
132 r = __keyDerivationFunction.Construct(keyDerivationFunction.GetAlgorithmObjectId(), pkdfParam.get());
133 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier.", GetErrorMessage(r));
135 std::unique_ptr< IAlgorithmParameters > pEncParam(encryptionScheme.GetParametersN());
137 SysTryReturn(NID_SEC_CRYPTO, pEncParam != null, r, r, "[%s] Failed to get the parameters.", GetErrorMessage(r));
139 r = __encryptionScheme.Construct(encryptionScheme.GetAlgorithmObjectId(), pEncParam.get());
140 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier.", GetErrorMessage(r));
147 _Pkcs05PbEs2ParametersImpl::GetEncodedDataN(void) const
149 result r = E_SUCCESS;
150 PBE2PARAM* pPbes2 = null;
151 std::unique_ptr< ByteBuffer > pEncPbeParam;
152 std::unique_ptr< Tizen::Base::ByteBuffer > pSaltBuf;
153 Tizen::Base::String prfOid = null;
160 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
161 SysAssertf(__encryptionScheme.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
163 Tizen::Base::String objectId = __encryptionScheme.GetAlgorithmObjectId();
165 std::unique_ptr< IAlgorithmParameters > pParams(__encryptionScheme.GetParametersN());
166 SysTryReturn(NID_SEC_CRYPTO, pParams != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
168 std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyParams(dynamic_cast< Pkcs05PbKdf2Parameters* >(__keyDerivationFunction.GetParametersN()));
169 SysTryReturn(NID_SEC_CRYPTO, pKeyParams != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
171 pPbes2 = PBE2PARAM_new();
172 SysTryCatch(NID_SEC_CRYPTO, pPbes2 != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
174 // set up the keyfunc
176 pSaltBuf = std::unique_ptr< Tizen::Base::ByteBuffer >(new (std::nothrow) ByteBuffer());
177 SysTryCatch(NID_SEC_CRYPTO, pSaltBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
179 r = pSaltBuf->Construct(pKeyParams->GetSaltValue());
180 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
182 prfOid = (pKeyParams->GetPrf()).GetAlgorithmObjectId();
183 prfNid = _PkcsUtility::ConvertToNid(prfOid);
185 pPbes2->keyfunc = _PkcsUtility::GenerateKdfParametersN(pKeyParams->GetIterationCount(), const_cast< unsigned char* >(pSaltBuf->GetPointer()), pSaltBuf->GetRemaining(), prfNid, pKeyParams->GetDerivedKeyLength());
186 SysTryCatch(NID_SEC_CRYPTO, pPbes2->keyfunc != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
188 // set up the pPbes2->encryption
189 pPbes2->encryption = X509_ALGOR_new();
190 SysTryCatch(NID_SEC_CRYPTO, pPbes2->encryption != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
192 pPbes2->encryption = _PkcsUtility::GenerateAlgorithmIdentifierStructureN(objectId, pParams.get());
193 SysTryCatch(NID_SEC_CRYPTO, pPbes2->encryption != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
195 // encode the PBE2PARAM structure
197 value = i2d_PBE2PARAM(pPbes2, &pTemp);
198 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
200 pEncPbeParam = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
201 SysTryCatch(NID_SEC_CRYPTO, pEncPbeParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
203 r = pEncPbeParam->Construct(value);
204 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
206 r = pEncPbeParam->SetArray(pTemp, 0, value);
207 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
209 pEncPbeParam->Flip();
215 PBE2PARAM_free(pPbes2);
216 pEncPbeParam.reset(null);
221 return pEncPbeParam.release();
225 const AlgorithmIdentifier&
226 _Pkcs05PbEs2ParametersImpl::GetKeyDerivationAlgorithm(void) const
230 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
231 SysAssertf(__encryptionScheme.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
233 return __keyDerivationFunction;
236 const AlgorithmIdentifier&
237 _Pkcs05PbEs2ParametersImpl::GetEncryptionScheme(void) const
240 return __encryptionScheme;
243 PkcsAlgorithmParameterType
244 _Pkcs05PbEs2ParametersImpl::GetType(void) const
247 return PKCS_ALGO_PARAM_TYPE_PKCS05_PBES02;
251 _Pkcs05PbEs2ParametersImpl::Equals(const Object& obj) const
255 const _Pkcs05PbEs2ParametersImpl* pOther = dynamic_cast< const _Pkcs05PbEs2ParametersImpl* >(&obj);
257 SysTryReturn(NID_SEC_CRYPTO, pOther != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
264 SysTryReturn(NID_SEC_CRYPTO, pOther->GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
265 SysTryReturn(NID_SEC_CRYPTO, pOther->GetEncryptionScheme().GetAlgorithmObjectId().GetLength() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
267 value = (__keyDerivationFunction.Equals(pOther->GetKeyDerivationAlgorithm())) && (__encryptionScheme.Equals(pOther->GetEncryptionScheme()));
274 _Pkcs05PbEs2ParametersImpl::GetHashCode(void) const
276 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
277 SysAssertf(__encryptionScheme.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
279 return __keyDerivationFunction.GetHashCode() + __encryptionScheme.GetHashCode();
282 _Pkcs05PbEs2ParametersImpl*
283 _Pkcs05PbEs2ParametersImpl::GetInstance(Pkcs05PbEs2Parameters& pkcs05PbEs2Parameters)
285 return pkcs05PbEs2Parameters.__pPkcs05PbEs2ParametersImpl;
288 const _Pkcs05PbEs2ParametersImpl*
289 _Pkcs05PbEs2ParametersImpl::GetInstance(const Pkcs05PbEs2Parameters& pkcs05PbEs2Parameters)
291 return pkcs05PbEs2Parameters.__pPkcs05PbEs2ParametersImpl;
294 } } } // end of namespace Pkcs