• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucert/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 #ifdef UCERT_HOST_BUILD
 24 #define USIGN_EXEC "usign"
 25 #else
 26 #define USIGN_EXEC "/usr/bin/usign"
 27 #endif
 28 
 29 /*
 30  * check for revoker deadlink in pubkeydir
 31  * return true if a revoker exists, false otherwise
 32  */
 33 int _usign_key_is_revoked(const char *fingerprint, const char *pubkeydir) {
 34         char tml[64] = {0};
 35         char rfname[256] = {0};
 36 
 37         snprintf(rfname, sizeof(rfname)-1, "%s/%s", pubkeydir, fingerprint);
 38         if (readlink(rfname, tml, sizeof(tml)) > 0 &&
 39             !strcmp(tml, ".revoked.")) {
 40                 return true;
 41         };
 42 
 43         return false;
 44 }
 45 
 46 #ifdef UCERT_FULL
 47 /*
 48  * call usign -S ...
 49  * return WEXITSTATUS or -1 if fork fails
 50  */
 51 int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
 52         pid_t pid;
 53         int status;
 54         const char *usign_argv[16] = {0};
 55         unsigned int usign_argc = 0;
 56 
 57         usign_argv[usign_argc++] = USIGN_EXEC;
 58         usign_argv[usign_argc++] = "-S";
 59         usign_argv[usign_argc++] = "-m";
 60         usign_argv[usign_argc++] = msgfile;
 61         usign_argv[usign_argc++] = "-s";
 62         usign_argv[usign_argc++] = seckeyfile;
 63         usign_argv[usign_argc++] = "-x";
 64         usign_argv[usign_argc++] = sigfile;
 65 
 66         if (quiet)
 67                 usign_argv[usign_argc++] = "-q";
 68 
 69         pid = fork();
 70         switch (pid) {
 71         case -1:
 72                 return -1;
 73 
 74         case 0:
 75                 execvp(usign_argv[0], (char *const *)usign_argv);
 76                 if (!quiet)
 77                         perror("Failed to execute usign");
 78                 _exit(1);
 79         }
 80 
 81         waitpid(pid, &status, 0);
 82         return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
 83 }
 84 #else
 85 int usign_s(const char *msgfile, const char *seckeyfile, const char *sigfile, bool quiet) {
 86         return -1;
 87 };
 88 #endif
 89 
 90 /*
 91  * call usign -F ... and set fingerprint returned
 92  * return WEXITSTATUS or -1 if fork fails
 93  */
 94 static int usign_f(char fingerprint[17], const char *pubkeyfile, const char *seckeyfile, const char *sigfile, bool quiet) {
 95         int fds[2];
 96         FILE *f;
 97         pid_t pid;
 98         int status;
 99         const char *usign_argv[16] = {0};
100         unsigned int usign_argc = 0;
101 
102         if (pipe(fds))
103                 return -1;
104 
105         usign_argv[usign_argc++] = USIGN_EXEC;
106         usign_argv[usign_argc++] = "-F";
107 
108         if (pubkeyfile) {
109                 usign_argv[usign_argc++] = "-p";
110                 usign_argv[usign_argc++] = pubkeyfile;
111         }
112 
113         if (seckeyfile) {
114                 usign_argv[usign_argc++] = "-s";
115                 usign_argv[usign_argc++] = seckeyfile;
116         }
117 
118         if (sigfile) {
119                 usign_argv[usign_argc++] = "-x";
120                 usign_argv[usign_argc++] = sigfile;
121         }
122 
123         pid = fork();
124         switch (pid) {
125         case -1:
126                 return -1;
127 
128         case 0:
129                 dup2(fds[1], 1);
130 
131                 close(fds[0]);
132                 close(fds[1]);
133 
134                 execvp(usign_argv[0], (char *const *)usign_argv);
135                 if (!quiet)
136                         perror("Failed to execute usign");
137                 _exit(1);
138         }
139 
140         close(fds[1]);
141 
142         waitpid(pid, &status, 0);
143         status = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
144 
145         if (!fingerprint || status) {
146                 close(fds[0]);
147                 return status;
148         }
149 
150         f = fdopen(fds[0], "r");
151         if (fread(fingerprint, 1, 16, f) != 16)
152                 status = -1;
153         fclose(f);
154         if (status)
155                 return status;
156 
157         fingerprint[16] = '\0';
158         if (strspn(fingerprint, "0123456789abcdefABCDEF") != 16)
159                 status = -1;
160 
161         return status;
162 }
163 
164 /*
165  * call usign -F -p ...
166  */
167 int usign_f_pubkey(char fingerprint[17], const char *pubkeyfile, bool quiet) {
168         return usign_f(fingerprint, pubkeyfile, NULL, NULL, quiet);
169 }
170 
171 /*
172  * call usign -F -s ...
173  */
174 int usign_f_seckey(char fingerprint[17], const char *seckeyfile, bool quiet) {
175         return usign_f(fingerprint, NULL, seckeyfile, NULL, quiet);
176 }
177 
178 /*
179  * call usign -F -x ...
180  */
181 int usign_f_sig(char fingerprint[17], const char *sigfile, bool quiet) {
182         return usign_f(fingerprint, NULL, NULL, sigfile, quiet);
183 }
184 
185 
186 /*
187  * call usign -V ...
188  * return WEXITSTATUS or -1 if fork fails
189  */
190 int usign_v(const char *msgfile, const char *pubkeyfile,
191             const char *pubkeydir, const char *sigfile, bool quiet) {
192         pid_t pid;
193         int status;
194         const char *usign_argv[16] = {0};
195         unsigned int usign_argc = 0;
196         char fingerprint[17];
197 
198         if (usign_f_sig(fingerprint, sigfile, quiet)) {
199                 if (!quiet)
200                         fprintf(stderr, "cannot get signing key fingerprint\n");
201                 return 1;
202         }
203 
204         if (pubkeydir && _usign_key_is_revoked(fingerprint, pubkeydir)) {
205                 if (!quiet)
206                         fprintf(stderr, "key %s has been revoked!\n", fingerprint);
207                 return 1;
208         }
209         usign_argv[usign_argc++] = USIGN_EXEC;
210         usign_argv[usign_argc++] = "-V";
211         usign_argv[usign_argc++] = "-m";
212         usign_argv[usign_argc++] = msgfile;
213 
214         if (quiet)
215                 usign_argv[usign_argc++] = "-q";
216 
217         if (pubkeyfile) {
218                 usign_argv[usign_argc++] = "-p";
219                 usign_argv[usign_argc++] = pubkeyfile;
220         }
221 
222         if (pubkeydir) {
223                 usign_argv[usign_argc++] = "-P";
224                 usign_argv[usign_argc++] = pubkeydir;
225         }
226 
227         if (sigfile) {
228                 usign_argv[usign_argc++] = "-x";
229                 usign_argv[usign_argc++] = sigfile;
230         }
231 
232         pid = fork();
233         switch (pid) {
234         case -1:
235                 return -1;
236 
237         case 0:
238                 execvp(usign_argv[0], (char *const *)usign_argv);
239                 if (!quiet)
240                         perror("Failed to execute usign");
241                 _exit(1);
242         }
243 
244         waitpid(pid, &status, 0);
245         return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
246 }
247 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt