bool Wallet::generateKeyPair() { // FIXME: initialize OpenSSL elsewhere soon initialize(); qCInfo(commerce) << "Generating keypair."; auto keyPair = generateECKeypair(); if (!keyPair.first) { qCWarning(commerce) << "Empty keypair"; return false; } writeBackupInstructions(); // TODO: redo this soon -- need error checking and so on writeSecurityImage(_securityImage, keyFilePath()); QString key = keyPair.first->toBase64(); _publicKeys.push_back(key); qCDebug(commerce) << "public key:" << key; _isOverridingServer = false; // It's arguable whether we want to change the receiveAt every time, but: // 1. It's certainly needed the first time, when createIfNeeded answers true. // 2. It is maximally private, and we can step back from that later if desired. // 3. It maximally exercises all the machinery, so we are most likely to surface issues now. auto ledger = DependencyManager::get<Ledger>(); return ledger->receiveAt(key, key, getWallet()); }
bool Wallet::writeWallet(const QString& newPassphrase) { EC_KEY* keys = readKeys(keyFilePath()); auto ledger = DependencyManager::get<Ledger>(); // Remove any existing locker, because it will be out of date. if (!_publicKeys.isEmpty() && !ledger->receiveAt(_publicKeys.first(), _publicKeys.first(), QByteArray())) { return false; // FIXME: receiveAt could fail asynchronously. } if (keys) { // we read successfully, so now write to a new temp file QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); QString oldPassphrase = *_passphrase; if (!newPassphrase.isEmpty()) { setPassphrase(newPassphrase); } if (writeKeys(tempFileName, keys)) { if (writeSecurityImage(_securityImage, tempFileName)) { // ok, now move the temp file to the correct spot QFile(QString(keyFilePath())).remove(); QFile(tempFileName).rename(QString(keyFilePath())); qCDebug(commerce) << "wallet written successfully"; emit keyFilePathIfExistsResult(getKeyFilePath()); if (!walletIsAuthenticatedWithPassphrase() || !ledger->receiveAt()) { // FIXME: Should we fail the whole operation? // Tricky, because we'll need the the key and file from the TEMP location... qCWarning(commerce) << "Failed to update locker"; } return true; } else { qCDebug(commerce) << "couldn't write security image to temp wallet"; } } else { qCDebug(commerce) << "couldn't write keys to temp wallet"; } // if we are here, we failed, so cleanup QFile(tempFileName).remove(); if (!newPassphrase.isEmpty()) { setPassphrase(oldPassphrase); } } else { qCDebug(commerce) << "couldn't read wallet - bad passphrase?"; // TODO: review this, but it seems best to reset the passphrase // since we couldn't decrypt the existing wallet (or is doesn't // exist perhaps). setPassphrase(""); } return false; }
bool Wallet::writeWallet(const QString& newPassphrase) { EC_KEY* keys = readKeys(keyFilePath().toStdString().c_str()); if (keys) { // we read successfully, so now write to a new temp file QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); QString oldPassphrase = *_passphrase; if (!newPassphrase.isEmpty()) { setPassphrase(newPassphrase); } if (writeKeys(tempFileName.toStdString().c_str(), keys)) { if (writeSecurityImage(_securityImage, tempFileName)) { // ok, now move the temp file to the correct spot QFile(QString(keyFilePath())).remove(); QFile(tempFileName).rename(QString(keyFilePath())); qCDebug(commerce) << "wallet written successfully"; emit keyFilePathIfExistsResult(getKeyFilePath()); return true; } else { qCDebug(commerce) << "couldn't write security image to temp wallet"; } } else { qCDebug(commerce) << "couldn't write keys to temp wallet"; } // if we are here, we failed, so cleanup QFile(tempFileName).remove(); if (!newPassphrase.isEmpty()) { setPassphrase(oldPassphrase); } } else { qCDebug(commerce) << "couldn't read wallet - bad passphrase?"; // TODO: review this, but it seems best to reset the passphrase // since we couldn't decrypt the existing wallet (or is doesn't // exist perhaps). setPassphrase(""); } return false; }