Exemplo n.º 1
0
bool GenerateAuthCookie(std::string *cookie_out)
{
    const size_t COOKIE_SIZE = 32;
    unsigned char rand_pwd[COOKIE_SIZE];
    GetRandBytes(rand_pwd, COOKIE_SIZE);
    std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE);

    /** the umask determines what permissions are used to create this file -
     * these are set to 077 in init.cpp unless overridden with -sysperms.
     */
    std::ofstream file;
    fs::path filepath_tmp = GetAuthCookieFile(true);
    file.open(filepath_tmp.string().c_str());
    if (!file.is_open()) {
        LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string());
        return false;
    }
    file << cookie;
    file.close();

    fs::path filepath = GetAuthCookieFile(false);
    if (!RenameOver(filepath_tmp, filepath)) {
        LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string());
        return false;
    }
    LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());

    if (cookie_out)
        *cookie_out = cookie;
    return true;
}
Exemplo n.º 2
0
/**
 * Returns a string (consisting of 8 random bytes) suitable for use as an
 * obfuscating XOR key.
 */
std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
{
    unsigned char buff[OBFUSCATE_KEY_NUM_BYTES];
    GetRandBytes(buff, OBFUSCATE_KEY_NUM_BYTES);
    return std::vector<unsigned char>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]);

}
Exemplo n.º 3
0
void seed_insecure_rand(bool fDeterministic)
{
    // The seed values have some unlikely fixed points which we avoid.
    if (fDeterministic) {
        insecure_rand_Rz = insecure_rand_Rw = 11;
    } else {
        uint32_t tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x9068ffffU);
        insecure_rand_Rz = tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x464fffffU);
        insecure_rand_Rw = tmp;
    }
}
Exemplo n.º 4
0
// Send a ping to serialize the connection and ensure we can figure out
// when the remote peer thinks it finished sending us data. This reflects
// a minor design weakness in BIP 37 as the merkleblock message does not
// say how many transactions the remote peer thinks we have: this normally
// doesn't matter, but if we have received transactions and then dropped t
// hem due to various policies or running out of memory, then we won't be
// able to reassemble the block. So we must ask the peer to send the
// transactions again.
void SendPing(CNode& pfrom) {
    pfrom.thinBlockNonce = 0;
    while (pfrom.thinBlockNonce == 0)
        GetRandBytes((unsigned char*)&pfrom.thinBlockNonce,
                sizeof(pfrom.thinBlockNonce));

    pfrom.PushMessage("ping", pfrom.thinBlockNonce);
}
Exemplo n.º 5
0
SecureString CMnemonic::Generate(int strength)
{
    if (strength % 32 || strength < 128 || strength > 256) {
        return SecureString();
    }
    SecureVector data(32);
    GetRandBytes(&data[0], 32);
    SecureString mnemonic = FromData(data, strength / 8);
    return mnemonic;
}
Exemplo n.º 6
0
uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;

    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
}
Exemplo n.º 7
0
uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;
#ifdef USE_UNSAFE_RANDOM // use this if you want to test with valgrind
    return random() % nMax;
#else
    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
#endif
}
Exemplo n.º 8
0
void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];

    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Produce output
    hasher.Finalize(buf);
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}
Exemplo n.º 9
0
bool CBanDB::Write(const banmap_t& banSet)
{
    // Generate random temporary filename
    unsigned short randv = 0;
    GetRandBytes((unsigned char*)&randv, sizeof(randv));
    std::string tmpfn = strprintf("banlist.dat.%04x", randv);

    // serialize banlist, checksum data up to that point, then append csum
    CDataStream ssBanlist(SER_DISK, CLIENT_VERSION);
    ssBanlist << FLATDATA(Params().MessageStart());
    ssBanlist << banSet;
    uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end());
    ssBanlist << hash;

    // open temp output file, and associate with CAutoFile
    boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
    FILE *file = fopen(pathTmp.string().c_str(), "wb");
    CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
    if (fileout.IsNull())
        return error("%s: Failed to open file %s", __func__, pathTmp.string());

    // Write and commit header, data
    try {
        fileout << ssBanlist;
    }
    catch (const std::exception& e) {
        return error("%s: Serialize or I/O error - %s", __func__, e.what());
    }
    FileCommit(fileout.Get());
    fileout.fclose();

    // replace existing banlist.dat, if any, with new banlist.dat.XXXX
    if (!RenameOver(pathTmp, pathBanlist))
        return error("%s: Rename-into-place failed", __func__);

    return true;
}
Exemplo n.º 10
0
uint256 GetRandHash()
{
    uint256 hash;
    GetRandBytes((unsigned char*)&hash, sizeof(hash));
    return hash;
}
Exemplo n.º 11
0
void PaymentServerTests::paymentServerTests()
{
    SelectParams(CBaseChainParams::MAIN);
    OptionsModel optionsModel;
    PaymentServer* server = new PaymentServer(nullptr, false);
    X509_STORE* caStore = X509_STORE_new();
    X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64));
    PaymentServer::LoadRootCAs(caStore);
    server->setOptionsModel(&optionsModel);
    server->uiReady();

    std::vector<unsigned char> data;
    SendCoinsRecipient r;
    QString merchant;

    // Now feed PaymentRequests to server, and observe signals it produces

    // This payment request validates directly against the
    // caCert1 certificate authority:
    data = DecodeBase64(paymentrequest1_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString("testmerchant.org"));

    // Signed, but expired, merchant cert in the request:
    data = DecodeBase64(paymentrequest2_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString(""));

    // 10-long certificate chain, all intermediates valid:
    data = DecodeBase64(paymentrequest3_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString("testmerchant8.org"));

    // Long certificate chain, with an expired certificate in the middle:
    data = DecodeBase64(paymentrequest4_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString(""));

    // Validly signed, but by a CA not in our root CA list:
    data = DecodeBase64(paymentrequest5_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString(""));

    // Try again with no root CA's, verifiedMerchant should be empty:
    caStore = X509_STORE_new();
    PaymentServer::LoadRootCAs(caStore);
    data = DecodeBase64(paymentrequest1_cert1_BASE64);
    r = handleRequest(server, data);
    r.paymentRequest.getMerchant(caStore, merchant);
    QCOMPARE(merchant, QString(""));

    // Load second root certificate
    caStore = X509_STORE_new();
    X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
    PaymentServer::LoadRootCAs(caStore);

    QByteArray byteArray;

    // For the tests below we just need the payment request data from
    // paymentrequestdata.h parsed + stored in r.paymentRequest.
    //
    // These tests require us to bypass the following normal client execution flow
    // shown below to be able to explicitly just trigger a certain condition!
    //
    // handleRequest()
    // -> PaymentServer::eventFilter()
    //   -> PaymentServer::handleURIOrFile()
    //     -> PaymentServer::readPaymentRequestFromFile()
    //       -> PaymentServer::processPaymentRequest()

    // Contains a testnet paytoaddress, so payment request network doesn't match client network:
    data = DecodeBase64(paymentrequest1_cert2_BASE64);
    byteArray = QByteArray((const char*)data.data(), data.size());
    r.paymentRequest.parse(byteArray);
    // Ensure the request is initialized, because network "main" is default, even for
    // uninitialized payment requests and that will fail our test here.
    QVERIFY(r.paymentRequest.IsInitialized());
    QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false);

    // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01):
    data = DecodeBase64(paymentrequest2_cert2_BASE64);
    byteArray = QByteArray((const char*)data.data(), data.size());
    r.paymentRequest.parse(byteArray);
    // Ensure the request is initialized
    QVERIFY(r.paymentRequest.IsInitialized());
    // compares 1 < GetTime() == false (treated as expired payment request)
    QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);

    // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t):
    // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1 (int32_t)
    // -1 is 1969-12-31 23:59:59 (for a 32 bit time values)
    data = DecodeBase64(paymentrequest3_cert2_BASE64);
    byteArray = QByteArray((const char*)data.data(), data.size());
    r.paymentRequest.parse(byteArray);
    // Ensure the request is initialized
    QVERIFY(r.paymentRequest.IsInitialized());
    // compares 9223372036854775807 < GetTime() == false (treated as unexpired payment request)
    QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), false);

    // Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64):
    // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0 (int32_t)
    // 0 is 1970-01-01 00:00:00 (for a 32 bit time values)
    data = DecodeBase64(paymentrequest4_cert2_BASE64);
    byteArray = QByteArray((const char*)data.data(), data.size());
    r.paymentRequest.parse(byteArray);
    // Ensure the request is initialized
    QVERIFY(r.paymentRequest.IsInitialized());
    // compares -9223372036854775808 < GetTime() == true (treated as expired payment request)
    QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);

    // Test BIP70 DoS protection:
    unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
    GetRandBytes(randData, sizeof(randData));
    // Write data to a temp file:
    QTemporaryFile tempFile;
    tempFile.open();
    tempFile.write((const char*)randData, sizeof(randData));
    tempFile.close();
    // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false
    QCOMPARE(PaymentServer::verifySize(tempFile.size()), false);

    // Payment request with amount overflow (amount is set to 21000001 BTC):
    data = DecodeBase64(paymentrequest5_cert2_BASE64);
    byteArray = QByteArray((const char*)data.data(), data.size());
    r.paymentRequest.parse(byteArray);
    // Ensure the request is initialized
    QVERIFY(r.paymentRequest.IsInitialized());
    // Extract address and amount from the request
    QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
    for (const std::pair<CScript, CAmount>& sendingTo : sendingTos) {
        CTxDestination dest;
        if (ExtractDestination(sendingTo.first, dest))
            QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
    }

    delete server;
}
Exemplo n.º 12
0
void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply)
{
    if (reply.code == 250) {
        std::set<std::string> methods;
        std::string cookiefile;
        /*
         * 250-AUTH METHODS=COOKIE,SAFECOOKIE COOKIEFILE="/home/x/.tor/control_auth_cookie"
         * 250-AUTH METHODS=NULL
         * 250-AUTH METHODS=HASHEDPASSWORD
         */
        for (const std::string &s : reply.lines) {
            std::pair<std::string,std::string> l = SplitTorReplyLine(s);
            if (l.first == "AUTH") {
                std::map<std::string,std::string> m = ParseTorReplyMapping(l.second);
                std::map<std::string,std::string>::iterator i;
                if ((i = m.find("METHODS")) != m.end())
                    boost::split(methods, i->second, boost::is_any_of(","));
                if ((i = m.find("COOKIEFILE")) != m.end())
                    cookiefile = i->second;
            } else if (l.first == "VERSION") {
                std::map<std::string,std::string> m = ParseTorReplyMapping(l.second);
                std::map<std::string,std::string>::iterator i;
                if ((i = m.find("Tor")) != m.end()) {
                    LogPrint("tor", "tor: Connected to Tor version %s\n", i->second);
                }
            }
        }
        for (const std::string &s : methods) {
            LogPrint("tor", "tor: Supported authentication method: %s\n", s);
        }
        // Prefer NULL, otherwise SAFECOOKIE. If a password is provided, use HASHEDPASSWORD
        /* Authentication:
         *   cookie:   hex-encoded ~/.tor/control_auth_cookie
         *   password: "******"
         */
        std::string torpassword = GetArg("-torpassword", "");
        if (!torpassword.empty()) {
            if (methods.count("HASHEDPASSWORD")) {
                LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n");
                boost::replace_all(torpassword, "\"", "\\\"");
                conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2));
            } else {
                LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n");
            }
        } else if (methods.count("NULL")) {
            LogPrint("tor", "tor: Using NULL authentication\n");
            conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2));
        } else if (methods.count("SAFECOOKIE")) {
            // Cookie: hexdump -e '32/1 "%02x""\n"'  ~/.tor/control_auth_cookie
            LogPrint("tor", "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile);
            std::pair<bool,std::string> status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE);
            if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) {
                // conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2));
                cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end());
                clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0);
                GetRandBytes(&clientNonce[0], TOR_NONCE_SIZE);
                conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2));
            } else {
                if (status_cookie.first) {
                    LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE);
                } else {
                    LogPrintf("tor: Authentication cookie %s could not be opened (check permissions)\n", cookiefile);
                }
            }
        } else if (methods.count("HASHEDPASSWORD")) {
            LogPrintf("tor: The only supported authentication mechanism left is password, but no password provided with -torpassword\n");
        } else {
            LogPrintf("tor: No supported authentication method\n");
        }
    } else {
        LogPrintf("tor: Requesting protocol info failed\n");
    }
}
Exemplo n.º 13
0
SaltedTxidHasher::SaltedTxidHasher()
{
    GetRandBytes((unsigned char*)&k0, sizeof(k0));
    GetRandBytes((unsigned char*)&k1, sizeof(k1));
}