2 // Open Service Platform
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FSecRsaKeyConverter.cpp
20 * @brief This is the implementation file for RsaKeyConverter class.
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>
39 using namespace Tizen::Base;
40 using namespace Tizen::Security;
43 namespace Tizen { namespace Security
46 RsaKeyConverter::RsaKeyConverter(void)
51 RsaKeyConverter::~RsaKeyConverter(void)
56 RsaKeyConverter::ConvertPrivateKeyFormatN(RsaKeyFormat format, const IPrivateKey& key)
60 const byte* pKey = null;
61 std::unique_ptr< ByteBuffer > pOutBuffer;
63 EVP_PKEY* pEvpKey = null;
66 bool isPemFormat = false;
68 SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
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));
73 pKey = pPrivateKey->GetPointer();
74 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
76 keyLen = pPrivateKey->GetRemaining();
77 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
79 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
83 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
84 if (pPrivKeyInfo != null)
86 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
87 PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
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.");
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.");
99 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
106 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
110 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
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.");
117 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
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.");
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.");
128 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
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.");
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.");
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.");
142 if (isPemFormat == true)
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");
151 OPENSSL_free(pBuffer);
158 EVP_PKEY_free(pEvpKey);
166 return pOutBuffer.release();
170 RsaKeyConverter::ConvertPublicKeyFormatN(RsaKeyFormat format, const IPublicKey& key)
172 result r = E_SUCCESS;
173 byte* pBuffer = null;
174 const byte* pKey = null;
175 std::unique_ptr< ByteBuffer > pOutBuffer;
177 EVP_PKEY* pEvpKey = null;
180 bool isPemFormat = false;
182 SysTryReturn(NID_SEC, format != RSA_KEY_FORMAT_UNKNOWN, null, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
184 std::unique_ptr< ByteBuffer > pPublicKey(key.GetEncodedN());
185 SysTryReturn(NID_SEC, pPublicKey, null, r, "[%s] Failed to get the public key", GetErrorMessage(r));
187 pKey = pPublicKey->GetPointer();
188 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
190 keyLen = pPublicKey->GetRemaining();
191 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
193 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
197 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
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.");
205 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
208 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
216 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
219 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
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.");
226 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
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.");
234 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
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.");
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.");
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.");
249 if (isPemFormat == true)
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");
259 OPENSSL_free(pBuffer);
266 EVP_PKEY_free(pEvpKey);
276 pOutBuffer.reset(null);
279 return pOutBuffer.release();
284 RsaKeyConverter::ConvertDerToPemN(RsaKeyFormat format, const IKey& key)
286 result r = E_SUCCESS;
287 const byte* pKey = null;
289 EVP_PKEY* pEvpKey = null;
290 std::unique_ptr< byte[] > pData;
291 std::unique_ptr< ByteBuffer > pOutBuffer;
292 std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
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.");
300 pKey = pEncodedInputBuffer->GetPointer();
301 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
303 keyLen = pEncodedInputBuffer->GetRemaining();
304 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
308 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
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.");
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.");
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.");
322 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
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.");
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.");
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.");
336 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
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.");
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.");
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.");
349 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
351 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
352 if (pPrivKeyInfo != null)
354 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
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