2 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
19 * @brief This is the implementation file for _Pkcs08EncryptedPrivateKeyInfoImpl class.
21 * This header file contains the implementation of _Pkcs08EncryptedPrivateKeyInfoImpl class.
27 #include <openssl/evp.h>
28 #include <openssl/bn.h>
29 #include <openssl/x509.h>
30 #include <openssl/crypto.h>
31 #include <openssl/asn1t.h>
32 #include <openssl/asn1.h>
33 #include <openssl/objects.h>
34 #include <unique_ptr.h>
35 #include <FBaseSysLog.h>
36 #include <FBaseByteBuffer.h>
37 #include <FBaseResult.h>
38 #include <FSecPkcsPkcs08PrivateKeyInfo.h>
39 #include <FSecPkcsPkcs08EncryptedPrivateKeyInfo.h>
40 #include <FSecPkcsIAlgorithmParameters.h>
41 #include <FSecPkcsAlgorithmIdentifier.h>
42 #include <FSecPkcsTypes.h>
44 #include "FSecPkcs_PkcsUtility.h"
45 #include "FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.h"
47 using namespace Tizen::Base;
49 namespace Tizen { namespace Security { namespace Pkcs
52 //EncryptedPrivateKeyInfo Class Life cycle
55 _Pkcs08EncryptedPrivateKeyInfoImpl::_Pkcs08EncryptedPrivateKeyInfoImpl(void)
60 _Pkcs08EncryptedPrivateKeyInfoImpl::~_Pkcs08EncryptedPrivateKeyInfoImpl(void)
66 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
70 X509_SIG* pPkcs8Key = null;
71 Tizen::Base::String prfOid = null;
72 std::unique_ptr< IAlgorithmParameters > pEncParam;
73 Tizen::Base::ByteBuffer encryptedKeyBuffer;
74 const byte* pBuffer = null;
75 byte* pDigestValue = null;
80 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
82 pBuffer = encodedData.GetPointer();
83 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
85 bufferLen = encodedData.GetRemaining();
86 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
88 pPkcs8Key = d2i_X509_SIG(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
89 SysTryReturnResult(NID_SEC_CRYPTO, pPkcs8Key != null, E_INVALID_ARG, "The specified input parameter is invalid.");
91 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.");
95 prf_nid = OBJ_obj2nid(pPkcs8Key->algor->algorithm);
96 prfOid = _PkcsUtility::ConvertToOid(prf_nid);
99 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
101 pEncParam = std::unique_ptr< IAlgorithmParameters >(_PkcsUtility::GernerateParametersFromOidN(prfOid, pPkcs8Key->algor));
102 SysTryCatch(NID_SEC_CRYPTO, pEncParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
104 r = __encryptionAlgorithm.Construct(prfOid, pEncParam.get());
105 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
109 pDigestValue = pPkcs8Key->digest->data;
110 SysTryCatch(NID_SEC_CRYPTO, pDigestValue, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
112 digestLength = pPkcs8Key->digest->length;
113 SysTryCatch(NID_SEC_CRYPTO, digestLength > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
115 r = encryptedKeyBuffer.Construct(digestLength);
116 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
118 r = encryptedKeyBuffer.SetArray(pDigestValue, 0, digestLength);
119 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
121 encryptedKeyBuffer.Flip();
122 r = __encryptedData.Construct(encryptedKeyBuffer);
123 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
127 X509_SIG_free(pPkcs8Key);
132 // Encrypted Private Key Info Class Operations
134 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& encryptedData)
136 result r = E_SUCCESS;
138 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
140 SysTryReturn(NID_SEC_CRYPTO, encryptedData.GetRemaining() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
142 std::unique_ptr< IAlgorithmParameters > pParam(algorithmId.GetParametersN());
143 SysTryReturn(NID_SEC_CRYPTO, pParam != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
145 r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), pParam.get());
146 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier instance for encryption algorithm.", GetErrorMessage(r));
148 r = __encryptedData.Construct(encryptedData);
149 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
157 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& key, const Tizen::Base::ByteBuffer& encodedPrivateKeyInfoBuffer)
159 result r = E_SUCCESS;
161 SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
163 SysTryReturnResult(NID_SEC_CRYPTO, key.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
164 SysTryReturnResult(NID_SEC_CRYPTO, encodedPrivateKeyInfoBuffer.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
166 std::unique_ptr< IAlgorithmParameters > pParam(algorithmId.GetParametersN());
167 SysTryReturnResult(NID_SEC_CRYPTO, pParam, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
169 r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), pParam.get());
170 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct algorithm identifier instance for encryption algorithm..", GetErrorMessage(r));
172 std::unique_ptr< ByteBuffer > pEncData(_PkcsUtility::EncryptDecryptN(algorithmId, key, encodedPrivateKeyInfoBuffer, 1));
173 SysTryReturnResult(NID_SEC_CRYPTO, pEncData, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
175 r = __encryptedData.Construct(*pEncData);
176 SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
181 const AlgorithmIdentifier&
182 _Pkcs08EncryptedPrivateKeyInfoImpl::GetAlgorithm(void) const
185 return __encryptionAlgorithm;
189 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncryptedDataN(void) const
191 result r = E_SUCCESS;
195 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
196 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
198 std::unique_ptr< ByteBuffer > pEncryptedData(new (std::nothrow) ByteBuffer());
199 SysTryReturn(NID_SEC_CRYPTO, pEncryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
201 r = pEncryptedData->Construct(__encryptedData);
202 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
204 return pEncryptedData.release();
209 _Pkcs08EncryptedPrivateKeyInfoImpl::DecryptN(const Tizen::Base::ByteBuffer& key)
211 std::unique_ptr< ByteBuffer > pDecryptedData;
215 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
216 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
218 SysTryReturn(NID_SEC_CRYPTO, key.GetRemaining() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
220 pDecryptedData = std::unique_ptr< ByteBuffer >(_PkcsUtility::EncryptDecryptN(__encryptionAlgorithm, key, __encryptedData, 0));
221 SysTryReturn(NID_SEC_CRYPTO, pDecryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
223 return pDecryptedData.release();
227 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncodedDataN(void) const
230 result r = E_SUCCESS;
231 X509_SIG* sig = null;
232 ASN1_OCTET_STRING* pDigest = null;
233 std::unique_ptr< ByteBuffer > pEncPrivKey;
234 int digestLength = 0;
237 byte* pDigestData = null;
240 std::unique_ptr< IAlgorithmParameters > pParam;
244 SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
245 SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
247 sig = X509_SIG_new();
248 SysTryReturn(NID_SEC_CRYPTO, sig != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
250 pDigest = M_ASN1_OCTET_STRING_new();
251 SysTryReturn(NID_SEC_CRYPTO, pDigest != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
253 digestLength = __encryptedData.GetRemaining();
255 pDigest->data = static_cast< unsigned char* >(OPENSSL_malloc(digestLength));
256 SysTryReturn(NID_SEC_CRYPTO, pDigest->data != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
258 pDigest->length = digestLength;
260 pDigestData = const_cast< byte* >(__encryptedData.GetPointer());
261 memcpy(pDigest->data, pDigestData, digestLength);
263 sig->digest = pDigest;
265 prf_nid = _PkcsUtility::ConvertToNid(__encryptionAlgorithm.GetAlgorithmObjectId());
267 sig->algor = X509_ALGOR_new();
268 SysTryReturn(NID_SEC_CRYPTO, sig->algor != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
270 pParam = std::unique_ptr< IAlgorithmParameters >(__encryptionAlgorithm.GetParametersN());
271 SysTryCatch(NID_SEC_CRYPTO, pParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
273 sig->algor = _PkcsUtility::GenerateAlgorithmIdentifierStructureN(__encryptionAlgorithm.GetAlgorithmObjectId(), pParam.get());
274 SysTryCatch(NID_SEC_CRYPTO, sig->algor != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
276 value = i2d_X509_SIG(sig, &pTemp);
277 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
279 pEncPrivKey = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
280 SysTryCatch(NID_SEC_CRYPTO, pEncPrivKey, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
282 r = pEncPrivKey->Construct(value);
283 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
285 r = pEncPrivKey->SetArray(pTemp, 0, value);
286 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
294 pEncPrivKey.reset(null);
298 return pEncPrivKey.release();
302 _Pkcs08EncryptedPrivateKeyInfoImpl*
303 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
305 return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
308 const _Pkcs08EncryptedPrivateKeyInfoImpl*
309 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(const Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
311 return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;