// 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; }
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); }
bool RippleAddress::verifySignature(uint256 const& hash, const std::string& strSig) const { Blob vchSig(strSig.begin(), strSig.end()); return(verifySignature(hash, vchSig)); }