Merge "[Security] Fixed memory leaks through valgrind tool" into tizen_2.1
[platform/framework/native/appfw.git] / src / security / FSecRsaKeyConverter.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                FSecRsaKeyConverter.cpp
20  * @brief               This is the implementation file for RsaKeyConverter class.
21  */
22
23 #include <unique_ptr.h>
24 #include <openssl/bn.h>
25 #include <openssl/evp.h>
26 #include <openssl/dh.h>
27 #include <openssl/rsa.h>
28 #include <openssl/x509.h>
29 #include <openssl/pem.h>
30 #include <FBaseResult.h>
31 #include <FBaseErrors.h>
32 #include <FSecIPublicKey.h>
33 #include <FSecIPrivateKey.h>
34 #include <FSecPrivateKey.h>
35 #include <FSecPublicKey.h>
36 #include <FBaseSysLog.h>
37 #include <FSecRsaKeyConverter.h>
38
39 using namespace Tizen::Base;
40 using namespace Tizen::Security;
41
42
43 namespace Tizen { namespace Security
44 {
45
46 RsaKeyConverter::RsaKeyConverter(void)
47 {
48
49 }
50
51 RsaKeyConverter::~RsaKeyConverter(void)
52 {
53 }
54
55 ByteBuffer*
56 RsaKeyConverter::ConvertPrivateKeyFormatN(RsaKeyFormat format, const IPrivateKey& key)
57 {
58         result r = E_SUCCESS;
59         byte* pBuffer = null;
60         const byte* pKey = null;
61         std::unique_ptr< ByteBuffer > pOutBuffer;
62         BIO* pBio = null;
63         EVP_PKEY* pEvpKey = null;
64         int ret = 0;
65         int keyLen = 0;
66         bool isPemFormat = false;
67
68         SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
69
70         std::unique_ptr< ByteBuffer > pPrivateKey(key.GetEncodedN());
71         SysTryReturn(NID_SEC, pPrivateKey != null, null, r, "[%s] Failed to get the public key", GetErrorMessage(r));
72
73         pKey = pPrivateKey->GetPointer();
74         SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
75
76         keyLen = pPrivateKey->GetRemaining();
77         SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
78
79         pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
80
81         if (pEvpKey == null)
82         {
83                 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
84                 if (pPrivKeyInfo != null)
85                 {
86                         pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
87                         PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
88                 }
89
90         }
91         if (pEvpKey == null)
92         {
93                 pBio = BIO_new(BIO_s_mem());
94                 SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
95
96                 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
97                 SysTryCatch(NID_SEC, readCount > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
98
99                 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
100                 if (pEvpKey != null)
101                 {
102                         isPemFormat = true;
103                 }
104         }
105
106         SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
107
108         switch (format)
109         {
110         case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
111         {
112                 ret = i2d_PrivateKey(pEvpKey, &pBuffer);
113                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
114         }
115         break;
116
117         case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
118         {
119                 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = EVP_PKEY2PKCS8(pEvpKey);
120                 SysTryCatch(NID_SEC, pPrivKeyInfo != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
121
122                 ret = i2d_PKCS8_PRIV_KEY_INFO(pPrivKeyInfo, &pBuffer);
123                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
124         }
125         break;
126
127         default:
128                 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
129
130         }
131
132         pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
133         SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
134
135         r = pOutBuffer->Construct(ret);
136         SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
137
138         r = pOutBuffer->SetArray(pBuffer, 0, ret);
139         SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
140         pOutBuffer->Flip();
141
142         if (isPemFormat == true)
143         {
144                 PrivateKey key;
145                 r = key.SetKey(*pOutBuffer.get());
146                 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
147                 pOutBuffer = std::unique_ptr< ByteBuffer >(ConvertDerToPemN(format, key));
148                 SysTryCatch(NID_SEC, pOutBuffer != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to convert der to pem encoded byte buffer");
149         }
150
151         OPENSSL_free(pBuffer);
152         pBuffer = null;
153
154 CATCH:
155
156         if (pEvpKey != null)
157         {
158                 EVP_PKEY_free(pEvpKey);
159         }
160
161         if (pBio != null)
162         {
163                 BIO_free(pBio);
164         }
165
166         return pOutBuffer.release();
167 }
168
169 ByteBuffer*
170 RsaKeyConverter::ConvertPublicKeyFormatN(RsaKeyFormat format, const IPublicKey& key)
171 {
172         result r = E_SUCCESS;
173         byte* pBuffer = null;
174         const byte* pKey = null;
175         std::unique_ptr< ByteBuffer > pOutBuffer;
176         BIO* pBio = null;
177         EVP_PKEY* pEvpKey = null;
178         int ret = 0;
179         int keyLen = 0;
180         bool isPemFormat = false;
181
182         SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
183
184         std::unique_ptr< ByteBuffer > pPublicKey(key.GetEncodedN());
185         SysTryReturn(NID_SEC, pPublicKey, null, r, "[%s] Failed to get the public key", GetErrorMessage(r));
186
187         pKey = pPublicKey->GetPointer();
188         SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
189
190         keyLen = pPublicKey->GetRemaining();
191         SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
192
193         pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
194
195         if (pEvpKey == null)
196         {
197                 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
198
199         }
200         if (pEvpKey == null)
201         {
202                 pBio = BIO_new(BIO_s_mem());
203                 SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
204
205                 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
206                 if (readCount > 0)
207                 {
208                         pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
209                 }
210                 if (pEvpKey != null)
211                 {
212                         isPemFormat = true;
213                 }
214         }
215
216         SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
217         switch (format)
218         {
219         case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
220         {
221                 ret = i2d_PublicKey(pEvpKey, &pBuffer);
222                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
223         }
224         break;
225
226         case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
227         {
228                 ret = i2d_PUBKEY(pEvpKey, &pBuffer);
229                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
230         }
231         break;
232
233         default:
234                 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
235
236         }
237
238         pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
239         SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
240
241         r = pOutBuffer->Construct(ret);
242         SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
243
244         r = pOutBuffer->SetArray(pBuffer, 0, ret);
245         SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
246
247         pOutBuffer->Flip();
248
249         if (isPemFormat == true)
250         {
251                 PublicKey key;
252                 r = key.SetKey(*pOutBuffer);
253                 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
254                 pOutBuffer.reset(ConvertDerToPemN(format, key));
255                 //pOutBuffer = std::unique_ptr< ByteBuffer >(ConvertDerToPemN(format, key));
256                 SysTryCatch(NID_SEC, pOutBuffer != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to convert der to pem encoded byte buffer");
257         }
258
259         OPENSSL_free(pBuffer);
260         pBuffer = null;
261
262 CATCH:
263
264         if (pEvpKey != null)
265         {
266                 EVP_PKEY_free(pEvpKey);
267         }
268
269         if (pBio != null)
270         {
271                 BIO_free(pBio);
272         }
273
274         if (IsFailed(r))
275         {
276                 pOutBuffer.reset(null);
277         }
278
279         return pOutBuffer.release();
280 }
281
282
283 ByteBuffer*
284 RsaKeyConverter::ConvertDerToPemN(RsaKeyFormat format, const IKey& key)
285 {
286         result r = E_SUCCESS;
287         const byte* pKey = null;
288         BIO* pBio = null;
289         EVP_PKEY* pEvpKey = null;
290         std::unique_ptr< byte[] > pData;
291         std::unique_ptr< ByteBuffer > pOutBuffer;
292         std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
293         int ret = 0;
294         int keyLen = 0;
295         int dataLen = 0;
296
297         pEncodedInputBuffer = std::unique_ptr< ByteBuffer >(key.GetEncodedN());
298         SysTryReturn(NID_SEC, pEncodedInputBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
299
300         pKey = pEncodedInputBuffer->GetPointer();
301         SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
302
303         keyLen = pEncodedInputBuffer->GetRemaining();
304         SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
305
306         switch (format)
307         {
308         case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
309         {
310                 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
311                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
312
313                 pBio = BIO_new(BIO_s_mem());
314                 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
315
316                 ret = PEM_write_bio_PrivateKey(pBio, pEvpKey, null, null, 0, null, null);
317                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
318
319         }
320         break;
321
322         case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
323         {
324                 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
325                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
326
327                 pBio = BIO_new(BIO_s_mem());
328                 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
329
330                 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
331                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
332
333         }
334         break;
335
336         case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
337         {
338                 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
339                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
340
341                 pBio = BIO_new(BIO_s_mem());
342                 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
343
344                 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
345                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
346         }
347         break;
348
349         case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
350         {
351                 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
352                 if (pPrivKeyInfo != null)
353                 {
354                         pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
355                         PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
356                 }
357                 pBio = BIO_new(BIO_s_mem());
358                 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
359
360                 ret = PEM_write_bio_PrivateKey(pBio, pEvpKey, null, null, 0, null, null);
361                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
362         }
363
364         break;
365
366         default:
367
368                 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
369         }
370
371         dataLen = BIO_get_mem_data(pBio, null);
372         SysTryCatch(NID_SEC, dataLen > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
373
374         pData = std::unique_ptr< byte[] >(new (std::nothrow) byte[dataLen]);
375         SysTryCatch(NID_SEC, pData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
376
377         ret = BIO_read(pBio, pData.get(), dataLen);
378         SysTryCatch(NID_SEC, ret > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
379
380         pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
381         SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
382
383         r = pOutBuffer->Construct(ret);
384         SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
385
386         r = pOutBuffer->SetArray(pData.get(), 0, ret);
387         SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
388
389         pOutBuffer->Flip();
390
391 CATCH:
392         if (pEvpKey != null)
393         {
394
395                 EVP_PKEY_free(pEvpKey);
396         }
397
398         if (pBio != null)
399         {
400                 BIO_free(pBio);
401         }
402
403         return pOutBuffer.release();
404 }
405
406 ByteBuffer*
407 RsaKeyConverter::ConvertPemToDerN(RsaKeyFormat format, const IKey& key)
408 {
409         result r = E_SUCCESS;
410         int keyLen = 0;
411         int ret = 0;
412         const byte* pKey = null;
413         byte* pBuffer = null;
414         BIO* pBio = null;
415         EVP_PKEY* pEvpKey = null;
416         std::unique_ptr< ByteBuffer > pOutBuffer;
417         std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
418
419         pEncodedInputBuffer = std::unique_ptr< ByteBuffer >(key.GetEncodedN());
420         SysTryReturn(NID_SEC, pEncodedInputBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
421
422         pKey = pEncodedInputBuffer->GetPointer();
423         SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
424
425         keyLen = pEncodedInputBuffer->GetRemaining();
426         SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
427
428         pBio = BIO_new(BIO_s_mem());
429         SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
430
431         int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
432         SysTryCatch(NID_SEC, readCount > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
433
434         switch (format)
435         {
436         case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
437         {
438                 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
439                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
440
441                 ret = i2d_PrivateKey(pEvpKey, &pBuffer);
442                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
443         }
444         break;
445
446         case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
447         {
448                 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
449                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
450
451                 ret = i2d_PublicKey(pEvpKey, &pBuffer);
452                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
453         }
454         break;
455
456         case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
457         {
458                 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
459                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
460
461                 ret = i2d_PUBKEY(pEvpKey, &pBuffer);
462                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
463         }
464         break;
465
466         case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
467         {
468                 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
469                 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
470
471                 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = EVP_PKEY2PKCS8(pEvpKey);
472                 SysTryCatch(NID_SEC, pPrivKeyInfo != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
473
474                 ret = i2d_PKCS8_PRIV_KEY_INFO(pPrivKeyInfo, &pBuffer);
475                 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
476         }
477         break;
478
479         default:
480                 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
481
482         }
483
484         pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
485         SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
486
487         r = pOutBuffer->Construct(ret);
488         SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
489
490         r = pOutBuffer->SetArray(pBuffer, 0, ret);
491         SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
492
493         pOutBuffer->Flip();
494
495         OPENSSL_free(pBuffer);
496         pBuffer = null;
497
498 CATCH:
499
500         if (pEvpKey != null)
501         {
502                 EVP_PKEY_free(pEvpKey);
503         }
504
505         if (pBio != null)
506         {
507                 BIO_free(pBio);
508         }
509
510         return pOutBuffer.release();
511
512 }
513
514 } } //Tizen::Security