From owner-svn-soc-all@freebsd.org Tue Aug 18 15:14:07 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E27A69BCB11 for ; Tue, 18 Aug 2015 15:14:06 +0000 (UTC) (envelope-from def@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C6DA036F for ; Tue, 18 Aug 2015 15:14:06 +0000 (UTC) (envelope-from def@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id t7IFE6Rq021996 for ; Tue, 18 Aug 2015 15:14:06 GMT (envelope-from def@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id t7IFE5L5021447 for svn-soc-all@FreeBSD.org; Tue, 18 Aug 2015 15:14:05 GMT (envelope-from def@FreeBSD.org) Date: Tue, 18 Aug 2015 15:14:05 GMT Message-Id: <201508181514.t7IFE5L5021447@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to def@FreeBSD.org using -f From: def@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289881 - soc2013/def/crashdump-head/sbin/cryptcore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Aug 2015 15:14:07 -0000 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 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 #include +#include +#include +#include +#include #include #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) {