2 // Open Service Platform
3 // Copyright (c) 2012 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 FSecCert_CertPrivateKeyInfo.cpp
20 * @brief This file contains implementation of X509 Certificate private key.
29 #include <unique_ptr.h>
33 #include <openssl/evp.h>
34 #include <openssl/x509.h>
35 #include <openssl/pkcs12.h>
37 #include <FIoFileAttributes.h>
38 #include <FBaseByteBuffer.h>
39 #include <FBaseString.h>
40 #include <FBaseResult.h>
41 #include <FBaseSysLog.h>
42 #include <FSec_DeviceKeyGenerator.h>
43 #include <FSecISecretKey.h>
44 #include "FSecCert_CertPrivateKeyInfo.h"
46 using namespace Tizen::Base;
47 using namespace Tizen::Io;
48 using namespace Tizen::Security;
50 namespace Tizen { namespace Security { namespace Cert
53 _CertPrivateKeyInfo::_CertPrivateKeyInfo(void)
60 _CertPrivateKeyInfo::_CertPrivateKeyInfo(char* pFileName)
64 SetPrivateKey(pFileName);
67 _CertPrivateKeyInfo::_CertPrivateKeyInfo(byte* pBuf, int bufSize)
69 __privateKeyLen = bufSize;
70 __pPrivateKey = std::unique_ptr< byte[] >(new (std::nothrow) byte[bufSize]);
71 SysTryReturnVoidResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
73 memcpy(__pPrivateKey.get(), pBuf, bufSize);
76 _CertPrivateKeyInfo::~_CertPrivateKeyInfo()
80 // return DER encoded form
82 _CertPrivateKeyInfo::GetPrivateKeyN(int& keyLen, byte** ppPrivKey)
84 SysTryReturnVoidResult(NID_SEC_CERT, __pPrivateKey != null, E_SYSTEM, "Private key is not set.");
85 keyLen = __privateKeyLen;
86 *ppPrivKey = new (std::nothrow) byte[keyLen + 1];
87 SysTryReturnVoidResult(NID_SEC_CERT, *ppPrivKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
89 memset(*ppPrivKey, 0, keyLen + 1);
90 memcpy(*ppPrivKey, __pPrivateKey.get(), keyLen);
94 _CertPrivateKeyInfo::GetEncDecPrivateKeyN(int& keyLen, byte** ppPrivKey, int encDecBit)
97 byte uniqueKey[16] = {0};
98 byte ivData[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
105 std::unique_ptr< ISecretKey > pSecKey(reinterpret_cast< ISecretKey* >(_DeviceKeyGenerator::GenerateDeviceKeyN(aesBlockLen)));
106 SysTryReturnResult(NID_SEC_CERT, pSecKey != null, E_SYSTEM, "Failed to generate secret key.");
108 std::unique_ptr< ByteBuffer > pKeyBuf(pSecKey->GetEncodedN());
109 SysAssertf(pKeyBuf != null, "Failed to get encoded secret key.");
111 memset(uniqueKey, 0, aesBlockLen);
112 memcpy(uniqueKey, reinterpret_cast< const char* >(pKeyBuf->GetPointer()), aesBlockLen);
114 *ppPrivKey = new (std::nothrow) byte[__privateKeyLen + aesBlockLen + 1];
115 SysTryReturnResult(NID_SEC_CERT, *ppPrivKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
117 memset(*ppPrivKey, 0, __privateKeyLen + aesBlockLen + 1);
121 EVP_CIPHER_CTX_init(&ctx);
123 err = EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), null, uniqueKey, ivData, encDecBit);
124 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to initialized cipher.");
126 err = EVP_CipherUpdate(&ctx, *ppPrivKey, &keyLen, __pPrivateKey.get(), __privateKeyLen);
127 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to update cipher.");
129 err = EVP_CipherFinal_ex(&ctx, *ppPrivKey + keyLen, &lenData);
130 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to do cipher final.");
132 keyLen = keyLen + lenData;
137 EVP_CIPHER_CTX_init(&ctx);
139 std::unique_ptr< byte[] > pPlainText(new (std::nothrow) byte[__privateKeyLen + 1]);
140 SysTryReturnResult(NID_SEC_CERT, pPlainText != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
142 memset(pPlainText.get(), 0, __privateKeyLen + 1);
143 err = EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), null, uniqueKey, ivData, encDecBit);
144 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to initialized cipher.");
146 err = EVP_CipherUpdate(&ctx, pPlainText.get(), reinterpret_cast< int* >(&keyLen), __pPrivateKey.get(), __privateKeyLen);
147 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to update cipher.");
149 err = EVP_CipherFinal_ex(&ctx, pPlainText.get() + keyLen, &outLength);
150 SysTryCatch(NID_SEC_CERT, err == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to do cipher final.");
152 *ppPrivKey = pPlainText.release();
153 keyLen = keyLen + outLength;
157 EVP_CIPHER_CTX_cleanup(&ctx);
162 _CertPrivateKeyInfo::GetPkcs8EncDecKeyN(int& keyLen, byte** ppPrivKey, int encDecBit)
164 result r = E_SUCCESS;
165 byte uniqueKey[16] = {0};
166 int aesBlockLen = 16;
167 const EVP_CIPHER* pCipher = null;
168 X509_SIG* pPkcs8Key = null;
169 PKCS8_PRIV_KEY_INFO* p8inf = null;
170 EVP_PKEY* pKey = null;
171 const unsigned char* pTempPriKey = null;
173 byte* pPrivKey = null;
175 std::unique_ptr< ISecretKey > pSecKey(reinterpret_cast< ISecretKey* >(_DeviceKeyGenerator::GenerateDeviceKeyN(aesBlockLen)));
176 SysTryReturnResult(NID_SEC_CERT, pSecKey != null, E_SYSTEM, "Failed to generate secret key.");
178 std::unique_ptr< ByteBuffer > pKeyBuf(pSecKey->GetEncodedN());
179 SysAssertf(pKeyBuf != null, "Failed to get encoded secret key.");
181 memset(uniqueKey, 0, aesBlockLen);
182 memcpy(uniqueKey, reinterpret_cast< const char* >(pKeyBuf->GetPointer()), aesBlockLen);
184 std::unique_ptr< const unsigned char > pTempPrivateKey(new unsigned char[__privateKeyLen + 1]);
185 SysTryReturnResult(NID_SEC_CERT, pTempPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
187 memcpy((void*) pTempPrivateKey.get(), __pPrivateKey.get(), __privateKeyLen);
188 tempkeyLen = __privateKeyLen;
192 pTempPriKey = pTempPrivateKey.get();
193 pKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pTempPriKey, tempkeyLen);
194 SysTryCatch(NID_SEC_CERT, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
196 p8inf = EVP_PKEY2PKCS8(pKey);
197 SysTryCatch(NID_SEC_CERT, p8inf != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
199 //Encryption : supported PKCS#5 v2.0 algo are PBE-SHA1-RC2-64 PBE-MD2-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES
200 pPkcs8Key = PKCS8_encrypt(NID_pbeWithSHA1AndRC2_CBC, pCipher, reinterpret_cast< const char* >(uniqueKey), aesBlockLen, null, 0, PKCS5_DEFAULT_ITER, p8inf);
201 SysTryCatch(NID_SEC_CERT, pPkcs8Key != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key encryption failed");
203 keyLen = i2d_X509_SIG(pPkcs8Key, &pPrivKey);
204 SysTryCatch(NID_SEC_CERT, keyLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
210 pTempPriKey = pTempPrivateKey.get();
211 pPkcs8Key = d2i_X509_SIG(null, &pTempPriKey, tempkeyLen);
212 SysTryCatch(NID_SEC_CERT, pPkcs8Key != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
214 p8inf = PKCS8_decrypt(pPkcs8Key, reinterpret_cast< const char* >(uniqueKey), aesBlockLen);
215 SysTryCatch(NID_SEC_CERT, p8inf != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key decryption failed");
217 pKey = EVP_PKCS82PKEY(p8inf);
218 SysTryCatch(NID_SEC_CERT, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
220 keyLen = i2d_PrivateKey(pKey, reinterpret_cast< unsigned char** >(&pPrivKey));
221 SysTryCatch(NID_SEC_CERT, keyLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
225 PKCS8_PRIV_KEY_INFO_free(p8inf);
226 X509_SIG_free(pPkcs8Key);
228 *ppPrivKey = pPrivKey;
233 PKCS8_PRIV_KEY_INFO_free(p8inf);
234 X509_SIG_free(pPkcs8Key);
235 OPENSSL_free(pPrivKey);
241 _CertPrivateKeyInfo::SetPrivateKey(int keyLen, byte* pPrivKey)
243 __pPrivateKey.reset(null);
246 SysTryReturnResult(NID_SEC_CERT, pPrivKey != null, E_INVALID_ARG, "Invalid input argument.");
248 __pPrivateKey = std::unique_ptr< byte[] >(new (std::nothrow) byte[keyLen + 1]);
249 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
251 __privateKeyLen = keyLen;
252 memcpy(__pPrivateKey.get(), pPrivKey, keyLen);
253 __pPrivateKey[keyLen] = 0;
259 _CertPrivateKeyInfo::SetPrivateKey(char* pFileName)
261 result r = E_SUCCESS;
262 String fileName(pFileName);
269 __pPrivateKey.reset(null);
271 SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_INVALID_ARG, "Invalid input argument.");
273 r = File::GetAttributes(fileName, attr);
274 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get file attributes.");
276 size = attr.GetFileSize();
277 SysTryReturn(NID_SEC_CERT, size > 0, r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
278 SysTryReturn(NID_SEC_CERT, size < _MAX_CERT_PRIVATE_KEY_SIZE, r, r, "[%s] File size exceeds maximum specified length.", GetErrorMessage(r));
280 __privateKeyLen = size;
283 r = file.Construct(fileName, L"r");
284 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed in construct file.", GetErrorMessage(r));
286 __pPrivateKey = std::unique_ptr< byte[] >(new (std::nothrow) byte[size]);
287 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
289 readCnt = file.Read(__pPrivateKey.get(), size);
292 if ((readCnt == size && !IsFailed(r)))
294 byte* pPrivateKey = null;
296 GetPkcs8EncDecKeyN(priKeyLen, &pPrivateKey, 0);
297 SysTryReturnResult(NID_SEC_CERT, pPrivateKey, E_SYSTEM, "Failed to get decrypted private key from file.");
299 std::unique_ptr< byte[] > pPrivateKeyAuto(pPrivateKey);
301 memset(__pPrivateKey.get(), 0, __privateKeyLen);
302 memcpy(__pPrivateKey.get(), pPrivateKey, priKeyLen);
303 __privateKeyLen = priKeyLen;
309 } } } //Tizen::Security::Cert