#include <errno.h>
#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
#include <solv/transaction.h>
#include <pakfire/archive.h>
static int pakfire_transaction_verify(struct pakfire_transaction* transaction,
struct pakfire_package* pkg, struct pakfire_archive* archive) {
+ int r;
+
+ const char* nevra = pakfire_package_get_nevra(pkg);
+
// Nothing to do if this step does not have an archive
- if (!archive)
+ if (!archive) {
+ DEBUG(transaction->pakfire, "Package %s requires no archive\n", nevra);
return 0;
+ }
- pakfire_archive_verify_status_t status;
+ enum pakfire_digests digest_type = PAKFIRE_DIGEST_NONE;
- // Verify the archive
- int r = pakfire_archive_verify(archive, &status, NULL);
- if (r)
- return r;
+ // Fetch digest from package
+ const unsigned char* expected_digest = pakfire_package_get_digest(pkg, &digest_type);
+ if (!expected_digest) {
+ DEBUG(transaction->pakfire, "Package %s has no digest\n", nevra);
+ return 0;
+ }
- // This function will return a binary status which is zero for success and
- // anything else for errors, etc...
- switch (status) {
- // Good
- case PAKFIRE_ARCHIVE_VERIFY_OK:
- case PAKFIRE_ARCHIVE_VERIFY_KEY_EXPIRED:
- return 0;
+ unsigned char computed_digest[EVP_MAX_MD_SIZE];
+ size_t digest_length = 0;
- // Bad
- default:
- break;
+ // Compute digest of the archive
+ r = pakfire_archive_digest(archive, digest_type, computed_digest, &digest_length);
+ if (r) {
+ ERROR(transaction->pakfire, "Could not compute digest for %s: %m\n", nevra);
+ return r;
}
- return 1;
+ // Compare digests
+ r = CRYPTO_memcmp(computed_digest, expected_digest, digest_length);
+ if (r) {
+ ERROR(transaction->pakfire, "Digests of %s do not match\n", nevra);
+ return 1;
+ }
+
+ return 0;
}
static int pakfire_transaction_run_script(struct pakfire_transaction* transaction,