예제 #1
0
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);
        }
    }
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}