crypt.c (3857B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <fcntl.h> 3 #include <stdint.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <unistd.h> 8 9 #include "../crypt.h" 10 #include "../text.h" 11 #include "../util.h" 12 13 static int 14 hexdec(int c) 15 { 16 if (c >= '0' && c <= '9') 17 return c - '0'; 18 else if (c >= 'A' && c <= 'F') 19 return c - 'A' + 10; 20 else if (c >= 'a' && c <= 'f') 21 return c - 'a' + 10; 22 return -1; /* unknown character */ 23 } 24 25 static int 26 mdcheckline(const char *s, uint8_t *md, size_t sz) 27 { 28 size_t i; 29 int b1, b2; 30 31 for (i = 0; i < sz; i++) { 32 if (!*s || (b1 = hexdec(*s++)) < 0) 33 return -1; /* invalid format */ 34 if (!*s || (b2 = hexdec(*s++)) < 0) 35 return -1; /* invalid format */ 36 if ((uint8_t)((b1 << 4) | b2) != md[i]) 37 return 0; /* value mismatch */ 38 } 39 return (i == sz) ? 1 : 0; 40 } 41 42 static void 43 mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz, 44 int *formatsucks, int *noread, int *nonmatch) 45 { 46 int fd; 47 size_t bufsiz = 0; 48 int r; 49 char *line = NULL, *file, *p; 50 51 while (getline(&line, &bufsiz, listfp) > 0) { 52 file = strchr(line, ' '); 53 if (file == NULL || (file[1] != ' ' && file[1] != '*')) { 54 (*formatsucks)++; 55 continue; 56 } 57 if (file - line != sz * 2) { 58 (*formatsucks)++; /* checksum length mismatch */ 59 continue; 60 } 61 *file = '\0'; 62 file += 2; 63 for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */ 64 *p = '\0'; 65 if ((fd = open(file, O_RDONLY)) < 0) { 66 weprintf("open %s:", file); 67 (*noread)++; 68 continue; 69 } 70 if (cryptsum(ops, fd, file, md)) { 71 (*noread)++; 72 continue; 73 } 74 r = mdcheckline(line, md, sz); 75 if (r == 1) { 76 printf("%s: OK\n", file); 77 } else if (r == 0) { 78 printf("%s: FAILED\n", file); 79 (*nonmatch)++; 80 } else { 81 (*formatsucks)++; 82 } 83 close(fd); 84 } 85 free(line); 86 } 87 88 int 89 cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz) 90 { 91 FILE *fp; 92 int formatsucks = 0, noread = 0, nonmatch = 0, ret = 0; 93 94 if (argc == 0) { 95 mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch); 96 } else { 97 for (; *argv; argc--, argv++) { 98 if ((*argv)[0] == '-' && !(*argv)[1]) { 99 fp = stdin; 100 } else if (!(fp = fopen(*argv, "r"))) { 101 weprintf("fopen %s:", *argv); 102 ret = 1; 103 continue; 104 } 105 mdchecklist(fp, ops, md, sz, &formatsucks, &noread, &nonmatch); 106 if (fp != stdin) 107 fclose(fp); 108 } 109 } 110 111 if (formatsucks) { 112 weprintf("%d improperly formatted line%s\n", 113 formatsucks, formatsucks > 1 ? "s" : ""); 114 ret = 1; 115 } 116 if (noread) { 117 weprintf("%d listed file%s could not be read\n", 118 noread, noread > 1 ? "s" : ""); 119 ret = 1; 120 } 121 if (nonmatch) { 122 weprintf("%d computed checksum%s did NOT match\n", 123 nonmatch, nonmatch > 1 ? "s" : ""); 124 ret = 1; 125 } 126 127 return ret; 128 } 129 130 int 131 cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz) 132 { 133 int fd; 134 int ret = 0; 135 136 if (argc == 0) { 137 if (cryptsum(ops, 0, "<stdin>", md)) 138 ret = 1; 139 else 140 mdprint(md, "<stdin>", sz); 141 } else { 142 for (; *argv; argc--, argv++) { 143 if ((*argv)[0] == '-' && !(*argv)[1]) { 144 *argv = "<stdin>"; 145 fd = 0; 146 } else if ((fd = open(*argv, O_RDONLY)) < 0) { 147 weprintf("open %s:", *argv); 148 ret = 1; 149 continue; 150 } 151 if (cryptsum(ops, fd, *argv, md)) 152 ret = 1; 153 else 154 mdprint(md, *argv, sz); 155 if (fd != 0) 156 close(fd); 157 } 158 } 159 160 return ret; 161 } 162 163 int 164 cryptsum(struct crypt_ops *ops, int fd, const char *f, uint8_t *md) 165 { 166 uint8_t buf[BUFSIZ]; 167 ssize_t n; 168 169 ops->init(ops->s); 170 while ((n = read(fd, buf, sizeof(buf))) > 0) 171 ops->update(ops->s, buf, n); 172 if (n < 0) { 173 weprintf("%s: read error:", f); 174 return 1; 175 } 176 ops->sum(ops->s, md); 177 return 0; 178 } 179 180 void 181 mdprint(const uint8_t *md, const char *f, size_t len) 182 { 183 size_t i; 184 185 for (i = 0; i < len; i++) 186 printf("%02x", md[i]); 187 printf(" %s\n", f); 188 }