本文整理汇总了C++中OTPayload类的典型用法代码示例。如果您正苦于以下问题:C++ OTPayload类的具体用法?C++ OTPayload怎么用?C++ OTPayload使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了OTPayload类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: OT_ASSERT
// Low-level
//
// (Internal) ASCII-Armored key ====> (Internal) Actual loaded OpenSSL key.
//
//
EVP_PKEY * OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::InstantiatePublicKey(OTPasswordData * pPWData/*=NULL*/)
{
OT_ASSERT(m_pKey == NULL);
OT_ASSERT(backlink->m_p_ascKey != NULL);
OT_ASSERT(backlink->IsPublic());
const char * szFunc = "OTAsymmetricKey_OpenSSL::InstantiatePublicKey";
// ------------------------------
EVP_PKEY * pReturnKey = NULL;
OTPayload theData;
// -----------------------------------------------
// This base64 decodes the string m_p_ascKey into the
// binary payload object "theData"
//
backlink->m_p_ascKey->GetData(theData);
if (theData.GetSize() > 0)
{
// -------------------------------------------
// Next, copy theData's contents into a new BIO_mem_buf,
// so OpenSSL can load the key out of it.
//
OpenSSL_BIO keyBio = BIO_new_mem_buf(static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())),
theData.GetSize());
OT_ASSERT_MSG(NULL != keyBio, "OTAsymmetricKey_OpenSSL::InstantiatePublicKey: Assert: NULL != keyBio \n");
// -------------------------------------------
// Next we load up the key from the BIO string into an instantiated key object.
//
OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::InstantiatePublicKey is calling PEM_read_bio_PUBKEY...");
if (NULL == pPWData)
pPWData = &thePWData;
pReturnKey = PEM_read_bio_PUBKEY(keyBio, NULL, OTAsymmetricKey::GetPasswordCallback(), pPWData);
// -------------------------------------------
// -------------------------------------------
backlink->ReleaseKeyLowLevel(); // Release whatever loaded key I might have already had.
if (NULL != pReturnKey)
{
m_pKey = pReturnKey;
OTLog::vOutput(4, "%s: Success reading public key from ASCII-armored data:\n\n%s\n\n",
szFunc, backlink->m_p_ascKey->Get());
return m_pKey;
}
}
OTLog::vError("%s: Failed reading public key from ASCII-armored data:\n\n%s\n\n",
szFunc, backlink->m_p_ascKey->Get());
return NULL;
}
示例2: SetupHeader
void SetupHeader( union u_header * pCMD, int nTypeID, int nCmdID, OTPayload & thePayload)
{
pCMD->fields.type_id = nTypeID;
pCMD->fields.command_id = nCmdID;
// pCMD->fields.size = thePayload.GetSize();
pCMD->fields.size = htonl(thePayload.GetSize()); // think this is causing problems
pCMD->fields.checksum = CalcChecksum(pCMD->buf, OT_CMD_HEADER_SIZE-1);
BYTE byChecksum = (BYTE)pCMD->fields.checksum;
int nChecksum = byChecksum;
uint32_t nTemp = thePayload.GetSize();
fprintf(stderr, "(Payload size %d, TYPE %d command, checksum: %d...)\n", nTemp, nTypeID, nChecksum);
}
示例3: SetupHeader
void SetupHeader( union u_header * pCMD, int nTypeID, int nCmdID, OTPayload & thePayload)
{
OT_ASSERT(NULL != pCMD);
pCMD->fields.type_id = (nTypeID > 0) ? static_cast<BYTE>(nTypeID) : '\0';
pCMD->fields.command_id = (nCmdID > 0) ? static_cast<BYTE>(nCmdID) : '\0';
// pCMD->fields.size = thePayload.GetSize();
pCMD->fields.size = htonl(thePayload.GetSize()); // think this is causing problems
pCMD->fields.checksum = CalcChecksum(pCMD->buf, OT_CMD_HEADER_SIZE-1);
BYTE byChecksum = (BYTE)pCMD->fields.checksum;
int nChecksum = byChecksum;
uint32_t nTemp = thePayload.GetSize();
OTLog::vOutput(4, "(Payload size %d, TYPE %d command, checksum: %d...)\n", nTemp, nTypeID, nChecksum);
}
示例4: GenerateNewAccount
// The above method uses this one internally...
bool OTAccount::GenerateNewAccount(const OTPseudonym & theServer, const OTMessage & theMessage,
const OTAccount::AccountType eAcctType/*=OTAccount::simple*/)
{
// First we generate a secure random number into a binary object.
OTPayload thePayload;
thePayload.SetPayloadSize(100);
if (!RAND_bytes((unsigned char*)thePayload.GetPayloadPointer(), 100))
{
OTLog::Error("The PRNG is not seeded!\n");
// abort( );
return false;
}
// Next we calculate that binary object into a message digest (an OTIdentifier).
OTIdentifier newID;
if (!newID.CalculateDigest(thePayload))
{
OTLog::Error("Error generating new account ID.\n");
return false;
}
// Next we get that digest (which is a binary hash number)
// and extract a human-readable standard string format of that hash,
// into an OTString.
OTString strID(newID);
SetRealAccountID(newID); // Set the account number based on what we just generated.
SetPurportedAccountID(newID); // Might as well set them both. (Safe here to do so, for once.)
m_strName.Set(strID); // So it's not blank. The user can always change it.
// Next we create the full path filename for the account using the ID.
m_strFilename.Format("%s%s%s%s%s", OTLog::Path(), OTLog::PathSeparator(),
OTLog::AccountFolder(),
OTLog::PathSeparator(), strID.Get());
// Then we try to load it, in order to make sure that it doesn't already exist.
if (LoadContractRawFile())
{
OTLog::Error("Error generating new account ID, account already exists.\n");
return false;
}
// Set up the various important starting values of the account.
m_AcctType = eAcctType; // account type defaults to OTAccount::simple. But there are also issuer accts...
// for basket accounts, the server is the user.
if (OTAccount::basket == eAcctType)
{
theServer.GetIdentifier(m_AcctUserID);
}
else
{
m_AcctUserID.SetString(theMessage.m_strNymID);
}
m_AcctAssetTypeID.SetString(theMessage.m_strAssetID);
OTString TEMPstr(m_AcctAssetTypeID);
OTLog::vOutput(3, "Creating new account, type:\n%s\nChanged to ID then back to string:\n%s\n",
theMessage.m_strAssetID.Get(), TEMPstr.Get());
OTIdentifier SERVER_ID(theMessage.m_strServerID);
SetRealServerID(SERVER_ID); // todo this assumes the serverID on the message is correct. It's vetted, but still...
SetPurportedServerID(SERVER_ID);
const time_t tDate = time(NULL); // Today, now.
m_BalanceDate.Format("%d", tDate);
m_BalanceAmount.Set("0");
// Sign the Account (so we know that we did)... Otherwise someone could put a fake
// account file on the server if the code wasn't designed to verify the signature on the
// account.
SignContract(theServer);
SaveContract();
// Save the Account to storage (based on its ID.)
SaveAccount();
// Don't know why I had this here. Putting SaveAccount() instead.
// OTString strFilename(m_strFilename);
// SaveContract(strFilename.Get()); // Saves the account to a specific filename
// No need to create the inbox and outbox ledgers...they will be created automatically
// if they do not exist when they are needed.
return true;
}
示例5: OTPAYLOAD_GetMessage
bool OTPAYLOAD_GetMessage(OTPayload & thePayload, OTMessage & theMessage)
{
return thePayload.GetMessage(theMessage);
}
示例6: OT_ASSERT
// Process my reply back out to the client. @something.
// For TCP / SSL mode.
void OTClientConnection::ProcessReply(OTMessage &theReply)
{
OT_ASSERT(NULL != m_pPublicKey);
int err = 0;
uint32_t nwritten = 0;
bool bSendCommand = false;
bool bSendPayload = false;
u_header theCMD;
OTPayload thePayload;
memset((void *)theCMD.buf, 0, OT_CMD_HEADER_SIZE); // todo cast
// For now let's send ALL replies in Envelopes (encrypted to public key of client)
// IF we have a public key, that is. Otherwise we send as a normal message.
//
// All messages already require either a public key, or a nymID used to look up a
// public key. So given that I have that information when I reply, I might as well
// ENCRYPT my reply to that same public key. More secure that way.
//
// The wallet (and server) are both ready to open and process these encrypted envelopes.
// If GetKey() returns something, that means the key was set in there, it's
// not just a null pointer. This means we can use it! So let's encrypt to it.
if (m_pPublicKey->IsPublic())
{
OTString strEnvelopeContents(theReply);
// Save the ready-to-go message into a string.
OTEnvelope theEnvelope;
// Seal the string up into an encrypted Envelope
theEnvelope.Seal(*m_pPublicKey, strEnvelopeContents);
// From here on out, theMessage is disposable. OTPayload takes over.
// OTMessage doesn't care about checksums and headers.
thePayload.SetEnvelope(theEnvelope);
// Now that the payload is ready, we'll set up the header.
SetupHeader(&theCMD, CMD_TYPE_1, TYPE_1_CMD_2, thePayload);
}
else
{
thePayload.SetMessage(theReply);
// Now that the payload is ready, we'll set up the header.
SetupHeader(&theCMD, CMD_TYPE_1, TYPE_1_CMD_1, thePayload);
}
bSendCommand = true;
bSendPayload = true;
OTLog::vOutput(2, "\n****************************************************************\n"
"===> Finished setting up header for response.\nFirst 9 bytes are: %d %d %d %d %d %d %d %d %d...\n",
theCMD.buf[0], theCMD.buf[1], theCMD.buf[2], theCMD.buf[3], theCMD.buf[4],
theCMD.buf[5], theCMD.buf[6], theCMD.buf[7], theCMD.buf[8]);
// ------------------------------------------------------------------------------
/*
// Write to Client
strcpy(buffer, "Hello Client!");
SFSocketWrite(clientSocket, buffer, strlen(buffer));
*/
if (bSendCommand)
{
const unsigned int nHeaderSize = OT_CMD_HEADER_SIZE;
for (nwritten = 0; nwritten < nHeaderSize; nwritten += err)
{
// err = SFSocketWrite(m_pSocket, theCMD.buf + nwritten, nHeaderSize - nwritten);
#ifdef _WIN32
if (0 == err || SOCKET_ERROR == err) // 0 means disconnect. error means error. >0 means bytes read.
#else
if (err <= 0)
#endif
break;
}
}
// At this point, we have sent the header across the pipe.
if (bSendPayload)
{
uint32_t nPayloadSize = thePayload.GetSize();
for (nwritten = 0; nwritten < nPayloadSize; nwritten += err)
{
// err = SFSocketWrite(m_pSocket, (unsigned char *)thePayload.GetPayloadPointer() + nwritten, nPayloadSize - nwritten);
#ifdef _WIN32
if (0 == err || SOCKET_ERROR == err) // 0 means disconnect. error means error. >0 means bytes read.
//.........这里部分代码省略.........
示例7: if
// A certain number of bytes are expected in the payload, according to the header.
// This function tries to read that many bytes, and inserts them into an OTPayload object.
// From there, a simple method call extracts the message, we return true, and the message
// gets added to our internal list for processing.
bool OTClientConnection::ProcessType1Cmd(u_header & theCMD, OTMessage & theMessage)
{
// At this point, the checksum has already validated.
// Might as well get the PAYLOAD next.
// int err;
uint32_t nread, lSize = theCMD.fields.size;
// Make sure our byte-order is correct here.
// theCMD.fields.size = ntohl(theCMD.fields.size); // I was doing this twice!! This is already done when the header is first read.
// setup the buffer we are reading into
OTPayload thePayload;
nread = thePayload.ReadBytesFrom(m_Buffer, lSize);
/*
// actually read the payload from the socket into the buffer.
for (nread = 0; nread < theCMD.fields.size; nread += err)
{
err = SFSocketRead(m_pSocket,
(unsigned char *)thePayload.GetPayloadPointer() + nread,
theCMD.fields.size - nread);
// if we don't read anything more, stop reading and move on
if (err <= 0)
break;
}
*/
// TODO fix the buffering so that if a complete command has not yet been received, it saves the other
// bytes instead of discarding them. For now I'll just sleep for a second to make sure the entire command
// was received.
// sleep(1);
// ------------------------------------------------------------
// Try to interpret the command number.
// Right now we support signed messages and encrypted envelopes containing
// signed messages.
switch (theCMD.fields.command_id) {
case TYPE_1_CMD_1:
OTLog::Output(2, "Received Type 1 CMD 1:\nThere is a signed OTMessage in the payload.\n");
break;
case TYPE_1_CMD_2:
OTLog::Output(2, "Received Type 1 CMD 2:\n"
"There is an encrypted OTEnvelope (containing signed OTMessage) in the payload.\n");
break;
default:
OTLog::vError("Received unexpected command number %d in OTClientConnection::ProcessType1Cmd\n",
theCMD.fields.command_id);
break;
}
// ------------------------------------------------------------
// Hm, that's weird. It was a 0 size payload message. DoS?
if (theCMD.fields.size == 0)
{
OTLog::Output(2, "(The payload was a 0 size.)\n");
return true;
}
// Uh-oh, somehow the number of bytes read was less than what we expected...
else if (nread < theCMD.fields.size)
{
// TODO: Verify that the amount read matched the amount expected
// if not, we have a problem that needs to be handled.
// Long term solution is to buffer the data as a comes in and just
// add it to the buffer.
// Then if we don't have the complete message yet, we just come around next
// time some data is read, and we add that to the buffer, THEN we check to see
// if there are enough bytes yet read to match the amount expected according to
// the header.
//
// Until I can do that, I'm not yet TRULY asynchronous. TODO: lookup a good buffer class.
OTLog::Error("Number of bytes read did NOT match size in header.\n");
return false;
}
else
OTLog::vOutput(2, "Loaded a payload, size: %d\n", theCMD.fields.size);
// ------------------------------------------------------------
// Okay so now we've received the expected size from the socket. Let's transfer it
// into an object type that we can manipulate here in code. (Message or Envelope.)
// a signed OTMessage
if (TYPE_1_CMD_1 == theCMD.fields.command_id)
{
#ifdef _WIN32
if (OTPAYLOAD_GetMessage(thePayload, theMessage))
#else
if (thePayload.GetMessage(theMessage))
#endif
{
OTLog::Output(2, "Successfully retrieved payload message...\n");
//.........这里部分代码省略.........
示例8: OT_ASSERT
bool OTEnvelope::Decrypt(OTString & theOutput, const OTSymmetricKey & theKey, const OTPassword & thePassword)
{
const char * szFunc = "OTEnvelope::Decrypt";
// ------------------------------------------------
OT_ASSERT((thePassword.isPassword() && (thePassword.getPasswordSize() > 0)) || (thePassword.isMemory() && (thePassword.getMemorySize() > 0)));
OT_ASSERT(theKey.IsGenerated());
// -----------------------------------------------
OTPassword theRawSymmetricKey;
if (false == theKey.GetRawKeyFromPassphrase(thePassword, theRawSymmetricKey))
{
OTLog::vError("%s: Failed trying to retrieve raw symmetric key using password. (Wrong password?)\n",
szFunc);
return false;
}
// -----------------------------------------------
//
uint32_t nRead = 0;
uint32_t nRunningTotal = 0;
m_dataContents.reset(); // Reset the fread position on this object to 0.
// ****************************************************************************
//
// Read the ENVELOPE TYPE (as network order version -- and convert to host version.)
//
// 0 == Error
// 1 == Asymmetric Key (this function -- Seal / Open)
// 2 == Symmetric Key (other functions -- Encrypt / Decrypt use this.)
// Anything else: error.
//
uint16_t env_type_n = 0;
if (0 == (nRead = m_dataContents.OTfread(reinterpret_cast<uint8_t*>(&env_type_n),
static_cast<uint32_t>(sizeof(env_type_n)))))
{
OTLog::vError("%s: Error reading Envelope Type. Expected asymmetric(1) or symmetric (2).\n", szFunc);
return false;
}
nRunningTotal += nRead;
OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(env_type_n)));
// ----------------------------------------------------------------------------
// convert that envelope type from network to HOST endian.
//
const uint16_t env_type = static_cast<uint16_t>(ntohs(static_cast<uint16_t>(env_type_n)));
// nRunningTotal += env_type; // NOPE! Just because envelope type is 1 or 2, doesn't mean we add 1 or 2 extra bytes to the length here. Nope!
if (2 != env_type)
{
const uint32_t l_env_type = static_cast<uint32_t>(env_type);
OTLog::vError("%s: Error: Expected Envelope for Symmetric key (type 2) but instead found type: %ld.\n",
szFunc, l_env_type);
return false;
}
// ****************************************************************************
//
// Read network-order IV size (and convert to host version)
//
const uint32_t max_iv_length = OTCryptoConfig::SymmetricIvSize(); // I believe this is a max length, so it may not match the actual length of the IV.
// Read the IV SIZE (network order version -- convert to host version.)
//
uint32_t iv_size_n = 0;
if (0 == (nRead = m_dataContents.OTfread(reinterpret_cast<uint8_t*>(&iv_size_n),
static_cast<uint32_t>(sizeof(iv_size_n)))))
{
OTLog::vError("%s: Error reading IV Size.\n", szFunc);
return false;
}
nRunningTotal += nRead;
OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(iv_size_n)));
// ----------------------------------------------------------------------------
// convert that iv size from network to HOST endian.
//
const uint32_t iv_size_host_order = ntohl(iv_size_n);
if (iv_size_host_order > max_iv_length)
{
OTLog::vError("%s: Error: iv_size (%ld) is larger than max_iv_length (%ld).\n",
szFunc, static_cast<long>(iv_size_host_order), static_cast<long>(max_iv_length));
return false;
}
// nRunningTotal += iv_size_host_order; // Nope!
// ****************************************************************************
//
// Then read the IV (initialization vector) itself.
//
OTPayload theIV;
theIV.SetPayloadSize(iv_size_host_order);
if (0 == (nRead = m_dataContents.OTfread(static_cast<uint8_t*>(const_cast<void *>(theIV.GetPayloadPointer())),
static_cast<uint32_t>(iv_size_host_order))))
{
OTLog::vError("%s: Error reading initialization vector.\n", szFunc);
return false;
}
nRunningTotal += nRead;
OT_ASSERT(nRead == static_cast<uint32_t>(iv_size_host_order));
//.........这里部分代码省略.........
示例9: GenerateNewAccount
// The above method uses this one internally...
bool OTAccount::GenerateNewAccount(const OTPseudonym & theServer, const OTMessage & theMessage,
const OTAccount::AccountType eAcctType/*=OTAccount::simple*/,
int64_t lStashTransNum/*=0*/)
{
const char *szFunc = "OTAccount::GenerateNewAccount";
// -----------------------------------------------
// First we generate a secure random number into a binary object...
//
OTPayload thePayload;
if (false == thePayload.Randomize(100)) // todo hardcoding. Plus: is 100 bytes of random a little much here?
{
OTLog::vError("%s: Failed trying to acquire random numbers.\n", szFunc);
return false;
}
// --------------------------------------------------
//
// Next we calculate that binary object into a message digest (an OTIdentifier).
//
OTIdentifier newID;
if (!newID.CalculateDigest(thePayload))
{
OTLog::vError("%s: Error generating new account ID.\n", szFunc);
return false;
}
// --------------------------------------------------
//
// Next we get that digest (which is a binary hash number)
// and extract a human-readable standard string format of that hash,
// into an OTString.
//
OTString strID(newID);
SetRealAccountID(newID); // Set the account number based on what we just generated.
SetPurportedAccountID(newID); // Might as well set them both. (Safe here to do so, for once.)
m_strName.Set(strID); // So it's not blank. The user can always change it.
// Next we create the full path filename for the account using the ID.
//
m_strFoldername = OTFolders::Account().Get();
m_strFilename = strID.Get();
// Then we try to load it, in order to make sure that it doesn't already exist.
// --------------------------------------------------------------------
if (OTDB::Exists(m_strFoldername.Get(), m_strFilename.Get()))
{
OTLog::vError("%s: Account already exists: %s\n", szFunc,
m_strFilename.Get());
return false;
}
// --------------------------------------------------------------------
// Set up the various important starting values of the account.
m_AcctType = eAcctType; // account type defaults to OTAccount::simple. But there are also issuer accts...
// --------------------------------------------------------------------
if (IsInternalServerAcct()) // basket, basketsub, mint, voucher, and stash accounts are all "owned" by the server.
{
theServer.GetIdentifier(m_AcctUserID);
}
else
{
m_AcctUserID.SetString(theMessage.m_strNymID);
}
// --------------------------------------------------------------------
m_AcctAssetTypeID.SetString(theMessage.m_strAssetID);
OTLog::vOutput(3, "%s: Creating new account, type:\n%s\n", szFunc,
theMessage.m_strAssetID.Get());
OTIdentifier SERVER_ID(theMessage.m_strServerID);
SetRealServerID(SERVER_ID); // todo this assumes the serverID on the message is correct. It's vetted, but still...
SetPurportedServerID(SERVER_ID);
const time64_t tDate = OTTimeGetCurrentTime(); // Today, now.
m_BalanceDate.Format("%d", tDate);
m_BalanceAmount.Set("0");
// --------------------------------------------------------------------
if (IsStashAcct())
{
OT_ASSERT_MSG(lStashTransNum > 0,
"You created a stash account, but with a zero-or-negative transaction number for its cron item.");
m_lStashTransNum = lStashTransNum;
}
// --------------------------------------------------------------------
// Sign the Account (so we know that we did)... Otherwise someone could put a fake
// account file on the server if the code wasn't designed to verify the signature on the
// account.
SignContract(theServer);
//.........这里部分代码省略.........
示例10: BIO_new
//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;
}
示例11: EVP_des_ede3_cbc
// NOTE: OpenSSL will store the EVP_PKEY inside the X509, and when I get it,
// I'm not supposed to destroy the x509 until I destroy the EVP_PKEY FIRST!
// (AND it reference-counts.)
// Since I want ability to destroy the two, independent of each other, I made
// static functions here for copying public and private keys, so I am ALWAYS
// working with MY OWN copy of any given key, and not OpenSSL's reference-counted
// one.
//
// Furthermore, BIO_mem_buf doesn't allocate its own memory, but uses the memory
// you pass to it. You CANNOT free that memory until you destroy the BIO.
//
// That's why you see me copying one bio into a payload, before copying it into
// the next bio. Todo security: copy it into an OTPassword here, instead of an
// OTPayload, which is safer, and more appropriate for a private key. Make sure
// OTPassword can accommodate a bit larger size than what it does now.
//
//static // CALLER must EVP_pkey_free!
EVP_PKEY * OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::CopyPrivateKey(EVP_PKEY & theKey, OTPasswordData * pPWData/*=NULL*/, OTPassword * pImportPassword/*=NULL*/)
{
const EVP_CIPHER * pCipher = EVP_des_ede3_cbc(); // todo should this algorithm be hardcoded?
// ----------------------------------------
// Create a new memory buffer on the OpenSSL side
OpenSSL_BIO bmem = BIO_new(BIO_s_mem());
OT_ASSERT(NULL != bmem);
EVP_PKEY * pReturnKey = NULL;
// ----------------------------------------
// write a private key to that buffer, from theKey
//
OTPasswordData thePWDataWrite("OTAsymmetricKey_OpenSSL::CopyPrivateKey is calling PEM_write_bio_PrivateKey...");
// todo optimization: might just remove the password callback here, and just write the private key in the clear,
// and then load it up again, saving the encrypt/decrypt step that otherwise occurs, and then as long as we OpenSSL_cleanse
// the BIO, then it SHOULD stil be safe, right?
//
int32_t nWriteBio = false;
if (NULL == pImportPassword)
nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, pCipher,
NULL, 0, OTAsymmetricKey::GetPasswordCallback(), NULL == pPWData ? &thePWDataWrite : pPWData);
else
nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, pCipher,
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
{
OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", __FUNCTION__);
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.
//
const int64_t lSize = BIO_get_mem_data(bmem, &pChar);
const uint32_t nSize = static_cast<uint32_t>(lSize);
if (nSize > 0)
{
OTPayload theData;
// 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.
if (NULL != pv)
{
// -----------------------------------------------
// Next, copy theData's contents into a new BIO_mem_buf,
// so OpenSSL can load the key out of it.
//
OpenSSL_BIO keyBio = BIO_new_mem_buf(static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())),
theData.GetSize());
OT_ASSERT_MSG(NULL != keyBio, "OTAsymmetricKey_OpenSSL::CopyPrivateKey: Assert: NULL != keyBio \n");
// -------------------------------------------
// Next we load up the key from the BIO string into an instantiated key object.
//
OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::CopyPrivateKey is calling PEM_read_bio_PUBKEY...");
if (NULL == pImportPassword)
pReturnKey = PEM_read_bio_PrivateKey( keyBio, NULL, OTAsymmetricKey::GetPasswordCallback(), NULL == pPWData ? &thePWData : pPWData);
else
pReturnKey = PEM_read_bio_PrivateKey( keyBio, NULL, 0, const_cast<void*>(reinterpret_cast<const void*>(pImportPassword->getPassword())));
// -------------------------------------------
}
else
OTLog::vError("%s: Error: Failed copying memory from BIO into OTPayload.\n");
// -------------------------------------------
}
else
{
//.........这里部分代码省略.........