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