socsvn commit: r289881 - soc2013/def/crashdump-head/sbin/cryptcore

def at FreeBSD.org def at FreeBSD.org
Tue Aug 18 15:14:07 UTC 2015


Author: def
Date: Tue Aug 18 15:14:05 2015
New Revision: 289881
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289881

Log:
  Generate a key in the capability mode.

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

Modified: soc2013/def/crashdump-head/sbin/cryptcore/Makefile
==============================================================================
--- soc2013/def/crashdump-head/sbin/cryptcore/Makefile	Tue Aug 18 14:54:29 2015	(r289880)
+++ soc2013/def/crashdump-head/sbin/cryptcore/Makefile	Tue Aug 18 15:14:05 2015	(r289881)
@@ -2,11 +2,13 @@
 
 SRCS=	${PROG}.c
 
-LIBADD=	crypto pjdlog
+LIBADD=	capsicum crypto nv pjdlog
 
 MAN=
 
 CFLAGS+=-I${.CURDIR}/../../sys
+CFLAGS+=-I${.CURDIR}/../../lib/libcapsicum
+CFLAGS+=-I${.CURDIR}/../../lib/libnv
 CFLAGS+=-I${.CURDIR}/../../lib/libpjdlog
 
 .include <bsd.prog.mk>

Modified: soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c
==============================================================================
--- soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c	Tue Aug 18 14:54:29 2015	(r289880)
+++ soc2013/def/crashdump-head/sbin/cryptcore/cryptcore.c	Tue Aug 18 15:14:05 2015	(r289881)
@@ -16,20 +16,16 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <libcapsicum.h>
+#include <libcapsicum_service.h>
+#include <libcapsicum_sysctl.h>
+#include <nv.h>
 #include <pjdlog.h>
 
 #define	CRYPTCORE_CMD_GENKEY	0x01
 #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)
 {
 
@@ -67,9 +63,44 @@
 	PJDLOG_ABORT("Parent process didn't handle the exit status of its child.");
 }
 
+static cap_channel_t *
+cryptcore_genkey_sandbox(cap_channel_t *capcas)
+{
+	cap_channel_t *capsysctl;
+	nvlist_t *limits;
+
+	capsysctl = cap_service_open(capcas, "system.sysctl");
+	if (capsysctl == NULL) {
+		pjdlog_errno(LOG_ERR, "Unable to open system.sysctl service");
+		goto failed;
+	}
+
+	limits = nvlist_create(0);
+	if (limits == NULL) {
+		pjdlog_error("Unable to create an nvlist.");
+		goto failed;
+	}
+	nvlist_add_number(limits, "security.ekcd.setup", CAP_SYSCTL_WRITE);
+	if (cap_limit_set(capsysctl, limits) == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to limit system.sysctl service");
+		goto failed;
+	}
+
+	if (cap_enter() == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to enter capability mode"); 
+		goto failed;
+	}
+
+	return (capsysctl);
+failed:
+	cap_close(capsysctl);
+	return (NULL);
+}
+
 static bool
 cryptcore_genkey(const char *pubkeyfile)
 {
+	cap_channel_t *capcas, *capsysctl;
 	FILE *fp;
 	struct kerneldumpsetup *kds;
 	RSA *pubkey;
@@ -79,6 +110,11 @@
 
 	PJDLOG_ASSERT(pubkeyfile != NULL);
 
+	capsysctl = NULL;
+	fp = NULL;
+	kds = NULL;
+	pubkey = NULL;
+
 	pid = fork();
 	if (pid == -1) {
 		pjdlog_errno(LOG_ERR, "Unable to create child process");
@@ -88,23 +124,39 @@
 	if (pid > 0)
 		return (wait_for_process(pid) == 0);
 
+	fp = fopen(pubkeyfile, "r");
+	if (fp == NULL) {
+		pjdlog_errno(LOG_ERR, "Unable to open %s", pubkeyfile);
+		goto failed;
+	}
+
+	capcas = cap_init();
+	if (capcas != NULL) {
+		capsysctl = cryptcore_genkey_sandbox(capcas);
+		if (capsysctl == NULL)
+			goto failed;
+	}
+	cap_close(capcas);
+
 	pubkey = RSA_new();
 	if (pubkey == NULL)
 		pjdlog_exitx(1, "Unable to allocate an RSA structure.");
 
-	fp = fopen(pubkeyfile, "r");
-	if (fp == NULL)
-		pjdlog_exit(1, "Unable to open %s", pubkeyfile);
 	pubkey = PEM_read_RSA_PUBKEY(fp, &pubkey, NULL, NULL);
 	fclose(fp);
-	if (pubkey == NULL)
-		pjdlog_exitx(1, "Unable to read data from %s.", pubkeyfile);
+	fp = NULL;
+	if (pubkey == NULL) {
+		pjdlog_error("Unable to read data from %s.", pubkeyfile);
+		goto failed;
+	}
 
 	pubkeysize = RSA_size(pubkey);
 	kdssize = sizeof(*kds) + pubkeysize;
 	kds = calloc(1, kdssize);
-	if (kds == NULL)
-		pjdlog_exit(1, "Unable to allocate kernel dump setup");
+	if (kds == NULL) {
+		pjdlog_errno(LOG_ERR, "Unable to allocate kernel dump setup");
+		goto failed;
+	}
 
 	arc4random_buf(kds->kds_key, sizeof(kds->kds_key));
 	if (RSA_public_encrypt(sizeof(kds->kds_key), kds->kds_key,
@@ -113,28 +165,54 @@
 		goto failed;
 	}
 	kds->kds_encryptedkeylen = pubkeysize;
+	RSA_free(pubkey);
+	pubkey = NULL;
 
 	/*
 	 * From this moment on keys have to be erased before exit.
 	 */
-	if (sysctlbyname("security.ekcd.setup", NULL, NULL,
-	    kds, kdssize) != 0) {
-		pjdlog_errno(LOG_ERR, "Unable to set key");
-		goto failed;
+	if (capsysctl != NULL) {
+		if (cap_sysctlbyname(capsysctl, "security.ekcd.setup", NULL,
+		    NULL, kds, kdssize) != 0) {
+			pjdlog_errno(LOG_ERR, "Unable to set key");
+			goto failed;
+		}
+	} else {
+		if (sysctlbyname("security.ekcd.setup", NULL, NULL,
+		    kds, kdssize) != 0) {
+			pjdlog_errno(LOG_ERR, "Unable to set key");
+			goto failed;
+		}
 	}
 
 	bzero(kds, kdssize);
 	free(kds);
-	RSA_free(pubkey);
+	cap_close(capsysctl);
 	exit(0);
 failed:
-	bzero(kds, kdssize);
+	if (fp != NULL)
+		fclose(fp);
+	if (kds != NULL)
+		bzero(kds, kdssize);
 	free(kds);
 	RSA_free(pubkey);
+	cap_close(capsysctl);
 	exit(1);
 }
 
 static bool
+cryptcore_decrypt_sandbox(void)
+{
+
+	if (cap_enter() == -1) {
+		pjdlog_errno(LOG_ERR, "Unable to enter capability mode"); 
+		return (false);
+	}
+
+	return (true);
+}
+
+static bool
 cryptcore_decrypt(const char *privkeyfile, const char *keyfile,
     const char *input, const char *output)
 {
@@ -190,7 +268,8 @@
 		goto failed;
 	}
 
-	sandbox();
+	if (!cryptcore_decrypt_sandbox())
+		goto failed;
 
 	privkey = RSA_new();
 	if (privkey == NULL) {


More information about the svn-soc-all mailing list