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_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
20 * @brief This is the implementation file for _Pkcs08EncryptedPrivateKeyInfoImpl class.
22 * This header file contains the implementation of _Pkcs08EncryptedPrivateKeyInfoImpl class.
28 #include <openssl/evp.h>
29 #include <openssl/bn.h>
30 #include <openssl/x509.h>
31 #include <openssl/crypto.h>
32 #include <openssl/asn1t.h>
33 #include <openssl/asn1.h>
34 #include <openssl/objects.h>
35 #include <unique_ptr.h>
36 #include <FBaseSysLog.h>
37 #include <FBaseByteBuffer.h>
38 #include <FBaseResult.h>
39 #include <FSecPkcsPkcs08PrivateKeyInfo.h>
40 #include <FSecPkcsPkcs08EncryptedPrivateKeyInfo.h>
41 #include <FSecPkcsIAlgorithmParameters.h>
42 #include <FSecPkcsAlgorithmIdentifier.h>
43 #include <FSecPkcsTypes.h>
45 #include "FSecPkcs_PkcsUtility.h"
46 #include "FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.h"
48 using namespace Tizen::Base;
50 namespace Tizen { namespace Security { namespace Pkcs
53 //EncryptedPrivateKeyInfo Class Life cycle
56 _Pkcs08EncryptedPrivateKeyInfoImpl::_Pkcs08EncryptedPrivateKeyInfoImpl(void)
61 _Pkcs08EncryptedPrivateKeyInfoImpl::~_Pkcs08EncryptedPrivateKeyInfoImpl(void)
67 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
71 X509_SIG* pPkcs8Key = null;
72 Tizen::Base::String prfOid = null;
73 std::unique_ptr< IAlgorithmParameters > pEncParam;
74 Tizen::Base::ByteBuffer encryptedKeyBuffer;
75 const byte* pBuffer = null;
76 byte* pDigestValue = null;
81 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
83 pBuffer = encodedData.GetPointer();
84 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
86 bufferLen = encodedData.GetRemaining();
87 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
89 pPkcs8Key = d2i_X509_SIG(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
90 SysTryReturnResult(NID_SEC_CRYPTO, pPkcs8Key != null, E_INVALID_ARG, "The specified input parameter is invalid.");
92 SysTryCatch(NID_SEC_CRYPTO, pPkcs8Key->digest->type == V_ASN1_OCTET_STRING, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
96 prf_nid = OBJ_obj2nid(pPkcs8Key->algor->algorithm);
97 prfOid = _PkcsUtility::ConvertToOid(prf_nid);
100 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
102 pEncParam = std::unique_ptr< IAlgorithmParameters >(_PkcsUtility::GernerateParametersFromOidN(prfOid, pPkcs8Key->algor));
103 SysTryCatch(NID_SEC_CRYPTO, pEncParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
105 r = __encryptionAlgorithm.Construct(prfOid, pEncParam.get());
106 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
110 pDigestValue = pPkcs8Key->digest->data;
111 SysTryCatch(NID_SEC_CRYPTO, pDigestValue, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
113 digestLength = pPkcs8Key->digest->length;
114 SysTryCatch(NID_SEC_CRYPTO, digestLength > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
116 r = encryptedKeyBuffer.Construct(digestLength);
117 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
119 r = encryptedKeyBuffer.SetArray(pDigestValue, 0, digestLength);
120 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
122 encryptedKeyBuffer.Flip();
123 r = __encryptedData.Construct(encryptedKeyBuffer);
124 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
128 X509_SIG_free(pPkcs8Key);
133 // Encrypted Private Key Info Class Operations
135 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& encryptedData)
137 result r = E_SUCCESS;
139 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
141 SysTryReturn(NID_SEC_CRYPTO, encryptedData.GetRemaining() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
143 r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), algorithmId.GetParametersN());
144 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier instance for encryption algorithm.", GetErrorMessage(r));
146 r = __encryptedData.Construct(encryptedData);
147 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
155 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& key, const Tizen::Base::ByteBuffer& encodedPrivateKeyInfoBuffer)
157 result r = E_SUCCESS;
159 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
161 SysTryReturnResult(NID_SEC_CRYPTO, key.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
162 SysTryReturnResult(NID_SEC_CRYPTO, encodedPrivateKeyInfoBuffer.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
164 std::unique_ptr< IAlgorithmParameters > pParam(algorithmId.GetParametersN());
165 SysTryReturnResult(NID_SEC_CRYPTO, pParam, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
167 r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), pParam.get());
168 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct algorithm identifier instance for encryption algorithm..", GetErrorMessage(r));
170 std::unique_ptr< ByteBuffer > pEncData(_PkcsUtility::EncryptDecryptN(algorithmId, key, encodedPrivateKeyInfoBuffer, 1));
171 SysTryReturnResult(NID_SEC_CRYPTO, pEncData, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
173 r = __encryptedData.Construct(*pEncData);
174 SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
179 const AlgorithmIdentifier&
180 _Pkcs08EncryptedPrivateKeyInfoImpl::GetAlgorithm(void) const
183 return __encryptionAlgorithm;
187 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncryptedDataN(void) const
189 result r = E_SUCCESS;
193 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
194 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
196 std::unique_ptr< ByteBuffer > pEncryptedData(new (std::nothrow) ByteBuffer());
197 SysTryReturn(NID_SEC_CRYPTO, pEncryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
199 r = pEncryptedData->Construct(__encryptedData);
200 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
202 return pEncryptedData.release();
207 _Pkcs08EncryptedPrivateKeyInfoImpl::DecryptN(const Tizen::Base::ByteBuffer& key)
209 std::unique_ptr< ByteBuffer > pDecryptedData;
213 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
214 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
216 SysTryReturn(NID_SEC_CRYPTO, key.GetRemaining() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
218 pDecryptedData = std::unique_ptr< ByteBuffer >(_PkcsUtility::EncryptDecryptN(__encryptionAlgorithm, key, __encryptedData, 0));
219 SysTryReturn(NID_SEC_CRYPTO, pDecryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
221 return pDecryptedData.release();
225 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncodedDataN(void) const
228 result r = E_SUCCESS;
229 X509_SIG* sig = null;
230 ASN1_OCTET_STRING* pDigest = null;
231 std::unique_ptr< ByteBuffer > pEncPrivKey;
232 int digestLength = 0;
235 byte* pDigestData = null;
238 std::unique_ptr< IAlgorithmParameters > pParam;
242 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
243 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
245 sig = X509_SIG_new();
246 SysTryReturn(NID_SEC_CRYPTO, sig != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
248 pDigest = M_ASN1_OCTET_STRING_new();
249 SysTryReturn(NID_SEC_CRYPTO, pDigest != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
251 digestLength = __encryptedData.GetRemaining();
253 pDigest->data = static_cast< unsigned char* >(OPENSSL_malloc(digestLength));
254 SysTryReturn(NID_SEC_CRYPTO, pDigest->data != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
256 pDigest->length = digestLength;
258 pDigestData = const_cast< byte* >(__encryptedData.GetPointer());
259 memcpy(pDigest->data, pDigestData, digestLength);
261 sig->digest = pDigest;
263 prf_nid = _PkcsUtility::ConvertToNid(__encryptionAlgorithm.GetAlgorithmObjectId());
265 sig->algor = X509_ALGOR_new();
266 SysTryReturn(NID_SEC_CRYPTO, sig->algor != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
268 pParam = std::unique_ptr< IAlgorithmParameters >(__encryptionAlgorithm.GetParametersN());
269 SysTryCatch(NID_SEC_CRYPTO, pParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
271 sig->algor = _PkcsUtility::GenerateAlgorithmIdentifierStructureN(__encryptionAlgorithm.GetAlgorithmObjectId(), pParam.get());
272 SysTryCatch(NID_SEC_CRYPTO, sig->algor != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
274 value = i2d_X509_SIG(sig, &pTemp);
275 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
277 pEncPrivKey = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
278 SysTryCatch(NID_SEC_CRYPTO, pEncPrivKey, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
280 r = pEncPrivKey->Construct(value);
281 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
283 r = pEncPrivKey->SetArray(pTemp, 0, value);
284 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
292 pEncPrivKey.reset(null);
296 return pEncPrivKey.release();
300 _Pkcs08EncryptedPrivateKeyInfoImpl*
301 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
303 return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
306 const _Pkcs08EncryptedPrivateKeyInfoImpl*
307 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(const Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
309 return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;