Merge pull request #12049 from zfox23/RC61.1_commerce_fixEcdsaError1

RC61.1: Commerce: Fix some rezzing errors; Fix ECDSA errors
This commit is contained in:
John Conklin II 2017-12-21 17:46:32 -08:00 committed by GitHub
commit 5a839ebd93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 16 deletions

View file

@ -61,7 +61,7 @@ void Ledger::send(const QString& endpoint, const QString& success, const QString
void Ledger::signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure) { void Ledger::signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure) {
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
QString signature = key.isEmpty() ? "" : wallet->signWithKey(text, key); QString signature = wallet->signWithKey(text, key);
QJsonObject request; QJsonObject request;
request[propertyName] = QString(text); request[propertyName] = QString(text);
if (!controlled_failure) { if (!controlled_failure) {

View file

@ -547,13 +547,16 @@ QStringList Wallet::listPublicKeys() {
// the horror of code pages and so on (changing the bytes) by just returning a base64 // the horror of code pages and so on (changing the bytes) by just returning a base64
// encoded string representing the signature (suitable for http, etc...) // encoded string representing the signature (suitable for http, etc...)
QString Wallet::signWithKey(const QByteArray& text, const QString& key) { QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
qCInfo(commerce) << "Signing text" << text << "with key" << key;
EC_KEY* ecPrivateKey = NULL; EC_KEY* ecPrivateKey = NULL;
auto keyFilePathString = keyFilePath().toStdString();
if ((ecPrivateKey = readPrivateKey(keyFilePath().toStdString().c_str()))) { if ((ecPrivateKey = readPrivateKey(keyFilePath().toStdString().c_str()))) {
unsigned char* sig = new unsigned char[ECDSA_size(ecPrivateKey)]; unsigned char* sig = new unsigned char[ECDSA_size(ecPrivateKey)];
unsigned int signatureBytes = 0; unsigned int signatureBytes = 0;
qCInfo(commerce) << "Hashing and signing plaintext" << text << "with key at address" << ecPrivateKey;
QByteArray hashedPlaintext = QCryptographicHash::hash(text, QCryptographicHash::Sha256); QByteArray hashedPlaintext = QCryptographicHash::hash(text, QCryptographicHash::Sha256);
@ -746,12 +749,10 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer<ReceivedMessage> pack
} }
EC_KEY_free(ec); EC_KEY_free(ec);
QByteArray ba = sig.toLocal8Bit();
const char *sigChar = ba.data();
QByteArray textByteArray; QByteArray textByteArray;
if (status > -1) { if (status > -1) {
textByteArray = QByteArray(sigChar, (int) strlen(sigChar)); textByteArray = sig.toUtf8();
} }
textByteArraySize = textByteArray.size(); textByteArraySize = textByteArray.size();
int certIDSize = certID.size(); int certIDSize = certID.size();

View file

@ -2513,7 +2513,8 @@ bool EntityItemProperties::verifySignature(const QString& publicKey, const QByte
return false; return false;
} }
const unsigned char* key = reinterpret_cast<const unsigned char*>(publicKey.toUtf8().constData()); auto keyByteArray = publicKey.toUtf8();
auto key = keyByteArray.constData();
int keyLength = publicKey.length(); int keyLength = publicKey.length();
BIO *bio = BIO_new_mem_buf((void*)key, keyLength); BIO *bio = BIO_new_mem_buf((void*)key, keyLength);
@ -2531,19 +2532,23 @@ bool EntityItemProperties::verifySignature(const QString& publicKey, const QByte
// ECSDA verification prototype: note that type is currently ignored // ECSDA verification prototype: note that type is currently ignored
// int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, // int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
// const unsigned char *sig, int siglen, EC_KEY *eckey); // const unsigned char *sig, int siglen, EC_KEY *eckey);
bool answer = ECDSA_verify(0, int answer = ECDSA_verify(0,
digest, digest,
digestLength, digestLength,
signature, signature,
signatureLength, signatureLength,
ec); ec);
long error = ERR_get_error(); long error = ERR_get_error();
if (error != 0) { if (error != 0 || answer == -1) {
const char* error_str = ERR_error_string(error, NULL); qCWarning(entities) << "ERROR while verifying signature!"
qCWarning(entities) << "ERROR while verifying signature! EC error:" << error_str
<< "\nKey:" << publicKey << "\nutf8 Key Length:" << keyLength << "\nKey:" << publicKey << "\nutf8 Key Length:" << keyLength
<< "\nDigest:" << digest << "\nDigest Length:" << digestLength << "\nDigest:" << digest << "\nDigest Length:" << digestLength
<< "\nSignature:" << signature << "\nSignature Length:" << signatureLength; << "\nSignature:" << signature << "\nSignature Length:" << signatureLength;
while (error != 0) {
const char* error_str = ERR_error_string(error, NULL);
qCWarning(entities) << "EC error:" << error_str;
error = ERR_get_error();
}
} }
EC_KEY_free(ec); EC_KEY_free(ec);
if (bio) { if (bio) {
@ -2552,7 +2557,7 @@ bool EntityItemProperties::verifySignature(const QString& publicKey, const QByte
if (evp_key) { if (evp_key) {
EVP_PKEY_free(evp_key); EVP_PKEY_free(evp_key);
} }
return answer; return (answer == 1);
} else { } else {
if (bio) { if (bio) {
BIO_free(bio); BIO_free(bio);

View file

@ -1189,13 +1189,15 @@ bool EntityTree::verifyNonce(const QString& certID, const QString& nonce, Entity
key = sent.second; key = sent.second;
} }
QString annotatedKey = "-----BEGIN PUBLIC KEY-----\n" + key.insert(64, "\n") + "\n-----END PUBLIC KEY-----"; QString annotatedKey = "-----BEGIN PUBLIC KEY-----\n" + key.insert(64, "\n") + "\n-----END PUBLIC KEY-----\n";
bool verificationSuccess = EntityItemProperties::verifySignature(annotatedKey.toUtf8(), actualNonce.toUtf8(), nonce.toUtf8()); QByteArray hashedActualNonce = QCryptographicHash::hash(QByteArray(actualNonce.toUtf8()), QCryptographicHash::Sha256);
bool verificationSuccess = EntityItemProperties::verifySignature(annotatedKey.toUtf8(), hashedActualNonce, QByteArray::fromBase64(nonce.toUtf8()));
if (verificationSuccess) { if (verificationSuccess) {
qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded."; qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded.";
} else { } else {
qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed for nonce" << actualNonce << "key" << key << "signature" << nonce; qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed. Actual nonce:" << actualNonce <<
"\nHashed actual nonce (digest):" << hashedActualNonce << "\nSent nonce (signature)" << nonce << "\nKey" << key;
} }
return verificationSuccess; return verificationSuccess;

View file

@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityEdit: case PacketType::EntityEdit:
case PacketType::EntityData: case PacketType::EntityData:
case PacketType::EntityPhysics: case PacketType::EntityPhysics:
return static_cast<PacketVersion>(EntityVersion::HazeEffect); return static_cast<PacketVersion>(EntityVersion::OwnershipChallengeFix);
case PacketType::EntityQuery: case PacketType::EntityQuery:
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConnectionIdentifier); return static_cast<PacketVersion>(EntityQueryPacketVersion::ConnectionIdentifier);

View file

@ -199,7 +199,8 @@ QDebug operator<<(QDebug debug, const PacketType& type);
enum class EntityVersion : PacketVersion { enum class EntityVersion : PacketVersion {
StrokeColorProperty = 77, StrokeColorProperty = 77,
HasDynamicOwnershipTests, HasDynamicOwnershipTests,
HazeEffect HazeEffect,
OwnershipChallengeFix
}; };
enum class EntityScriptCallMethodVersion : PacketVersion { enum class EntityScriptCallMethodVersion : PacketVersion {