mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 13:40:02 +02:00
refactor
This commit is contained in:
parent
899999a4c6
commit
abf41300dd
4 changed files with 23 additions and 92 deletions
|
@ -2505,28 +2505,25 @@ QByteArray EntityItemProperties::getStaticCertificateHash() const {
|
||||||
return QCryptographicHash::hash(getStaticCertificateJSON(), QCryptographicHash::Sha256);
|
return QCryptographicHash::hash(getStaticCertificateJSON(), QCryptographicHash::Sha256);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItemProperties::verifyStaticCertificateProperties() {
|
// FIXME: This is largely copied from EntityItemProperties::verifyStaticCertificateProperties, which should be refactored to use this.
|
||||||
// True IIF a non-empty certificateID matches the static certificate json.
|
// I also don't like the nested-if style, but for this step I'm deliberately preserving the similarity.
|
||||||
// I.e., if we can verify that the certificateID was produced by High Fidelity signing the static certificate hash.
|
bool EntityItemProperties::verifySignature(const QString& publicKey, const QByteArray& digestByteArray, const QByteArray& signatureByteArray) {
|
||||||
|
|
||||||
if (getCertificateID().isEmpty()) {
|
if (digestByteArray.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray marketplacePublicKeyByteArray = EntityItem::_marketplacePublicKey.toUtf8();
|
const unsigned char* key = reinterpret_cast<const unsigned char*>(publicKey.toUtf8().constData());
|
||||||
const unsigned char* marketplacePublicKey = reinterpret_cast<const unsigned char*>(marketplacePublicKeyByteArray.constData());
|
int keyLength = publicKey.length();
|
||||||
int marketplacePublicKeyLength = marketplacePublicKeyByteArray.length();
|
|
||||||
|
|
||||||
BIO *bio = BIO_new_mem_buf((void*)marketplacePublicKey, marketplacePublicKeyLength);
|
BIO *bio = BIO_new_mem_buf((void*)key, keyLength);
|
||||||
EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
||||||
if (evp_key) {
|
if (evp_key) {
|
||||||
EC_KEY* ec = EVP_PKEY_get1_EC_KEY(evp_key);
|
EC_KEY* ec = EVP_PKEY_get1_EC_KEY(evp_key);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
const QByteArray digestByteArray = getStaticCertificateHash();
|
|
||||||
const unsigned char* digest = reinterpret_cast<const unsigned char*>(digestByteArray.constData());
|
const unsigned char* digest = reinterpret_cast<const unsigned char*>(digestByteArray.constData());
|
||||||
int digestLength = digestByteArray.length();
|
int digestLength = digestByteArray.length();
|
||||||
|
|
||||||
const QByteArray signatureByteArray = QByteArray::fromBase64(getCertificateID().toUtf8());
|
|
||||||
const unsigned char* signature = reinterpret_cast<const unsigned char*>(signatureByteArray.constData());
|
const unsigned char* signature = reinterpret_cast<const unsigned char*>(signatureByteArray.constData());
|
||||||
int signatureLength = signatureByteArray.length();
|
int signatureLength = signatureByteArray.length();
|
||||||
|
|
||||||
|
@ -2543,9 +2540,8 @@ bool EntityItemProperties::verifyStaticCertificateProperties() {
|
||||||
long error = ERR_get_error();
|
long error = ERR_get_error();
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
const char* error_str = ERR_error_string(error, NULL);
|
||||||
qCWarning(entities) << "ERROR while verifying static certificate properties! EC error:" << error_str
|
qCWarning(entities) << "ERROR while verifying signature! EC error:" << error_str
|
||||||
<< "\nStatic Cert JSON:" << getStaticCertificateJSON()
|
<< "\nKey:" << publicKey << "\nutf8 Key Length:" << keyLength
|
||||||
<< "\nKey:" << EntityItem::_marketplacePublicKey << "\nKey Length:" << marketplacePublicKeyLength
|
|
||||||
<< "\nDigest:" << digest << "\nDigest Length:" << digestLength
|
<< "\nDigest:" << digest << "\nDigest Length:" << digestLength
|
||||||
<< "\nSignature:" << signature << "\nSignature Length:" << signatureLength;
|
<< "\nSignature:" << signature << "\nSignature Length:" << signatureLength;
|
||||||
}
|
}
|
||||||
|
@ -2557,7 +2553,8 @@ bool EntityItemProperties::verifyStaticCertificateProperties() {
|
||||||
EVP_PKEY_free(evp_key);
|
EVP_PKEY_free(evp_key);
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (bio) {
|
if (bio) {
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
}
|
}
|
||||||
|
@ -2566,16 +2563,23 @@ bool EntityItemProperties::verifyStaticCertificateProperties() {
|
||||||
}
|
}
|
||||||
long error = ERR_get_error();
|
long error = ERR_get_error();
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
const char* error_str = ERR_error_string(error, NULL);
|
||||||
qCWarning(entities) << "Failed to verify static certificate properties! EC error:" << error_str;
|
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC key error:" << error_str;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (bio) {
|
if (bio) {
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
}
|
}
|
||||||
long error = ERR_get_error();
|
long error = ERR_get_error();
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
const char* error_str = ERR_error_string(error, NULL);
|
||||||
qCWarning(entities) << "Failed to verify static certificate properties! EC error:" << error_str;
|
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC PEM error:" << error_str;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItemProperties::verifyStaticCertificateProperties() {
|
||||||
|
// True IIF a non-empty certificateID matches the static certificate json.
|
||||||
|
// I.e., if we can verify that the certificateID was produced by High Fidelity signing the static certificate hash.
|
||||||
|
return verifySignature(EntityItem::_marketplacePublicKey, getStaticCertificateHash(), QByteArray::fromBase64(getCertificateID().toUtf8()));
|
||||||
|
}
|
||||||
|
|
|
@ -339,6 +339,7 @@ public:
|
||||||
QByteArray getStaticCertificateJSON() const;
|
QByteArray getStaticCertificateJSON() const;
|
||||||
QByteArray getStaticCertificateHash() const;
|
QByteArray getStaticCertificateHash() const;
|
||||||
bool verifyStaticCertificateProperties();
|
bool verifyStaticCertificateProperties();
|
||||||
|
static bool verifySignature(const QString& key, const QByteArray& text, const QByteArray& signature);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString getCollisionMaskAsString() const;
|
QString getCollisionMaskAsString() const;
|
||||||
|
|
|
@ -1190,7 +1190,7 @@ bool EntityTree::verifyNonce(const QString& certID, const QString& nonce, Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
QString annotatedKey = "-----BEGIN PUBLIC KEY-----\n" + key + "\n-----END PUBLIC KEY-----";
|
QString annotatedKey = "-----BEGIN PUBLIC KEY-----\n" + key + "\n-----END PUBLIC KEY-----";
|
||||||
bool verificationSuccess = verifySignature(annotatedKey.toUtf8(), actualNonce.toUtf8(), nonce.toUtf8());
|
bool verificationSuccess = EntityItemProperties::verifySignature(annotatedKey.toUtf8(), actualNonce.toUtf8(), nonce.toUtf8());
|
||||||
|
|
||||||
if (verificationSuccess) {
|
if (verificationSuccess) {
|
||||||
qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded.";
|
qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded.";
|
||||||
|
@ -1201,79 +1201,6 @@ bool EntityTree::verifyNonce(const QString& certID, const QString& nonce, Entity
|
||||||
return verificationSuccess;
|
return verificationSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This is largely copied from EntityItemProperties::verifyStaticCertificateProperties, which should be refactored to use this.
|
|
||||||
// I also don't like the nested-if style, but for this step I'm deliberately preserving the similarity.
|
|
||||||
bool EntityTree::verifySignature(const QString& publicKey, const QByteArray& digestByteArray, const QByteArray& signatureByteArray) {
|
|
||||||
|
|
||||||
if (digestByteArray.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned char* key = reinterpret_cast<const unsigned char*>(publicKey.toUtf8().constData());
|
|
||||||
int keyLength = publicKey.length();
|
|
||||||
|
|
||||||
BIO *bio = BIO_new_mem_buf((void*)key, keyLength);
|
|
||||||
EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
if (evp_key) {
|
|
||||||
EC_KEY* ec = EVP_PKEY_get1_EC_KEY(evp_key);
|
|
||||||
if (ec) {
|
|
||||||
const unsigned char* digest = reinterpret_cast<const unsigned char*>(digestByteArray.constData());
|
|
||||||
int digestLength = digestByteArray.length();
|
|
||||||
|
|
||||||
const unsigned char* signature = reinterpret_cast<const unsigned char*>(signatureByteArray.constData());
|
|
||||||
int signatureLength = signatureByteArray.length();
|
|
||||||
|
|
||||||
ERR_clear_error();
|
|
||||||
// ECSDA verification prototype: note that type is currently ignored
|
|
||||||
// int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
|
|
||||||
// const unsigned char *sig, int siglen, EC_KEY *eckey);
|
|
||||||
bool answer = ECDSA_verify(0,
|
|
||||||
digest,
|
|
||||||
digestLength,
|
|
||||||
signature,
|
|
||||||
signatureLength,
|
|
||||||
ec);
|
|
||||||
long error = ERR_get_error();
|
|
||||||
if (error != 0) {
|
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
|
||||||
qCWarning(entities) << "ERROR while verifying signature! EC error:" << error_str
|
|
||||||
<< "\nKey:" << publicKey << "\nutf8 Key Length:" << keyLength
|
|
||||||
<< "\nDigest:" << digest << "\nDigest Length:" << digestLength
|
|
||||||
<< "\nSignature:" << signature << "\nSignature Length:" << signatureLength;
|
|
||||||
}
|
|
||||||
EC_KEY_free(ec);
|
|
||||||
if (bio) {
|
|
||||||
BIO_free(bio);
|
|
||||||
}
|
|
||||||
if (evp_key) {
|
|
||||||
EVP_PKEY_free(evp_key);
|
|
||||||
}
|
|
||||||
return answer;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (bio) {
|
|
||||||
BIO_free(bio);
|
|
||||||
}
|
|
||||||
if (evp_key) {
|
|
||||||
EVP_PKEY_free(evp_key);
|
|
||||||
}
|
|
||||||
long error = ERR_get_error();
|
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
|
||||||
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC key error:" << error_str;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (bio) {
|
|
||||||
BIO_free(bio);
|
|
||||||
}
|
|
||||||
long error = ERR_get_error();
|
|
||||||
const char* error_str = ERR_error_string(error, NULL);
|
|
||||||
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC PEM error:" << error_str;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityTree::processChallengeOwnershipRequestPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) {
|
void EntityTree::processChallengeOwnershipRequestPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) {
|
||||||
int certIDByteArraySize;
|
int certIDByteArraySize;
|
||||||
int textByteArraySize;
|
int textByteArraySize;
|
||||||
|
|
|
@ -277,7 +277,6 @@ public:
|
||||||
|
|
||||||
QByteArray computeNonce(const QString& certID, const QString ownerKey);
|
QByteArray computeNonce(const QString& certID, const QString ownerKey);
|
||||||
bool verifyNonce(const QString& certID, const QString& nonce, EntityItemID& id);
|
bool verifyNonce(const QString& certID, const QString& nonce, EntityItemID& id);
|
||||||
static bool verifySignature(const QString& key, const QByteArray& text, const QByteArray& signature);
|
|
||||||
|
|
||||||
void setMyAvatar(std::shared_ptr<AvatarData> myAvatar) { _myAvatar = myAvatar; }
|
void setMyAvatar(std::shared_ptr<AvatarData> myAvatar) { _myAvatar = myAvatar; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue