//static bool OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::ArmorPrivateKey(EVP_PKEY & theKey, OTASCIIArmor & ascKey, Timer & theTimer, OTPasswordData * pPWData/*=NULL*/, OTPassword * pImportPassword/*=NULL*/) { bool bReturnVal = false; ascKey.Release(); // ---------------------------------------- // Create a new memory buffer on the OpenSSL side OpenSSL_BIO bmem = BIO_new(BIO_s_mem()); OT_ASSERT(NULL != bmem); int64_t lSize = 0; // ---------------------------------------- // write a private key to that buffer, from theKey // OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::ArmorPrivateKey is calling PEM_write_bio_PrivateKey..."); if (NULL == pPWData) pPWData = &thePWData; int32_t nWriteBio = 0; if (NULL == pImportPassword) nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, EVP_des_ede3_cbc(), // todo should this algorithm be hardcoded? NULL, 0, OTAsymmetricKey::GetPasswordCallback(), pPWData); else nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, EVP_des_ede3_cbc(), // todo should this algorithm be hardcoded? NULL, 0, 0, const_cast<void*>(reinterpret_cast<const void*>(pImportPassword->getPassword()))); if (0 == nWriteBio) { OTLog::vError("%s: Failed writing EVP_PKEY to memory buffer.\n", __FUNCTION__); } else { // TODO (remove theTimer entirely. OTCachedKey replaces already.) // I set this timer because the above required a password. But now that master key is working, // the above would flow through even WITHOUT the user typing his passphrase (since master key still // not timed out.) Resulting in THIS timer being reset! Todo: I already shortened this timer to 30 // seconds, but need to phase it down to 0 and then remove it entirely! Master key takes over now! // theTimer.start(); // Note: this isn't the ultimate timer solution. See notes in ReleaseKeyLowLevel. // -------------------- OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", __FUNCTION__); OTPayload theData; char * pChar = NULL; // After the below call, pChar will point to the memory buffer where the private key supposedly is, // and lSize will contain the size of that memory. // lSize = BIO_get_mem_data(bmem, &pChar); uint32_t nSize = static_cast<uint32_t>(lSize); if (nSize > 0) { // Set the buffer size in our own memory. theData.SetPayloadSize(nSize); // void * pv = OTPassword::safe_memcpy((static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer()))), // destination theData.GetSize(), // size of destination buffer. pChar, // source nSize); // length of source. // bool bZeroSource=false); // if true, sets the source buffer to zero after copying is done. // ------------------------------------------------ // This base64 encodes the private key data, which // is already encrypted to its passphase as well. // ascKey.SetData(theData); OTLog::vOutput(5, "%s: Success copying private key into memory.\n", __FUNCTION__); bReturnVal = true; } else { OTLog::vError("%s: Failed copying private key into memory.\n", __FUNCTION__); } } return bReturnVal; }
// Take a public key, theKey (input), and create an armored version of // it into ascKey (output.) // // OpenSSL loaded key ===> ASCII-Armored export of same key. // //static // bool OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::ArmorPublicKey(EVP_PKEY & theKey, OTASCIIArmor & ascKey) { bool bReturnVal = false; const char * szFunc = "OTAsymmetricKey_OpenSSL::ArmorPublicKey"; ascKey.Release(); // ---------------------------------------- // Create a new memory buffer on the OpenSSL side OpenSSL_BIO bmem = BIO_new(BIO_s_mem()); OT_ASSERT_MSG(NULL != bmem, "OTAsymmetricKey_OpenSSL::ArmorPublicKey: ASSERT: NULL != bmem"); int64_t lSize = 0; // ---------------------------------------- // write a public key to that buffer, from theKey (parameter.) // int32_t nWriteBio = PEM_write_bio_PUBKEY(bmem, &theKey); if (0 == nWriteBio) { OTLog::vError("%s: Error: Failed writing EVP_PKEY to memory buffer.\n", szFunc); } else { OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", szFunc); OTPayload theData; char * pChar = NULL; // After the below call, pChar will point to the memory buffer where the public key // supposedly is, and lSize will contain the size of that memory. // lSize = BIO_get_mem_data(bmem, &pChar); uint32_t nSize = static_cast<uint32_t>(lSize); // todo security, etc. Fix this assumed type conversion. if (nSize > 0) { // Set the buffer size in our own memory. theData.SetPayloadSize(nSize); // void * pv = OTPassword::safe_memcpy((static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer()))), // destination theData.GetSize(), // size of destination buffer. pChar, // source nSize); // length of source. // bool bZeroSource=false); // if true, sets the source buffer to zero after copying is done. // ------------------------------------------------ // This base64 encodes the public key data // ascKey.SetData(theData); OTLog::vOutput(5, "%s: Success copying public key into memory.\n", szFunc); bReturnVal = true; } else { OTLog::vError("%s: Failed copying public key into memory.\n", szFunc); } } return bReturnVal; }