1 /* $OpenBSD: helper.c,v 1.18 2019/06/28 13:32:41 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * If we meet some day, and you think this stuff is worth it, you 21 * can buy me a beer in return. Poul-Henning Kamp 22 */ 23 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 27 #include <errno.h> 28 #include <fcntl.h> 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include <hashinc> 35 36 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 37 38 char * 39 HASHEnd(HASH_CTX *ctx, char *buf) 40 { 41 int i; 42 u_int8_t digest[HASH_DIGEST_LENGTH]; 43 static const char hex[] = "0123456789abcdef"; 44 45 if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL) 46 return (NULL); 47 48 HASHFinal(digest, ctx); 49 for (i = 0; i < HASH_DIGEST_LENGTH; i++) { 50 buf[i + i] = hex[digest[i] >> 4]; 51 buf[i + i + 1] = hex[digest[i] & 0x0f]; 52 } 53 buf[i + i] = '\0'; 54 explicit_bzero(digest, sizeof(digest)); 55 return (buf); 56 } 57 DEF_WEAK(HASHEnd); 58 59 char * 60 HASHFileChunk(const char *filename, char *buf, off_t off, off_t len) 61 { 62 struct stat sb; 63 u_char buffer[BUFSIZ]; 64 HASH_CTX ctx; 65 int fd, save_errno; 66 ssize_t nr; 67 68 HASHInit(&ctx); 69 70 if ((fd = open(filename, O_RDONLY)) == -1) 71 return (NULL); 72 if (len == 0) { 73 if (fstat(fd, &sb) == -1) { 74 save_errno = errno; 75 close(fd); 76 errno = save_errno; 77 return (NULL); 78 } 79 len = sb.st_size; 80 } 81 if (off > 0 && lseek(fd, off, SEEK_SET) == -1) { 82 save_errno = errno; 83 close(fd); 84 errno = save_errno; 85 return (NULL); 86 } 87 88 while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), len))) > 0) { 89 HASHUpdate(&ctx, buffer, nr); 90 if (len > 0 && (len -= nr) == 0) 91 break; 92 } 93 94 save_errno = errno; 95 close(fd); 96 errno = save_errno; 97 return (nr == -1 ? NULL : HASHEnd(&ctx, buf)); 98 } 99 DEF_WEAK(HASHFileChunk); 100 101 char * 102 HASHFile(const char *filename, char *buf) 103 { 104 return (HASHFileChunk(filename, buf, 0, 0)); 105 } 106 DEF_WEAK(HASHFile); 107 108 char * 109 HASHData(const u_char *data, size_t len, char *buf) 110 { 111 HASH_CTX ctx; 112 113 HASHInit(&ctx); 114 HASHUpdate(&ctx, data, len); 115 return (HASHEnd(&ctx, buf)); 116 } 117 DEF_WEAK(HASHData); 118