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.get());
253 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
254 pOutBuffer = std::unique_ptr< ByteBuffer >(ConvertDerToPemN(format, key));
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);
273 return pOutBuffer.release();
278 RsaKeyConverter::ConvertDerToPemN(RsaKeyFormat format, const IKey& key)
280 result r = E_SUCCESS;
281 const byte* pKey = null;
283 EVP_PKEY* pEvpKey = null;
284 std::unique_ptr< byte[] > pData;
285 std::unique_ptr< ByteBuffer > pOutBuffer;
286 std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
291 pEncodedInputBuffer = std::unique_ptr< ByteBuffer >(key.GetEncodedN());
292 SysTryReturn(NID_SEC, pEncodedInputBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
294 pKey = pEncodedInputBuffer->GetPointer();
295 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
297 keyLen = pEncodedInputBuffer->GetRemaining();
298 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
302 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
304 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
305 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
307 pBio = BIO_new(BIO_s_mem());
308 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
310 ret = PEM_write_bio_PrivateKey(pBio, pEvpKey, null, null, 0, null, null);
311 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
316 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
318 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
319 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
321 pBio = BIO_new(BIO_s_mem());
322 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
324 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
325 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
330 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
332 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
333 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
335 pBio = BIO_new(BIO_s_mem());
336 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
338 ret = PEM_write_bio_PUBKEY(pBio, pEvpKey);
339 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
343 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
345 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
346 if (pPrivKeyInfo != null)
348 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
349 PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
351 pBio = BIO_new(BIO_s_mem());
352 SysTryCatch(NID_SEC, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
354 ret = PEM_write_bio_PrivateKey(pBio, pEvpKey, null, null, 0, null, null);
355 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
362 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
365 dataLen = BIO_get_mem_data(pBio, null);
366 SysTryCatch(NID_SEC, dataLen > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
368 pData = std::unique_ptr< byte[] >(new (std::nothrow) byte[dataLen]);
369 SysTryCatch(NID_SEC, pData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
371 ret = BIO_read(pBio, pData.get(), dataLen);
372 SysTryCatch(NID_SEC, ret > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
374 pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
375 SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
377 r = pOutBuffer->Construct(ret);
378 SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
380 r = pOutBuffer->SetArray(pData.get(), 0, ret);
381 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
389 EVP_PKEY_free(pEvpKey);
397 return pOutBuffer.release();
401 RsaKeyConverter::ConvertPemToDerN(RsaKeyFormat format, const IKey& key)
403 result r = E_SUCCESS;
406 const byte* pKey = null;
407 byte* pBuffer = null;
409 EVP_PKEY* pEvpKey = null;
410 std::unique_ptr< ByteBuffer > pOutBuffer;
411 std::unique_ptr< ByteBuffer > pEncodedInputBuffer;
413 pEncodedInputBuffer = std::unique_ptr< ByteBuffer >(key.GetEncodedN());
414 SysTryReturn(NID_SEC, pEncodedInputBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
416 pKey = pEncodedInputBuffer->GetPointer();
417 SysTryReturn(NID_SEC, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
419 keyLen = pEncodedInputBuffer->GetRemaining();
420 SysTryReturn(NID_SEC, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
422 pBio = BIO_new(BIO_s_mem());
423 SysTryReturn(NID_SEC, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
425 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
426 SysTryCatch(NID_SEC, readCount > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
430 case RSA_KEY_FORMAT_PKCS01_PRIVATE_KEY:
432 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
433 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
435 ret = i2d_PrivateKey(pEvpKey, &pBuffer);
436 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
440 case RSA_KEY_FORMAT_PKCS01_PUBLIC_KEY:
442 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
443 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
445 ret = i2d_PublicKey(pEvpKey, &pBuffer);
446 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
450 case RSA_KEY_FORMAT_X509_PUBLIC_KEY:
452 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
453 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
455 ret = i2d_PUBKEY(pEvpKey, &pBuffer);
456 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
460 case RSA_KEY_FORMAT_PKCS08_PRIVATE_KEY:
462 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
463 SysTryCatch(NID_SEC, pEvpKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
465 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = EVP_PKEY2PKCS8(pEvpKey);
466 SysTryCatch(NID_SEC, pPrivKeyInfo != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
468 ret = i2d_PKCS8_PRIV_KEY_INFO(pPrivKeyInfo, &pBuffer);
469 SysTryCatch(NID_SEC, ret != -1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
474 SysTryCatch(NID_SEC, false, r = E_INVALID_ARG, E_INVALID_ARG, " [E_INVALID_ARG] The specified input parameter is invalid.");
478 pOutBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
479 SysTryCatch(NID_SEC, pOutBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
481 r = pOutBuffer->Construct(ret);
482 SysTryCatch(NID_SEC, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
484 r = pOutBuffer->SetArray(pBuffer, 0, ret);
485 SysTryCatch(NID_SEC, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
489 OPENSSL_free(pBuffer);
496 EVP_PKEY_free(pEvpKey);
504 return pOutBuffer.release();
508 } } //Tizen::Security