nsresult SRICheckDataVerifier::VerifyHash(const SRIMetadata& aMetadata, uint32_t aHashIndex, const nsACString& aSourceFileURI, nsIConsoleReportCollector* aReporter) { NS_ENSURE_ARG_POINTER(aReporter); nsAutoCString base64Hash; aMetadata.GetHash(aHashIndex, &base64Hash); SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u]=%s", aHashIndex, base64Hash.get())); nsAutoCString binaryHash; if (NS_WARN_IF(NS_FAILED(Base64Decode(base64Hash, binaryHash)))) { nsTArray<nsString> params; aReporter->AddConsoleReport(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("Sub-resource Integrity"), nsContentUtils::eSECURITY_PROPERTIES, aSourceFileURI, 0, 0, NS_LITERAL_CSTRING("InvalidIntegrityBase64"), const_cast<const nsTArray<nsString>&>(params)); return NS_ERROR_SRI_CORRUPT; } uint32_t hashLength; int8_t hashType; aMetadata.GetHashType(&hashType, &hashLength); if (binaryHash.Length() != hashLength) { nsTArray<nsString> params; aReporter->AddConsoleReport(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("Sub-resource Integrity"), nsContentUtils::eSECURITY_PROPERTIES, aSourceFileURI, 0, 0, NS_LITERAL_CSTRING("InvalidIntegrityLength"), const_cast<const nsTArray<nsString>&>(params)); return NS_ERROR_SRI_CORRUPT; } if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) { nsAutoCString encodedHash; nsresult rv = Base64Encode(mComputedHash, encodedHash); if (NS_SUCCEEDED(rv)) { SRILOG(("SRICheckDataVerifier::VerifyHash, mComputedHash=%s", encodedHash.get())); } } if (!binaryHash.Equals(mComputedHash)) { SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] did not match", aHashIndex)); return NS_ERROR_SRI_CORRUPT; } SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] verified successfully", aHashIndex)); return NS_OK; }
/** * Compute the hash of a sub-resource and compare it with the expected * value. */ static nsresult VerifyHash(const SRIMetadata& aMetadata, uint32_t aHashIndex, uint32_t aStringLen, const uint8_t* aString, const nsIDocument* aDocument) { NS_ENSURE_ARG_POINTER(aString); NS_ENSURE_ARG_POINTER(aDocument); nsAutoCString base64Hash; aMetadata.GetHash(aHashIndex, &base64Hash); SRILOG(("SRICheck::VerifyHash, hash[%u]=%s", aHashIndex, base64Hash.get())); nsAutoCString binaryHash; if (NS_WARN_IF(NS_FAILED(Base64Decode(base64Hash, binaryHash)))) { nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("Sub-resource Integrity"), aDocument, nsContentUtils::eSECURITY_PROPERTIES, "InvalidIntegrityBase64"); return NS_ERROR_SRI_CORRUPT; } uint32_t hashLength; int8_t hashType; aMetadata.GetHashType(&hashType, &hashLength); if (binaryHash.Length() != hashLength) { nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("Sub-resource Integrity"), aDocument, nsContentUtils::eSECURITY_PROPERTIES, "InvalidIntegrityLength"); return NS_ERROR_SRI_CORRUPT; } nsresult rv; nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance("@mozilla.org/security/hash;1", &rv); NS_ENSURE_SUCCESS(rv, rv); rv = cryptoHash->Init(hashType); NS_ENSURE_SUCCESS(rv, rv); rv = cryptoHash->Update(aString, aStringLen); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString computedHash; rv = cryptoHash->Finish(false, computedHash); NS_ENSURE_SUCCESS(rv, rv); if (!binaryHash.Equals(computedHash)) { SRILOG(("SRICheck::VerifyHash, hash[%u] did not match", aHashIndex)); return NS_ERROR_SRI_CORRUPT; } SRILOG(("SRICheck::VerifyHash, hash[%u] verified successfully", aHashIndex)); return NS_OK; }