| 
									
										
										
										
											2013-10-07 17:03:26 +01:00
										 |  |  | /* See LICENSE file for copyright and license details. */ | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | #include <stdint.h>
 | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | #include "../crypt.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | #include "../text.h"
 | 
					
						
							|  |  |  | #include "../util.h"
 | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-04-04 11:09:46 +01:00
										 |  |  | hexdec(int c) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	if (c >= '0' && c <= '9') | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 		return c - '0'; | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	else if (c >= 'A' && c <= 'F') | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 		return c - 'A' + 10; | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	else if (c >= 'a' && c <= 'f') | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 		return c - 'a' + 10; | 
					
						
							|  |  |  | 	return -1; /* unknown character */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-04-04 11:09:46 +01:00
										 |  |  | mdcheckline(const char *s, uint8_t *md, size_t sz) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 	size_t i; | 
					
						
							|  |  |  | 	int b1, b2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	for (i = 0; i < sz; i++) { | 
					
						
							|  |  |  | 		if (!*s || (b1 = hexdec(*s++)) < 0) | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			return -1; /* invalid format */ | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		if (!*s || (b2 = hexdec(*s++)) < 0) | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			return -1; /* invalid format */ | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		if ((uint8_t)((b1 << 4) | b2) != md[i]) | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			return 0; /* value mismatch */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return (i == sz) ? 1 : 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | cryptcheck(char *sumfile, int argc, char *argv[], | 
					
						
							|  |  |  | 	  struct crypt_ops *ops, uint8_t *md, size_t sz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	FILE *cfp, *fp; | 
					
						
							| 
									
										
										
										
											2014-03-23 13:45:52 +01:00
										 |  |  | 	char *line = NULL, *file, *p; | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 	int r, nonmatch = 0, formatsucks = 0, noread = 0, ret = 0; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 	size_t bufsiz = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 22:16:29 +01:00
										 |  |  | 	if (!sumfile) | 
					
						
							| 
									
										
										
										
											2014-05-05 11:11:37 +03:00
										 |  |  | 		cfp = stdin; | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	else if (!(cfp = fopen(sumfile, "r"))) | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 		eprintf("fopen %s:", sumfile); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	while (agetline(&line, &bufsiz, cfp) != -1) { | 
					
						
							|  |  |  | 		if (!(file = strstr(line, "  "))) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			formatsucks++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		if ((file - line) / 2 != sz) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			formatsucks++; /* checksum length mismatch */ | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		*file = '\0'; | 
					
						
							|  |  |  | 		file += 2; | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */ | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 		*p = '\0'; | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		if (!(fp = fopen(file, "r"))) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			weprintf("fopen %s:", file); | 
					
						
							|  |  |  | 			noread++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cryptsum(ops, fp, file, md); | 
					
						
							|  |  |  | 		r = mdcheckline(line, md, sz); | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		if (r == 1) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			printf("%s: OK\n", file); | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 		} else if (r == 0) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 			printf("%s: FAILED\n", file); | 
					
						
							|  |  |  | 			nonmatch++; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			formatsucks++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		fclose(fp); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-13 22:16:29 +01:00
										 |  |  | 	if (sumfile) | 
					
						
							| 
									
										
										
										
											2014-05-05 11:11:37 +03:00
										 |  |  | 		fclose(cfp); | 
					
						
							| 
									
										
										
										
											2014-03-23 13:45:52 +01:00
										 |  |  | 	free(line); | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	if (formatsucks > 0) { | 
					
						
							| 
									
										
										
										
											2014-03-23 18:58:43 +00:00
										 |  |  | 		weprintf("%d lines are improperly formatted\n", formatsucks); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 		ret = 1; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	if (noread > 0) { | 
					
						
							| 
									
										
										
										
											2014-03-23 18:58:43 +00:00
										 |  |  | 		weprintf("%d listed file could not be read\n", noread); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 		ret = 1; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 	if (nonmatch > 0) { | 
					
						
							| 
									
										
										
										
											2014-03-23 18:58:43 +00:00
										 |  |  | 		weprintf("%d computed checksums did NOT match\n", nonmatch); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 		ret = 1; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:18:38 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-02 11:17:55 +01:00
										 |  |  | int | 
					
						
							|  |  |  | cryptmain(int argc, char *argv[], | 
					
						
							|  |  |  | 	  struct crypt_ops *ops, uint8_t *md, size_t sz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 	int ret = 0; | 
					
						
							| 
									
										
										
										
											2013-09-02 11:17:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (argc == 0) { | 
					
						
							|  |  |  | 		cryptsum(ops, stdin, "<stdin>", md); | 
					
						
							|  |  |  | 		mdprint(md, "<stdin>", sz); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		for (; argc > 0; argc--) { | 
					
						
							| 
									
										
										
										
											2014-11-13 22:16:29 +01:00
										 |  |  | 			if (!(fp = fopen(*argv, "r"))) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:23:56 +01:00
										 |  |  | 				weprintf("fopen %s:", *argv); | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 				ret = 1; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:23:56 +01:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-11-13 19:54:28 +01:00
										 |  |  | 			if (cryptsum(ops, fp, *argv, md) == 1) | 
					
						
							| 
									
										
										
										
											2014-10-02 23:46:04 +01:00
										 |  |  | 				ret = 1; | 
					
						
							| 
									
										
										
										
											2014-03-23 12:30:34 +01:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				mdprint(md, *argv, sz); | 
					
						
							| 
									
										
										
										
											2013-09-02 11:17:55 +01:00
										 |  |  | 			fclose(fp); | 
					
						
							|  |  |  | 			argv++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-23 12:30:34 +01:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2013-09-02 11:17:55 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | int | 
					
						
							|  |  |  | cryptsum(struct crypt_ops *ops, FILE *fp, const char *f, | 
					
						
							|  |  |  | 	 uint8_t *md) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-22 14:14:08 +00:00
										 |  |  | 	uint8_t buf[BUFSIZ]; | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | 	size_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ops->init(ops->s); | 
					
						
							|  |  |  | 	while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) | 
					
						
							|  |  |  | 		ops->update(ops->s, buf, n); | 
					
						
							|  |  |  | 	if (ferror(fp)) { | 
					
						
							| 
									
										
										
										
											2014-03-23 12:30:34 +01:00
										 |  |  | 		weprintf("read error: %s:", f); | 
					
						
							| 
									
										
										
										
											2013-07-07 15:29:45 +01:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ops->sum(ops->s, md); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | mdprint(const uint8_t *md, const char *f, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < len; i++) | 
					
						
							|  |  |  | 		printf("%02x", md[i]); | 
					
						
							|  |  |  | 	printf("  %s\n", f); | 
					
						
							|  |  |  | } |