- X509_KEYPAIR *keypair;
- DIGEST *digest = NULL;
- crypto_error_t err;
- uint64_t saved_bytes;
- crypto_digest_t signing_algorithm = have_sha2 ?
- CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
- crypto_digest_t algorithm;
- SIGNATURE *sig = rctx.sig;
-
-
- if (!jcr->crypto.pki_sign) {
- /*
- * no signature OK
- */
- return true;
- }
- if (!sig) {
- if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
- Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
- jcr->last_fname);
- goto bail_out;
- }
- return true;
- }
-
- /*
- * Iterate through the trusted signers
- */
- foreach_alist(keypair, jcr->crypto.pki_signers) {
- err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
- switch (err) {
- case CRYPTO_ERROR_NONE:
- Dmsg0(50, "== Got digest\n");
- /*
- * We computed jcr->crypto.digest using signing_algorithm while writing
- * the file. If it is not the same as the algorithm used for
- * this file, punt by releasing the computed algorithm and
- * computing by re-reading the file.
- */
- if (algorithm != signing_algorithm) {
- if (jcr->crypto.digest) {
- crypto_digest_free(jcr->crypto.digest);
- jcr->crypto.digest = NULL;
- }
- }
- if (jcr->crypto.digest) {
- /*
- * Use digest computed while writing the file to verify the signature
- */
- if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
- Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
- Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
- jcr->last_fname, crypto_strerror(err));
- goto bail_out;
- }
- } else {
- /*
- * Signature found, digest allocated. Old method,
- * re-read the file and compute the digest
- */
- jcr->crypto.digest = digest;
-
- /*
- * Checksum the entire file
- * Make sure we don't modify JobBytes by saving and restoring it
- */
- saved_bytes = jcr->JobBytes;
- if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) {
- Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
- jcr->last_fname);
- jcr->JobBytes = saved_bytes;
- goto bail_out;
- }
- jcr->JobBytes = saved_bytes;
-
- /*
- * Verify the signature
- */
- if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
- Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
- Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
- jcr->last_fname, crypto_strerror(err));
- goto bail_out;
- }
- jcr->crypto.digest = NULL;
- }
-
- /*
- * Valid signature
- */
- Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
- crypto_digest_free(digest);
- return true;
-
- case CRYPTO_ERROR_NOSIGNER:
- /*
- * Signature not found, try again
- */
- if (digest) {
- crypto_digest_free(digest);
- digest = NULL;
- }
- continue;
- default:
- /*
- * Something strange happened (that shouldn't happen!)...
- */
- Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
- goto bail_out;