Skip to content

Commit

Permalink
Merge pull request namecoin#213 from phelixnmc/strict_DER_checks_guard
Browse files Browse the repository at this point in the history
Strict DER checks guard
workaround OpenSSL strict DER checks helter-skelter
  • Loading branch information
phelixbtc committed Jan 11, 2015
2 parents d7b0adc + d7a950f commit 1289289
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions src/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,24 @@ class CKey

bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
{
// -1 = error, 0 = bad sig, 1 = good
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
if (vchSig.empty())
return false;
return true;

// adapted from https://github.com/bitcoin/bitcoin/commit/488ed32f2ada1d1dd108fc245d025c4d5f252783
// 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];
d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size());
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;
}

static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig)
Expand All @@ -184,23 +198,23 @@ class CKey
return false;
return key.Verify(hash, vchSig);
}

void SetCompressedPubKey(bool fCompressed = true);

// create a compact signature (65 bytes), which allows reconstructing the used public key
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
// 0x1D = second key with even y, 0x1E = second key with odd y
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);

// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);

// Verify a compact signature
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
};

#endif

0 comments on commit 1289289

Please sign in to comment.