Skip to content

Commit

Permalink
Restore of encrypted data fails when not all files are created.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent a5b918a commit 42fd076
Showing 1 changed file with 58 additions and 56 deletions.
114 changes: 58 additions & 56 deletions src/filed/restore.c
Expand Up @@ -628,72 +628,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:
Expand Down

0 comments on commit 42fd076

Please sign in to comment.