Print this page
6862532 "cryptoadm: failed to parse configuration" error
6353443 domestic (crypt) source build leaves stuff it shouldn't
6818180 mac(1) printed "invalid key" error message when user input an invalid passphrase


   2  * CDDL HEADER START
   3  *
   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
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * digest.c
  28  *
  29  * Implements digest(1) and mac(1) commands
  30  * If command name is mac, performs mac operation
  31  * else perform digest operation
  32  *
  33  * See the man pages for digest and mac for details on
  34  * how these commands work.
  35  */
  36 
  37 #include <stdio.h>
  38 #include <stdlib.h>
  39 #include <unistd.h>
  40 #include <fcntl.h>
  41 #include <ctype.h>
  42 #include <strings.h>


  54 #define BUFFERSIZE      (4096)          /* Buffer size for reading file */
  55 
  56 /*
  57  * RESULTLEN - large enough size in bytes to hold result for
  58  * digest and mac results for all mechanisms
  59  */
  60 #define RESULTLEN       (512)
  61 
  62 /*
  63  * Exit Status codes
  64  */
  65 #ifndef EXIT_SUCCESS
  66 #define EXIT_SUCCESS    0       /* No errors */
  67 #define EXIT_FAILURE    1       /* All errors except usage */
  68 #endif /* EXIT_SUCCESS */
  69 
  70 #define EXIT_USAGE      2       /* usage/syntax error */
  71 
  72 #define MAC_NAME        "mac"           /* name of mac command */
  73 #define MAC_OPTIONS     "lva:k:T:K:"            /* for getopt */
  74 #define DIGEST_NAME     "digest"        /* name of mac command */
  75 #define DIGEST_OPTIONS  "lva:"          /* for getopt */
  76 

  77 static boolean_t vflag = B_FALSE;       /* -v (verbose) flag, optional */
  78 static boolean_t aflag = B_FALSE;       /* -a <algorithm> flag, required */
  79 static boolean_t lflag = B_FALSE;       /* -l flag, for mac and digest */
  80 static boolean_t kflag = B_FALSE;
  81 static boolean_t Tflag = B_FALSE;
  82 static boolean_t Kflag = B_FALSE;
  83 
  84 static char *keyfile = NULL;    /* name of keyfile */
  85 static char *token_label = NULL;
  86 static char *key_label = NULL;
  87 
  88 static CK_BYTE buf[BUFFERSIZE];
  89 
  90 struct mech_alias {
  91         CK_MECHANISM_TYPE type;
  92         char *alias;
  93         CK_ULONG keysize_min;
  94         CK_ULONG keysize_max;
  95         int keysize_unit;
  96         boolean_t available;
  97 };
  98 
  99 #define MECH_ALIASES_COUNT 11
 100 
 101 static struct mech_alias mech_aliases[] = {
 102         { CKM_SHA_1, "sha1", ULONG_MAX, 0L, 8, B_FALSE },
 103         { CKM_MD5, "md5", ULONG_MAX, 0L, 8, B_FALSE },
 104         { CKM_DES_MAC, "des_mac", ULONG_MAX, 0L, 8, B_FALSE },
 105         { CKM_SHA_1_HMAC, "sha1_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 106         { CKM_MD5_HMAC, "md5_hmac", ULONG_MAX, 0L, 8, B_FALSE },


 109         { CKM_SHA512, "sha512", ULONG_MAX, 0L, 8, B_FALSE },
 110         { CKM_SHA256_HMAC, "sha256_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 111         { CKM_SHA384_HMAC, "sha384_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 112         { CKM_SHA512_HMAC, "sha512_hmac", ULONG_MAX, 0L, 8, B_FALSE }
 113 };
 114 
 115 static CK_BBOOL true = TRUE;
 116 
 117 static void usage(boolean_t mac_cmd);
 118 static int execute_cmd(char *algo_str, int filecount,
 119         char **filelist, boolean_t mac_cmd);
 120 static CK_RV do_mac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
 121         int fd, CK_OBJECT_HANDLE key, CK_BYTE_PTR *psignature,
 122         CK_ULONG_PTR psignaturelen);
 123 static CK_RV do_digest(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
 124         int fd, CK_BYTE_PTR *pdigest, CK_ULONG_PTR pdigestlen);
 125 
 126 int
 127 main(int argc, char **argv)
 128 {
 129 
 130         extern char *optarg;
 131         extern int optind;
 132         int errflag = 0;        /* We had an optstr parse error */
 133         char c;                 /* current getopts flag */
 134         char *algo_str;         /* mechanism/algorithm string */
 135         int filecount;
 136         boolean_t mac_cmd;      /* if TRUE, do mac, else do digest */
 137         char *optstr;
 138         char **filelist;        /* list of files */
 139         char *cmdname = NULL;   /* name of command */
 140 
 141         (void) setlocale(LC_ALL, "");
 142 #if !defined(TEXT_DOMAIN)       /* Should be defiend by cc -D */
 143 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 144 #endif
 145         (void) textdomain(TEXT_DOMAIN);
 146 
 147         /*
 148          * Based on command name, determine
 149          * type of command. mac is mac


 413                                     !strlen(token_label)) {
 414                                         token_label = pkcs11_default_token();
 415                                 }
 416 
 417                                 status = pkcs11_get_pass(token_label,
 418                                     (char **)&pkeydata, &keylen,
 419                                     0, B_FALSE);
 420                         } else if (keyfile != NULL) {
 421                                 /* get the key file */
 422                                 status = pkcs11_read_data(keyfile,
 423                                     (void **)&pkeydata, &keylen);
 424                         } else {
 425                                 /* get the key from input */
 426                                 status = pkcs11_get_pass(NULL,
 427                                     (char **)&pkeydata, &keylen,
 428                                     0, B_FALSE);
 429                         }
 430 
 431                         if (status != 0 || keylen == 0 || pkeydata == NULL) {
 432                                 cryptoerror(LOG_STDERR,
 433                                     Kflag ? gettext("invalid passphrase.") :

 434                                     gettext("invalid key."));
 435                                 return (EXIT_FAILURE);
 436                         }
 437                 }
 438         }
 439 
 440         /* Initialize, and get list of slots */
 441         rv = C_Initialize(NULL);
 442         if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
 443                 cryptoerror(LOG_STDERR,
 444                     gettext("failed to initialize PKCS #11 framework: %s"),
 445                     pkcs11_strerror(rv));
 446                 return (EXIT_FAILURE);
 447         }
 448 
 449         /* Get slot count */
 450         rv = C_GetSlotList(0, NULL_PTR, &slotcount);
 451         if (rv != CKR_OK || slotcount == 0) {
 452                 cryptoerror(LOG_STDERR, gettext(
 453                     "failed to find any cryptographic provider,"
 454                     "please check with your system administrator: %s"),
 455                     pkcs11_strerror(rv));
 456                 exitcode = EXIT_FAILURE;
 457                 goto cleanup;
 458         }
 459 
 460         /* Found at least one slot, allocate memory for slot list */
 461         pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
 462         if (pSlotList == NULL_PTR) {
 463                 int err = errno;
 464                 cryptoerror(LOG_STDERR, gettext("malloc: %s\n"),
 465                     strerror(err));
 466                 exitcode = EXIT_FAILURE;
 467                 goto cleanup;
 468         }
 469 
 470         /* Get the list of slots */
 471         if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
 472                 cryptoerror(LOG_STDERR, gettext(
 473                     "failed to find any cryptographic provider,"
 474                     "please check with your system administrator: %s"),
 475                     pkcs11_strerror(rv));
 476                 exitcode = EXIT_FAILURE;
 477                 goto cleanup;
 478         }
 479 
 480         /*
 481          * Obtain list of algorithms if -l option was given
 482          */
 483         if (lflag) {
 484 
 485                 for (slot = 0; slot < slotcount; slot++) {
 486 
 487                         /* Iterate through each mechanism */
 488                         for (mek = 0; mek < MECH_ALIASES_COUNT; mek++) {
 489                                 rv = C_GetMechanismInfo(pSlotList[slot],
 490                                     mech_aliases[mek].type, &info);
 491 
 492                                 /* Only check algorithms that can be used */
 493                                 if ((rv != CKR_OK) ||




   2  * CDDL HEADER START
   3  *
   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
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * digest.c
  28  *
  29  * Implements digest(1) and mac(1) commands
  30  * If command name is mac, performs mac operation
  31  * else perform digest operation
  32  *
  33  * See the man pages for digest and mac for details on
  34  * how these commands work.
  35  */
  36 
  37 #include <stdio.h>
  38 #include <stdlib.h>
  39 #include <unistd.h>
  40 #include <fcntl.h>
  41 #include <ctype.h>
  42 #include <strings.h>


  54 #define BUFFERSIZE      (4096)          /* Buffer size for reading file */
  55 
  56 /*
  57  * RESULTLEN - large enough size in bytes to hold result for
  58  * digest and mac results for all mechanisms
  59  */
  60 #define RESULTLEN       (512)
  61 
  62 /*
  63  * Exit Status codes
  64  */
  65 #ifndef EXIT_SUCCESS
  66 #define EXIT_SUCCESS    0       /* No errors */
  67 #define EXIT_FAILURE    1       /* All errors except usage */
  68 #endif /* EXIT_SUCCESS */
  69 
  70 #define EXIT_USAGE      2       /* usage/syntax error */
  71 
  72 #define MAC_NAME        "mac"           /* name of mac command */
  73 #define MAC_OPTIONS     "lva:k:T:K:"    /* for getopt */
  74 #define DIGEST_NAME     "digest"        /* name of digest command */
  75 #define DIGEST_OPTIONS  "lva:"          /* for getopt */
  76 
  77 /* Saved command line options */
  78 static boolean_t vflag = B_FALSE;       /* -v (verbose) flag, optional */
  79 static boolean_t aflag = B_FALSE;       /* -a <algorithm> flag, required */
  80 static boolean_t lflag = B_FALSE;       /* -l flag, for mac and digest */
  81 static boolean_t kflag = B_FALSE;       /* -k keyfile */
  82 static boolean_t Tflag = B_FALSE;       /* -T token_spec */
  83 static boolean_t Kflag = B_FALSE;       /* -K key_label */
  84 
  85 static char *keyfile = NULL;     /* name of file containing key value */
  86 static char *token_label = NULL; /* tokensSpec: tokenName[:manufId[:serial]] */
  87 static char *key_label = NULL;   /* PKCS#11 symmetric token key label */
  88 
  89 static CK_BYTE buf[BUFFERSIZE];
  90 
  91 struct mech_alias {
  92         CK_MECHANISM_TYPE type;
  93         char *alias;
  94         CK_ULONG keysize_min;
  95         CK_ULONG keysize_max;
  96         int keysize_unit;
  97         boolean_t available;
  98 };
  99 
 100 #define MECH_ALIASES_COUNT 11
 101 
 102 static struct mech_alias mech_aliases[] = {
 103         { CKM_SHA_1, "sha1", ULONG_MAX, 0L, 8, B_FALSE },
 104         { CKM_MD5, "md5", ULONG_MAX, 0L, 8, B_FALSE },
 105         { CKM_DES_MAC, "des_mac", ULONG_MAX, 0L, 8, B_FALSE },
 106         { CKM_SHA_1_HMAC, "sha1_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 107         { CKM_MD5_HMAC, "md5_hmac", ULONG_MAX, 0L, 8, B_FALSE },


 110         { CKM_SHA512, "sha512", ULONG_MAX, 0L, 8, B_FALSE },
 111         { CKM_SHA256_HMAC, "sha256_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 112         { CKM_SHA384_HMAC, "sha384_hmac", ULONG_MAX, 0L, 8, B_FALSE },
 113         { CKM_SHA512_HMAC, "sha512_hmac", ULONG_MAX, 0L, 8, B_FALSE }
 114 };
 115 
 116 static CK_BBOOL true = TRUE;
 117 
 118 static void usage(boolean_t mac_cmd);
 119 static int execute_cmd(char *algo_str, int filecount,
 120         char **filelist, boolean_t mac_cmd);
 121 static CK_RV do_mac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
 122         int fd, CK_OBJECT_HANDLE key, CK_BYTE_PTR *psignature,
 123         CK_ULONG_PTR psignaturelen);
 124 static CK_RV do_digest(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
 125         int fd, CK_BYTE_PTR *pdigest, CK_ULONG_PTR pdigestlen);
 126 
 127 int
 128 main(int argc, char **argv)
 129 {

 130         extern char *optarg;
 131         extern int optind;
 132         int errflag = 0;        /* We had an optstr parse error */
 133         char c;                 /* current getopts flag */
 134         char *algo_str;         /* mechanism/algorithm string */
 135         int filecount;
 136         boolean_t mac_cmd;      /* if TRUE, do mac, else do digest */
 137         char *optstr;
 138         char **filelist;        /* list of files */
 139         char *cmdname = NULL;   /* name of command */
 140 
 141         (void) setlocale(LC_ALL, "");
 142 #if !defined(TEXT_DOMAIN)       /* Should be defiend by cc -D */
 143 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 144 #endif
 145         (void) textdomain(TEXT_DOMAIN);
 146 
 147         /*
 148          * Based on command name, determine
 149          * type of command. mac is mac


 413                                     !strlen(token_label)) {
 414                                         token_label = pkcs11_default_token();
 415                                 }
 416 
 417                                 status = pkcs11_get_pass(token_label,
 418                                     (char **)&pkeydata, &keylen,
 419                                     0, B_FALSE);
 420                         } else if (keyfile != NULL) {
 421                                 /* get the key file */
 422                                 status = pkcs11_read_data(keyfile,
 423                                     (void **)&pkeydata, &keylen);
 424                         } else {
 425                                 /* get the key from input */
 426                                 status = pkcs11_get_pass(NULL,
 427                                     (char **)&pkeydata, &keylen,
 428                                     0, B_FALSE);
 429                         }
 430 
 431                         if (status != 0 || keylen == 0 || pkeydata == NULL) {
 432                                 cryptoerror(LOG_STDERR,
 433                                     (Kflag || (keyfile == NULL)) ?
 434                                     gettext("invalid passphrase.") :
 435                                     gettext("invalid key."));
 436                                 return (EXIT_FAILURE);
 437                         }
 438                 }
 439         }
 440 
 441         /* Initialize, and get list of slots */
 442         rv = C_Initialize(NULL);
 443         if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
 444                 cryptoerror(LOG_STDERR,
 445                     gettext("failed to initialize PKCS #11 framework: %s"),
 446                     pkcs11_strerror(rv));
 447                 return (EXIT_FAILURE);
 448         }
 449 
 450         /* Get slot count */
 451         rv = C_GetSlotList(0, NULL_PTR, &slotcount);
 452         if (rv != CKR_OK || slotcount == 0) {
 453                 cryptoerror(LOG_STDERR, gettext(
 454                     "failed to find any cryptographic provider; "
 455                     "please check with your system administrator: %s"),
 456                     pkcs11_strerror(rv));
 457                 exitcode = EXIT_FAILURE;
 458                 goto cleanup;
 459         }
 460 
 461         /* Found at least one slot, allocate memory for slot list */
 462         pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
 463         if (pSlotList == NULL_PTR) {
 464                 int err = errno;
 465                 cryptoerror(LOG_STDERR, gettext("malloc: %s\n"),
 466                     strerror(err));
 467                 exitcode = EXIT_FAILURE;
 468                 goto cleanup;
 469         }
 470 
 471         /* Get the list of slots */
 472         if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
 473                 cryptoerror(LOG_STDERR, gettext(
 474                     "failed to find any cryptographic provider; "
 475                     "please check with your system administrator: %s"),
 476                     pkcs11_strerror(rv));
 477                 exitcode = EXIT_FAILURE;
 478                 goto cleanup;
 479         }
 480 
 481         /*
 482          * Obtain list of algorithms if -l option was given
 483          */
 484         if (lflag) {
 485 
 486                 for (slot = 0; slot < slotcount; slot++) {
 487 
 488                         /* Iterate through each mechanism */
 489                         for (mek = 0; mek < MECH_ALIASES_COUNT; mek++) {
 490                                 rv = C_GetMechanismInfo(pSlotList[slot],
 491                                     mech_aliases[mek].type, &info);
 492 
 493                                 /* Only check algorithms that can be used */
 494                                 if ((rv != CKR_OK) ||