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 FSecRsaKeyConverter.cpp
19 * @brief This is the implementation file for RsaKeyConverter class.
22 #include <unique_ptr.h>
23 #include <openssl/bn.h>
24 #include <openssl/evp.h>
25 #include <openssl/dh.h>
26 #include <openssl/rsa.h>
27 #include <openssl/x509.h>
28 #include <openssl/pem.h>
29 #include <FBaseResult.h>
30 #include <FBaseErrors.h>
31 #include <FSecIPublicKey.h>
32 #include <FSecIPrivateKey.h>
33 #include <FSecPrivateKey.h>
34 #include <FSecPublicKey.h>
35 #include <FBaseSysLog.h>
36 #include <FSecRsaKeyConverter.h>
38 using namespace Tizen::Base;
39 using namespace Tizen::Security;
42 namespace Tizen { namespace Security
45 RsaKeyConverter::RsaKeyConverter(void)
50 RsaKeyConverter::~RsaKeyConverter(void)
55 RsaKeyConverter::ConvertPrivateKeyFormatN(RsaKeyFormat format, const IPrivateKey& key)
59 const byte* pKey = null;
60 std::unique_ptr< ByteBuffer > pOutBuffer;
62 EVP_PKEY* pEvpKey = null;
65 bool isPemFormat = false;
67 SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
69 std::unique_ptr< ByteBuffer > pPrivateKey(key.GetEncodedN());
70 SysTryReturn(NID_SEC, pPrivateKey != null, null, r, "[%s] Failed to get the public key", GetErrorMessage(r));
72 pKey = pPrivateKey->GetPointer();
73 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
75 keyLen = pPrivateKey->GetRemaining();
76 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
78 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
82 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
83 if (pPrivKeyInfo != null)
85 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
86 PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
92 pBio = BIO_new(BIO_s_mem());
93 SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
95 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
96 SysTryCatch(NID_SEC, readCount > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
98 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
105 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
109 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
111 ret = i2d_PrivateKey(pEvpKey, &pBuffer);
112 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
116 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
118 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = EVP_PKEY2PKCS8(pEvpKey);
119 SysTryCatch(NID_SEC, pPrivKeyInfo != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
121 ret = i2d_PKCS8_PRIV_KEY_INFO(pPrivKeyInfo, &pBuffer);
122 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
127 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
131 pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
132 SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
134 r = pOutBuffer->Construct(ret);
135 SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
137 r = pOutBuffer->SetArray(pBuffer, 0, ret);
138 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
141 if (isPemFormat == true)
144 r = nKey.SetKey(*pOutBuffer.get());
145 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
146 pOutBuffer = std::unique_ptr< ByteBuffer >(ConvertDerToPemN(format, nKey));
147 SysTryCatch(NID_SEC, pOutBuffer != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to convert der to pem encoded byte buffer");
150 OPENSSL_free(pBuffer);
157 EVP_PKEY_free(pEvpKey);
165 return pOutBuffer.release();
169 RsaKeyConverter::ConvertPublicKeyFormatN(RsaKeyFormat format, const IPublicKey& key)
171 result r = E_SUCCESS;
172 byte* pBuffer = null;
173 const byte* pKey = null;
174 std::unique_ptr< ByteBuffer > pOutBuffer;
176 EVP_PKEY* pEvpKey = null;
179 bool isPemFormat = false;
181 SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
183 std::unique_ptr< ByteBuffer > pPublicKey(key.GetEncodedN());
184 SysTryReturn(NID_SEC, pPublicKey, null, r, "[%s] Failed to get the public key", GetErrorMessage(r));
186 pKey = pPublicKey->GetPointer();
187 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
189 keyLen = pPublicKey->GetRemaining();
190 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
192 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
196 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
201 pBio = BIO_new(BIO_s_mem());
202 SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
204 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
207 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
215 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
218 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
220 ret = i2d_PublicKey(pEvpKey, &pBuffer);
221 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
225 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
227 ret = i2d_PUBKEY(pEvpKey, &pBuffer);
228 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
233 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
237 pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
238 SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
240 r = pOutBuffer->Construct(ret);
241 SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
243 r = pOutBuffer->SetArray(pBuffer, 0, ret);
244 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
248 if (isPemFormat == true)
251 r = nKey.SetKey(*pOutBuffer);
252 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
253 pOutBuffer.reset(ConvertDerToPemN(format, nKey));
254 //pOutBuffer = std::unique_ptr< ByteBuffer >(ConvertDerToPemN(format, nKey));
255 SysTryCatch(NID_SEC, pOutBuffer != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to convert der to pem encoded byte buffer");
258 OPENSSL_free(pBuffer);
265 EVP_PKEY_free(pEvpKey);
275 pOutBuffer.reset(null);
278 return pOutBuffer.release();
283 RsaKeyConverter::ConvertDerToPemN(RsaKeyFormat format, const IKey& key)
285 result r = E_SUCCESS;
286 const byte* pKey = null;
288 EVP_PKEY* pEvpKey = null;
289 std::unique_ptr< byte[] > pData;
290 std::unique_ptr< ByteBuffer > pOutBuffer;
291 std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
296 pEncodedInputBuffer = std::unique_ptr< ByteBuffer >(key.GetEncodedN());
297 SysTryReturn(NID_SEC, pEncodedInputBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
299 pKey = pEncodedInputBuffer->GetPointer();
300 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
302 keyLen = pEncodedInputBuffer->GetRemaining();
303 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
307 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
309 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
310 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
312 pBio = BIO_new(BIO_s_mem());
313 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
315 ret = PEM_write_bio_PrivateKey(pBio, pEvpKey, null, null, 0, null, null);
316 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
321 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
323 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
324 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
326 pBio = BIO_new(BIO_s_mem());
327 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
329 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
330 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
335 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
337 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
338 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
340 pBio = BIO_new(BIO_s_mem());
341 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
343 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
344 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
348 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
350 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
351 if (pPrivKeyInfo != null)
353 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
354 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid");
355 PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
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.");
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.");
368 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
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.");
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.");
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.");
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.");
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.");
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.");
395 EVP_PKEY_free(pEvpKey);
403 return pOutBuffer.release();
407 RsaKeyConverter::ConvertPemToDerN(RsaKeyFormat format, const IKey& key)
409 result r = E_SUCCESS;
412 const byte* pKey = null;
413 byte* pBuffer = null;
415 EVP_PKEY* pEvpKey = null;
416 std::unique_ptr< ByteBuffer > pOutBuffer;
417 std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
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.");
422 pKey = pEncodedInputBuffer->GetPointer();
423 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
425 keyLen = pEncodedInputBuffer->GetRemaining();
426 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
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.");
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.");
436 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
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.");
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.");
446 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
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.");
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.");
456 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
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.");
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.");
466 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
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.");
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.");
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.");
480 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
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.");
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.");
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.");
495 OPENSSL_free(pBuffer);
502 EVP_PKEY_free(pEvpKey);
510 return pOutBuffer.release();
514 } } //Tizen::Security