PaymentCode::PaymentCode(const std::string& base58) { OTData rawCode; App::Me().Crypto().Util().Base58CheckDecode(base58, rawCode); if (81 == rawCode.GetSize()) { uint8_t prependByte, features; rawCode.OTfread(&prependByte, 1); rawCode.OTfread(&version_, 1); rawCode.OTfread(&features, 1); if (features & 0x80) { hasBitmessage_ = true; } OTData key; key.SetSize(33); chain_code_.SetSize(32); OT_ASSERT(33 == key.GetSize()); OT_ASSERT(32 == chain_code_.GetSize()); rawCode.OTfread(static_cast<uint8_t*>(const_cast<void*>(key.GetPointer())), key.GetSize()); rawCode.OTfread(static_cast<uint8_t*>(const_cast<void*>(chain_code_.GetPointer())), chain_code_.GetSize()); ConstructKey(key, chain_code_); if (hasBitmessage_) { rawCode.OTfread(&bitmessage_version_, 1); rawCode.OTfread(&bitmessage_stream_, 1); } } }
String CryptoUtil::Nonce(const uint32_t size, OTData& rawOutput) const { rawOutput.zeroMemory(); rawOutput.SetSize(size); OTPassword source; source.randomizeMemory(size); String nonce(Base58CheckEncode(source)); rawOutput.Assign(source.getMemory(), source.getMemorySize()); return nonce; }
const OTData PaymentCode::Pubkey() const { OTData pubkey; pubkey.SetSize(33); if (pubkey_) { std::dynamic_pointer_cast<AsymmetricKeySecp256k1>(pubkey_)->GetKey(pubkey); } OT_ASSERT(33 == pubkey.GetSize()); return pubkey; }
bool OTEnvelope::Decrypt(String& 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)) { otErr << szFunc << ": Failed trying to retrieve raw symmetric key " "using password. (Wrong password?)\n"; 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))))) { otErr << szFunc << ": Error reading Envelope Type. Expected " "asymmetric(1) or symmetric (2).\n"; 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 = ntohs(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); otErr << szFunc << ": Error: Expected Envelope for Symmetric key (type " "2) but instead found type: " << l_env_type << ".\n"; 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))))) { otErr << szFunc << ": Error reading IV Size.\n"; 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) { otErr << szFunc << ": Error: iv_size (" << static_cast<int64_t>(iv_size_host_order) << ") is larger than max_iv_length (" << static_cast<int64_t>(max_iv_length) << ").\n"; return false; } // nRunningTotal += iv_size_host_order; // Nope! // Then read the IV (initialization vector) itself. // OTData theIV; theIV.SetSize(iv_size_host_order); if (0 == (nRead = m_dataContents.OTfread( static_cast<uint8_t*>(const_cast<void*>(theIV.GetPointer())), static_cast<uint32_t>(iv_size_host_order)))) { otErr << szFunc << ": Error reading initialization vector.\n"; return false; } nRunningTotal += nRead; OT_ASSERT(nRead == static_cast<uint32_t>(iv_size_host_order)); OT_ASSERT(nRead <= max_iv_length); // We create an OTData object to store the ciphertext itself, which // begins AFTER the end of the IV. // So we see pointer + nRunningTotal as the starting point for the // ciphertext. // the size of the ciphertext, meanwhile, is the size of the entire thing, // MINUS nRunningTotal. // OTData theCipherText( static_cast<const void*>( static_cast<const uint8_t*>(m_dataContents.GetPointer()) + nRunningTotal), m_dataContents.GetSize() - nRunningTotal); // Now we've got all the pieces together, let's try to decrypt it... // OTData thePlaintext; // for output. const bool bDecrypted = OTCrypto::It()->Decrypt( theRawSymmetricKey, // The symmetric key, in clear form. static_cast<const char*>( theCipherText.GetPointer()), // This is the Ciphertext. theCipherText.GetSize(), theIV, thePlaintext); // OUTPUT. (Recovered plaintext.) You can pass // OTPassword& OR OTData& here (either will // work.) // theOutput is where we'll put the decrypted data. // theOutput.Release(); if (bDecrypted) { // Make sure it's null-terminated... // uint32_t nIndex = thePlaintext.GetSize() - 1; (static_cast<uint8_t*>( const_cast<void*>(thePlaintext.GetPointer())))[nIndex] = '\0'; // Set it into theOutput (to return the plaintext to the caller) // theOutput.Set(static_cast<const char*>(thePlaintext.GetPointer())); } return bDecrypted; }