add comments and license headers
[project/ucert.git] / usign-exec.c
1 /*
2 * wrapper functions around the usign executable
3 * Copyright (C) 2018 Daniel Golle <daniel@makrotopia.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15 #include <stdbool.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <sys/wait.h>
20
21 #include "usign.h"
22
23 int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
24 pid_t pid;
25 int status;
26 const char *usign_argv[16] = {0};
27 unsigned int usign_argc = 0;
28
29 usign_argv[usign_argc++] = "/usr/bin/usign";
30 usign_argv[usign_argc++] = "-S";
31 usign_argv[usign_argc++] = "-m";
32 usign_argv[usign_argc++] = msgfile;
33 usign_argv[usign_argc++] = "-s";
34 usign_argv[usign_argc++] = seckeyfile;
35 usign_argv[usign_argc++] = "-x";
36 usign_argv[usign_argc++] = sigfile;
37
38 if (quiet)
39 usign_argv[usign_argc++] = "-q";
40
41 pid = fork();
42 switch (pid) {
43 case -1:
44 return -1;
45
46 case 0:
47 if (execv(usign_argv[0], usign_argv))
48 return -1;
49
50 break;
51
52 default:
53 waitpid(pid, &status, 0);
54 return WEXITSTATUS(status);
55 }
56
57 return -1;
58 }
59
60 static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckeyfile, const char *sigfile) {
61 int fds[2];
62 pid_t pid;
63 int status;
64 const char *usign_argv[16] = {0};
65 unsigned int usign_argc = 0;
66
67 if (pipe(fds))
68 return -1;
69
70 usign_argv[usign_argc++] = "/usr/bin/usign";
71 usign_argv[usign_argc++] = "-F";
72
73 if (pubkeyfile) {
74 usign_argv[usign_argc++] = "-p";
75 usign_argv[usign_argc++] = pubkeyfile;
76 }
77
78 if (seckeyfile) {
79 usign_argv[usign_argc++] = "-s";
80 usign_argv[usign_argc++] = seckeyfile;
81 }
82
83 if (sigfile) {
84 usign_argv[usign_argc++] = "-x";
85 usign_argv[usign_argc++] = sigfile;
86 }
87
88 pid = fork();
89 switch (pid) {
90 case -1:
91 return -1;
92
93 case 0:
94 dup2(fds[1], 1);
95
96 close(0);
97 close(2);
98 close(fds[0]);
99 close(fds[1]);
100
101 if (execv(usign_argv[0], usign_argv))
102 return -1;
103
104 break;
105
106 default:
107 waitpid(pid, &status, 0);
108 if (fingerprint && !WEXITSTATUS(status)) {
109 memset(fingerprint, 0, 16);
110 read(fds[0], fingerprint, 16);
111 fingerprint[16] = '\0';
112 }
113 close(fds[0]);
114 close(fds[1]);
115 return WEXITSTATUS(status);
116 }
117
118 return -1;
119 }
120
121 int usign_f_pubkey(char *fingerprint, const char *pubkeyfile) {
122 return usign_f(fingerprint, pubkeyfile, NULL, NULL);
123 }
124
125 int usign_f_seckey(char *fingerprint, const char *seckeyfile) {
126 return usign_f(fingerprint, NULL, seckeyfile, NULL);
127 }
128
129 int usign_f_sig(char *fingerprint, const char *sigfile) {
130 return usign_f(fingerprint, NULL, NULL, sigfile);
131 }
132
133 int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) {
134 char tml[64] = {0};
135 char rfname[256] = {0};
136
137 snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint);
138 if (readlink(rfname, tml, sizeof(tml)) > 0 &&
139 !strcmp(tml, ".revoked.")) {
140 return true;
141 };
142
143 return false;
144 }
145
146 int usign_v(const char *msgfile, const char *pubkeyfile,
147 const char *pubkeydir, const char *sigfile, bool quiet) {
148 pid_t pid;
149 int status;
150 const char *usign_argv[16] = {0};
151 unsigned int usign_argc = 0;
152 char fingerprint[17];
153
154 if (usign_f_sig(fingerprint, sigfile))
155 return 1;
156
157 if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir))
158 return 1;
159
160 usign_argv[usign_argc++] = "/usr/bin/usign";
161 usign_argv[usign_argc++] = "-V";
162 usign_argv[usign_argc++] = "-m";
163 usign_argv[usign_argc++] = msgfile;
164
165 if (quiet)
166 usign_argv[usign_argc++] = "-q";
167
168 if (pubkeyfile) {
169 usign_argv[usign_argc++] = "-p";
170 usign_argv[usign_argc++] = pubkeyfile;
171 }
172
173 if (pubkeydir) {
174 usign_argv[usign_argc++] = "-P";
175 usign_argv[usign_argc++] = pubkeydir;
176 }
177
178 if (sigfile) {
179 usign_argv[usign_argc++] = "-x";
180 usign_argv[usign_argc++] = sigfile;
181 }
182
183 pid = fork();
184 switch (pid) {
185 case -1:
186 return -1;
187
188 case 0:
189 if (execv(usign_argv[0], usign_argv))
190 return -1;
191
192 break;
193
194 default:
195 waitpid(pid, &status, 0);
196 return WEXITSTATUS(status);
197 }
198
199 return -1;
200 }