+/*
+ * wrapper functions around the usign executable
+ * Copyright (C) 2018 Daniel Golle <daniel@makrotopia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "usign.h"
+#ifdef UCERT_HOST_BUILD
+#define USIGN_EXEC "usign"
+#else
+#define USIGN_EXEC "/usr/bin/usign"
+#endif
+
+/*
+ * check for revoker deadlink in pubkeydir
+ * return true if a revoker exists, false otherwise
+ */
+int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) {
+ char tml[64] = {0};
+ char rfname[256] = {0};
+
+ snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint);
+ if (readlink(rfname, tml, sizeof(tml)) > 0 &&
+ !strcmp(tml, ".revoked.")) {
+ return true;
+ };
+
+ return false;
+}
+
+#ifdef UCERT_FULL
+/*
+ * call usign -S ...
+ * return WEXITSTATUS or -1 if fork fails
+ */
int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
pid_t pid;
int status;
const char *usign_argv[16] = {0};
unsigned int usign_argc = 0;
- usign_argv[usign_argc++] = "/usr/bin/usign";
+ usign_argv[usign_argc++] = USIGN_EXEC;
usign_argv[usign_argc++] = "-S";
usign_argv[usign_argc++] = "-m";
usign_argv[usign_argc++] = msgfile;
return -1;
case 0:
- if (execv(usign_argv[0], usign_argv))
- return -1;
-
- break;
-
- default:
- waitpid(pid, &status, 0);
- return WEXITSTATUS(status);
+ execvp(usign_argv[0], (char *const *)usign_argv);
+ if (!quiet)
+ perror("Failed to execute usign");
+ _exit(1);
}
- return -1;
+ waitpid(pid, &status, 0);
+ return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}
-
-static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckeyfile, const char *sigfile) {
+#else
+int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
+ return -1;
+};
+#endif
+
+/*
+ * call usign -F ... and set fingerprint returned
+ * return WEXITSTATUS or -1 if fork fails
+ */
+static int usign_f(char fingerprint[17], const char *pubkeyfile, const char *seckeyfile, const char *sigfile, bool quiet) {
int fds[2];
+ FILE *f;
pid_t pid;
int status;
const char *usign_argv[16] = {0};
if (pipe(fds))
return -1;
- usign_argv[usign_argc++] = "/usr/bin/usign";
+ usign_argv[usign_argc++] = USIGN_EXEC;
usign_argv[usign_argc++] = "-F";
if (pubkeyfile) {
case 0:
dup2(fds[1], 1);
- close(0);
- close(2);
close(fds[0]);
close(fds[1]);
- if (execv(usign_argv[0], usign_argv))
- return -1;
+ execvp(usign_argv[0], (char *const *)usign_argv);
+ if (!quiet)
+ perror("Failed to execute usign");
+ _exit(1);
+ }
+
+ close(fds[1]);
- break;
+ waitpid(pid, &status, 0);
+ status = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
- default:
- waitpid(pid, &status, 0);
- if (fingerprint && !WEXITSTATUS(status)) {
- memset(fingerprint, 0, 16);
- read(fds[0], fingerprint, 16);
- fingerprint[16] = '\0';
- }
+ if (!fingerprint || status) {
close(fds[0]);
- close(fds[1]);
- return WEXITSTATUS(status);
+ return status;
}
- return -1;
-}
+ f = fdopen(fds[0], "r");
+ if (fread(fingerprint, 1, 16, f) != 16)
+ status = -1;
+ fclose(f);
+ if (status)
+ return status;
-int usign_f_pubkey(char *fingerprint, const char *pubkeyfile) {
- return usign_f(fingerprint, pubkeyfile, NULL, NULL);
-}
+ fingerprint[16] = '\0';
+ if (strspn(fingerprint, "0123456789abcdefABCDEF") != 16)
+ status = -1;
-int usign_f_seckey(char *fingerprint, const char *seckeyfile) {
- return usign_f(fingerprint, NULL, seckeyfile, NULL);
+ return status;
}
-int usign_f_sig(char *fingerprint, const char *sigfile) {
- return usign_f(fingerprint, NULL, NULL, sigfile);
+/*
+ * call usign -F -p ...
+ */
+int usign_f_pubkey(char fingerprint[17], const char *pubkeyfile, bool quiet) {
+ return usign_f(fingerprint, pubkeyfile, NULL, NULL, quiet);
}
-int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) {
- char tml[64] = {0};
- char rfname[256] = {0};
-
- snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint);
- if (readlink(rfname, tml, sizeof(tml)) > 0 &&
- !strcmp(tml, ".revoked.")) {
- return true;
- };
+/*
+ * call usign -F -s ...
+ */
+int usign_f_seckey(char fingerprint[17], const char *seckeyfile, bool quiet) {
+ return usign_f(fingerprint, NULL, seckeyfile, NULL, quiet);
+}
- return false;
+/*
+ * call usign -F -x ...
+ */
+int usign_f_sig(char fingerprint[17], const char *sigfile, bool quiet) {
+ return usign_f(fingerprint, NULL, NULL, sigfile, quiet);
}
+
+/*
+ * call usign -V ...
+ * return WEXITSTATUS or -1 if fork fails
+ */
int usign_v(const char *msgfile, const char *pubkeyfile,
const char *pubkeydir, const char *sigfile, bool quiet) {
pid_t pid;
unsigned int usign_argc = 0;
char fingerprint[17];
- if (usign_f_sig(fingerprint, sigfile))
+ if (usign_f_sig(fingerprint, sigfile, quiet)) {
+ if (!quiet)
+ fprintf(stderr, "cannot get signing key fingerprint\n");
return 1;
+ }
- if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir))
+ if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir)) {
+ if (!quiet)
+ fprintf(stderr, "key %s has been revoked!\n", fingerprint);
return 1;
-
- usign_argv[usign_argc++] = "/usr/bin/usign";
+ }
+ usign_argv[usign_argc++] = USIGN_EXEC;
usign_argv[usign_argc++] = "-V";
usign_argv[usign_argc++] = "-m";
usign_argv[usign_argc++] = msgfile;
return -1;
case 0:
- if (execv(usign_argv[0], usign_argv))
- return -1;
-
- break;
-
- default:
- waitpid(pid, &status, 0);
- return WEXITSTATUS(status);
+ execvp(usign_argv[0], (char *const *)usign_argv);
+ if (!quiet)
+ perror("Failed to execute usign");
+ _exit(1);
}
- return -1;
+ waitpid(pid, &status, 0);
+ return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}