Beispiel #1
0
// Credit: https://github.com/ppcoin/ppcoin/pull/101/files
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSigParam)
{
    // Prevent the problem described here:
    // https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-July/009697.html
    // by removing the extra length bytes
    std::vector<unsigned char> vchSig(vchSigParam.begin(), vchSigParam.end());
    if (vchSig.size() > 1 && vchSig[1] & 0x80)
    {
        unsigned char nLengthBytes = vchSig[1] & 0x7f;

        if (vchSig.size() < 2 + nLengthBytes)
            return false;

        if (nLengthBytes > 4)
        {
            unsigned char nExtraBytes = nLengthBytes - 4;
            for (unsigned char i = 0; i < nExtraBytes; i++)
                if (vchSig[2 + i])
                    return false;
            vchSig.erase(vchSig.begin() + 2, vchSig.begin() + 2 + nExtraBytes);
            vchSig[1] = 0x80 | (nLengthBytes - nExtraBytes);
        }
    }

    if (vchSig.empty())
        return false;

    // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    assert(norm_sig);
    if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
    {
        /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
         * error. But OpenSSL's own use of this function redundantly frees the
         * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
         * clear contract for the function behaving the same way is more
         * conservative.
         */
        ECDSA_SIG_free(norm_sig);
        return false;
    }
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
Beispiel #2
0
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSigParam)
{
    // Fix invalid signature with crafted length by removing extra length bytes
    std::vector<unsigned char> vchSig(vchSigParam.begin(), vchSigParam.end());
    if (vchSig.size() > 1 && vchSig[1] & 0x80)
    {
        unsigned char nLengthBytes = vchSig[1] & 0x7f;

        if (vchSig.size() < 2 + nLengthBytes)   // Avoid invalid memory access on crafted signature
            return false;

        if (nLengthBytes > 4)
        {
            unsigned char nExtraBytes = nLengthBytes - 4;
            for (unsigned char i = 0; i < nExtraBytes; i++)
                if (vchSig[2 + i])
                    return false;
            vchSig.erase(vchSig.begin() + 2, vchSig.begin() + 2 + nExtraBytes);
            vchSig[1] = 0x80 | (nLengthBytes - nExtraBytes);
        }
    }

    if (vchSig.empty())
        return false;

    // New versions of OpenSSL will reject non-canonical DER signatures. De/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    assert(norm_sig);
    if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
    {
        /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on error.
         * But OpenSSL's own use of this function redundantly frees the result.
         * As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a clear contract for the function behaving the same way is more conservative. */
        ECDSA_SIG_free(norm_sig);
        return false;
    }
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
bool COeruShield::IsBlockIdentified(const CBlock *pblock, const int nHeight) const
{
    CTransaction coinbaseTx;
    if ( ! GetCoinbaseTx(pblock, coinbaseTx))
        return false;

    CBitcoinAddress coinbaseAddress;
    if ( ! GetCoinbaseAddress(coinbaseTx, coinbaseAddress))
        return false;

    COeruTxOut oeruTxOut;
    if ( ! FindOeruVOut(coinbaseTx, oeruTxOut)) {
       LogPrint("OeruShield", "%s: No valid oeru vout found\n", __FUNCTION__);
       return false;
    }

    std::vector<unsigned char> vchData;
    if (!oeruTxOut.GetOpReturnData(vchData)) {
       LogPrint("OeruShield", "%s: No OP_RETURN data found\n", __FUNCTION__);
       return false;
    }

    std::vector<unsigned char> vchSig(
        vchData.begin() + COeruShield::OERU_BYTES.size(),
        vchData.end()
    );
    std::string strMessage = std::to_string(nHeight);

    CSignatureChecker signatureChecker;
    if (signatureChecker.VerifySignature(strMessage, vchSig, coinbaseAddress)) {
        LogPrint("OeruShield", "%s: Valid OERU signature on block %d\n",
                __FUNCTION__, nHeight);
        return true;
    } else {
        LogPrint("OeruShield", "%s: No valid OERU signature on block %d\n",
                __FUNCTION__, nHeight);
        return false;
    }
}
bool RippleAddress::verifyNodePublic(const uint256& hash, const std::string& strSig) const
{
	std::vector<unsigned char> vchSig(strSig.begin(), strSig.end());

	return verifyNodePublic(hash, vchSig);
}
Beispiel #5
0
bool RippleAddress::verifySignature(uint256 const& hash, const std::string& strSig) const
{
	Blob vchSig(strSig.begin(), strSig.end());
	return(verifySignature(hash, vchSig));
}