Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Aug 2015 10:38:19 GMT
From:      def@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r289867 - soc2013/def/crashdump-head/sbin/cryptcore
Message-ID:  <201508181038.t7IAcJoq089518@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: def
Date: Tue Aug 18 10:38:18 2015
New Revision: 289867
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289867

Log:
  Decrypt a crash dump in the capability mode.

Modified:
  soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c

Modified: soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c
==============================================================================
--- soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c	Tue Aug 18 10:05:32 2015	(r289866)
+++ soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c	Tue Aug 18 10:38:18 2015	(r289867)
@@ -1,3 +1,4 @@
+#include <sys/capsicum.h>
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/kerneldump.h>
@@ -21,6 +22,14 @@
 #define	CRYPTCORE_CMD_DECRYPT	0x02
 
 static void
+sandbox(void)
+{
+
+	if (cap_enter() != 0)
+		pjdlog_exit(1, "Unable to enter capability mode");
+}
+
+static void
 usage(void)
 {
 
@@ -58,7 +67,7 @@
 	PJDLOG_ABORT("Parent process didn't handle the exit status of its child.");
 }
 
-static void
+static bool
 cryptcore_genkey(const char *pubkeyfile)
 {
 	FILE *fp;
@@ -107,13 +116,12 @@
 	bzero(kds, kdssize);
 	free(kds);
 	RSA_free(pubkey);
-
-	return;
+	return (true);
 failed:
 	bzero(kds, kdssize);
 	free(kds);
 	RSA_free(pubkey);
-	exit(1);
+	return (false);
 }
 
 static bool
@@ -125,7 +133,7 @@
 	FILE *fp;
 	struct kerneldumpkey *kdk;
 	RSA *privkey;
-	int err, fd, ofd, olen, privkeysize;
+	int error, ifd, kfd, ofd, olen, privkeysize;
 	ssize_t bytes, size;
 	size_t bufused;
 	pid_t pid;
@@ -135,57 +143,85 @@
 	PJDLOG_ASSERT(input != NULL);
 	PJDLOG_ASSERT(output != NULL);
 
+	fp = NULL;
+	ifd = -1;
+	kdk = NULL;
+	kfd = -1;
+	ofd = -1;
+	privkey = NULL;
+
 	pid = fork();
 	if (pid == -1) {
-		pjdlog_exit(1, "Unable to create child process");
+		pjdlog_errno(LOG_ERR, "Unable to create child process");
 		return (false);
 	}
 
 	if (pid > 0)
 		return (wait_for_process(pid) == 0);
 
-	ofd = -1;
-	fd = -1;
+	kfd = open(keyfile, O_RDONLY);
+	if (kfd == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to open %s", keyfile);
+		goto failed;
+	}
+	ifd = open(input, O_RDONLY);
+	if (ifd == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to open %s", input);
+		goto failed;
+	}
+	ofd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+	if (ofd == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to open %s", output);
+		goto failed;
+	}
+	fp = fopen(privkeyfile, "r");
+	if (fp == NULL) {
+		pjdlog_errno(LOG_ERR, "Unable to open %s", privkeyfile);
+		goto failed;
+	}
+
+	sandbox();
 
 	privkey = RSA_new();
-	if (privkey == NULL)
-		pjdlog_exitx(1, "Unable to allocate an RSA structure.");
+	if (privkey == NULL) {
+		pjdlog_error("Unable to allocate an RSA structure.");
+		goto failed;
+	}
 	EVP_CIPHER_CTX_init(&ctx);
 
 	kdk = calloc(1, sizeof(*kdk));
-	if (kdk == NULL)
-		pjdlog_exit(1, "Unable to allocate kernel dump key");
+	if (kdk == NULL) {
+		pjdlog_errno(LOG_ERR, "Unable to allocate kernel dump key");
+		goto failed;
+	}
 
-	fd = open(keyfile, O_RDONLY);
-	if (fd == -1)
-		pjdlog_exit(1, "Unable to open %s", keyfile);
-	size = read(fd, kdk, sizeof(*kdk));
+	size = read(kfd, kdk, sizeof(*kdk));
 	if (size == (ssize_t)sizeof(*kdk)) {
 		kdk = realloc(kdk, kdk->kdk_size);
-		if (kdk == NULL)
-			pjdlog_exit(1, "Unable to reallocate kernel dump key");
-		size += read(fd, &kdk->kdk_encryptedkey,
+		if (kdk == NULL) {
+			pjdlog_errno(LOG_ERR, "Unable to reallocate kernel dump key");
+			goto failed;
+		}
+		size += read(kfd, &kdk->kdk_encryptedkey,
 		    kdk->kdk_size - sizeof(*kdk));
 	}
-	err = errno;
-	close(fd);
-	fd = -1;
+	error = errno;
+	close(kfd);
+	kfd = -1;
 	if (size != (ssize_t)kdk->kdk_size) {
-		errno = err;
-		pjdlog_exit(1, "Unable to read data from %s", keyfile);
+		errno = error;
+		pjdlog_errno(LOG_ERR, "Unable to read data from %s", keyfile);
+		goto failed;
 	}
 
-	fp = fopen(privkeyfile, "r");
-	if (fp == NULL)
-		pjdlog_exit(1, "Unable to open %s", privkeyfile);
 	privkey = PEM_read_RSAPrivateKey(fp, &privkey, NULL, NULL);
 	fclose(fp);
-	if (privkey == NULL)
-		pjdlog_exitx(1, "Unable to read data from %s.", privkeyfile);
+	fp = NULL;
+	if (privkey == NULL) {
+		pjdlog_error("Unable to read data from %s.", privkeyfile);
+		goto failed;
+	}
 
-	/*
-	 * From this moment on keys have to be erased before exit.
-	 */
 	privkeysize = RSA_size(privkey);
 	if (privkeysize != (int)kdk->kdk_encryptedkeylen) {
 		pjdlog_error("RSA modulus size mismatch: equals %db and should be %ub.",
@@ -197,24 +233,15 @@
 		pjdlog_error("Unable to decrypt key.");
 		goto failed;
 	}
-
-	fd = open(input, O_RDONLY);
-	if (fd == -1) {
-		pjdlog_errno(LOG_ERR, "Unable to open %s", input);
-		goto failed;
-	}
-	ofd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-	if (ofd == -1) {
-		pjdlog_errno(LOG_ERR, "Unable to open %s", output);
-		goto failed;
-	}
+	RSA_free(privkey);
+	privkey = NULL;
 
 	EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, kdk->kdk_iv);
 	EVP_CIPHER_CTX_set_key_length(&ctx, sizeof(key));
 	EVP_CIPHER_CTX_set_padding(&ctx, 0);
 
 	bufused = 0;
-	while ((bytes = read(fd, buf + bufused, sizeof(buf) - bufused)) > 0) {
+	while ((bytes = read(ifd, buf + bufused, sizeof(buf) - bufused)) > 0) {
 		bufused += bytes;
 		if (bufused != sizeof(buf))
 			continue;
@@ -238,23 +265,26 @@
 		goto failed;
 	}
 
+	close(ofd);
+	close(ifd);
 	bzero(key, sizeof(key));
 	bzero(buf, sizeof(buf));
 	EVP_CIPHER_CTX_cleanup(&ctx);
-	RSA_free(privkey);
-
-	close(ofd);
-	close(fd);
-
+	free(kdk);
 	exit(0);
 failed:
 	if (ofd >= 0)
 		close(ofd);
-	if (fd >= 0)
-		close(fd);
+	if (ifd >= 0)
+		close(kfd);
+	if (kfd >= 0)
+		close(kfd);
+	if (fp != NULL)
+		fclose(fp);
 	bzero(key, sizeof(key));
 	bzero(buf, sizeof(buf));
 	EVP_CIPHER_CTX_cleanup(&ctx);
+	free(kdk);
 	RSA_free(privkey);
 	exit(1);
 }
@@ -338,12 +368,14 @@
 
 	switch (cmd) {
 	case CRYPTCORE_CMD_GENKEY:
-		cryptcore_genkey(rsakeyfile);
+		if (!cryptcore_genkey(rsakeyfile))
+			exit(1);
 		break;
 	case CRYPTCORE_CMD_DECRYPT:
 		if (!cryptcore_decrypt(rsakeyfile, keyfile, input, output)) {
 			if (unlink(output) != 0)
 				pjdlog_exit(1, "Unable to remove output");
+			exit(1);
 		}
 		break;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508181038.t7IAcJoq089518>