1 /* $OpenBSD: helper.c,v 1.15 2015/11/01 03:45:29 guenther 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)) < 0) 71 return (NULL); 72 if (len == 0) { 73 if (fstat(fd, &sb) == -1) { 74 close(fd); 75 return (NULL); 76 } 77 len = sb.st_size; 78 } 79 if (off > 0 && lseek(fd, off, SEEK_SET) < 0) { 80 close(fd); 81 return (NULL); 82 } 83 84 while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), len))) > 0) { 85 HASHUpdate(&ctx, buffer, (size_t)nr); 86 if (len > 0 && (len -= nr) == 0) 87 break; 88 } 89 90 save_errno = errno; 91 close(fd); 92 errno = save_errno; 93 return (nr < 0 ? NULL : HASHEnd(&ctx, buf)); 94 } 95 DEF_WEAK(HASHFileChunk); 96 97 char * 98 HASHFile(const char *filename, char *buf) 99 { 100 return (HASHFileChunk(filename, buf, (off_t)0, (off_t)0)); 101 } 102 DEF_WEAK(HASHFile); 103 104 char * 105 HASHData(const u_char *data, size_t len, char *buf) 106 { 107 HASH_CTX ctx; 108 109 HASHInit(&ctx); 110 HASHUpdate(&ctx, data, len); 111 return (HASHEnd(&ctx, buf)); 112 } 113 DEF_WEAK(HASHData); 114