[Pkcs] Added one SysTryReturnResult statement
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.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_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
20  * @brief               This is the implementation file for _Pkcs08EncryptedPrivateKeyInfoImpl class.
21  *
22  * This header file contains the implementation of _Pkcs08EncryptedPrivateKeyInfoImpl class.
23  *
24  */
25
26
27 #include <new>
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>
44
45 #include "FSecPkcs_PkcsUtility.h"
46 #include "FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.h"
47
48 using namespace Tizen::Base;
49
50 namespace Tizen { namespace Security { namespace Pkcs
51 {
52
53 //EncryptedPrivateKeyInfo Class Life cycle
54
55 //Default Constructor
56 _Pkcs08EncryptedPrivateKeyInfoImpl::_Pkcs08EncryptedPrivateKeyInfoImpl(void)
57 {
58 }
59
60 //Default Destructor
61 _Pkcs08EncryptedPrivateKeyInfoImpl::~_Pkcs08EncryptedPrivateKeyInfoImpl(void)
62 {
63         //do nothing
64 }
65
66 result
67 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
68 {
69         result r = E_SUCCESS;
70
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;
77         int bufferLen = 0;
78         int digestLength = 0;
79         int prf_nid = 0;
80
81         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
82
83         pBuffer = encodedData.GetPointer();
84         SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
85
86         bufferLen = encodedData.GetRemaining();
87         SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
88
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.");
91
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.");
93
94         if (pPkcs8Key->algor)
95         {
96                 prf_nid = OBJ_obj2nid(pPkcs8Key->algor->algorithm);
97                 prfOid = _PkcsUtility::ConvertToOid(prf_nid);
98
99                 r = GetLastResult();
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.");
101
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.");
104
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.");
107
108         }
109
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.");
112
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.");
115
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.");
118
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.");
121
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.");
125
126 CATCH:
127
128         X509_SIG_free(pPkcs8Key);
129         return r;
130
131 }
132
133 // Encrypted Private Key Info Class Operations
134 result
135 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& encryptedData)
136 {
137         result r = E_SUCCESS;
138
139         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
140
141         SysTryReturn(NID_SEC_CRYPTO, encryptedData.GetRemaining() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
142
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));
145
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.");
148
149         return r;
150
151 }
152
153
154 result
155 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& key, const Tizen::Base::ByteBuffer& encodedPrivateKeyInfoBuffer)
156 {
157         result r = E_SUCCESS;
158
159         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
160
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.");
163
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.");
166
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));
169
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.");
172
173         r = __encryptedData.Construct(*pEncData);
174         SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
175
176         return r;
177 }
178
179 const AlgorithmIdentifier&
180 _Pkcs08EncryptedPrivateKeyInfoImpl::GetAlgorithm(void) const
181 {
182         ClearLastResult();
183         return __encryptionAlgorithm;
184 }
185
186 ByteBuffer*
187 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncryptedDataN(void) const
188 {
189         result r = E_SUCCESS;
190
191         ClearLastResult();
192
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.");
195
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.");
198
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.");
201
202         return pEncryptedData.release();
203
204 }
205
206 ByteBuffer*
207 _Pkcs08EncryptedPrivateKeyInfoImpl::DecryptN(const Tizen::Base::ByteBuffer& key)
208 {
209         std::unique_ptr< ByteBuffer > pDecryptedData;
210
211         ClearLastResult();
212
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.");
215
216         SysTryReturn(NID_SEC_CRYPTO, key.GetRemaining() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG]  The specified input parameter is invalid.");
217
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.");
220
221         return pDecryptedData.release();
222 }
223
224 ByteBuffer*
225 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncodedDataN(void) const
226 {
227
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;
233         int prf_nid = 0;
234         int value = 0;
235         byte* pDigestData = null;
236         byte* pTemp = null;
237
238         std::unique_ptr< IAlgorithmParameters > pParam;
239
240         ClearLastResult();
241
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.");
244
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.");
247
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.");
250
251         digestLength = __encryptedData.GetRemaining();
252
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.");
255
256         pDigest->length = digestLength;
257
258         pDigestData = const_cast< byte* >(__encryptedData.GetPointer());
259         memcpy(pDigest->data, pDigestData, digestLength);
260
261         sig->digest = pDigest;
262
263         prf_nid = _PkcsUtility::ConvertToNid(__encryptionAlgorithm.GetAlgorithmObjectId());
264
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.");
267
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.");
270
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.");
273
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.");
276
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.");
279
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.");
282
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.");
285
286         pEncPrivKey->Flip();
287
288 CATCH:
289
290         if (IsFailed(r))
291         {
292                 pEncPrivKey.reset(null);
293         }
294         X509_SIG_free(sig);
295         SetLastResult(r);
296         return pEncPrivKey.release();
297
298 }
299
300 _Pkcs08EncryptedPrivateKeyInfoImpl*
301 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
302 {
303         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
304 }
305
306 const _Pkcs08EncryptedPrivateKeyInfoImpl*
307 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(const Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
308 {
309         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
310 }
311
312 } } }