crypt.c - sbase - suckless unix tools
(HTM) git clone git://git.suckless.org/sbase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
crypt.c (3700B)
---
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 if (!(file = strstr(line, " "))) {
53 (*formatsucks)++;
54 continue;
55 }
56 if ((file - line) / 2 != sz) {
57 (*formatsucks)++; /* checksum length mismatch */
58 continue;
59 }
60 *file = '\0';
61 file += 2;
62 for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */
63 *p = '\0';
64 if ((fd = open(file, O_RDONLY)) < 0) {
65 weprintf("open %s:", file);
66 (*noread)++;
67 continue;
68 }
69 if (cryptsum(ops, fd, file, md)) {
70 (*noread)++;
71 continue;
72 }
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 close(fd);
83 }
84 free(line);
85 }
86
87 int
88 cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
89 {
90 FILE *fp;
91 int formatsucks = 0, noread = 0, nonmatch = 0, ret = 0;
92
93 if (argc == 0) {
94 mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch);
95 } else {
96 for (; *argv; argc--, argv++) {
97 if ((*argv)[0] == '-' && !(*argv)[1]) {
98 fp = stdin;
99 } else if (!(fp = fopen(*argv, "r"))) {
100 weprintf("fopen %s:", *argv);
101 ret = 1;
102 continue;
103 }
104 mdchecklist(fp, ops, md, sz, &formatsucks, &noread, &nonmatch);
105 if (fp != stdin)
106 fclose(fp);
107 }
108 }
109
110 if (formatsucks) {
111 weprintf("%d lines are improperly formatted\n", formatsucks);
112 ret = 1;
113 }
114 if (noread) {
115 weprintf("%d listed file could not be read\n", noread);
116 ret = 1;
117 }
118 if (nonmatch) {
119 weprintf("%d computed checksums did NOT match\n", nonmatch);
120 ret = 1;
121 }
122
123 return ret;
124 }
125
126 int
127 cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
128 {
129 int fd;
130 int ret = 0;
131
132 if (argc == 0) {
133 if (cryptsum(ops, 0, "<stdin>", md))
134 ret = 1;
135 else
136 mdprint(md, "<stdin>", sz);
137 } else {
138 for (; *argv; argc--, argv++) {
139 if ((*argv)[0] == '-' && !(*argv)[1]) {
140 *argv = "<stdin>";
141 fd = 0;
142 } else if ((fd = open(*argv, O_RDONLY)) < 0) {
143 weprintf("open %s:", *argv);
144 ret = 1;
145 continue;
146 }
147 if (cryptsum(ops, fd, *argv, md))
148 ret = 1;
149 else
150 mdprint(md, *argv, sz);
151 if (fd != 0)
152 close(fd);
153 }
154 }
155
156 return ret;
157 }
158
159 int
160 cryptsum(struct crypt_ops *ops, int fd, const char *f, uint8_t *md)
161 {
162 uint8_t buf[BUFSIZ];
163 ssize_t n;
164
165 ops->init(ops->s);
166 while ((n = read(fd, buf, sizeof(buf))) > 0)
167 ops->update(ops->s, buf, n);
168 if (n < 0) {
169 weprintf("%s: read error:", f);
170 return 1;
171 }
172 ops->sum(ops->s, md);
173 return 0;
174 }
175
176 void
177 mdprint(const uint8_t *md, const char *f, size_t len)
178 {
179 size_t i;
180
181 for (i = 0; i < len; i++)
182 printf("%02x", md[i]);
183 printf(" %s\n", f);
184 }