1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2016 Toomas Soome <tsoome@me.com> 14 * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved. 15 */ 16 17 /* 18 * Create sha1 hash for file. 19 * 20 * NOTE: This is hardwired for now, so use libmd's SHA1 for simplicity. 21 */ 22 23 #include <stdio.h> 24 #include <errno.h> 25 #include <string.h> 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <fcntl.h> 29 #include <locale.h> 30 #include <sha1.h> 31 #include <cryptoutil.h> 32 #include "bootadm.h" 33 34 #define BUFFERSIZE (64 * 1024) 35 static uint8_t buf[BUFFERSIZE]; 36 37 int 38 bootadm_digest(const char *filename, char **result) 39 { 40 int fd; 41 char *resultstr = NULL; 42 uint8_t *resultbuf; 43 int resultstrlen, resultlen, exitcode; 44 SHA1_CTX sha1_ctx; 45 ssize_t nread; 46 47 /* Allocate a buffer to store result. */ 48 resultlen = SHA1_DIGEST_LENGTH; 49 if ((resultbuf = malloc(resultlen)) == NULL) { 50 bam_print(gettext("out of memory\n")); 51 exitcode = BAM_ERROR; 52 goto cleanup; 53 } 54 55 if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) { 56 bam_print(gettext("can not open input file %s\n"), filename); 57 exitcode = BAM_ERROR; 58 goto cleanup; 59 } 60 61 SHA1Init(&sha1_ctx); 62 while ((nread = read(fd, buf, sizeof (buf))) > 0) 63 SHA1Update(&sha1_ctx, buf, nread); 64 if (nread == -1) { 65 bam_print(gettext("error reading file: %s\n"), strerror(errno)); 66 exitcode = BAM_ERROR; 67 goto cleanup; 68 } 69 SHA1Final(resultbuf, &sha1_ctx); 70 71 /* Allocate a buffer to store result string */ 72 resultstrlen = 2 * resultlen + 1; /* Two hex chars per byte. */ 73 if ((resultstr = malloc(resultstrlen)) == NULL) { 74 bam_print(gettext("out of memory\n")); 75 exitcode = BAM_ERROR; 76 goto cleanup; 77 } 78 79 tohexstr(resultbuf, resultlen, resultstr, resultstrlen); 80 exitcode = BAM_SUCCESS; 81 (void) close(fd); 82 cleanup: 83 if (exitcode == BAM_ERROR) { 84 free(resultstr); 85 resultstr = NULL; 86 } 87 88 free(resultbuf); 89 90 *result = resultstr; 91 return (exitcode); 92 } 93