From ae186120d1e71a327434d743d4a6a84ea12460f5 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Thu, 20 Jun 2013 19:54:23 +0200 Subject: [PATCH] Restore of encrypted data fails when not all files are created. We should check if a file is actually extracted when checking if we encounter an unexpected STREAM_ENCRYPTED_SESSION_DATA. The rctx.cs is setup by a call to crypto_session_decode() and that session lingers until its teared down by close_previous_stream() but that only occurs when the next file is actually extracted. So if we extract one encrypted file and not the one after that the rctx.cs will not be cleared until we hit the next extracted file or the end of the restore. So we should only handle the session at all when we extract the file as otherwise it makes absolutely no sense to even consider the encrypted session data stream at all as we will be skipping the file extract anyway and skip all encrypted data blocks. Fixes #192: Restore of PKI encrypted data fails if some of the files should not be replaced --- src/filed/restore.c | 114 ++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/filed/restore.c b/src/filed/restore.c index 85b45fa7d3f..21a9b483a8d 100644 --- a/src/filed/restore.c +++ b/src/filed/restore.c @@ -622,72 +622,74 @@ void do_restore(JCR *jcr) /* * Data stream */ - case STREAM_ENCRYPTED_SESSION_DATA: + case STREAM_ENCRYPTED_SESSION_DATA: { crypto_error_t cryptoerr; - /* - * Is this an unexpected session data entry? - */ - if (rctx.cs) { - Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n")); - rctx.extract = false; - bclose(&rctx.bfd); - continue; - } - - /* - * Do we have any keys at all? - */ - if (!jcr->crypto.pki_recipients) { - Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n")); - rctx.extract = false; - bclose(&rctx.bfd); - break; - } - - if (jcr->crypto.digest) { - crypto_digest_free(jcr->crypto.digest); - } - jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm); - if (!jcr->crypto.digest) { - Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n")); - rctx.extract = false; - bclose(&rctx.bfd); - break; - } + if (rctx.extract) { + /* + * Is this an unexpected session data entry? + */ + if (rctx.cs) { + Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n")); + rctx.extract = false; + bclose(&rctx.bfd); + continue; + } - /* - * Decode and save session keys. - */ - cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, - jcr->crypto.pki_recipients, &rctx.cs); - switch(cryptoerr) { - case CRYPTO_ERROR_NONE: /* - * Success + * Do we have any keys at all? */ - break; - case CRYPTO_ERROR_NORECIPIENT: - Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n")); - break; - case CRYPTO_ERROR_DECRYPTION: - Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n")); - break; - default: + if (!jcr->crypto.pki_recipients) { + Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n")); + rctx.extract = false; + bclose(&rctx.bfd); + break; + } + + if (jcr->crypto.digest) { + crypto_digest_free(jcr->crypto.digest); + } + jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm); + if (!jcr->crypto.digest) { + Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n")); + rctx.extract = false; + bclose(&rctx.bfd); + break; + } + /* - * Shouldn't happen + * Decode and save session keys. */ - Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr)); - break; - } + cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, + jcr->crypto.pki_recipients, &rctx.cs); + switch(cryptoerr) { + case CRYPTO_ERROR_NONE: + /* + * Success + */ + break; + case CRYPTO_ERROR_NORECIPIENT: + Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n")); + break; + case CRYPTO_ERROR_DECRYPTION: + Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n")); + break; + default: + /* + * Shouldn't happen + */ + Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr)); + break; + } - if (cryptoerr != CRYPTO_ERROR_NONE) { - rctx.extract = false; - bclose(&rctx.bfd); - continue; + if (cryptoerr != CRYPTO_ERROR_NONE) { + rctx.extract = false; + bclose(&rctx.bfd); + continue; + } } - break; + } case STREAM_FILE_DATA: case STREAM_SPARSE_DATA: