socsvn commit: r289867 - soc2013/def/crashdump-head/sbin/cryptcore
def at FreeBSD.org
def at FreeBSD.org
Tue Aug 18 10:38:20 UTC 2015
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;
}
More information about the svn-soc-all
mailing list