take care of revokers in verify path
[oweals/ucert.git] / usign-exec.c
1 #include <stdbool.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/wait.h>
6
7 #include "usign.h"
8
9 int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
10         pid_t pid;
11         int status;
12         const char *usign_argv[16] = {0};
13         unsigned int usign_argc = 0;
14
15         usign_argv[usign_argc++] = "/usr/bin/usign";
16         usign_argv[usign_argc++] = "-S";
17         usign_argv[usign_argc++] = "-m";
18         usign_argv[usign_argc++] = msgfile;
19         usign_argv[usign_argc++] = "-s";
20         usign_argv[usign_argc++] = seckeyfile;
21         usign_argv[usign_argc++] = "-x";
22         usign_argv[usign_argc++] = sigfile;
23
24         if (quiet)
25                 usign_argv[usign_argc++] = "-q";
26
27         pid = fork();
28         switch (pid) {
29         case -1:
30                 return -1;
31
32         case 0:
33                 if (execv(usign_argv[0], usign_argv))
34                         return -1;
35
36                 break;
37
38         default:
39                 waitpid(pid, &status, 0);
40                 return WEXITSTATUS(status);
41         }
42
43         return -1;
44 }
45
46 static int usign_f(char *fingerprint, const char *pubkeyfile, const char *seckeyfile, const char *sigfile) {
47         int fds[2];
48         pid_t pid;
49         int status;
50         const char *usign_argv[16] = {0};
51         unsigned int usign_argc = 0;
52
53         if (pipe(fds))
54                 return -1;
55
56         usign_argv[usign_argc++] = "/usr/bin/usign";
57         usign_argv[usign_argc++] = "-F";
58
59         if (pubkeyfile) {
60                 usign_argv[usign_argc++] = "-p";
61                 usign_argv[usign_argc++] = pubkeyfile;
62         }
63
64         if (seckeyfile) {
65                 usign_argv[usign_argc++] = "-s";
66                 usign_argv[usign_argc++] = seckeyfile;
67         }
68
69         if (sigfile) {
70                 usign_argv[usign_argc++] = "-x";
71                 usign_argv[usign_argc++] = sigfile;
72         }
73
74         pid = fork();
75         switch (pid) {
76         case -1:
77                 return -1;
78
79         case 0:
80                 dup2(fds[1], 1);
81
82                 close(0);
83                 close(2);
84                 close(fds[0]);
85                 close(fds[1]);
86
87                 if (execv(usign_argv[0], usign_argv))
88                         return -1;
89
90                 break;
91
92         default:
93                 waitpid(pid, &status, 0);
94                 if (fingerprint && !WEXITSTATUS(status)) {
95                         memset(fingerprint, 0, 16);
96                         read(fds[0], fingerprint, 16);
97                         fingerprint[16] = '\0';
98                 }
99                 close(fds[0]);
100                 close(fds[1]);
101                 return WEXITSTATUS(status);
102         }
103
104         return -1;
105 }
106
107 int usign_f_pubkey(char *fingerprint, const char *pubkeyfile) {
108         return usign_f(fingerprint, pubkeyfile, NULL, NULL);
109 }
110
111 int usign_f_seckey(char *fingerprint, const char *seckeyfile) {
112         return usign_f(fingerprint, NULL, seckeyfile, NULL);
113 }
114
115 int usign_f_sig(char *fingerprint, const char *sigfile) {
116         return usign_f(fingerprint, NULL, NULL, sigfile);
117 }
118
119 int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) {
120         char tml[64] = {0};
121         char rfname[256] = {0};
122
123         snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint);
124         if (readlink(rfname, tml, sizeof(tml)) > 0 &&
125             !strcmp(tml, ".revoked.")) {
126                 return true;
127         };
128
129         return false;
130 }
131
132 int usign_v(const char *msgfile, const char *pubkeyfile,
133             const char *pubkeydir, const char *sigfile, bool quiet) {
134         pid_t pid;
135         int status;
136         const char *usign_argv[16] = {0};
137         unsigned int usign_argc = 0;
138         char fingerprint[17];
139
140         if (usign_f_sig(fingerprint, sigfile))
141                 return 1;
142
143         if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir))
144                 return 1;
145
146         usign_argv[usign_argc++] = "/usr/bin/usign";
147         usign_argv[usign_argc++] = "-V";
148         usign_argv[usign_argc++] = "-m";
149         usign_argv[usign_argc++] = msgfile;
150
151         if (quiet)
152                 usign_argv[usign_argc++] = "-q";
153
154         if (pubkeyfile) {
155                 usign_argv[usign_argc++] = "-p";
156                 usign_argv[usign_argc++] = pubkeyfile;
157         }
158
159         if (pubkeydir) {
160                 usign_argv[usign_argc++] = "-P";
161                 usign_argv[usign_argc++] = pubkeydir;
162         }
163
164         if (sigfile) {
165                 usign_argv[usign_argc++] = "-x";
166                 usign_argv[usign_argc++] = sigfile;
167         }
168
169         pid = fork();
170         switch (pid) {
171         case -1:
172                 return -1;
173
174         case 0:
175                 if (execv(usign_argv[0], usign_argv))
176                         return -1;
177
178                 break;
179
180         default:
181                 waitpid(pid, &status, 0);
182                 return WEXITSTATUS(status);
183         }
184
185         return -1;
186 }