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