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
bootadm_digest(const char * filename,char ** result)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