Merge "Revert "Fix prevent defect for locales"" into devel_3.0_main
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
1 //
2 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file                FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
19  * @brief               This is the implementation file for _Pkcs08EncryptedPrivateKeyInfoImpl class.
20  *
21  * This header file contains the implementation of _Pkcs08EncryptedPrivateKeyInfoImpl class.
22  *
23  */
24
25
26 #include <new>
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>
43
44 #include "FSecPkcs_PkcsUtility.h"
45 #include "FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.h"
46
47 using namespace Tizen::Base;
48
49 namespace Tizen { namespace Security { namespace Pkcs
50 {
51
52 //EncryptedPrivateKeyInfo Class Life cycle
53
54 //Default Constructor
55 _Pkcs08EncryptedPrivateKeyInfoImpl::_Pkcs08EncryptedPrivateKeyInfoImpl(void)
56 {
57 }
58
59 //Default Destructor
60 _Pkcs08EncryptedPrivateKeyInfoImpl::~_Pkcs08EncryptedPrivateKeyInfoImpl(void)
61 {
62         //do nothing
63 }
64
65 result
66 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
67 {
68         result r = E_SUCCESS;
69
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;
76         int bufferLen = 0;
77         int digestLength = 0;
78         int prf_nid = 0;
79
80         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
81
82         pBuffer = encodedData.GetPointer();
83         SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
84
85         bufferLen = encodedData.GetRemaining();
86         SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
87
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.");
90
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.");
92
93         if (pPkcs8Key->algor)
94         {
95                 prf_nid = OBJ_obj2nid(pPkcs8Key->algor->algorithm);
96                 prfOid = _PkcsUtility::ConvertToOid(prf_nid);
97
98                 r = GetLastResult();
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.");
100
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.");
103
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.");
106
107         }
108
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.");
111
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.");
114
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.");
117
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.");
120
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.");
124
125 CATCH:
126
127         X509_SIG_free(pPkcs8Key);
128         return r;
129
130 }
131
132 // Encrypted Private Key Info Class Operations
133 result
134 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& encryptedData)
135 {
136         result r = E_SUCCESS;
137
138         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
139
140         SysTryReturn(NID_SEC_CRYPTO, encryptedData.GetRemaining() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
141
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.");
144
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));
147
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.");
150
151         return r;
152
153 }
154
155
156 result
157 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& key, const Tizen::Base::ByteBuffer& encodedPrivateKeyInfoBuffer)
158 {
159         result r = E_SUCCESS;
160
161         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
162
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.");
165
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.");
168
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));
171
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.");
174
175         r = __encryptedData.Construct(*pEncData);
176         SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
177
178         return r;
179 }
180
181 const AlgorithmIdentifier&
182 _Pkcs08EncryptedPrivateKeyInfoImpl::GetAlgorithm(void) const
183 {
184         ClearLastResult();
185         return __encryptionAlgorithm;
186 }
187
188 ByteBuffer*
189 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncryptedDataN(void) const
190 {
191         result r = E_SUCCESS;
192
193         ClearLastResult();
194
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.");
197
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.");
200
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.");
203
204         return pEncryptedData.release();
205
206 }
207
208 ByteBuffer*
209 _Pkcs08EncryptedPrivateKeyInfoImpl::DecryptN(const Tizen::Base::ByteBuffer& key)
210 {
211         std::unique_ptr< ByteBuffer > pDecryptedData;
212
213         ClearLastResult();
214
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.");
217
218         SysTryReturn(NID_SEC_CRYPTO, key.GetRemaining() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG]  The specified input parameter is invalid.");
219
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.");
222
223         return pDecryptedData.release();
224 }
225
226 ByteBuffer*
227 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncodedDataN(void) const
228 {
229
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;
235         int prf_nid = 0;
236         int value = 0;
237         byte* pDigestData = null;
238         byte* pTemp = null;
239
240         std::unique_ptr< IAlgorithmParameters > pParam;
241
242         ClearLastResult();
243
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.");
246
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.");
249
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.");
252
253         digestLength = __encryptedData.GetRemaining();
254
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.");
257
258         pDigest->length = digestLength;
259
260         pDigestData = const_cast< byte* >(__encryptedData.GetPointer());
261         memcpy(pDigest->data, pDigestData, digestLength);
262
263         sig->digest = pDigest;
264
265         prf_nid = _PkcsUtility::ConvertToNid(__encryptionAlgorithm.GetAlgorithmObjectId());
266
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.");
269
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.");
272
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.");
275
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.");
278
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.");
281
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.");
284
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.");
287
288         pEncPrivKey->Flip();
289
290 CATCH:
291
292         if (IsFailed(r))
293         {
294                 pEncPrivKey.reset(null);
295         }
296         X509_SIG_free(sig);
297         SetLastResult(r);
298         return pEncPrivKey.release();
299
300 }
301
302 _Pkcs08EncryptedPrivateKeyInfoImpl*
303 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
304 {
305         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
306 }
307
308 const _Pkcs08EncryptedPrivateKeyInfoImpl*
309 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(const Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
310 {
311         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
312 }
313
314 } } }