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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/boot/bootadm/bootadm_digest.c
          +++ new/usr/src/cmd/boot/bootadm/bootadm_digest.c
   1    1  /*
   2      - * CDDL HEADER START
        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.
   3    6   *
   4      - * The contents of this file are subject to the terms of the
   5      - * Common Development and Distribution License (the "License").
   6      - * You may not use this file except in compliance with the License.
   7      - *
   8      - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9      - * or http://www.opensolaris.org/os/licensing.
  10      - * See the License for the specific language governing permissions
  11      - * and limitations under the License.
  12      - *
  13      - * When distributing Covered Code, include this CDDL HEADER in each
  14      - * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15      - * If applicable, add the following below this CDDL HEADER, with the
  16      - * fields enclosed by brackets "[]" replaced with your own identifying
  17      - * information: Portions Copyright [yyyy] [name of copyright owner]
  18      - *
  19      - * CDDL HEADER END
        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.
  20   10   */
       11 +
  21   12  /*
  22      - * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23      - * Use is subject to license terms.
  24      - */
  25      -/*
  26   13   * Copyright 2016 Toomas Soome <tsoome@me.com>
       14 + * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  27   15   */
  28   16  
  29   17  /*
  30   18   * Create sha1 hash for file.
       19 + *
       20 + * NOTE:  This is hardwired for now, so use libmd's SHA1 for simplicity.
  31   21   */
  32   22  
  33   23  #include <stdio.h>
  34   24  #include <errno.h>
  35   25  #include <string.h>
  36   26  #include <sys/types.h>
  37   27  #include <sys/stat.h>
  38   28  #include <fcntl.h>
  39      -#include <security/cryptoki.h>
  40      -#include <cryptoutil.h>
  41   29  #include <locale.h>
       30 +#include <sha1.h>
       31 +#include <cryptoutil.h>
  42   32  #include "bootadm.h"
  43   33  
  44      -#define BUFFERSIZE      (1024 * 64)
  45      -#define RESULTLEN       (512)
  46      -static CK_BYTE buf[BUFFERSIZE];
       34 +#define BUFFERSIZE (64 * 1024)
       35 +static uint8_t buf[BUFFERSIZE];
  47   36  
  48      -/*
  49      - * do_digest - Compute digest of a file. Borrowed from digest.
  50      - *
  51      - *  hSession - session
  52      - *  pmech - ptr to mechanism to be used for digest
  53      - *  fd  - file descriptor
  54      - *  pdigest - buffer  where digest result is returned
  55      - *  pdigestlen - length of digest buffer on input,
  56      - *               length of result on output
  57      - */
  58      -static CK_RV
  59      -do_digest(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
  60      -    int fd, CK_BYTE_PTR *pdigest, CK_ULONG_PTR pdigestlen)
  61      -{
  62      -        CK_RV rv;
  63      -        ssize_t nread;
  64      -        int err;
  65      -
  66      -        if ((rv = C_DigestInit(hSession, pmech)) != CKR_OK) {
  67      -                return (rv);
  68      -        }
  69      -
  70      -        while ((nread = read(fd, buf, sizeof (buf))) > 0) {
  71      -                /* Get the digest */
  72      -                rv = C_DigestUpdate(hSession, buf, (CK_ULONG)nread);
  73      -                if (rv != CKR_OK)
  74      -                        return (rv);
  75      -        }
  76      -
  77      -        /* There was a read error */
  78      -        if (nread == -1) {
  79      -                err = errno;
  80      -                bam_print(gettext("error reading file: %s\n"), strerror(err));
  81      -                return (CKR_GENERAL_ERROR);
  82      -        }
  83      -
  84      -        rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
  85      -
  86      -        /* result too big to fit? Allocate a bigger buffer */
  87      -        if (rv == CKR_BUFFER_TOO_SMALL) {
  88      -                *pdigest = realloc(*pdigest, *pdigestlen);
  89      -
  90      -                if (*pdigest == NULL) {
  91      -                        err = errno;
  92      -                        bam_print(gettext("realloc: %s\n"), strerror(err));
  93      -                        return (CKR_HOST_MEMORY);
  94      -                }
  95      -
  96      -                rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
  97      -        }
  98      -
  99      -        return (rv);
 100      -}
 101      -
 102   37  int
 103   38  bootadm_digest(const char *filename, char **result)
 104   39  {
 105   40          int fd;
 106      -        CK_RV rv;
 107      -        CK_ULONG slotcount;
 108      -        CK_SLOT_ID slotID;
 109      -        CK_SLOT_ID_PTR pSlotList = NULL;
 110      -        CK_MECHANISM_TYPE mech_type = CKM_SHA_1;
 111      -        CK_MECHANISM_INFO info;
 112      -        CK_MECHANISM mech;
 113      -        CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
 114      -        CK_BYTE_PTR resultbuf = NULL;
 115      -        CK_ULONG resultlen;
 116   41          char *resultstr = NULL;
 117      -        int resultstrlen;
 118      -        int i, exitcode;
       42 +        uint8_t *resultbuf;
       43 +        int resultstrlen, resultlen, exitcode;
       44 +        SHA1_CTX sha1_ctx;
       45 +        ssize_t nread;
 119   46  
 120      -        /* Initialize, and get list of slots */
 121      -        rv = C_Initialize(NULL);
 122      -        if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
 123      -                bam_print(gettext(
 124      -                    "failed to initialize PKCS #11 framework: %s\n"),
 125      -                    pkcs11_strerror(rv));
 126      -                return (BAM_ERROR);
 127      -        }
 128      -
 129      -        /* Get slot count */
 130      -        rv = C_GetSlotList(0, NULL, &slotcount);
 131      -        if (rv != CKR_OK || slotcount == 0) {
 132      -                bam_print(gettext(
 133      -                    "failed to find any cryptographic provider: %s\n"),
 134      -                    pkcs11_strerror(rv));
 135      -                exitcode = BAM_ERROR;
 136      -                goto cleanup;
 137      -        }
 138      -
 139      -        /* Found at least one slot, allocate memory for slot list */
 140      -        pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
 141      -        if (pSlotList == NULL) {
 142      -                bam_print(gettext("out of memory\n"));
 143      -                exitcode = BAM_ERROR;
 144      -                goto cleanup;
 145      -        }
 146      -
 147      -        /* Get the list of slots */
 148      -        if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
 149      -                bam_print(gettext(
 150      -                    "failed to find any cryptographic provider; "
 151      -                    "please check with your system administrator: %s\n"),
 152      -                    pkcs11_strerror(rv));
 153      -                exitcode = BAM_ERROR;
 154      -                goto cleanup;
 155      -        }
 156      -
 157      -        /* Find a slot with matching mechanism */
 158      -        for (i = 0; i < slotcount; i++) {
 159      -                slotID = pSlotList[i];
 160      -                rv = C_GetMechanismInfo(slotID, mech_type, &info);
 161      -                if (rv != CKR_OK) {
 162      -                        continue; /* to the next slot */
 163      -                } else {
 164      -                        if (info.flags & CKF_DIGEST)
 165      -                                break;
 166      -                }
 167      -        }
 168      -
 169      -        /* Show error if no matching mechanism found */
 170      -        if (i == slotcount) {
 171      -                bam_print(gettext("no cryptographic provider was "
 172      -                    "found for sha1\n"));
 173      -                exitcode = BAM_ERROR;
 174      -                goto cleanup;
 175      -        }
 176      -
 177      -        /* Mechanism is supported. Go ahead & open a session */
 178      -        rv = C_OpenSession(slotID, CKF_SERIAL_SESSION,
 179      -            NULL, NULL, &hSession);
 180      -
 181      -        if (rv != CKR_OK) {
 182      -                bam_print(gettext("can not open PKCS#11 session: %s\n"),
 183      -                    pkcs11_strerror(rv));
 184      -                exitcode = BAM_ERROR;
 185      -                goto cleanup;
 186      -        }
 187      -
 188   47          /* Allocate a buffer to store result. */
 189      -        resultlen = RESULTLEN;
       48 +        resultlen = SHA1_DIGEST_LENGTH;
 190   49          if ((resultbuf = malloc(resultlen)) == NULL) {
 191   50                  bam_print(gettext("out of memory\n"));
 192   51                  exitcode = BAM_ERROR;
 193   52                  goto cleanup;
 194   53          }
 195   54  
 196      -        mech.mechanism = mech_type;
 197      -        mech.pParameter = NULL;
 198      -        mech.ulParameterLen = 0;
 199      -        exitcode = BAM_SUCCESS;
 200      -
 201   55          if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) {
 202   56                  bam_print(gettext("can not open input file %s\n"), filename);
 203   57                  exitcode = BAM_ERROR;
 204   58                  goto cleanup;
 205   59          }
 206   60  
 207      -        rv = do_digest(hSession, &mech, fd, &resultbuf, &resultlen);
 208      -
 209      -        if (rv != CKR_OK) {
 210      -                bam_print(gettext("crypto operation failed for "
 211      -                    "file %s: %s\n"), filename, pkcs11_strerror(rv));
       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));
 212   66                  exitcode = BAM_ERROR;
 213   67                  goto cleanup;
 214   68          }
       69 +        SHA1Final(resultbuf, &sha1_ctx);
 215   70  
 216   71          /* Allocate a buffer to store result string */
 217      -        resultstrlen = 2 * resultlen + 1;
       72 +        resultstrlen = 2 * resultlen + 1;       /* Two hex chars per byte. */
 218   73          if ((resultstr = malloc(resultstrlen)) == NULL) {
 219   74                  bam_print(gettext("out of memory\n"));
 220   75                  exitcode = BAM_ERROR;
 221   76                  goto cleanup;
 222   77          }
 223   78  
 224   79          tohexstr(resultbuf, resultlen, resultstr, resultstrlen);
 225      -
       80 +        exitcode = BAM_SUCCESS;
 226   81          (void) close(fd);
 227   82  cleanup:
 228   83          if (exitcode == BAM_ERROR) {
 229   84                  free(resultstr);
 230   85                  resultstr = NULL;
 231   86          }
 232   87  
 233   88          free(resultbuf);
 234      -        free(pSlotList);
 235   89  
 236      -        if (hSession != CK_INVALID_HANDLE)
 237      -                (void) C_CloseSession(hSession);
 238      -
 239      -        (void) C_Finalize(NULL);
 240      -
 241   90          *result = resultstr;
 242   91          return (exitcode);
 243   92  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX