Print this page
6414175 kcf.conf's supportedlist not providing much usefulness

@@ -1,12 +1,11 @@
 /*
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.

@@ -18,16 +17,14 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <strings.h>
 #include <unistd.h>

@@ -93,12 +90,12 @@
  * provider pointed by pent.  Return NULL if out of memory.
  */
 crypto_load_soft_disabled_t *
 setup_soft_dis(entry_t *pent)
 {
-        crypto_load_soft_disabled_t     *pload_soft_dis;
-        mechlist_t      *plist;
+        crypto_load_soft_disabled_t     *pload_soft_dis = NULL;
+        mechlist_t      *plist = NULL;
         size_t  extra_mech_size = 0;
         uint_t  dis_count;
         int     i;
 
         if (pent == NULL) {

@@ -138,12 +135,12 @@
  * provider pointed by pent.  Return NULL if out of memory.
  */
 crypto_load_dev_disabled_t *
 setup_dev_dis(entry_t *pent)
 {
-        crypto_load_dev_disabled_t      *pload_dev_dis;
-        mechlist_t      *plist;
+        crypto_load_dev_disabled_t      *pload_dev_dis = NULL;
+        mechlist_t      *plist = NULL;
         size_t  extra_mech_size = 0;
         uint_t  dis_count;
         int     i;
         char    pname[MAXNAMELEN];
         int     inst_num;

@@ -214,10 +211,12 @@
 
 
 /*
  * Prepare the calling argument for the GET_SOFT_INFO call for the provider
  * with the number of mechanisms specified in the second argument.
+ *
+ * Called by get_soft_info().
  */
 static crypto_get_soft_info_t *
 setup_get_soft_info(char *provname, int count)
 {
         crypto_get_soft_info_t *psoft_info;

@@ -249,11 +248,11 @@
  */
 int
 get_dev_list(crypto_get_dev_list_t **ppdevlist)
 {
         crypto_get_dev_list_t *pdevlist;
-        int fd;
+        int                     fd = -1;
         int count = DEFAULT_DEV_NUM;
 
         pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
             sizeof (crypto_dev_list_entry_t) * (count - 1));
         if (pdevlist == NULL) {

@@ -320,11 +319,11 @@
 {
         crypto_get_dev_info_t *dev_info;
         mechlist_t *phead;
         mechlist_t *pcur;
         mechlist_t *pmech;
-        int fd;
+        int             fd = -1;
         int i;
         int rc;
 
         if (devname == NULL || count < 1) {
                 cryptodebug("get_dev_info(): devname is NULL or bogus count");

@@ -393,45 +392,64 @@
         (void) close(fd);
         return (rc);
 }
 
 
-
 /*
  * Get the supported mechanism list of the software provider from kernel.
+ *
+ * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
+ * If NULL, this function calls get_kcfconf_info() internally.
  */
 int
-get_soft_info(char *provname, mechlist_t **ppmechlist)
+get_soft_info(char *provname, mechlist_t **ppmechlist,
+        entrylist_t *phardlist, entrylist_t *psoftlist)
 {
+        boolean_t               in_kernel = B_FALSE;
         crypto_get_soft_info_t  *psoft_info;
         mechlist_t      *phead;
         mechlist_t      *pmech;
         mechlist_t      *pcur;
-        entry_t *pent;
+        entry_t                 *pent = NULL;
         int     count;
-        int     fd;
+        int                     fd = -1;
         int     rc;
         int     i;
 
         if (provname == NULL) {
                 return (FAILURE);
         }
 
         if (getzoneid() == GLOBAL_ZONEID) {
                 /* use kcf.conf for kernel software providers in global zone */
-                if ((pent = getent_kef(provname)) == NULL) {
-                        cryptoerror(LOG_STDERR, gettext("%s does not exist."),
-                            provname);
+                if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
+                    NULL) {
+
+                        /* No kcf.conf entry for this provider */
+                        if (check_kernel_for_soft(provname, NULL, &in_kernel)
+                            == FAILURE) {
                         return (FAILURE);
+                        } else if (in_kernel == B_FALSE) {
+                                cryptoerror(LOG_STDERR,
+                                    gettext("%s does not exist."), provname);
+                                return (FAILURE);
                 }
+
+                        /*
+                         * Set mech count to 1.  It will be reset to the
+                         * correct value later if the setup buffer is too small.
+                         */
+                        count = 1;
+                } else {
                 count = pent->sup_count;
                 free_entry(pent);
+                }
         } else {
                 /*
-                 * kcf.conf not there in non-global zone, set mech count to 1;
-                 * it will be reset to the correct value later if the setup
-                 * buffer is too small
+                 * kcf.conf not there in non-global zone: set mech count to 1.
+                 * It will be reset to the correct value later if the setup
+                 * buffer is too small.
                  */
                 count = 1;
         }
 
         if ((psoft_info = setup_get_soft_info(provname, count)) == NULL) {

@@ -481,11 +499,11 @@
                 free(psoft_info);
                 return (FAILURE);
         }
 
 
-        /* Get the mechanism list and return it */
+        /* Build the mechanism linked list and return it */
         rc = SUCCESS;
         phead = pcur = NULL;
         for (i = 0; i < psoft_info->si_count; i++) {
                 pmech = create_mech(&psoft_info->si_list[i][0]);
                 if (pmech == NULL) {

@@ -519,11 +537,11 @@
 get_soft_list(crypto_get_soft_list_t **ppsoftlist)
 {
         crypto_get_soft_list_t *psoftlist = NULL;
         int count = DEFAULT_SOFT_NUM;
         int len;
-        int fd;
+        int     fd = -1;
 
         if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
                 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
                     ADMIN_IOCTL_DEVICE, strerror(errno));
                 return (FAILURE);