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