Print this page
7945 simplify bootadm_digest.c
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
        
*** 1,243 ****
  /*
!  * CDDL HEADER START
   *
!  * The contents of this file are subject to the terms of the
!  * Common Development and Distribution License (the "License").
!  * You may not use this file except in compliance with the License.
!  *
!  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
!  * or http://www.opensolaris.org/os/licensing.
!  * See the License for the specific language governing permissions
!  * and limitations under the License.
!  *
!  * When distributing Covered Code, include this CDDL HEADER in each
!  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
!  * If applicable, add the following below this CDDL HEADER, with the
!  * fields enclosed by brackets "[]" replaced with your own identifying
!  * information: Portions Copyright [yyyy] [name of copyright owner]
!  *
!  * CDDL HEADER END
   */
  /*
-  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-  * Use is subject to license terms.
-  */
- /*
   * Copyright 2016 Toomas Soome <tsoome@me.com>
   */
  
  /*
   * Create sha1 hash for file.
   */
  
  #include <stdio.h>
  #include <errno.h>
  #include <string.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
- #include <security/cryptoki.h>
- #include <cryptoutil.h>
  #include <locale.h>
  #include "bootadm.h"
  
! #define BUFFERSIZE      (1024 * 64)
! #define RESULTLEN       (512)
! static CK_BYTE buf[BUFFERSIZE];
  
- /*
-  * do_digest - Compute digest of a file. Borrowed from digest.
-  *
-  *  hSession - session
-  *  pmech - ptr to mechanism to be used for digest
-  *  fd  - file descriptor
-  *  pdigest - buffer  where digest result is returned
-  *  pdigestlen - length of digest buffer on input,
-  *               length of result on output
-  */
- static CK_RV
- do_digest(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
-     int fd, CK_BYTE_PTR *pdigest, CK_ULONG_PTR pdigestlen)
- {
-         CK_RV rv;
-         ssize_t nread;
-         int err;
- 
-         if ((rv = C_DigestInit(hSession, pmech)) != CKR_OK) {
-                 return (rv);
-         }
- 
-         while ((nread = read(fd, buf, sizeof (buf))) > 0) {
-                 /* Get the digest */
-                 rv = C_DigestUpdate(hSession, buf, (CK_ULONG)nread);
-                 if (rv != CKR_OK)
-                         return (rv);
-         }
- 
-         /* There was a read error */
-         if (nread == -1) {
-                 err = errno;
-                 bam_print(gettext("error reading file: %s\n"), strerror(err));
-                 return (CKR_GENERAL_ERROR);
-         }
- 
-         rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
- 
-         /* result too big to fit? Allocate a bigger buffer */
-         if (rv == CKR_BUFFER_TOO_SMALL) {
-                 *pdigest = realloc(*pdigest, *pdigestlen);
- 
-                 if (*pdigest == NULL) {
-                         err = errno;
-                         bam_print(gettext("realloc: %s\n"), strerror(err));
-                         return (CKR_HOST_MEMORY);
-                 }
- 
-                 rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
-         }
- 
-         return (rv);
- }
- 
  int
  bootadm_digest(const char *filename, char **result)
  {
          int fd;
-         CK_RV rv;
-         CK_ULONG slotcount;
-         CK_SLOT_ID slotID;
-         CK_SLOT_ID_PTR pSlotList = NULL;
-         CK_MECHANISM_TYPE mech_type = CKM_SHA_1;
-         CK_MECHANISM_INFO info;
-         CK_MECHANISM mech;
-         CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
-         CK_BYTE_PTR resultbuf = NULL;
-         CK_ULONG resultlen;
          char *resultstr = NULL;
!         int resultstrlen;
!         int i, exitcode;
  
-         /* Initialize, and get list of slots */
-         rv = C_Initialize(NULL);
-         if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
-                 bam_print(gettext(
-                     "failed to initialize PKCS #11 framework: %s\n"),
-                     pkcs11_strerror(rv));
-                 return (BAM_ERROR);
-         }
- 
-         /* Get slot count */
-         rv = C_GetSlotList(0, NULL, &slotcount);
-         if (rv != CKR_OK || slotcount == 0) {
-                 bam_print(gettext(
-                     "failed to find any cryptographic provider: %s\n"),
-                     pkcs11_strerror(rv));
-                 exitcode = BAM_ERROR;
-                 goto cleanup;
-         }
- 
-         /* Found at least one slot, allocate memory for slot list */
-         pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
-         if (pSlotList == NULL) {
-                 bam_print(gettext("out of memory\n"));
-                 exitcode = BAM_ERROR;
-                 goto cleanup;
-         }
- 
-         /* Get the list of slots */
-         if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
-                 bam_print(gettext(
-                     "failed to find any cryptographic provider; "
-                     "please check with your system administrator: %s\n"),
-                     pkcs11_strerror(rv));
-                 exitcode = BAM_ERROR;
-                 goto cleanup;
-         }
- 
-         /* Find a slot with matching mechanism */
-         for (i = 0; i < slotcount; i++) {
-                 slotID = pSlotList[i];
-                 rv = C_GetMechanismInfo(slotID, mech_type, &info);
-                 if (rv != CKR_OK) {
-                         continue; /* to the next slot */
-                 } else {
-                         if (info.flags & CKF_DIGEST)
-                                 break;
-                 }
-         }
- 
-         /* Show error if no matching mechanism found */
-         if (i == slotcount) {
-                 bam_print(gettext("no cryptographic provider was "
-                     "found for sha1\n"));
-                 exitcode = BAM_ERROR;
-                 goto cleanup;
-         }
- 
-         /* Mechanism is supported. Go ahead & open a session */
-         rv = C_OpenSession(slotID, CKF_SERIAL_SESSION,
-             NULL, NULL, &hSession);
- 
-         if (rv != CKR_OK) {
-                 bam_print(gettext("can not open PKCS#11 session: %s\n"),
-                     pkcs11_strerror(rv));
-                 exitcode = BAM_ERROR;
-                 goto cleanup;
-         }
- 
          /* Allocate a buffer to store result. */
!         resultlen = RESULTLEN;
          if ((resultbuf = malloc(resultlen)) == NULL) {
                  bam_print(gettext("out of memory\n"));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
-         mech.mechanism = mech_type;
-         mech.pParameter = NULL;
-         mech.ulParameterLen = 0;
-         exitcode = BAM_SUCCESS;
- 
          if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) {
                  bam_print(gettext("can not open input file %s\n"), filename);
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
!         rv = do_digest(hSession, &mech, fd, &resultbuf, &resultlen);
! 
!         if (rv != CKR_OK) {
!                 bam_print(gettext("crypto operation failed for "
!                     "file %s: %s\n"), filename, pkcs11_strerror(rv));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
          /* Allocate a buffer to store result string */
!         resultstrlen = 2 * resultlen + 1;
          if ((resultstr = malloc(resultstrlen)) == NULL) {
                  bam_print(gettext("out of memory\n"));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
          tohexstr(resultbuf, resultlen, resultstr, resultstrlen);
! 
          (void) close(fd);
  cleanup:
          if (exitcode == BAM_ERROR) {
                  free(resultstr);
                  resultstr = NULL;
          }
  
          free(resultbuf);
-         free(pSlotList);
  
-         if (hSession != CK_INVALID_HANDLE)
-                 (void) C_CloseSession(hSession);
- 
-         (void) C_Finalize(NULL);
- 
          *result = resultstr;
          return (exitcode);
  }
--- 1,92 ----
  /*
!  * This file and its contents are supplied under the terms of the
!  * Common Development and Distribution License ("CDDL"), version 1.0.
!  * You may only use this file in accordance with the terms of version
!  * 1.0 of the CDDL.
   *
!  * A full copy of the text of the CDDL should have accompanied this
!  * source.  A copy of the CDDL is also available via the Internet at
!  * http://www.illumos.org/license/CDDL.
   */
+ 
  /*
   * Copyright 2016 Toomas Soome <tsoome@me.com>
+  * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
   */
  
  /*
   * Create sha1 hash for file.
+  *
+  * NOTE:  This is hardwired for now, so use libmd's SHA1 for simplicity.
   */
  
  #include <stdio.h>
  #include <errno.h>
  #include <string.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <locale.h>
+ #include <sha1.h>
+ #include <cryptoutil.h>
  #include "bootadm.h"
  
! #define BUFFERSIZE (64 * 1024)
! static uint8_t buf[BUFFERSIZE];
  
  int
  bootadm_digest(const char *filename, char **result)
  {
          int fd;
          char *resultstr = NULL;
!         uint8_t *resultbuf;
!         int resultstrlen, resultlen, exitcode;
!         SHA1_CTX sha1_ctx;
!         ssize_t nread;
  
          /* Allocate a buffer to store result. */
!         resultlen = SHA1_DIGEST_LENGTH;
          if ((resultbuf = malloc(resultlen)) == NULL) {
                  bam_print(gettext("out of memory\n"));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
          if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) {
                  bam_print(gettext("can not open input file %s\n"), filename);
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
!         SHA1Init(&sha1_ctx);
!         while ((nread = read(fd, buf, sizeof (buf))) > 0)
!                 SHA1Update(&sha1_ctx, buf, nread);
!         if (nread == -1) {
!                 bam_print(gettext("error reading file: %s\n"), strerror(errno));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
+         SHA1Final(resultbuf, &sha1_ctx);
  
          /* Allocate a buffer to store result string */
!         resultstrlen = 2 * resultlen + 1;       /* Two hex chars per byte. */
          if ((resultstr = malloc(resultstrlen)) == NULL) {
                  bam_print(gettext("out of memory\n"));
                  exitcode = BAM_ERROR;
                  goto cleanup;
          }
  
          tohexstr(resultbuf, resultlen, resultstr, resultstrlen);
!         exitcode = BAM_SUCCESS;
          (void) close(fd);
  cleanup:
          if (exitcode == BAM_ERROR) {
                  free(resultstr);
                  resultstr = NULL;
          }
  
          free(resultbuf);
  
          *result = resultstr;
          return (exitcode);
  }