Signature canonicalization and transaction mutation fixes

This commit is contained in:
David Schwartz
2014-02-18 18:37:55 -08:00
committed by Vinnie Falco
parent 93b44fcdc1
commit ae649ec917
17 changed files with 412 additions and 32 deletions

View File

@@ -271,16 +271,16 @@ public:
bool Sign (uint256 const& hash, Blob& vchSig)
{
unsigned char pchSig[10000];
unsigned int nSize = 0;
vchSig.clear ();
unsigned char pchSig[128];
unsigned int nSize = sizeof(pchSig)/sizeof(pchSig[0]) - 1;
if (!ECDSA_sign (0, (unsigned char*)hash.begin (), hash.size (), pchSig, &nSize, pkey))
return false;
vchSig.resize (nSize);
memcpy (&vchSig[0], pchSig, nSize);
size_t len = nSize;
makeCanonicalECDSASig (pchSig, len);
vchSig.resize (len);
memcpy (&vchSig[0], pchSig, len);
return true;
}

View File

@@ -161,12 +161,14 @@ void RippleAddress::setNodePublic (Blob const& vPublic)
SetData (VER_NODE_PUBLIC, vPublic);
}
bool RippleAddress::verifyNodePublic (uint256 const& hash, Blob const& vchSig) const
bool RippleAddress::verifyNodePublic (uint256 const& hash, Blob const& vchSig, ECDSA fullyCanonical) const
{
CKey pubkey = CKey ();
bool bVerified;
if (!pubkey.SetPubKey (getNodePublic ()))
bVerified = isCanonicalECDSASig (vchSig, fullyCanonical);
if (bVerified && !pubkey.SetPubKey (getNodePublic ()))
{
// Failed to set public key.
bVerified = false;
@@ -179,11 +181,11 @@ bool RippleAddress::verifyNodePublic (uint256 const& hash, Blob const& vchSig) c
return bVerified;
}
bool RippleAddress::verifyNodePublic (uint256 const& hash, const std::string& strSig) const
bool RippleAddress::verifyNodePublic (uint256 const& hash, const std::string& strSig, ECDSA fullyCanonical) const
{
Blob vchSig (strSig.begin (), strSig.end ());
return verifyNodePublic (hash, vchSig);
return verifyNodePublic (hash, vchSig, fullyCanonical);
}
//
@@ -442,12 +444,13 @@ void RippleAddress::setAccountPublic (const RippleAddress& generator, int seq)
setAccountPublic (pubkey.GetPubKey ());
}
bool RippleAddress::accountPublicVerify (uint256 const& uHash, Blob const& vucSig) const
bool RippleAddress::accountPublicVerify (uint256 const& uHash, Blob const& vucSig, ECDSA fullyCanonical) const
{
CKey ckPublic;
bool bVerified;
if (!ckPublic.SetPubKey (getAccountPublic ()))
bool bVerified = isCanonicalECDSASig (vucSig, fullyCanonical);
if (bVerified && !ckPublic.SetPubKey (getAccountPublic ()))
{
// Bad private key.
WriteLog (lsWARNING, RippleAddress) << "accountPublicVerify: Bad private key.";
@@ -919,7 +922,7 @@ public:
Blob vucTextSig;
naNodePrivate.signNodePrivate (uHash, vucTextSig);
expect (naNodePublic.verifyNodePublic (uHash, vucTextSig), "Verify failed.");
expect (naNodePublic.verifyNodePublic (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
// Construct a public generator from the seed.
RippleAddress naGenerator = RippleAddress::createGeneratorPublic (naSeed);
@@ -944,12 +947,14 @@ public:
// Check account signing.
expect (naAccountPrivate0.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic0.accountPublicVerify (uHash, vucTextSig), "Verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig), "Anti-verify failed.");
expect (naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
expect (naAccountPrivate1.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic1.accountPublicVerify (uHash, vucTextSig), "Verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig), "Anti-verify failed.");
expect (naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
// Check account encryption.
Blob vucTextCipher

View File

@@ -20,6 +20,8 @@
#ifndef RIPPLE_RIPPLEADDRESS_H
#define RIPPLE_RIPPLEADDRESS_H
#include "../ripple/sslutil/api/ECDSACanonical.h"
//
// Used to hold addresses and parse and produce human formats.
//
@@ -65,8 +67,8 @@ public:
bool setNodePublic (const std::string& strPublic);
void setNodePublic (Blob const& vPublic);
bool verifyNodePublic (uint256 const& hash, Blob const& vchSig) const;
bool verifyNodePublic (uint256 const& hash, const std::string& strSig) const;
bool verifyNodePublic (uint256 const& hash, Blob const& vchSig, ECDSA mustBeFullyCanonical) const;
bool verifyNodePublic (uint256 const& hash, const std::string& strSig, ECDSA mustBeFullyCanonical) const;
static RippleAddress createNodePublic (const RippleAddress& naSeed);
static RippleAddress createNodePublic (Blob const& vPublic);
@@ -127,7 +129,7 @@ public:
void setAccountPublic (Blob const& vPublic);
void setAccountPublic (const RippleAddress& generator, int seq);
bool accountPublicVerify (uint256 const& uHash, Blob const& vucSig) const;
bool accountPublicVerify (uint256 const& uHash, Blob const& vucSig, ECDSA mustBeFullyCanonical) const;
static RippleAddress createAccountPublic (Blob const& vPublic)
{

View File

@@ -38,6 +38,11 @@ public:
};
// VFALCO TODO Move all flags into this container after some study.
// Universal Transaction flags:
const uint32 tfFullyCanonicalSig = 0x80000000;
const uint32 tfUniversal = tfFullyCanonicalSig;
const uint32 tfUniversalMask = ~ tfUniversal;
// AccountSet flags:
// VFALCO TODO Javadoc comment every one of these constants
//const uint32 TxFlag::requireDestTag = 0x00010000;
@@ -62,18 +67,18 @@ const uint32 tfPassive = 0x00010000;
const uint32 tfImmediateOrCancel = 0x00020000;
const uint32 tfFillOrKill = 0x00040000;
const uint32 tfSell = 0x00080000;
const uint32 tfOfferCreateMask = ~ (tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
const uint32 tfOfferCreateMask = ~ (tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
// Payment flags:
const uint32 tfNoRippleDirect = 0x00010000;
const uint32 tfPartialPayment = 0x00020000;
const uint32 tfLimitQuality = 0x00040000;
const uint32 tfPaymentMask = ~ (tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
const uint32 tfPaymentMask = ~ (tfUniversal | tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
// TrustSet flags:
const uint32 tfSetfAuth = 0x00010000;
const uint32 tfSetNoRipple = 0x00020000;
const uint32 tfClearNoRipple = 0x00040000;
const uint32 tfTrustSetMask = ~ (tfSetfAuth | tfSetNoRipple | tfClearNoRipple);
const uint32 tfTrustSetMask = ~ (tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple);
#endif

View File

@@ -22,6 +22,7 @@
#include "../ripple_basics/ripple_basics.h"
#include "../ripple/json/ripple_json.h"
#include "../ripple/sslutil/api/ECDSACanonical.h"
struct bignum_st;
typedef struct bignum_st BIGNUM;