1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5 Copyright (C) 2011-2012 Planets Communications B.V.
6 Copyright (C) 2013-2016 Bareos GmbH & Co. KG
7
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
11 in the file LICENSE.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23 /*
24 * Kern Sibbald, March MM
25 * Extracted from other source files by Marco van Wieringen, June 2011
26 */
27 /**
28 * @file
29 * Functions to handle cryptology
30 */
31
32 #include "include/bareos.h"
33 #include "filed/filed.h"
34 #include "filed/restore.h"
35 #include "findlib/find_one.h"
36 #include "lib/edit.h"
37
38 namespace filedaemon {
39
40 #ifdef HAVE_SHA2
41 const bool have_sha2 = true;
42 #else
43 const bool have_sha2 = false;
44 #endif
45
UnserCryptoPacketLen(RestoreCipherContext * ctx)46 static void UnserCryptoPacketLen(RestoreCipherContext *ctx)
47 {
48 unser_declare;
49 if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
50 UnserBegin(&ctx->buf[0], CRYPTO_LEN_SIZE);
51 unser_uint32(ctx->packet_len);
52 ctx->packet_len += CRYPTO_LEN_SIZE;
53 }
54 }
55
CryptoSessionStart(JobControlRecord * jcr,crypto_cipher_t cipher)56 bool CryptoSessionStart(JobControlRecord *jcr, crypto_cipher_t cipher)
57 {
58 /**
59 * Create encryption session data and a cached, DER-encoded session data
60 * structure. We use a single session key for each backup, so we'll encode
61 * the session data only once.
62 */
63 if (jcr->crypto.pki_encrypt) {
64 uint32_t size = 0;
65
66 /**
67 * Create per-job session encryption context
68 */
69 jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients);
70 if (!jcr->crypto.pki_session) {
71 Jmsg(jcr, M_FATAL, 0, _("Cannot create a new crypto session probably unsupported cipher configured.\n"));
72 return false;
73 }
74
75 /**
76 * Get the session data size
77 */
78 if (!CryptoSessionEncode(jcr->crypto.pki_session, (uint8_t *)0, &size)) {
79 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
80 return false;
81 }
82
83 /**
84 * Allocate buffer
85 */
86 jcr->crypto.pki_session_encoded = GetMemory(size);
87
88 /**
89 * Encode session data
90 */
91 if (!CryptoSessionEncode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) {
92 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
93 return false;
94 }
95
96 /**
97 * ... and store the encoded size
98 */
99 jcr->crypto.pki_session_encoded_size = size;
100
101 /**
102 * Allocate the encryption/decryption buffer
103 */
104 jcr->crypto.crypto_buf = GetMemory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
105 }
106
107 return true;
108 }
109
CryptoSessionEnd(JobControlRecord * jcr)110 void CryptoSessionEnd(JobControlRecord *jcr)
111 {
112 if (jcr->crypto.crypto_buf) {
113 FreePoolMemory(jcr->crypto.crypto_buf);
114 jcr->crypto.crypto_buf = NULL;
115 }
116 if (jcr->crypto.pki_session) {
117 CryptoSessionFree(jcr->crypto.pki_session);
118 }
119 if (jcr->crypto.pki_session_encoded) {
120 FreePoolMemory(jcr->crypto.pki_session_encoded);
121 jcr->crypto.pki_session_encoded = NULL;
122 }
123 }
124
CryptoSessionSend(JobControlRecord * jcr,BareosSocket * sd)125 bool CryptoSessionSend(JobControlRecord *jcr, BareosSocket *sd)
126 {
127 POOLMEM *msgsave;
128
129 /** Send our header */
130 Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
131 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
132
133 msgsave = sd->msg;
134 sd->msg = jcr->crypto.pki_session_encoded;
135 sd->message_length = jcr->crypto.pki_session_encoded_size;
136 jcr->JobBytes += sd->message_length;
137
138 Dmsg1(100, "Send data len=%d\n", sd->message_length);
139 sd->send();
140 sd->msg = msgsave;
141 sd->signal(BNET_EOD);
142 return true;
143 }
144
145 /**
146 * Verify the signature for the last restored file
147 * Return value is either true (signature correct)
148 * or false (signature could not be verified).
149 * TODO landonf: Implement without using FindOneFile and
150 * without re-reading the file.
151 */
VerifySignature(JobControlRecord * jcr,r_ctx & rctx)152 bool VerifySignature(JobControlRecord *jcr, r_ctx &rctx)
153 {
154 X509_KEYPAIR *keypair = nullptr;
155 DIGEST *digest = NULL;
156 crypto_error_t err;
157 uint64_t saved_bytes;
158 crypto_digest_t signing_algorithm = have_sha2 ?
159 CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
160 crypto_digest_t algorithm;
161 SIGNATURE *sig = rctx.sig;
162
163 if (!jcr->crypto.pki_sign) {
164 /*
165 * no signature OK
166 */
167 return true;
168 }
169 if (!sig) {
170 if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
171 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
172 jcr->last_fname);
173 goto bail_out;
174 }
175 return true;
176 }
177
178 /*
179 * Iterate through the trusted signers
180 */
181 foreach_alist(keypair, jcr->crypto.pki_signers) {
182 err = CryptoSignGetDigest(sig, jcr->crypto.pki_keypair, algorithm, &digest);
183 switch (err) {
184 case CRYPTO_ERROR_NONE:
185 Dmsg0(50, "== Got digest\n");
186 /*
187 * We computed jcr->crypto.digest using signing_algorithm while writing
188 * the file. If it is not the same as the algorithm used for
189 * this file, punt by releasing the computed algorithm and
190 * computing by re-reading the file.
191 */
192 if (algorithm != signing_algorithm) {
193 if (jcr->crypto.digest) {
194 CryptoDigestFree(jcr->crypto.digest);
195 jcr->crypto.digest = NULL;
196 }
197 }
198 if (jcr->crypto.digest) {
199 /*
200 * Use digest computed while writing the file to verify the signature
201 */
202 if ((err = CryptoSignVerify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) {
203 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
204 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
205 jcr->last_fname, crypto_strerror(err));
206 goto bail_out;
207 }
208 } else {
209 /*
210 * Signature found, digest allocated. Old method,
211 * re-read the file and compute the digest
212 */
213 jcr->crypto.digest = digest;
214
215 /*
216 * Checksum the entire file
217 * Make sure we don't modify JobBytes by saving and restoring it
218 */
219 saved_bytes = jcr->JobBytes;
220 if (FindOneFile(jcr, jcr->ff, DoFileDigest, jcr->last_fname, (dev_t)-1, 1) != 0) {
221 Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
222 jcr->last_fname);
223 jcr->JobBytes = saved_bytes;
224 goto bail_out;
225 }
226 jcr->JobBytes = saved_bytes;
227
228 /*
229 * Verify the signature
230 */
231 if ((err = CryptoSignVerify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
232 Dmsg1(50, "Bad signature on %s\n", jcr->last_fname);
233 Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"),
234 jcr->last_fname, crypto_strerror(err));
235 goto bail_out;
236 }
237 jcr->crypto.digest = NULL;
238 }
239
240 /*
241 * Valid signature
242 */
243 Dmsg1(50, "Signature good on %s\n", jcr->last_fname);
244 CryptoDigestFree(digest);
245 return true;
246
247 case CRYPTO_ERROR_NOSIGNER:
248 /*
249 * Signature not found, try again
250 */
251 if (digest) {
252 CryptoDigestFree(digest);
253 digest = NULL;
254 }
255 continue;
256 default:
257 /*
258 * Something strange happened (that shouldn't happen!)...
259 */
260 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
261 goto bail_out;
262 }
263 }
264
265 /*
266 * No signer
267 */
268 Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
269
270 bail_out:
271 if (digest) {
272 CryptoDigestFree(digest);
273 }
274 return false;
275 }
276
277 /**
278 * In the context of jcr, flush any remaining data from the cipher context,
279 * writing it to bfd.
280 * Return value is true on success, false on failure.
281 */
FlushCipher(JobControlRecord * jcr,BareosWinFilePacket * bfd,uint64_t * addr,char * flags,int32_t stream,RestoreCipherContext * cipher_ctx)282 bool FlushCipher(JobControlRecord *jcr, BareosWinFilePacket *bfd, uint64_t *addr, char *flags, int32_t stream, RestoreCipherContext *cipher_ctx)
283 {
284 uint32_t decrypted_len = 0;
285 char *wbuf; /* write buffer */
286 uint32_t wsize; /* write size */
287 char ec1[50]; /* Buffer printing huge values */
288 bool second_pass = false;
289
290 again:
291 /*
292 * Write out the remaining block and free the cipher context
293 */
294 cipher_ctx->buf = CheckPoolMemorySize(cipher_ctx->buf, cipher_ctx->buf_len +
295 cipher_ctx->block_size);
296
297 if (!CryptoCipherFinalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
298 &decrypted_len)) {
299 /*
300 * Writing out the final, buffered block failed. Shouldn't happen.
301 */
302 Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
303 cipher_ctx->buf_len, decrypted_len, jcr->last_fname);
304 }
305
306 Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
307 /*
308 * If nothing new was decrypted, and our output buffer is empty, return
309 */
310 if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
311 return true;
312 }
313
314 cipher_ctx->buf_len += decrypted_len;
315
316 UnserCryptoPacketLen(cipher_ctx);
317 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
318 wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
319 /*
320 * Decrypted, possibly decompressed output here.
321 */
322 wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE];
323 cipher_ctx->buf_len -= cipher_ctx->packet_len;
324 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
325
326 if (BitIsSet(FO_SPARSE, flags) || BitIsSet(FO_OFFSETS, flags)) {
327 if (!SparseData(jcr, bfd, addr, &wbuf, &wsize)) {
328 return false;
329 }
330 }
331
332 if (BitIsSet(FO_COMPRESS, flags)) {
333 if (!DecompressData(jcr, jcr->last_fname, stream, &wbuf, &wsize, false)) {
334 return false;
335 }
336 }
337
338 Dmsg0(130, "Call StoreData\n");
339 if (!StoreData(jcr, bfd, wbuf, wsize, BitIsSet(FO_WIN32DECOMP, flags))) {
340 return false;
341 }
342 jcr->JobBytes += wsize;
343 Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
344
345 /*
346 * Move any remaining data to start of buffer
347 */
348 if (cipher_ctx->buf_len > 0) {
349 Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
350 memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
351 cipher_ctx->buf_len);
352 }
353 /*
354 * The packet was successfully written, reset the length so that the next
355 * packet length may be re-read by UnserCryptoPacketLen()
356 */
357 cipher_ctx->packet_len = 0;
358
359 if (cipher_ctx->buf_len >0 && !second_pass) {
360 second_pass = true;
361 goto again;
362 }
363
364 /*
365 * Stop decryption
366 */
367 cipher_ctx->buf_len = 0;
368 cipher_ctx->packet_len = 0;
369
370 return true;
371 }
372
DeallocateCipher(r_ctx & rctx)373 void DeallocateCipher(r_ctx &rctx)
374 {
375 /*
376 * Flush and deallocate previous stream's cipher context
377 */
378 if (rctx.cipher_ctx.cipher) {
379 FlushCipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, rctx.comp_stream, &rctx.cipher_ctx);
380 CryptoCipherFree(rctx.cipher_ctx.cipher);
381 rctx.cipher_ctx.cipher = NULL;
382 }
383 }
384
DeallocateForkCipher(r_ctx & rctx)385 void DeallocateForkCipher(r_ctx &rctx)
386 {
387 /*
388 * Flush and deallocate previous stream's fork cipher context
389 */
390 if (rctx.fork_cipher_ctx.cipher) {
391 FlushCipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, rctx.comp_stream, &rctx.fork_cipher_ctx);
392 CryptoCipherFree(rctx.fork_cipher_ctx.cipher);
393 rctx.fork_cipher_ctx.cipher = NULL;
394 }
395 }
396
397 /**
398 * Setup a encryption context
399 */
SetupEncryptionContext(b_ctx & bctx)400 bool SetupEncryptionContext(b_ctx &bctx)
401 {
402 uint32_t cipher_block_size;
403 bool retval = false;
404
405 if (BitIsSet(FO_ENCRYPT, bctx.ff_pkt->flags)) {
406 if (BitIsSet(FO_SPARSE, bctx.ff_pkt->flags) ||
407 BitIsSet(FO_OFFSETS, bctx.ff_pkt->flags)) {
408 Jmsg0(bctx.jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
409 goto bail_out;
410 }
411 /*
412 * Allocate the cipher context
413 */
414 if ((bctx.cipher_ctx = crypto_cipher_new(bctx.jcr->crypto.pki_session, true,
415 &cipher_block_size)) == NULL) {
416 /*
417 * Shouldn't happen!
418 */
419 Jmsg0(bctx.jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
420 goto bail_out;
421 }
422
423 /*
424 * Grow the crypto buffer, if necessary.
425 * CryptoCipherUpdate() will buffer up to (cipher_block_size - 1).
426 * We grow crypto_buf to the maximum number of blocks that
427 * could be returned for the given read buffer size.
428 * (Using the larger of either rsize or max_compress_len)
429 */
430 bctx.jcr->crypto.crypto_buf = CheckPoolMemorySize(bctx.jcr->crypto.crypto_buf,
431 (MAX(bctx.jcr->buf_size + (int)sizeof(uint32_t), (int32_t)bctx.max_compress_len) +
432 cipher_block_size - 1) / cipher_block_size * cipher_block_size);
433
434 bctx.wbuf = bctx.jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
435 }
436
437 retval = true;
438
439 bail_out:
440 return retval;
441 }
442
443 /**
444 * Setup a decryption context
445 */
SetupDecryptionContext(r_ctx & rctx,RestoreCipherContext & rcctx)446 bool SetupDecryptionContext(r_ctx &rctx, RestoreCipherContext &rcctx)
447 {
448 if (!rctx.cs) {
449 Jmsg1(rctx.jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), rctx.jcr->last_fname);
450 return false;
451 }
452
453 if ((rcctx.cipher = crypto_cipher_new(rctx.cs, false, &rcctx.block_size)) == NULL) {
454 Jmsg1(rctx.jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), rctx.jcr->last_fname);
455 FreeSession(rctx);
456 return false;
457 }
458
459 return true;
460 }
461
EncryptData(b_ctx * bctx,bool * need_more_data)462 bool EncryptData(b_ctx *bctx, bool *need_more_data)
463 {
464 bool retval = false;
465 uint32_t initial_len = 0;
466
467 /*
468 * Note, here we prepend the current record length to the beginning
469 * of the encrypted data. This is because both sparse and compression
470 * restore handling want records returned to them with exactly the
471 * same number of bytes that were processed in the backup handling.
472 * That is, both are block filters rather than a stream. When doing
473 * compression, the compression routines may buffer data, so that for
474 * any one record compressed, when it is decompressed the same size
475 * will not be obtained. Of course, the buffered data eventually comes
476 * out in subsequent CryptoCipherUpdate() calls or at least
477 * when CryptoCipherFinalize() is called. Unfortunately, this
478 * "feature" of encryption enormously complicates the restore code.
479 */
480 ser_declare;
481
482 if (BitIsSet(FO_SPARSE, bctx->ff_pkt->flags) ||
483 BitIsSet(FO_OFFSETS, bctx->ff_pkt->flags)) {
484 bctx->cipher_input_len += OFFSET_FADDR_SIZE;
485 }
486
487 /*
488 * Encrypt the length of the input block
489 */
490 uint8_t packet_len[sizeof(uint32_t)];
491
492 SerBegin(packet_len, sizeof(uint32_t));
493 ser_uint32(bctx->cipher_input_len); /* store data len in begin of buffer */
494 Dmsg1(20, "Encrypt len=%d\n", bctx->cipher_input_len);
495
496 if (!CryptoCipherUpdate(bctx->cipher_ctx, packet_len, sizeof(packet_len),
497 (uint8_t *)bctx->jcr->crypto.crypto_buf, &initial_len)) {
498 /*
499 * Encryption failed. Shouldn't happen.
500 */
501 Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n"));
502 goto bail_out;
503 }
504
505 /*
506 * Encrypt the input block
507 */
508 if (CryptoCipherUpdate(bctx->cipher_ctx, bctx->cipher_input, bctx->cipher_input_len,
509 (uint8_t *)&bctx->jcr->crypto.crypto_buf[initial_len],
510 &bctx->encrypted_len)) {
511 if ((initial_len + bctx->encrypted_len) == 0) {
512 /*
513 * No full block of data available, read more data
514 */
515 *need_more_data = true;
516 goto bail_out;
517 }
518
519 Dmsg2(400, "encrypted len=%d unencrypted len=%d\n",
520 bctx->encrypted_len, bctx->jcr->store_bsock->message_length);
521
522 bctx->jcr->store_bsock->message_length = initial_len + bctx->encrypted_len; /* set encrypted length */
523 } else {
524 /*
525 * Encryption failed. Shouldn't happen.
526 */
527 Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n"));
528 goto bail_out;
529 }
530
531 retval = true;
532
533 bail_out:
534 return retval;
535 }
536
DecryptData(JobControlRecord * jcr,char ** data,uint32_t * length,RestoreCipherContext * cipher_ctx)537 bool DecryptData(JobControlRecord *jcr, char **data, uint32_t *length, RestoreCipherContext *cipher_ctx)
538 {
539 uint32_t decrypted_len = 0; /* Decryption output length */
540
541 ASSERT(cipher_ctx->cipher);
542
543 /*
544 * NOTE: We must implement block preserving semantics for the
545 * non-streaming compression and sparse code.
546 *
547 * Grow the crypto buffer, if necessary.
548 * CryptoCipherUpdate() will process only whole blocks,
549 * buffering the remaining input.
550 */
551 cipher_ctx->buf = CheckPoolMemorySize(cipher_ctx->buf,
552 cipher_ctx->buf_len + *length + cipher_ctx->block_size);
553
554 /*
555 * Decrypt the input block
556 */
557 if (!CryptoCipherUpdate(cipher_ctx->cipher,
558 (const u_int8_t *)*data,
559 *length,
560 (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len],
561 &decrypted_len)) {
562 /*
563 * Decryption failed. Shouldn't happen.
564 */
565 Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
566 goto bail_out;
567 }
568
569 if (decrypted_len == 0) {
570 /*
571 * No full block of encrypted data available, write more data
572 */
573 *length = 0;
574 return true;
575 }
576
577 Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, *length);
578
579 cipher_ctx->buf_len += decrypted_len;
580 *data = cipher_ctx->buf;
581
582 /*
583 * If one full preserved block is available, write it to disk,
584 * and then buffer any remaining data. This should be effecient
585 * as long as Bareos's block size is not significantly smaller than the
586 * encryption block size (extremely unlikely!)
587 */
588 UnserCryptoPacketLen(cipher_ctx);
589 Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
590
591 if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) {
592 /*
593 * No full preserved block is available.
594 */
595 *length = 0;
596 return true;
597 }
598
599 /*
600 * We have one full block, set up the filter input buffers
601 */
602 *length = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
603 *data = &((*data)[CRYPTO_LEN_SIZE]); /* Skip the block length header */
604 cipher_ctx->buf_len -= cipher_ctx->packet_len;
605 Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", *length, cipher_ctx->buf_len);
606
607 return true;
608
609 bail_out:
610 return false;
611 }
612 } /* namespace filedaemon */
613