Exemple #1
0
// static
bool OTKeyring::IOS_StoreSecret(const OTString& strUser,
                                const OTPassword& thePassword,
                                const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    CFStringRef service_name = CFSTR("opentxs");
    CFStringRef account_name = CFStringCreateWithCString(nullptr, strUser.Get(),
                                                         kCFStringEncodingUTF8);
    CFDataRef vData = CFDataCreateWithBytesNoCopy(
        nullptr, thePassword.getMemory_uint8(), thePassword.getMemorySize(),
        kCFAllocatorNull);

    const void* keys[] = {kSecClass, kSecAttrService, kSecAttrAccount,
                          kSecValueData};
    const void* values[] = {kSecClassGenericPassword, service_name,
                            account_name, vData};
    CFDictionaryRef item =
        CFDictionaryCreate(nullptr, keys, values, 4, nullptr, nullptr);

    OSStatus theError = SecItemAdd(item, nullptr);

    CFRelease(item);
    CFRelease(vData);
    CFRelease(account_name);

    if (theError != noErr) {
        otErr << "OTKeyring::IOS_StoreSecret: Error in SecItemAdd.\n";
        return false;
    }

    return true;
}
serializedAsymmetricKey TrezorCrypto::SeedToPrivateKey(const OTPassword& seed)
    const
{
    serializedAsymmetricKey derivedKey;
    HDNode node;

    int result = ::hdnode_from_seed(
        static_cast<const uint8_t*>(seed.getMemory()),
        seed.getMemorySize(),
        &node);

    OT_ASSERT_MSG((1 == result), "Derivation of root node failed.");

    if (1 == result) {
        derivedKey = HDNodeToSerialized(node, TrezorCrypto::DERIVE_PRIVATE);
    }
    OTPassword root;
    App::Me().Crypto().Hash().Digest(
        CryptoHash::HASH160,
        seed,
        root);
    derivedKey->mutable_path()->set_root(
        root.getMemory(),
        root.getMemorySize());

    return derivedKey;
}
Exemple #3
0
// static
bool OTKeyring::Mac_StoreSecret(const OTString& strUser,
                                const OTPassword& thePassword,
                                const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    const std::string service_name = "opentxs";
    const std::string account_name = strUser.Get();

    OTMacKeychain theKeychain;
    void* vData =
        const_cast<void*>(static_cast<const void*>(thePassword.getMemory()));

    OSStatus theError = theKeychain.AddSecret(
        nullptr, service_name.size(), service_name.data(), account_name.size(),
        account_name.data(), thePassword.getMemorySize(),
        vData, // thePassword.getMemory()
        nullptr);
    if (theError != noErr) {
        otErr
            << "OTKeyring::Mac_StoreSecret: Error in theKeychain.AddSecret.\n";
        return false;
    }

    return true;
}
Exemple #4
0
bool Server::SetPrivateKey(const OTPassword& key) const
{
    if (CURVE_KEY_BYTES != key.getMemorySize()) {
        otErr << OT_METHOD << __FUNCTION__ << ": Invalid private key."
              << std::endl;

        return false;
    }

    return set_private_key(key.getMemory(), key.getMemorySize());
}
Exemple #5
0
// static
bool OTKeyring::Gnome_StoreSecret(const OTString& strUser,
                                  const OTPassword& thePassword,
                                  const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    OTData theData(thePassword.getMemory(), thePassword.getMemorySize());
    OTASCIIArmor ascData(theData);
    theData.zeroMemory(); // security reasons.

    OTString strOutput;
    const bool bSuccess =
        ascData.Exists() &&
        ascData.WriteArmoredString(strOutput, "DERIVED KEY"); // There's no
                                                              // default, to
                                                              // force you to
                                                              // enter the right
                                                              // string.
    ascData.zeroMemory();

    GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR;

    if (bSuccess && strOutput.Exists()) {
        theResult = gnome_keyring_store_password_sync(
            GNOME_KEYRING_NETWORK_PASSWORD,
            GNOME_KEYRING_DEFAULT, // GNOME_KEYRING_SESSION,
            str_display.c_str(), strOutput.Get(), "user", strUser.Get(),
            "protocol", "opentxs", // todo: hardcoding.
            nullptr);
        strOutput.zeroMemory();

        bool bResult = false;

        if (theResult == GNOME_KEYRING_RESULT_OK)
            bResult = true;
        else
            otErr << "OTKeyring::Gnome_StoreSecret: "
                  << "Failure in gnome_keyring_store_password_sync: "
                  << gnome_keyring_result_to_message(theResult) << '\n';

        return bResult;
    }

    otOut << "OTKeyring::Gnome_StoreSecret: No secret to store.\n";

    return false;
}
std::string TrezorCrypto::toWords(const OTPassword& seed) const
{
    std::string wordlist(
        ::mnemonic_from_data(
            static_cast<const uint8_t*>(seed.getMemory()),
            seed.getMemorySize()));
    return wordlist;
}
Exemple #7
0
String CryptoUtil::Base58CheckEncode(const OTPassword& input)
{
    const uint8_t* inputStart = static_cast<const uint8_t*>(input.getMemory());
    const uint8_t* inputEnd = inputStart + input.getMemorySize();

    String encodedInput = ::EncodeBase58Check(inputStart, inputEnd);
    return encodedInput;
}
Exemple #8
0
// static
bool OTKeyring::KWallet_StoreSecret(const OTString& strUser,
                                    const OTPassword& thePassword,
                                    const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    KWallet::Wallet* pWallet = OTKeyring::OpenKWallet();

    if (nullptr != pWallet) {
        const QString qstrKey(strUser.Get());

        OTData theData(thePassword.getMemory(), thePassword.getMemorySize());
        OTASCIIArmor ascData(theData);
        theData.zeroMemory(); // security reasons.

        OTString strOutput;
        const bool bSuccess =
            ascData.Exists() &&
            ascData.WriteArmoredString(
                strOutput, "DERIVED KEY"); // There's no default, to force you
                                           // to enter the right string.
        ascData.zeroMemory();

        // Set the password
        //
        bool bReturnVal = false;

        if (bSuccess && strOutput.Exists() &&
            pWallet->writePassword(qstrKey,
                                   QString::fromUtf8(strOutput.Get())) == 0)
            bReturnVal = true;
        else
            otErr << "OTKeyring::KWallet_StoreSecret: Failed trying to store "
                     "secret into KWallet.\n";

        strOutput.zeroMemory();

        return bReturnVal;
    }

    otErr << "OTKeyring::KWallet_StoreSecret: Unable to open kwallet.\n";

    return false;
}
Exemple #9
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;
}
bool OTPassword::Compare(OTPassword & rhs) const
{
    OT_ASSERT(this->isPassword() || this->isMemory());
    OT_ASSERT(rhs.isPassword()   || rhs.isMemory());
    
    if (this->isPassword() && !rhs.isPassword())
        return false;
    if (this->isMemory() && !rhs.isMemory())
        return false;
    
    const int nThisSize = this->isPassword() ? this->getPasswordSize() : this->getMemorySize();
    const int nRhsSize  = rhs.isPassword()   ? rhs.getPasswordSize()   : rhs.getMemorySize();
    
    if (nThisSize != nRhsSize)
        return false;
    
    if (0 == memcmp(this->isPassword() ? this->getPassword()   : this->getMemory(), 
                    rhs.isPassword()   ? rhs.getPassword()     : rhs.getMemory(), 
                    rhs.isPassword()   ? rhs.getPasswordSize() : rhs.getMemorySize()) )
        return true;
    
    return false;
}
Exemple #11
0
// static
bool OTKeyring::FlatFile_StoreSecret(const String& strUser,
                                     const OTPassword& thePassword,
                                     const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    const std::string str_pw_folder(OTKeyring::FlatFile_GetPasswordFolder());
    if (!str_pw_folder.empty()) {
        String strExactPath;
        strExactPath.Format("%s%s%s", str_pw_folder.c_str(),
                            Log::PathSeparator(), strUser.Get());
        const std::string str_ExactPath(strExactPath.Get());

        OTData theData(thePassword.getMemory(), thePassword.getMemorySize());
        OTASCIIArmor ascData(theData);
        theData.zeroMemory(); // security reasons.

        // Save the password
        //
        const bool bSaved =
            ascData.Exists() && ascData.SaveToExactPath(str_ExactPath);
        ascData.zeroMemory();

        if (!bSaved)
            otErr << "OTKeyring::FlatFile_StoreSecret: Failed trying to store "
                     "secret.\n";

        return bSaved;
    }

    otErr << "OTKeyring::FlatFile_StoreSecret: Unable to cache derived key, "
             "since password_folder not provided in config file.\n";

    return false;
}
Exemple #12
0
bool OTPassword::Compare(OTPassword& rhs) const
{
    OT_ASSERT(isPassword() || isMemory());
    OT_ASSERT(rhs.isPassword() || rhs.isMemory());

    if (isPassword() && !rhs.isPassword()) return false;
    if (isMemory() && !rhs.isMemory()) return false;

    const uint32_t nThisSize =
        isPassword() ? getPasswordSize() : getMemorySize();
    const uint32_t nRhsSize =
        rhs.isPassword() ? rhs.getPasswordSize() : rhs.getMemorySize();

    if (nThisSize != nRhsSize) return false;

    if (0 ==
        memcmp(isPassword() ? getPassword_uint8() : getMemory_uint8(),
               rhs.isPassword() ? rhs.getPassword_uint8()
                                : rhs.getMemory_uint8(),
               rhs.isPassword() ? rhs.getPasswordSize() : rhs.getMemorySize()))
        return true;

    return false;
}
Exemple #13
0
OTPassword::OTPassword(const OTPassword& rhs)
    : size_(0)
    , isText_(rhs.isPassword())
    , isBinary_(rhs.isMemory())
    , isPageLocked_(false)
    , blockSize_(
          rhs.blockSize_) // The buffer has this size+1 as its static size.
{
    if (isText_) {
        data_[0] = '\0';
        setPassword_uint8(rhs.getPassword_uint8(), rhs.getPasswordSize());
    }
    else if (isBinary_) {
        setMemory(rhs.getMemory_uint8(), rhs.getMemorySize());
    }
}
OTPassword::OTPassword(const OTPassword & rhs)
:	m_nPasswordSize(0),
    m_bIsText(rhs.isPassword()),
    m_bIsBinary(rhs.isMemory()),
    m_bIsPageLocked(false),
    m_theBlockSize(rhs.m_theBlockSize) // The buffer has this size+1 as its static size.
{
    if (m_bIsText)
    {
        m_szPassword[0] = '\0';
        setPassword_uint8(rhs.getPassword_uint8(), rhs.getPasswordSize());
    }
    else if (m_bIsBinary)
    {
        setMemory(rhs.getMemory_uint8(), rhs.getMemorySize());
    }
}
OTSymmetricKey Symmetric::Factory(
    const crypto::SymmetricProvider& engine,
    const OTPassword& raw)
{
    std::unique_ptr<implementation::Symmetric> output;

    if (!raw.isMemory()) { return OTSymmetricKey(output.release()); }

    output.reset(new implementation::Symmetric(engine));

    if (!output) { return OTSymmetricKey(output.release()); }

    OTPasswordData password("Encrypting a symmetric key.");
    output->EncryptKey(raw, password);
    output->key_size_ = raw.getMemorySize();

    return OTSymmetricKey(output.release());
}
Exemple #16
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;
}
Exemple #17
0
bool OTEnvelope::Encrypt(const String& theInput, OTSymmetricKey& theKey,
                         const OTPassword& thePassword)
{
    OT_ASSERT(
        (thePassword.isPassword() && (thePassword.getPasswordSize() > 0)) ||
        (thePassword.isMemory() && (thePassword.getMemorySize() > 0)));
    OT_ASSERT(theInput.Exists());

    // Generate a random initialization vector.
    //
    OTData theIV;

    if (!theIV.Randomize(OTCryptoConfig::SymmetricIvSize())) {
        otErr << __FUNCTION__ << ": Failed trying to randomly generate IV.\n";
        return false;
    }

    // If the symmetric key hasn't already been generated, we'll just do that
    // now...
    // (The passphrase is used to derive another key that is used to encrypt the
    // actual symmetric key, and to access it later.)
    //
    if ((false == theKey.IsGenerated()) &&
        (false == theKey.GenerateKey(thePassword))) {
        otErr << __FUNCTION__
              << ": Failed trying to generate symmetric key using password.\n";
        return false;
    }

    if (!theKey.HasHashCheck()) {
        if (!theKey.GenerateHashCheck(thePassword)) {
            otErr << __FUNCTION__
                  << ": Failed trying to generate hash check using password.\n";
            return false;
        }
    }

    OT_ASSERT(theKey.HasHashCheck());

    OTPassword theRawSymmetricKey;

    if (false ==
        theKey.GetRawKeyFromPassphrase(thePassword, theRawSymmetricKey)) {
        otErr << __FUNCTION__ << ": Failed trying to retrieve raw symmetric "
                                 "key using password.\n";
        return false;
    }

    OTData theCipherText;

    const bool bEncrypted = OTCrypto::It()->Encrypt(
        theRawSymmetricKey,       // The symmetric key, in clear form.
        theInput.Get(),           // This is the Plaintext.
        theInput.GetLength() + 1, // for null terminator
        theIV,                    // Initialization vector.
        theCipherText);           // OUTPUT. (Ciphertext.)

    //
    // Success?
    //
    if (!bEncrypted) {
        otErr << __FUNCTION__ << ": (static) call failed to encrypt. Wrong "
                                 "key? (Returning false.)\n";
        return false;
    }

    // This is where the envelope final contents will be placed,
    // including the envelope type, the size of the IV, the IV
    // itself, and the ciphertext.
    //
    m_dataContents.Release();

    // Write the ENVELOPE TYPE (network order version.)
    //
    // 0 == Error
    // 1 == Asymmetric Key  (other functions -- Seal / Open.)
    // 2 == Symmetric Key   (this function -- Encrypt / Decrypt.)
    // Anything else: error.

    // Calculate "network-order" version of envelope type 2.
    uint16_t env_type_n = htons(static_cast<uint16_t>(2));

    m_dataContents.Concatenate(reinterpret_cast<void*>(&env_type_n),
                               // (uint32_t here is the 2nd parameter to
                               // Concatenate, and has nothing to do with
                               // env_type_n being uint16_t)
                               static_cast<uint32_t>(sizeof(env_type_n)));

    // Write IV size (in network-order)
    //
    uint32_t ivlen =
        OTCryptoConfig::SymmetricIvSize(); // Length of IV for this cipher...
    OT_ASSERT(ivlen >= theIV.GetSize());
    uint32_t ivlen_n = htonl(
        theIV.GetSize()); // Calculate "network-order" version of iv length.

    m_dataContents.Concatenate(reinterpret_cast<void*>(&ivlen_n),
                               static_cast<uint32_t>(sizeof(ivlen_n)));

    // Write the IV itself.
    //
    m_dataContents.Concatenate(theIV.GetPointer(), theIV.GetSize());

    // Write the Ciphertext.
    //
    m_dataContents.Concatenate(theCipherText.GetPointer(),
                               theCipherText.GetSize());

    // We don't write the size of the ciphertext before the ciphertext itself,
    // since the decryption is able to deduce the size based on the total
    // envelope
    // size minus the other pieces. We might still want to add that size here,
    // however.
    // (for security / safety reasons.)

    return true;
}
Exemple #18
0
// static
bool OTKeyring::Windows_StoreSecret(const OTString& strUser,
                                    const OTPassword& thePassword,
                                    const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    DATA_BLOB input;
    input.pbData = const_cast<BYTE*>(
        reinterpret_cast<const BYTE*>(thePassword.getMemory()));
    input.cbData = static_cast<DWORD>(thePassword.getMemorySize());

    //    CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
    //    ZeroMemory(&PromptStruct, sizeof(PromptStruct));
    //    PromptStruct.cbSize = sizeof(PromptStruct);
    //    PromptStruct.dwPromptFlags = CRYPTPROTECT_PROMPT_ON_PROTECT;
    //    PromptStruct.szPrompt = L"This is a user prompt.";

    DATA_BLOB output;

    BOOL result = CryptProtectData(&input, L"", // description string
                                   nullptr,     // optional entropy
                                   nullptr,     // reserved
                                   nullptr,     //&PromptStruct
                                   0, &output);
    if (!result) {
        otErr << __FUNCTION__ << ": Failed calling Win32: CryptProtectData \n";
        return false;
    }

    //
    // this does a copy
    //
    //    std::string ciphertext;
    //    ciphertext.assign(reinterpret_cast<std::string::value_type*>(output.pbData),
    //                       output.cbData);

    OTData theOutput;
    theOutput.Assign(static_cast<void*>(output.pbData),
                     static_cast<uint32_t>(output.cbData));

    LocalFree(output.pbData); // Note: should have a check for nullptr here... ?
                              // And above...

    // Success encrypting to ciphertext (std::string or OTData)

    //
    // Write it to local storage.
    //
    if (theOutput.IsEmpty()) {
        otErr << __FUNCTION__
              << ": Error: Output of Win32 CryptProtectData was empty.\n";
    }
    else {
        OTASCIIArmor ascData(theOutput);
        const OTString strFoldername("win32_data"); // todo hardcoding.

        if (ascData.Exists())
            return ascData.WriteArmoredFile(strFoldername,
                                            strUser, // this is filename
                                            "WINDOWS KEYRING MASTERKEY");
    }

    return false;
}