10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51937Sizick  * Common Development and Distribution License (the "License").
61937Sizick  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
229341SAnthony.Scarpino@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <stdlib.h>
270Sstevel@tonic-gate #include <string.h>
280Sstevel@tonic-gate #include <security/cryptoki.h>
297188Smcpowers #include <sys/crypto/common.h>
300Sstevel@tonic-gate #include <arcfour.h>
310Sstevel@tonic-gate #include <aes_impl.h>
32676Sizick #include <blowfish_impl.h>
330Sstevel@tonic-gate #include <bignum.h>
340Sstevel@tonic-gate #include <des_impl.h>
350Sstevel@tonic-gate #include <rsa_impl.h>
360Sstevel@tonic-gate #include "softGlobal.h"
370Sstevel@tonic-gate #include "softObject.h"
380Sstevel@tonic-gate #include "softSession.h"
390Sstevel@tonic-gate #include "softKeystore.h"
400Sstevel@tonic-gate #include "softKeystoreUtil.h"
41676Sizick #include "softCrypt.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * This attribute table is used by the soft_lookup_attr()
460Sstevel@tonic-gate  * to validate the attributes.
470Sstevel@tonic-gate  */
480Sstevel@tonic-gate CK_ATTRIBUTE_TYPE attr_map[] = {
490Sstevel@tonic-gate 	CKA_PRIVATE,
500Sstevel@tonic-gate 	CKA_LABEL,
510Sstevel@tonic-gate 	CKA_APPLICATION,
520Sstevel@tonic-gate 	CKA_OBJECT_ID,
530Sstevel@tonic-gate 	CKA_CERTIFICATE_TYPE,
540Sstevel@tonic-gate 	CKA_ISSUER,
550Sstevel@tonic-gate 	CKA_SERIAL_NUMBER,
560Sstevel@tonic-gate 	CKA_AC_ISSUER,
570Sstevel@tonic-gate 	CKA_OWNER,
580Sstevel@tonic-gate 	CKA_ATTR_TYPES,
590Sstevel@tonic-gate 	CKA_SUBJECT,
600Sstevel@tonic-gate 	CKA_ID,
610Sstevel@tonic-gate 	CKA_SENSITIVE,
620Sstevel@tonic-gate 	CKA_START_DATE,
630Sstevel@tonic-gate 	CKA_END_DATE,
640Sstevel@tonic-gate 	CKA_MODULUS,
650Sstevel@tonic-gate 	CKA_MODULUS_BITS,
660Sstevel@tonic-gate 	CKA_PUBLIC_EXPONENT,
670Sstevel@tonic-gate 	CKA_PRIVATE_EXPONENT,
680Sstevel@tonic-gate 	CKA_PRIME_1,
690Sstevel@tonic-gate 	CKA_PRIME_2,
700Sstevel@tonic-gate 	CKA_EXPONENT_1,
710Sstevel@tonic-gate 	CKA_EXPONENT_2,
720Sstevel@tonic-gate 	CKA_COEFFICIENT,
730Sstevel@tonic-gate 	CKA_PRIME,
740Sstevel@tonic-gate 	CKA_SUBPRIME,
750Sstevel@tonic-gate 	CKA_BASE,
760Sstevel@tonic-gate 	CKA_EXTRACTABLE,
770Sstevel@tonic-gate 	CKA_LOCAL,
780Sstevel@tonic-gate 	CKA_NEVER_EXTRACTABLE,
790Sstevel@tonic-gate 	CKA_ALWAYS_SENSITIVE,
800Sstevel@tonic-gate 	CKA_MODIFIABLE,
810Sstevel@tonic-gate 	CKA_ECDSA_PARAMS,
824219Smcpowers 	CKA_EC_PARAMS,
830Sstevel@tonic-gate 	CKA_EC_POINT,
840Sstevel@tonic-gate 	CKA_SECONDARY_AUTH,
850Sstevel@tonic-gate 	CKA_AUTH_PIN_FLAGS,
860Sstevel@tonic-gate 	CKA_HW_FEATURE_TYPE,
870Sstevel@tonic-gate 	CKA_RESET_ON_INIT,
880Sstevel@tonic-gate 	CKA_HAS_RESET
890Sstevel@tonic-gate };
900Sstevel@tonic-gate 
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate  * attributes that exists only in public key objects
930Sstevel@tonic-gate  * Note: some attributes may also exist in one or two
940Sstevel@tonic-gate  *       other object classes, but they are also listed
950Sstevel@tonic-gate  *       because not all object have them.
960Sstevel@tonic-gate  */
970Sstevel@tonic-gate CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
980Sstevel@tonic-gate {
990Sstevel@tonic-gate 	CKA_SUBJECT,
1000Sstevel@tonic-gate 	CKA_ENCRYPT,
1010Sstevel@tonic-gate 	CKA_WRAP,
1020Sstevel@tonic-gate 	CKA_VERIFY,
1030Sstevel@tonic-gate 	CKA_VERIFY_RECOVER,
1040Sstevel@tonic-gate 	CKA_MODULUS,
1050Sstevel@tonic-gate 	CKA_MODULUS_BITS,
1060Sstevel@tonic-gate 	CKA_PUBLIC_EXPONENT,
1070Sstevel@tonic-gate 	CKA_PRIME,
1080Sstevel@tonic-gate 	CKA_SUBPRIME,
1090Sstevel@tonic-gate 	CKA_BASE,
1100Sstevel@tonic-gate 	CKA_TRUSTED,
1110Sstevel@tonic-gate 	CKA_ECDSA_PARAMS,
1120Sstevel@tonic-gate 	CKA_EC_PARAMS,
1130Sstevel@tonic-gate 	CKA_EC_POINT
1140Sstevel@tonic-gate };
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate /*
1170Sstevel@tonic-gate  * attributes that exists only in private key objects
1180Sstevel@tonic-gate  * Note: some attributes may also exist in one or two
1190Sstevel@tonic-gate  *       other object classes, but they are also listed
1200Sstevel@tonic-gate  *       because not all object have them.
1210Sstevel@tonic-gate  */
1220Sstevel@tonic-gate CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
1230Sstevel@tonic-gate {
1240Sstevel@tonic-gate 	CKA_DECRYPT,
1250Sstevel@tonic-gate 	CKA_UNWRAP,
1260Sstevel@tonic-gate 	CKA_SIGN,
1270Sstevel@tonic-gate 	CKA_SIGN_RECOVER,
1280Sstevel@tonic-gate 	CKA_MODULUS,
1290Sstevel@tonic-gate 	CKA_PUBLIC_EXPONENT,
1300Sstevel@tonic-gate 	CKA_PRIVATE_EXPONENT,
1310Sstevel@tonic-gate 	CKA_PRIME,
1320Sstevel@tonic-gate 	CKA_SUBPRIME,
1330Sstevel@tonic-gate 	CKA_BASE,
1340Sstevel@tonic-gate 	CKA_PRIME_1,
1350Sstevel@tonic-gate 	CKA_PRIME_2,
1360Sstevel@tonic-gate 	CKA_EXPONENT_1,
1370Sstevel@tonic-gate 	CKA_EXPONENT_2,
1380Sstevel@tonic-gate 	CKA_COEFFICIENT,
1390Sstevel@tonic-gate 	CKA_VALUE_BITS,
1400Sstevel@tonic-gate 	CKA_SUBJECT,
1410Sstevel@tonic-gate 	CKA_SENSITIVE,
1420Sstevel@tonic-gate 	CKA_EXTRACTABLE,
1430Sstevel@tonic-gate 	CKA_NEVER_EXTRACTABLE,
1440Sstevel@tonic-gate 	CKA_ALWAYS_SENSITIVE,
1450Sstevel@tonic-gate 	CKA_EC_PARAMS
1460Sstevel@tonic-gate };
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate /*
1490Sstevel@tonic-gate  * attributes that exists only in secret key objects
1500Sstevel@tonic-gate  * Note: some attributes may also exist in one or two
1510Sstevel@tonic-gate  *       other object classes, but they are also listed
1520Sstevel@tonic-gate  *       because not all object have them.
1530Sstevel@tonic-gate  */
1540Sstevel@tonic-gate CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate 	CKA_VALUE_LEN,
1570Sstevel@tonic-gate 	CKA_ENCRYPT,
1580Sstevel@tonic-gate 	CKA_DECRYPT,
1590Sstevel@tonic-gate 	CKA_WRAP,
1600Sstevel@tonic-gate 	CKA_UNWRAP,
1610Sstevel@tonic-gate 	CKA_SIGN,
1620Sstevel@tonic-gate 	CKA_VERIFY,
1630Sstevel@tonic-gate 	CKA_SENSITIVE,
1640Sstevel@tonic-gate 	CKA_EXTRACTABLE,
1650Sstevel@tonic-gate 	CKA_NEVER_EXTRACTABLE,
1660Sstevel@tonic-gate 	CKA_ALWAYS_SENSITIVE
1670Sstevel@tonic-gate };
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate  * attributes that exists only in domain parameter objects
1710Sstevel@tonic-gate  * Note: some attributes may also exist in one or two
1720Sstevel@tonic-gate  *       other object classes, but they are also listed
1730Sstevel@tonic-gate  *       because not all object have them.
1740Sstevel@tonic-gate  */
1750Sstevel@tonic-gate CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate 	CKA_PRIME,
1780Sstevel@tonic-gate 	CKA_SUBPRIME,
1790Sstevel@tonic-gate 	CKA_BASE,
1800Sstevel@tonic-gate 	CKA_PRIME_BITS,
1810Sstevel@tonic-gate 	CKA_SUBPRIME_BITS,
1820Sstevel@tonic-gate 	CKA_SUB_PRIME_BITS
1830Sstevel@tonic-gate };
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate /*
1860Sstevel@tonic-gate  * attributes that exists only in hardware feature objects
1870Sstevel@tonic-gate  *
1880Sstevel@tonic-gate  */
1890Sstevel@tonic-gate CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
1900Sstevel@tonic-gate {
1910Sstevel@tonic-gate 	CKA_HW_FEATURE_TYPE,
1920Sstevel@tonic-gate 	CKA_RESET_ON_INIT,
1930Sstevel@tonic-gate 	CKA_HAS_RESET
1940Sstevel@tonic-gate };
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate /*
1970Sstevel@tonic-gate  * attributes that exists only in certificate objects
1980Sstevel@tonic-gate  */
1990Sstevel@tonic-gate CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate 	CKA_CERTIFICATE_TYPE,
2020Sstevel@tonic-gate 	CKA_TRUSTED,
2030Sstevel@tonic-gate 	CKA_SUBJECT,
2040Sstevel@tonic-gate 	CKA_ID,
2050Sstevel@tonic-gate 	CKA_ISSUER,
2060Sstevel@tonic-gate 	CKA_AC_ISSUER,
2070Sstevel@tonic-gate 	CKA_SERIAL_NUMBER,
2080Sstevel@tonic-gate 	CKA_OWNER,
2090Sstevel@tonic-gate 	CKA_ATTR_TYPES
2100Sstevel@tonic-gate };
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate /*
2140Sstevel@tonic-gate  * Validate the attribute by using binary search algorithm.
2150Sstevel@tonic-gate  */
2160Sstevel@tonic-gate CK_RV
soft_lookup_attr(CK_ATTRIBUTE_TYPE type)2170Sstevel@tonic-gate soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 	size_t lower, middle, upper;
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	lower = 0;
2230Sstevel@tonic-gate 	upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	while (lower <= upper) {
2260Sstevel@tonic-gate 		/* Always starts from middle. */
2270Sstevel@tonic-gate 		middle = (lower + upper) / 2;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 		if (type > attr_map[middle]) {
2300Sstevel@tonic-gate 			/* Adjust the lower bound to upper half. */
2310Sstevel@tonic-gate 			lower = middle + 1;
2320Sstevel@tonic-gate 			continue;
2330Sstevel@tonic-gate 		}
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 		if (type == attr_map[middle]) {
2360Sstevel@tonic-gate 			/* Found it. */
2370Sstevel@tonic-gate 			return (CKR_OK);
2380Sstevel@tonic-gate 		}
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 		if (type < attr_map[middle]) {
2410Sstevel@tonic-gate 			/* Adjust the upper bound to lower half. */
2420Sstevel@tonic-gate 			upper = middle - 1;
2430Sstevel@tonic-gate 			continue;
2440Sstevel@tonic-gate 		}
2450Sstevel@tonic-gate 	}
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	/* Failed to find the matching attribute from the attribute table. */
2480Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate /*
2530Sstevel@tonic-gate  * Validate the attribute by using the following search algorithm:
2540Sstevel@tonic-gate  *
2550Sstevel@tonic-gate  * 1) Search for the most frequently used attributes first.
2560Sstevel@tonic-gate  * 2) If not found, search for the usage-purpose attributes - these
2570Sstevel@tonic-gate  *    attributes have dense set of values, therefore compiler will
2580Sstevel@tonic-gate  *    optimize it with a branch table and branch to the appropriate
2590Sstevel@tonic-gate  *    case.
2600Sstevel@tonic-gate  * 3) If still not found, use binary search for the rest of the
2610Sstevel@tonic-gate  *    attributes in the attr_map[] table.
2620Sstevel@tonic-gate  */
2630Sstevel@tonic-gate CK_RV
soft_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)2640Sstevel@tonic-gate soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2650Sstevel@tonic-gate 	CK_OBJECT_CLASS *class)
2660Sstevel@tonic-gate {
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	CK_ULONG i;
2690Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
2720Sstevel@tonic-gate 		/* First tier search */
2730Sstevel@tonic-gate 		switch (template[i].type) {
2740Sstevel@tonic-gate 		case CKA_CLASS:
2750Sstevel@tonic-gate 			*class = *((CK_OBJECT_CLASS*)template[i].pValue);
2760Sstevel@tonic-gate 			break;
2770Sstevel@tonic-gate 		case CKA_TOKEN:
2780Sstevel@tonic-gate 			break;
2790Sstevel@tonic-gate 		case CKA_KEY_TYPE:
2800Sstevel@tonic-gate 			break;
2810Sstevel@tonic-gate 		case CKA_VALUE:
2820Sstevel@tonic-gate 			break;
2830Sstevel@tonic-gate 		case CKA_VALUE_LEN:
2840Sstevel@tonic-gate 			break;
2850Sstevel@tonic-gate 		case CKA_VALUE_BITS:
2860Sstevel@tonic-gate 			break;
2870Sstevel@tonic-gate 		default:
2880Sstevel@tonic-gate 			/* Second tier search */
2890Sstevel@tonic-gate 			switch (template[i].type) {
2900Sstevel@tonic-gate 			case CKA_ENCRYPT:
2910Sstevel@tonic-gate 				break;
2920Sstevel@tonic-gate 			case CKA_DECRYPT:
2930Sstevel@tonic-gate 				break;
2940Sstevel@tonic-gate 			case CKA_WRAP:
2950Sstevel@tonic-gate 				break;
2960Sstevel@tonic-gate 			case CKA_UNWRAP:
2970Sstevel@tonic-gate 				break;
2980Sstevel@tonic-gate 			case CKA_SIGN:
2990Sstevel@tonic-gate 				break;
3000Sstevel@tonic-gate 			case CKA_SIGN_RECOVER:
3010Sstevel@tonic-gate 				break;
3020Sstevel@tonic-gate 			case CKA_VERIFY:
3030Sstevel@tonic-gate 				break;
3040Sstevel@tonic-gate 			case CKA_VERIFY_RECOVER:
3050Sstevel@tonic-gate 				break;
3060Sstevel@tonic-gate 			case CKA_DERIVE:
3070Sstevel@tonic-gate 				break;
3080Sstevel@tonic-gate 			default:
3090Sstevel@tonic-gate 				/* Third tier search */
3100Sstevel@tonic-gate 				rv = soft_lookup_attr(template[i].type);
3110Sstevel@tonic-gate 				if (rv != CKR_OK)
3120Sstevel@tonic-gate 					return (rv);
3130Sstevel@tonic-gate 				break;
3140Sstevel@tonic-gate 			}
3150Sstevel@tonic-gate 			break;
3160Sstevel@tonic-gate 		}
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 	return (rv);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate static void
cleanup_cert_attr(cert_attr_t * attr)3220Sstevel@tonic-gate cleanup_cert_attr(cert_attr_t *attr)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate 	if (attr) {
3250Sstevel@tonic-gate 		if (attr->value) {
3260Sstevel@tonic-gate 			(void) memset(attr->value, 0, attr->length);
3270Sstevel@tonic-gate 			free(attr->value);
3280Sstevel@tonic-gate 		}
3290Sstevel@tonic-gate 		attr->value = NULL;
3300Sstevel@tonic-gate 		attr->length = 0;
3310Sstevel@tonic-gate 	}
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate static CK_RV
copy_cert_attr(cert_attr_t * src_attr,cert_attr_t ** dest_attr)3350Sstevel@tonic-gate copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 	if (src_attr == NULL || dest_attr == NULL)
3400Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	if (src_attr->value == NULL)
3430Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 	/* free memory if its already allocated */
3460Sstevel@tonic-gate 	if (*dest_attr != NULL) {
3470Sstevel@tonic-gate 		if ((*dest_attr)->value != (CK_BYTE *)NULL)
3480Sstevel@tonic-gate 			free((*dest_attr)->value);
3490Sstevel@tonic-gate 	} else {
3500Sstevel@tonic-gate 		*dest_attr = malloc(sizeof (cert_attr_t));
3510Sstevel@tonic-gate 		if (*dest_attr == NULL)
3520Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
3530Sstevel@tonic-gate 	}
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	(*dest_attr)->value = NULL;
3560Sstevel@tonic-gate 	(*dest_attr)->length = 0;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	if (src_attr->length) {
3590Sstevel@tonic-gate 		(*dest_attr)->value = malloc(src_attr->length);
3600Sstevel@tonic-gate 		if ((*dest_attr)->value == NULL) {
3610Sstevel@tonic-gate 			free(*dest_attr);
3620Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
3630Sstevel@tonic-gate 		}
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 		(void) memcpy((*dest_attr)->value, src_attr->value,
3665697Smcpowers 		    src_attr->length);
3670Sstevel@tonic-gate 		(*dest_attr)->length = src_attr->length;
3680Sstevel@tonic-gate 	}
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	return (rv);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate void
soft_cleanup_cert_object(soft_object_t * object_p)3740Sstevel@tonic-gate soft_cleanup_cert_object(soft_object_t *object_p)
3750Sstevel@tonic-gate {
3760Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 	if (object_p->class != CKO_CERTIFICATE ||
3790Sstevel@tonic-gate 	    OBJ_CERT(object_p) == NULL)
3800Sstevel@tonic-gate 		return;
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	if (certtype == CKC_X_509) {
3830Sstevel@tonic-gate 		if (X509_CERT_SUBJECT(object_p) != NULL) {
3840Sstevel@tonic-gate 			cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
3850Sstevel@tonic-gate 			free(X509_CERT_SUBJECT(object_p));
3860Sstevel@tonic-gate 			X509_CERT_SUBJECT(object_p) = NULL;
3870Sstevel@tonic-gate 		}
3880Sstevel@tonic-gate 		if (X509_CERT_VALUE(object_p) != NULL) {
3890Sstevel@tonic-gate 			cleanup_cert_attr(X509_CERT_VALUE(object_p));
3900Sstevel@tonic-gate 			free(X509_CERT_VALUE(object_p));
3910Sstevel@tonic-gate 			X509_CERT_VALUE(object_p) = NULL;
3920Sstevel@tonic-gate 		}
3930Sstevel@tonic-gate 		free(OBJ_CERT(object_p));
3940Sstevel@tonic-gate 	} else if (certtype == CKC_X_509_ATTR_CERT) {
3950Sstevel@tonic-gate 		if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
3960Sstevel@tonic-gate 			cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
3970Sstevel@tonic-gate 			free(X509_ATTR_CERT_VALUE(object_p));
3980Sstevel@tonic-gate 			X509_ATTR_CERT_VALUE(object_p) = NULL;
3990Sstevel@tonic-gate 		}
4000Sstevel@tonic-gate 		if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
4010Sstevel@tonic-gate 			cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
4020Sstevel@tonic-gate 			free(X509_ATTR_CERT_OWNER(object_p));
4030Sstevel@tonic-gate 			X509_ATTR_CERT_OWNER(object_p) = NULL;
4040Sstevel@tonic-gate 		}
4050Sstevel@tonic-gate 		free(OBJ_CERT(object_p));
4060Sstevel@tonic-gate 	}
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate /*
4100Sstevel@tonic-gate  * Clean up and release all the storage in the extra attribute list
4110Sstevel@tonic-gate  * of an object.
4120Sstevel@tonic-gate  */
4130Sstevel@tonic-gate void
soft_cleanup_extra_attr(soft_object_t * object_p)4140Sstevel@tonic-gate soft_cleanup_extra_attr(soft_object_t *object_p)
4150Sstevel@tonic-gate {
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR extra_attr;
4180Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR tmp;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	extra_attr = object_p->extra_attrlistp;
4210Sstevel@tonic-gate 	while (extra_attr) {
4220Sstevel@tonic-gate 		tmp = extra_attr->next;
4230Sstevel@tonic-gate 		if (extra_attr->attr.pValue)
4240Sstevel@tonic-gate 			/*
4250Sstevel@tonic-gate 			 * All extra attributes in the extra attribute
4260Sstevel@tonic-gate 			 * list have pValue points to the value of the
4270Sstevel@tonic-gate 			 * attribute (with simple byte array type).
4280Sstevel@tonic-gate 			 * Free the storage for the value of the attribute.
4290Sstevel@tonic-gate 			 */
4300Sstevel@tonic-gate 			free(extra_attr->attr.pValue);
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 		/* Free the storage for the attribute_info struct. */
4330Sstevel@tonic-gate 		free(extra_attr);
4340Sstevel@tonic-gate 		extra_attr = tmp;
4350Sstevel@tonic-gate 	}
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	object_p->extra_attrlistp = NULL;
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate /*
4420Sstevel@tonic-gate  * Create the attribute_info struct to hold the object's attribute,
4430Sstevel@tonic-gate  * and add it to the extra attribute list of an object.
4440Sstevel@tonic-gate  */
4450Sstevel@tonic-gate CK_RV
soft_add_extra_attr(CK_ATTRIBUTE_PTR template,soft_object_t * object_p)4460Sstevel@tonic-gate soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
4470Sstevel@tonic-gate {
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR attrp;
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 	/* Allocate the storage for the attribute_info struct. */
4520Sstevel@tonic-gate 	attrp = calloc(1, sizeof (attribute_info_t));
4530Sstevel@tonic-gate 	if (attrp == NULL) {
4540Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
4550Sstevel@tonic-gate 	}
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 	/* Set up attribute_info struct. */
4580Sstevel@tonic-gate 	attrp->attr.type = template->type;
4590Sstevel@tonic-gate 	attrp->attr.ulValueLen = template->ulValueLen;
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	if ((template->pValue != NULL) &&
4620Sstevel@tonic-gate 	    (template->ulValueLen > 0)) {
4630Sstevel@tonic-gate 		/* Allocate storage for the value of the attribute. */
4640Sstevel@tonic-gate 		attrp->attr.pValue = malloc(template->ulValueLen);
4650Sstevel@tonic-gate 		if (attrp->attr.pValue == NULL) {
4660Sstevel@tonic-gate 			free(attrp);
4670Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
4680Sstevel@tonic-gate 		}
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 		(void) memcpy(attrp->attr.pValue, template->pValue,
4710Sstevel@tonic-gate 		    template->ulValueLen);
4720Sstevel@tonic-gate 	} else {
4730Sstevel@tonic-gate 		attrp->attr.pValue = NULL;
4740Sstevel@tonic-gate 	}
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	/* Insert the new attribute in front of extra attribute list. */
4770Sstevel@tonic-gate 	if (object_p->extra_attrlistp == NULL) {
4780Sstevel@tonic-gate 		object_p->extra_attrlistp = attrp;
4790Sstevel@tonic-gate 		attrp->next = NULL;
4800Sstevel@tonic-gate 	} else {
4810Sstevel@tonic-gate 		attrp->next = object_p->extra_attrlistp;
4820Sstevel@tonic-gate 		object_p->extra_attrlistp = attrp;
4830Sstevel@tonic-gate 	}
4840Sstevel@tonic-gate 
4850Sstevel@tonic-gate 	return (CKR_OK);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate CK_RV
soft_copy_certificate(certificate_obj_t * oldcert,certificate_obj_t ** newcert,CK_CERTIFICATE_TYPE type)4890Sstevel@tonic-gate soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
4900Sstevel@tonic-gate 		CK_CERTIFICATE_TYPE type)
4910Sstevel@tonic-gate {
4920Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
4930Sstevel@tonic-gate 	certificate_obj_t	*cert;
4940Sstevel@tonic-gate 	x509_cert_t		x509;
4950Sstevel@tonic-gate 	x509_attr_cert_t	x509_attr;
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate 	cert = calloc(1, sizeof (certificate_obj_t));
4980Sstevel@tonic-gate 	if (cert == NULL) {
4990Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
5000Sstevel@tonic-gate 	}
5010Sstevel@tonic-gate 
5020Sstevel@tonic-gate 	if (type == CKC_X_509) {
5030Sstevel@tonic-gate 		x509 = oldcert->cert_type_u.x509;
5040Sstevel@tonic-gate 		if (x509.subject)
5050Sstevel@tonic-gate 			if ((rv = copy_cert_attr(x509.subject,
5065697Smcpowers 			    &cert->cert_type_u.x509.subject)))
5070Sstevel@tonic-gate 				return (rv);
5080Sstevel@tonic-gate 		if (x509.value)
5090Sstevel@tonic-gate 			if ((rv = copy_cert_attr(x509.value,
5105697Smcpowers 			    &cert->cert_type_u.x509.value)))
5110Sstevel@tonic-gate 				return (rv);
5120Sstevel@tonic-gate 	} else if (type == CKC_X_509_ATTR_CERT) {
5130Sstevel@tonic-gate 		x509_attr = oldcert->cert_type_u.x509_attr;
5140Sstevel@tonic-gate 		if (x509_attr.owner)
5150Sstevel@tonic-gate 			if ((rv = copy_cert_attr(x509_attr.owner,
5165697Smcpowers 			    &cert->cert_type_u.x509_attr.owner)))
5170Sstevel@tonic-gate 				return (rv);
5180Sstevel@tonic-gate 		if (x509_attr.value)
5190Sstevel@tonic-gate 			if ((rv = copy_cert_attr(x509_attr.value,
5205697Smcpowers 			    &cert->cert_type_u.x509_attr.value)))
5210Sstevel@tonic-gate 				return (rv);
5220Sstevel@tonic-gate 	} else {
5230Sstevel@tonic-gate 		/* wrong certificate type */
5240Sstevel@tonic-gate 		rv = CKR_ATTRIBUTE_TYPE_INVALID;
5250Sstevel@tonic-gate 	}
5260Sstevel@tonic-gate 	if (rv == CKR_OK)
5270Sstevel@tonic-gate 		*newcert = cert;
5280Sstevel@tonic-gate 	return (rv);
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate /*
5320Sstevel@tonic-gate  * Copy the attribute_info struct from the old object to a new attribute_info
5330Sstevel@tonic-gate  * struct, and add that new struct to the extra attribute list of the new
5340Sstevel@tonic-gate  * object.
5350Sstevel@tonic-gate  */
5360Sstevel@tonic-gate CK_RV
soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,soft_object_t * object_p)5370Sstevel@tonic-gate soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
5380Sstevel@tonic-gate {
5390Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR attrp;
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 	/* Allocate attribute_info struct. */
5420Sstevel@tonic-gate 	attrp = calloc(1, sizeof (attribute_info_t));
5430Sstevel@tonic-gate 	if (attrp == NULL) {
5440Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
5450Sstevel@tonic-gate 	}
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 	attrp->attr.type = old_attrp->attr.type;
5480Sstevel@tonic-gate 	attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	if ((old_attrp->attr.pValue != NULL) &&
5515697Smcpowers 	    (old_attrp->attr.ulValueLen > 0)) {
5520Sstevel@tonic-gate 		attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
5530Sstevel@tonic-gate 		if (attrp->attr.pValue == NULL) {
5540Sstevel@tonic-gate 			free(attrp);
5550Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
5560Sstevel@tonic-gate 		}
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 		(void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
5590Sstevel@tonic-gate 		    old_attrp->attr.ulValueLen);
5600Sstevel@tonic-gate 	} else {
5610Sstevel@tonic-gate 		attrp->attr.pValue = NULL;
5620Sstevel@tonic-gate 	}
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 	/* Insert the new attribute in front of extra attribute list */
5650Sstevel@tonic-gate 	if (object_p->extra_attrlistp == NULL) {
5660Sstevel@tonic-gate 		object_p->extra_attrlistp = attrp;
5670Sstevel@tonic-gate 		attrp->next = NULL;
5680Sstevel@tonic-gate 	} else {
5690Sstevel@tonic-gate 		attrp->next = object_p->extra_attrlistp;
5700Sstevel@tonic-gate 		object_p->extra_attrlistp = attrp;
5710Sstevel@tonic-gate 	}
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate 	return (CKR_OK);
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate /*
5780Sstevel@tonic-gate  * Get the attribute triple from the extra attribute list in the object
5790Sstevel@tonic-gate  * (if the specified attribute type is found), and copy it to a template.
5800Sstevel@tonic-gate  * Note the type of the attribute to be copied is specified by the template,
5810Sstevel@tonic-gate  * and the storage is pre-allocated for the atrribute value in the template
5820Sstevel@tonic-gate  * for doing the copy.
5830Sstevel@tonic-gate  */
5840Sstevel@tonic-gate CK_RV
get_extra_attr_from_object(soft_object_t * object_p,CK_ATTRIBUTE_PTR template)5850Sstevel@tonic-gate get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
5860Sstevel@tonic-gate {
5870Sstevel@tonic-gate 
5880Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR extra_attr;
5890Sstevel@tonic-gate 	CK_ATTRIBUTE_TYPE type = template->type;
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 	extra_attr = object_p->extra_attrlistp;
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 	while (extra_attr) {
5940Sstevel@tonic-gate 		if (type == extra_attr->attr.type) {
5950Sstevel@tonic-gate 			/* Found it. */
5960Sstevel@tonic-gate 			break;
5970Sstevel@tonic-gate 		} else {
5980Sstevel@tonic-gate 			/* Does not match, try next one. */
5990Sstevel@tonic-gate 			extra_attr = extra_attr->next;
6000Sstevel@tonic-gate 		}
6010Sstevel@tonic-gate 	}
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 	if (extra_attr == NULL) {
6040Sstevel@tonic-gate 		/* A valid but un-initialized attribute. */
6050Sstevel@tonic-gate 		template->ulValueLen = 0;
6060Sstevel@tonic-gate 		return (CKR_OK);
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate 	/*
6100Sstevel@tonic-gate 	 * We found the attribute in the extra attribute list.
6110Sstevel@tonic-gate 	 */
6120Sstevel@tonic-gate 	if (template->pValue == NULL) {
6130Sstevel@tonic-gate 		template->ulValueLen = extra_attr->attr.ulValueLen;
6140Sstevel@tonic-gate 		return (CKR_OK);
6150Sstevel@tonic-gate 	}
6160Sstevel@tonic-gate 
6170Sstevel@tonic-gate 	if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
6180Sstevel@tonic-gate 		/*
6190Sstevel@tonic-gate 		 * The buffer provided by the application is large
6200Sstevel@tonic-gate 		 * enough to hold the value of the attribute.
6210Sstevel@tonic-gate 		 */
6220Sstevel@tonic-gate 		(void) memcpy(template->pValue, extra_attr->attr.pValue,
6230Sstevel@tonic-gate 		    extra_attr->attr.ulValueLen);
6240Sstevel@tonic-gate 		template->ulValueLen = extra_attr->attr.ulValueLen;
6250Sstevel@tonic-gate 		return (CKR_OK);
6260Sstevel@tonic-gate 	} else {
6270Sstevel@tonic-gate 		/*
6280Sstevel@tonic-gate 		 * The buffer provided by the application does
6290Sstevel@tonic-gate 		 * not have enough space to hold the value.
6300Sstevel@tonic-gate 		 */
6310Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
6320Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
6330Sstevel@tonic-gate 	}
6340Sstevel@tonic-gate }
6350Sstevel@tonic-gate 
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate /*
6380Sstevel@tonic-gate  * Modify the attribute triple in the extra attribute list of the object
6390Sstevel@tonic-gate  * if the specified attribute type is found. Otherwise, just add it to
6400Sstevel@tonic-gate  * list.
6410Sstevel@tonic-gate  */
6420Sstevel@tonic-gate CK_RV
set_extra_attr_to_object(soft_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)6430Sstevel@tonic-gate set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
6440Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
6450Sstevel@tonic-gate {
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR extra_attr;
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	extra_attr = object_p->extra_attrlistp;
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 	while (extra_attr) {
6520Sstevel@tonic-gate 		if (type == extra_attr->attr.type) {
6530Sstevel@tonic-gate 			/* Found it. */
6540Sstevel@tonic-gate 			break;
6550Sstevel@tonic-gate 		} else {
6560Sstevel@tonic-gate 			/* Does not match, try next one. */
6570Sstevel@tonic-gate 			extra_attr = extra_attr->next;
6580Sstevel@tonic-gate 		}
6590Sstevel@tonic-gate 	}
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	if (extra_attr == NULL) {
6620Sstevel@tonic-gate 		/*
6630Sstevel@tonic-gate 		 * This attribute is a new one, go ahead adding it to
6640Sstevel@tonic-gate 		 * the extra attribute list.
6650Sstevel@tonic-gate 		 */
6660Sstevel@tonic-gate 		return (soft_add_extra_attr(template, object_p));
6670Sstevel@tonic-gate 	}
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	/* We found the attribute in the extra attribute list. */
6700Sstevel@tonic-gate 	if ((template->pValue != NULL) &&
6710Sstevel@tonic-gate 	    (template->ulValueLen > 0)) {
6720Sstevel@tonic-gate 		if (template->ulValueLen > extra_attr->attr.ulValueLen) {
6730Sstevel@tonic-gate 			/* The old buffer is too small to hold the new value. */
6740Sstevel@tonic-gate 			if (extra_attr->attr.pValue != NULL)
6750Sstevel@tonic-gate 				/* Free storage for the old attribute value. */
6760Sstevel@tonic-gate 				free(extra_attr->attr.pValue);
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate 			/* Allocate storage for the new attribute value. */
6790Sstevel@tonic-gate 			extra_attr->attr.pValue = malloc(template->ulValueLen);
6800Sstevel@tonic-gate 			if (extra_attr->attr.pValue == NULL) {
6810Sstevel@tonic-gate 				return (CKR_HOST_MEMORY);
6820Sstevel@tonic-gate 			}
6830Sstevel@tonic-gate 		}
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 		/* Replace the attribute with new value. */
6860Sstevel@tonic-gate 		extra_attr->attr.ulValueLen = template->ulValueLen;
6870Sstevel@tonic-gate 		(void) memcpy(extra_attr->attr.pValue, template->pValue,
6880Sstevel@tonic-gate 		    template->ulValueLen);
6890Sstevel@tonic-gate 	} else {
6900Sstevel@tonic-gate 		extra_attr->attr.pValue = NULL;
6910Sstevel@tonic-gate 	}
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 	return (CKR_OK);
6940Sstevel@tonic-gate }
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate /*
6980Sstevel@tonic-gate  * Copy the big integer attribute value from template to a biginteger_t struct.
6990Sstevel@tonic-gate  */
7000Sstevel@tonic-gate CK_RV
get_bigint_attr_from_template(biginteger_t * big,CK_ATTRIBUTE_PTR template)7010Sstevel@tonic-gate get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate 	if ((template->pValue != NULL) &&
7050Sstevel@tonic-gate 	    (template->ulValueLen > 0)) {
7060Sstevel@tonic-gate 		/* Allocate storage for the value of the attribute. */
7070Sstevel@tonic-gate 		big->big_value = malloc(template->ulValueLen);
7080Sstevel@tonic-gate 		if (big->big_value == NULL) {
7090Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
7100Sstevel@tonic-gate 		}
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 		(void) memcpy(big->big_value, template->pValue,
7130Sstevel@tonic-gate 		    template->ulValueLen);
7140Sstevel@tonic-gate 		big->big_value_len = template->ulValueLen;
7150Sstevel@tonic-gate 	} else {
7160Sstevel@tonic-gate 		big->big_value = NULL;
7170Sstevel@tonic-gate 		big->big_value_len = 0;
7180Sstevel@tonic-gate 	}
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate 	return (CKR_OK);
7210Sstevel@tonic-gate }
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate /*
7250Sstevel@tonic-gate  * Copy the big integer attribute value from a biginteger_t struct in the
7260Sstevel@tonic-gate  * object to a template.
7270Sstevel@tonic-gate  */
7280Sstevel@tonic-gate CK_RV
get_bigint_attr_from_object(biginteger_t * big,CK_ATTRIBUTE_PTR template)7290Sstevel@tonic-gate get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
7300Sstevel@tonic-gate {
7310Sstevel@tonic-gate 
7320Sstevel@tonic-gate 	if (template->pValue == NULL) {
7330Sstevel@tonic-gate 		template->ulValueLen = big->big_value_len;
7340Sstevel@tonic-gate 		return (CKR_OK);
7350Sstevel@tonic-gate 	}
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 	if (big->big_value == NULL) {
7380Sstevel@tonic-gate 		template->ulValueLen = 0;
7390Sstevel@tonic-gate 		return (CKR_OK);
7400Sstevel@tonic-gate 	}
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 	if (template->ulValueLen >= big->big_value_len) {
7430Sstevel@tonic-gate 		/*
7440Sstevel@tonic-gate 		 * The buffer provided by the application is large
7450Sstevel@tonic-gate 		 * enough to hold the value of the attribute.
7460Sstevel@tonic-gate 		 */
7470Sstevel@tonic-gate 		(void) memcpy(template->pValue, big->big_value,
7480Sstevel@tonic-gate 		    big->big_value_len);
7490Sstevel@tonic-gate 		template->ulValueLen = big->big_value_len;
7500Sstevel@tonic-gate 		return (CKR_OK);
7510Sstevel@tonic-gate 	} else {
7520Sstevel@tonic-gate 		/*
7530Sstevel@tonic-gate 		 * The buffer provided by the application does
7540Sstevel@tonic-gate 		 * not have enough space to hold the value.
7550Sstevel@tonic-gate 		 */
7560Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
7570Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate /*
7630Sstevel@tonic-gate  * Copy the boolean data type attribute value from an object for the
7640Sstevel@tonic-gate  * specified attribute to the template.
7650Sstevel@tonic-gate  */
7660Sstevel@tonic-gate CK_RV
get_bool_attr_from_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)7670Sstevel@tonic-gate get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
7680Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
7690Sstevel@tonic-gate {
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate 	if (template->pValue == NULL) {
7720Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_BBOOL);
7730Sstevel@tonic-gate 		return (CKR_OK);
7740Sstevel@tonic-gate 	}
7750Sstevel@tonic-gate 
7760Sstevel@tonic-gate 	if (template->ulValueLen >= sizeof (CK_BBOOL)) {
7770Sstevel@tonic-gate 		/*
7780Sstevel@tonic-gate 		 * The buffer provided by the application is large
7790Sstevel@tonic-gate 		 * enough to hold the value of the attribute.
7800Sstevel@tonic-gate 		 */
7810Sstevel@tonic-gate 		if (object_p->bool_attr_mask & bool_flag) {
7820Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_TRUE;
7830Sstevel@tonic-gate 		} else {
7840Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_FALSE;
7850Sstevel@tonic-gate 		}
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_BBOOL);
7880Sstevel@tonic-gate 		return (CKR_OK);
7890Sstevel@tonic-gate 	} else {
7900Sstevel@tonic-gate 		/*
7910Sstevel@tonic-gate 		 * The buffer provided by the application does
7920Sstevel@tonic-gate 		 * not have enough space to hold the value.
7930Sstevel@tonic-gate 		 */
7940Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
7950Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
7960Sstevel@tonic-gate 	}
7970Sstevel@tonic-gate }
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate /*
8000Sstevel@tonic-gate  * Set the boolean data type attribute value in the object.
8010Sstevel@tonic-gate  */
8020Sstevel@tonic-gate CK_RV
set_bool_attr_to_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)8030Sstevel@tonic-gate set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
8040Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
8050Sstevel@tonic-gate {
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	if (*(CK_BBOOL *)template->pValue)
8080Sstevel@tonic-gate 		object_p->bool_attr_mask |= bool_flag;
8090Sstevel@tonic-gate 	else
8100Sstevel@tonic-gate 		object_p->bool_attr_mask &= ~bool_flag;
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate 	return (CKR_OK);
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 
8160Sstevel@tonic-gate /*
8170Sstevel@tonic-gate  * Copy the CK_ULONG data type attribute value from an object to the
8180Sstevel@tonic-gate  * template.
8190Sstevel@tonic-gate  */
8200Sstevel@tonic-gate CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)8210Sstevel@tonic-gate get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
8220Sstevel@tonic-gate {
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 	if (template->pValue == NULL) {
8250Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_ULONG);
8260Sstevel@tonic-gate 		return (CKR_OK);
8270Sstevel@tonic-gate 	}
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate 	if (template->ulValueLen >= sizeof (CK_ULONG)) {
8300Sstevel@tonic-gate 		/*
8310Sstevel@tonic-gate 		 * The buffer provided by the application is large
8320Sstevel@tonic-gate 		 * enough to hold the value of the attribute.
8330Sstevel@tonic-gate 		 * It is also assumed to be correctly aligned.
8340Sstevel@tonic-gate 		 */
8350Sstevel@tonic-gate 		*(CK_ULONG_PTR)template->pValue = value;
8360Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_ULONG);
8370Sstevel@tonic-gate 		return (CKR_OK);
8380Sstevel@tonic-gate 	} else {
8390Sstevel@tonic-gate 		/*
8400Sstevel@tonic-gate 		 * The buffer provided by the application does
8410Sstevel@tonic-gate 		 * not have enough space to hold the value.
8420Sstevel@tonic-gate 		 */
8430Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
8440Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
8450Sstevel@tonic-gate 	}
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate 
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate /*
8500Sstevel@tonic-gate  * Copy the CK_ULONG data type attribute value from a template to the
8510Sstevel@tonic-gate  * object.
8520Sstevel@tonic-gate  */
8537512SAnthony.Scarpino@Sun.COM static CK_RV
get_ulong_attr_from_template(CK_ULONG * value,CK_ATTRIBUTE_PTR template)8540Sstevel@tonic-gate get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
8550Sstevel@tonic-gate {
8560Sstevel@tonic-gate 
8577512SAnthony.Scarpino@Sun.COM 	if (template->ulValueLen < sizeof (CK_ULONG))
8587512SAnthony.Scarpino@Sun.COM 		return (CKR_ATTRIBUTE_VALUE_INVALID);
8597512SAnthony.Scarpino@Sun.COM 
8600Sstevel@tonic-gate 	if (template->pValue != NULL) {
8610Sstevel@tonic-gate 		*value = *(CK_ULONG_PTR)template->pValue;
8620Sstevel@tonic-gate 	} else {
8630Sstevel@tonic-gate 		*value = 0;
8640Sstevel@tonic-gate 	}
8657512SAnthony.Scarpino@Sun.COM 
8667512SAnthony.Scarpino@Sun.COM 	return (CKR_OK);
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate /*
8700Sstevel@tonic-gate  * Copy the big integer attribute value from source's biginteger_t to
8710Sstevel@tonic-gate  * destination's biginteger_t.
8720Sstevel@tonic-gate  */
8730Sstevel@tonic-gate void
copy_bigint_attr(biginteger_t * src,biginteger_t * dst)8740Sstevel@tonic-gate copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
8750Sstevel@tonic-gate {
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	if ((src->big_value != NULL) &&
8780Sstevel@tonic-gate 	    (src->big_value_len > 0)) {
8790Sstevel@tonic-gate 		/*
8800Sstevel@tonic-gate 		 * To do the copy, just have dst's big_value points
8810Sstevel@tonic-gate 		 * to src's.
8820Sstevel@tonic-gate 		 */
8830Sstevel@tonic-gate 		dst->big_value = src->big_value;
8840Sstevel@tonic-gate 		dst->big_value_len = src->big_value_len;
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 		/*
8870Sstevel@tonic-gate 		 * After the copy, nullify the src's big_value pointer.
8880Sstevel@tonic-gate 		 * It prevents any double freeing the value.
8890Sstevel@tonic-gate 		 */
8900Sstevel@tonic-gate 		src->big_value = NULL;
8910Sstevel@tonic-gate 		src->big_value_len = 0;
8920Sstevel@tonic-gate 	} else {
8930Sstevel@tonic-gate 		dst->big_value = NULL;
8940Sstevel@tonic-gate 		dst->big_value_len = 0;
8950Sstevel@tonic-gate 	}
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)8990Sstevel@tonic-gate get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
9000Sstevel@tonic-gate {
9010Sstevel@tonic-gate 	if ((src->pValue != NULL) &&
9020Sstevel@tonic-gate 	    (src->ulValueLen > 0)) {
9030Sstevel@tonic-gate 		/* Allocate storage for the value of the attribute. */
9040Sstevel@tonic-gate 		dest->pValue = malloc(src->ulValueLen);
9050Sstevel@tonic-gate 		if (dest->pValue == NULL) {
9060Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
9070Sstevel@tonic-gate 		}
9080Sstevel@tonic-gate 
9090Sstevel@tonic-gate 		(void) memcpy(dest->pValue, src->pValue,
9100Sstevel@tonic-gate 		    src->ulValueLen);
9110Sstevel@tonic-gate 		dest->ulValueLen = src->ulValueLen;
9120Sstevel@tonic-gate 		dest->type = src->type;
9130Sstevel@tonic-gate 	} else {
9140Sstevel@tonic-gate 		dest->pValue = NULL;
9150Sstevel@tonic-gate 		dest->ulValueLen = 0;
9160Sstevel@tonic-gate 		dest->type = src->type;
9170Sstevel@tonic-gate 	}
9180Sstevel@tonic-gate 
9190Sstevel@tonic-gate 	return (CKR_OK);
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate }
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate CK_RV
get_cert_attr_from_template(cert_attr_t ** dest,CK_ATTRIBUTE_PTR src)9240Sstevel@tonic-gate get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
9250Sstevel@tonic-gate {
9260Sstevel@tonic-gate 	if (src->pValue != NULL && src->ulValueLen > 0) {
9270Sstevel@tonic-gate 		/*
9280Sstevel@tonic-gate 		 * If the attribute was already set, clear out the
9290Sstevel@tonic-gate 		 * existing value and release the memory.
9300Sstevel@tonic-gate 		 */
9310Sstevel@tonic-gate 		if (*dest != NULL) {
9320Sstevel@tonic-gate 			if ((*dest)->value != NULL) {
9330Sstevel@tonic-gate 				(void) memset((*dest)->value, 0,
9345697Smcpowers 				    (*dest)->length);
9350Sstevel@tonic-gate 				free((*dest)->value);
9360Sstevel@tonic-gate 			}
9370Sstevel@tonic-gate 		} else {
9380Sstevel@tonic-gate 			*dest = malloc(sizeof (cert_attr_t));
9390Sstevel@tonic-gate 			if (*dest == NULL) {
9400Sstevel@tonic-gate 				return (CKR_HOST_MEMORY);
9410Sstevel@tonic-gate 			}
9420Sstevel@tonic-gate 			(void) memset(*dest, 0, sizeof (cert_attr_t));
9430Sstevel@tonic-gate 		}
9440Sstevel@tonic-gate 		(*dest)->value = malloc(src->ulValueLen);
9450Sstevel@tonic-gate 		if ((*dest)->value == NULL) {
9460Sstevel@tonic-gate 			free(*dest);
9470Sstevel@tonic-gate 			*dest = NULL;
9480Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
9490Sstevel@tonic-gate 		}
9500Sstevel@tonic-gate 		(void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
9510Sstevel@tonic-gate 		(*dest)->length = src->ulValueLen;
9520Sstevel@tonic-gate 	}
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 	return (CKR_OK);
9550Sstevel@tonic-gate }
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate /*
9580Sstevel@tonic-gate  * Copy the certificate attribute information to the template.
9590Sstevel@tonic-gate  * If the template attribute is not big enough, set the ulValueLen=-1
9600Sstevel@tonic-gate  * and return CKR_BUFFER_TOO_SMALL.
9610Sstevel@tonic-gate  */
9620Sstevel@tonic-gate static CK_RV
get_cert_attr_from_object(cert_attr_t * src,CK_ATTRIBUTE_PTR template)9630Sstevel@tonic-gate get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
9640Sstevel@tonic-gate {
9650Sstevel@tonic-gate 	if (template->pValue == NULL) {
9660Sstevel@tonic-gate 		template->ulValueLen = src->length;
9670Sstevel@tonic-gate 		return (CKR_OK);
9680Sstevel@tonic-gate 	} else if (template->ulValueLen >= src->length) {
9690Sstevel@tonic-gate 		/*
9700Sstevel@tonic-gate 		 * The buffer provided by the application is large
9710Sstevel@tonic-gate 		 * enough to hold the value of the attribute.
9720Sstevel@tonic-gate 		 */
9730Sstevel@tonic-gate 		(void) memcpy(template->pValue, src->value, src->length);
9740Sstevel@tonic-gate 		template->ulValueLen = src->length;
9750Sstevel@tonic-gate 		return (CKR_OK);
9760Sstevel@tonic-gate 	} else {
9770Sstevel@tonic-gate 		/*
9780Sstevel@tonic-gate 		 * The buffer provided by the application does
9790Sstevel@tonic-gate 		 * not have enough space to hold the value.
9800Sstevel@tonic-gate 		 */
9810Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
9820Sstevel@tonic-gate 		return (CKR_BUFFER_TOO_SMALL);
9830Sstevel@tonic-gate 	}
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)9870Sstevel@tonic-gate string_attr_cleanup(CK_ATTRIBUTE_PTR template)
9880Sstevel@tonic-gate {
9890Sstevel@tonic-gate 
9900Sstevel@tonic-gate 	if (template->pValue) {
9910Sstevel@tonic-gate 		free(template->pValue);
9920Sstevel@tonic-gate 		template->pValue = NULL;
9930Sstevel@tonic-gate 		template->ulValueLen = 0;
9940Sstevel@tonic-gate 	}
9950Sstevel@tonic-gate }
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate /*
9980Sstevel@tonic-gate  * Release the storage allocated for object attribute with big integer
9990Sstevel@tonic-gate  * value.
10000Sstevel@tonic-gate  */
10010Sstevel@tonic-gate void
bigint_attr_cleanup(biginteger_t * big)10020Sstevel@tonic-gate bigint_attr_cleanup(biginteger_t *big)
10030Sstevel@tonic-gate {
10040Sstevel@tonic-gate 
10050Sstevel@tonic-gate 	if (big == NULL)
10060Sstevel@tonic-gate 		return;
10070Sstevel@tonic-gate 
10080Sstevel@tonic-gate 	if (big->big_value) {
10090Sstevel@tonic-gate 		(void) memset(big->big_value, 0, big->big_value_len);
10100Sstevel@tonic-gate 		free(big->big_value);
10110Sstevel@tonic-gate 		big->big_value = NULL;
10120Sstevel@tonic-gate 		big->big_value_len = 0;
10130Sstevel@tonic-gate 	}
10140Sstevel@tonic-gate }
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate /*
10180Sstevel@tonic-gate  * Clean up and release all the storage allocated to hold the big integer
10190Sstevel@tonic-gate  * attributes associated with the type (i.e. class) of the object. Also,
10200Sstevel@tonic-gate  * release the storage allocated to the type of the object.
10210Sstevel@tonic-gate  */
10220Sstevel@tonic-gate void
soft_cleanup_object_bigint_attrs(soft_object_t * object_p)10230Sstevel@tonic-gate soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
10240Sstevel@tonic-gate {
10250Sstevel@tonic-gate 
10260Sstevel@tonic-gate 	CK_OBJECT_CLASS class = object_p->class;
10270Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
10280Sstevel@tonic-gate 
10290Sstevel@tonic-gate 
10300Sstevel@tonic-gate 	switch (class) {
10310Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
10320Sstevel@tonic-gate 		if (OBJ_PUB(object_p)) {
10330Sstevel@tonic-gate 			switch (keytype) {
10340Sstevel@tonic-gate 			case CKK_RSA:
10350Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
10360Sstevel@tonic-gate 				    object_p));
10370Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
10380Sstevel@tonic-gate 				    object_p));
10390Sstevel@tonic-gate 				break;
10400Sstevel@tonic-gate 
10410Sstevel@tonic-gate 			case CKK_DSA:
10420Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
10430Sstevel@tonic-gate 				    object_p));
10440Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
10450Sstevel@tonic-gate 				    object_p));
10460Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
10470Sstevel@tonic-gate 				    object_p));
10480Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
10490Sstevel@tonic-gate 				    object_p));
10500Sstevel@tonic-gate 				break;
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate 			case CKK_DH:
10530Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
10540Sstevel@tonic-gate 				    object_p));
10550Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH_BASE(
10560Sstevel@tonic-gate 				    object_p));
10570Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
10580Sstevel@tonic-gate 				    object_p));
10590Sstevel@tonic-gate 				break;
10600Sstevel@tonic-gate 
10610Sstevel@tonic-gate 			case CKK_X9_42_DH:
10620Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
10630Sstevel@tonic-gate 				    object_p));
10640Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
10650Sstevel@tonic-gate 				    object_p));
10660Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
10670Sstevel@tonic-gate 				    object_p));
10680Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
10690Sstevel@tonic-gate 				    object_p));
10700Sstevel@tonic-gate 				break;
10714219Smcpowers 			case CKK_EC:
10724219Smcpowers 				bigint_attr_cleanup(OBJ_PUB_EC_POINT(
10734219Smcpowers 				    object_p));
10744219Smcpowers 				break;
10750Sstevel@tonic-gate 			}
10760Sstevel@tonic-gate 
10770Sstevel@tonic-gate 			/* Release Public Key Object struct */
10780Sstevel@tonic-gate 			free(OBJ_PUB(object_p));
10790Sstevel@tonic-gate 			OBJ_PUB(object_p) = NULL;
10800Sstevel@tonic-gate 		}
10810Sstevel@tonic-gate 		break;
10820Sstevel@tonic-gate 
10830Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
10840Sstevel@tonic-gate 		if (OBJ_PRI(object_p)) {
10850Sstevel@tonic-gate 			switch (keytype) {
10860Sstevel@tonic-gate 			case CKK_RSA:
10870Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
10880Sstevel@tonic-gate 				    object_p));
10890Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
10900Sstevel@tonic-gate 				    object_p));
10910Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
10920Sstevel@tonic-gate 				    object_p));
10930Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
10940Sstevel@tonic-gate 				    object_p));
10950Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
10960Sstevel@tonic-gate 				    object_p));
10970Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
10980Sstevel@tonic-gate 				    object_p));
10990Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
11000Sstevel@tonic-gate 				    object_p));
11010Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
11020Sstevel@tonic-gate 				    object_p));
11030Sstevel@tonic-gate 				break;
11040Sstevel@tonic-gate 
11050Sstevel@tonic-gate 			case CKK_DSA:
11060Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
11070Sstevel@tonic-gate 				    object_p));
11080Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
11090Sstevel@tonic-gate 				    object_p));
11100Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
11110Sstevel@tonic-gate 				    object_p));
11120Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
11130Sstevel@tonic-gate 				    object_p));
11140Sstevel@tonic-gate 				break;
11150Sstevel@tonic-gate 
11160Sstevel@tonic-gate 			case CKK_DH:
11170Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
11180Sstevel@tonic-gate 				    object_p));
11190Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH_BASE(
11200Sstevel@tonic-gate 				    object_p));
11210Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
11220Sstevel@tonic-gate 				    object_p));
11230Sstevel@tonic-gate 				break;
11240Sstevel@tonic-gate 
11250Sstevel@tonic-gate 			case CKK_X9_42_DH:
11260Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
11270Sstevel@tonic-gate 				    object_p));
11280Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
11290Sstevel@tonic-gate 				    object_p));
11300Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
11310Sstevel@tonic-gate 				    object_p));
11320Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
11330Sstevel@tonic-gate 				    object_p));
11340Sstevel@tonic-gate 				break;
11354219Smcpowers 
11364219Smcpowers 			case CKK_EC:
11374219Smcpowers 				bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
11384219Smcpowers 				    object_p));
11394219Smcpowers 				break;
11400Sstevel@tonic-gate 			}
11410Sstevel@tonic-gate 
11420Sstevel@tonic-gate 			/* Release Private Key Object struct. */
11430Sstevel@tonic-gate 			free(OBJ_PRI(object_p));
11440Sstevel@tonic-gate 			OBJ_PRI(object_p) = NULL;
11450Sstevel@tonic-gate 		}
11460Sstevel@tonic-gate 		break;
11470Sstevel@tonic-gate 
11480Sstevel@tonic-gate 	case CKO_SECRET_KEY:
11490Sstevel@tonic-gate 		if (OBJ_SEC(object_p)) {
11500Sstevel@tonic-gate 			/* cleanup key data area */
11510Sstevel@tonic-gate 			if (OBJ_SEC_VALUE(object_p) != NULL &&
11520Sstevel@tonic-gate 			    OBJ_SEC_VALUE_LEN(object_p) > 0) {
11530Sstevel@tonic-gate 				(void) memset(OBJ_SEC_VALUE(object_p), 0,
11545697Smcpowers 				    OBJ_SEC_VALUE_LEN(object_p));
11550Sstevel@tonic-gate 				free(OBJ_SEC_VALUE(object_p));
11560Sstevel@tonic-gate 			}
11570Sstevel@tonic-gate 			/* cleanup key schedule data area */
11580Sstevel@tonic-gate 			if (OBJ_KEY_SCHED(object_p) != NULL &&
11590Sstevel@tonic-gate 			    OBJ_KEY_SCHED_LEN(object_p) > 0) {
11600Sstevel@tonic-gate 				(void) memset(OBJ_KEY_SCHED(object_p), 0,
11615697Smcpowers 				    OBJ_KEY_SCHED_LEN(object_p));
11620Sstevel@tonic-gate 				free(OBJ_KEY_SCHED(object_p));
11630Sstevel@tonic-gate 			}
11640Sstevel@tonic-gate 
11650Sstevel@tonic-gate 			/* Release Secret Key Object struct. */
11660Sstevel@tonic-gate 			free(OBJ_SEC(object_p));
11670Sstevel@tonic-gate 			OBJ_SEC(object_p) = NULL;
11680Sstevel@tonic-gate 		}
11690Sstevel@tonic-gate 		break;
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
11720Sstevel@tonic-gate 		if (OBJ_DOM(object_p)) {
11730Sstevel@tonic-gate 			switch (keytype) {
11740Sstevel@tonic-gate 			case CKK_DSA:
11750Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
11760Sstevel@tonic-gate 				    object_p));
11770Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
11780Sstevel@tonic-gate 				    object_p));
11790Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
11800Sstevel@tonic-gate 				    object_p));
11810Sstevel@tonic-gate 				break;
11820Sstevel@tonic-gate 
11830Sstevel@tonic-gate 			case CKK_DH:
11840Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
11850Sstevel@tonic-gate 				    object_p));
11860Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DH_BASE(
11870Sstevel@tonic-gate 				    object_p));
11880Sstevel@tonic-gate 				break;
11890Sstevel@tonic-gate 
11900Sstevel@tonic-gate 			case CKK_X9_42_DH:
11910Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
11920Sstevel@tonic-gate 				    object_p));
11930Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
11940Sstevel@tonic-gate 				    object_p));
11950Sstevel@tonic-gate 				bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
11960Sstevel@tonic-gate 				    object_p));
11970Sstevel@tonic-gate 				break;
11980Sstevel@tonic-gate 			}
11990Sstevel@tonic-gate 
12000Sstevel@tonic-gate 			/* Release Domain Parameters Object struct. */
12010Sstevel@tonic-gate 			free(OBJ_DOM(object_p));
12020Sstevel@tonic-gate 			OBJ_DOM(object_p) = NULL;
12030Sstevel@tonic-gate 		}
12040Sstevel@tonic-gate 		break;
12050Sstevel@tonic-gate 	}
12060Sstevel@tonic-gate }
12070Sstevel@tonic-gate 
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate /*
12100Sstevel@tonic-gate  * Parse the common attributes. Return to caller with appropriate return
12110Sstevel@tonic-gate  * value to indicate if the supplied template specifies a valid attribute
12120Sstevel@tonic-gate  * with a valid value.
12130Sstevel@tonic-gate  */
12140Sstevel@tonic-gate CK_RV
soft_parse_common_attrs(CK_ATTRIBUTE_PTR template,uchar_t * object_type)12150Sstevel@tonic-gate soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
12160Sstevel@tonic-gate {
12170Sstevel@tonic-gate 
12180Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate 	switch (template->type) {
12210Sstevel@tonic-gate 	case CKA_CLASS:
12220Sstevel@tonic-gate 		break;
12230Sstevel@tonic-gate 
12240Sstevel@tonic-gate 	/* default boolean attributes */
12250Sstevel@tonic-gate 	case CKA_TOKEN:
12260Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
12271937Sizick 			if (!soft_keystore_status(KEYSTORE_INITIALIZED))
12280Sstevel@tonic-gate 				return (CKR_DEVICE_REMOVED);
12290Sstevel@tonic-gate 			*object_type |= TOKEN_OBJECT;
12300Sstevel@tonic-gate 		}
12310Sstevel@tonic-gate 		break;
12320Sstevel@tonic-gate 
12330Sstevel@tonic-gate 	case CKA_PRIVATE:
12340Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
12350Sstevel@tonic-gate 			(void) pthread_mutex_lock(&soft_giant_mutex);
12360Sstevel@tonic-gate 			if (!soft_slot.authenticated) {
12370Sstevel@tonic-gate 				/*
12380Sstevel@tonic-gate 				 * Check if this is the special case when
12390Sstevel@tonic-gate 				 * the PIN is never initialized in the keystore.
12400Sstevel@tonic-gate 				 * If true, we will let it pass here and let
12410Sstevel@tonic-gate 				 * it fail with CKR_PIN_EXPIRED later on.
12420Sstevel@tonic-gate 				 */
12430Sstevel@tonic-gate 				if (!soft_slot.userpin_change_needed) {
12440Sstevel@tonic-gate 					(void) pthread_mutex_unlock(
12450Sstevel@tonic-gate 					    &soft_giant_mutex);
12460Sstevel@tonic-gate 					return (CKR_USER_NOT_LOGGED_IN);
12470Sstevel@tonic-gate 				}
12480Sstevel@tonic-gate 			}
12490Sstevel@tonic-gate 			(void) pthread_mutex_unlock(&soft_giant_mutex);
12500Sstevel@tonic-gate 			*object_type |= PRIVATE_OBJECT;
12510Sstevel@tonic-gate 		}
12520Sstevel@tonic-gate 		break;
12530Sstevel@tonic-gate 
12540Sstevel@tonic-gate 	case CKA_LABEL:
12550Sstevel@tonic-gate 		break;
12560Sstevel@tonic-gate 
12570Sstevel@tonic-gate 	default:
12580Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
12590Sstevel@tonic-gate 	}
12600Sstevel@tonic-gate 
12610Sstevel@tonic-gate 	return (rv);
12620Sstevel@tonic-gate }
12630Sstevel@tonic-gate 
12640Sstevel@tonic-gate 
12650Sstevel@tonic-gate /*
12660Sstevel@tonic-gate  * Build a Public Key Object.
12670Sstevel@tonic-gate  *
12680Sstevel@tonic-gate  * - Parse the object's template, and when an error is detected such as
12690Sstevel@tonic-gate  *   invalid attribute type, invalid attribute value, etc., return
12700Sstevel@tonic-gate  *   with appropriate return value.
12710Sstevel@tonic-gate  * - Set up attribute mask field in the object for the supplied common
12720Sstevel@tonic-gate  *   attributes that have boolean type.
12730Sstevel@tonic-gate  * - Build the attribute_info struct to hold the value of each supplied
12740Sstevel@tonic-gate  *   attribute that has byte array type. Link attribute_info structs
12750Sstevel@tonic-gate  *   together to form the extra attribute list of the object.
12760Sstevel@tonic-gate  * - Allocate storage for the Public Key object.
12770Sstevel@tonic-gate  * - Build the Public Key object according to the key type. Allocate
12780Sstevel@tonic-gate  *   storage to hold the big integer value for the supplied attributes
12790Sstevel@tonic-gate  *   that are required for a certain key type.
12800Sstevel@tonic-gate  *
12810Sstevel@tonic-gate  */
12820Sstevel@tonic-gate CK_RV
soft_build_public_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,soft_object_t * new_object,CK_ULONG mode,CK_KEY_TYPE key_type)12830Sstevel@tonic-gate soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
12840Sstevel@tonic-gate 	soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
12850Sstevel@tonic-gate {
12860Sstevel@tonic-gate 
12870Sstevel@tonic-gate 	ulong_t		i;
12880Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = (CK_KEY_TYPE)~0UL;
12890Sstevel@tonic-gate 	uint64_t	attr_mask = PUBLIC_KEY_DEFAULT;
12900Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
12910Sstevel@tonic-gate 	int		isLabel = 0;
12920Sstevel@tonic-gate 	/* Must set flags */
12930Sstevel@tonic-gate 	int		isModulus = 0;
12940Sstevel@tonic-gate 	int		isPubExpo = 0;
12950Sstevel@tonic-gate 	int		isPrime = 0;
12960Sstevel@tonic-gate 	int		isSubprime = 0;
12970Sstevel@tonic-gate 	int		isBase = 0;
12980Sstevel@tonic-gate 	int		isValue = 0;
12994219Smcpowers 	int		isECParam = 0;
13004219Smcpowers 	int		isECPoint = 0;
13010Sstevel@tonic-gate 	/* Must not set flags */
13020Sstevel@tonic-gate 	int		isModulusBits = 0;
13030Sstevel@tonic-gate 	CK_ULONG	modulus_bits = 0;
13040Sstevel@tonic-gate 
13050Sstevel@tonic-gate 	biginteger_t	modulus;
13060Sstevel@tonic-gate 	biginteger_t	pubexpo;
13075697Smcpowers 	biginteger_t	prime;
13085697Smcpowers 	biginteger_t	subprime;
13090Sstevel@tonic-gate 	biginteger_t	base;
13100Sstevel@tonic-gate 	biginteger_t	value;
13115697Smcpowers 	biginteger_t	point;
13120Sstevel@tonic-gate 	CK_ATTRIBUTE	string_tmp;
13135697Smcpowers 	CK_ATTRIBUTE	param_tmp;
13140Sstevel@tonic-gate 
13150Sstevel@tonic-gate 	public_key_obj_t  *pbk;
13160Sstevel@tonic-gate 	uchar_t	object_type = 0;
13170Sstevel@tonic-gate 
13189536SDina.Nimeh@Sun.COM 	CK_ATTRIBUTE	defpubexpo = { CKA_PUBLIC_EXPONENT,
13199536SDina.Nimeh@Sun.COM 	    (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
13209536SDina.Nimeh@Sun.COM 
13219536SDina.Nimeh@Sun.COM 	BIGNUM		n;
13229536SDina.Nimeh@Sun.COM 
13230Sstevel@tonic-gate 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
13240Sstevel@tonic-gate 	(void) memset(&modulus, 0x0, sizeof (biginteger_t));
13250Sstevel@tonic-gate 	(void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
13260Sstevel@tonic-gate 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
13270Sstevel@tonic-gate 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
13280Sstevel@tonic-gate 	(void) memset(&base, 0x0, sizeof (biginteger_t));
13290Sstevel@tonic-gate 	(void) memset(&value, 0x0, sizeof (biginteger_t));
13305697Smcpowers 	(void) memset(&point, 0x0, sizeof (biginteger_t));
13310Sstevel@tonic-gate 	string_tmp.pValue = NULL;
13325697Smcpowers 	param_tmp.pValue = NULL;
13330Sstevel@tonic-gate 
13340Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
13350Sstevel@tonic-gate 
13360Sstevel@tonic-gate 		/* Public Key Object Attributes */
13370Sstevel@tonic-gate 		switch (template[i].type) {
13380Sstevel@tonic-gate 
13390Sstevel@tonic-gate 		/* common key attributes */
13400Sstevel@tonic-gate 		case CKA_KEY_TYPE:
13410Sstevel@tonic-gate 			keytype = *((CK_KEY_TYPE*)template[i].pValue);
13420Sstevel@tonic-gate 			break;
13430Sstevel@tonic-gate 
13440Sstevel@tonic-gate 		case CKA_ID:
13450Sstevel@tonic-gate 		case CKA_START_DATE:
13460Sstevel@tonic-gate 		case CKA_END_DATE:
13470Sstevel@tonic-gate 
13480Sstevel@tonic-gate 		/* common public key attribute */
13490Sstevel@tonic-gate 		case CKA_SUBJECT:
13500Sstevel@tonic-gate 			/*
13510Sstevel@tonic-gate 			 * Allocate storage to hold the attribute
13520Sstevel@tonic-gate 			 * value with byte array type, and add it to
13530Sstevel@tonic-gate 			 * the extra attribute list of the object.
13540Sstevel@tonic-gate 			 */
13550Sstevel@tonic-gate 			rv = soft_add_extra_attr(&template[i],
13560Sstevel@tonic-gate 			    new_object);
13570Sstevel@tonic-gate 			if (rv != CKR_OK) {
13580Sstevel@tonic-gate 				goto fail_cleanup;
13590Sstevel@tonic-gate 			}
13600Sstevel@tonic-gate 			break;
13610Sstevel@tonic-gate 
13620Sstevel@tonic-gate 		/*
13630Sstevel@tonic-gate 		 * The following key related attribute types must
13640Sstevel@tonic-gate 		 * not be specified by C_CreateObject, C_GenerateKey(Pair).
13650Sstevel@tonic-gate 		 */
13660Sstevel@tonic-gate 		case CKA_LOCAL:
13670Sstevel@tonic-gate 		case CKA_KEY_GEN_MECHANISM:
13680Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
13690Sstevel@tonic-gate 			goto fail_cleanup;
13700Sstevel@tonic-gate 
13710Sstevel@tonic-gate 		/* Key related boolean attributes */
13720Sstevel@tonic-gate 		case CKA_DERIVE:
13730Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
13740Sstevel@tonic-gate 				attr_mask |= DERIVE_BOOL_ON;
13750Sstevel@tonic-gate 			break;
13760Sstevel@tonic-gate 
13770Sstevel@tonic-gate 		case CKA_ENCRYPT:
13780Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
13790Sstevel@tonic-gate 				attr_mask |= ENCRYPT_BOOL_ON;
13800Sstevel@tonic-gate 			else
13810Sstevel@tonic-gate 				attr_mask &= ~ENCRYPT_BOOL_ON;
13820Sstevel@tonic-gate 			break;
13830Sstevel@tonic-gate 
13840Sstevel@tonic-gate 		case CKA_VERIFY:
13850Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
13860Sstevel@tonic-gate 				attr_mask |= VERIFY_BOOL_ON;
13870Sstevel@tonic-gate 			else
13880Sstevel@tonic-gate 				attr_mask &= ~VERIFY_BOOL_ON;
13890Sstevel@tonic-gate 			break;
13900Sstevel@tonic-gate 
13910Sstevel@tonic-gate 		case CKA_VERIFY_RECOVER:
13920Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
13930Sstevel@tonic-gate 				attr_mask |= VERIFY_RECOVER_BOOL_ON;
13940Sstevel@tonic-gate 			else
13950Sstevel@tonic-gate 				attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
13960Sstevel@tonic-gate 			break;
13970Sstevel@tonic-gate 
13980Sstevel@tonic-gate 		case CKA_WRAP:
13990Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
14000Sstevel@tonic-gate 				attr_mask |= WRAP_BOOL_ON;
14010Sstevel@tonic-gate 			else
14020Sstevel@tonic-gate 				attr_mask &= ~WRAP_BOOL_ON;
14030Sstevel@tonic-gate 			break;
14040Sstevel@tonic-gate 
14050Sstevel@tonic-gate 		case CKA_TRUSTED:
14060Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
14070Sstevel@tonic-gate 				attr_mask |= TRUSTED_BOOL_ON;
14080Sstevel@tonic-gate 			break;
14090Sstevel@tonic-gate 
14100Sstevel@tonic-gate 		case CKA_MODIFIABLE:
14110Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
14120Sstevel@tonic-gate 				attr_mask |= NOT_MODIFIABLE_BOOL_ON;
14130Sstevel@tonic-gate 			break;
14140Sstevel@tonic-gate 
14150Sstevel@tonic-gate 		/*
14160Sstevel@tonic-gate 		 * The following key related attribute types must
14170Sstevel@tonic-gate 		 * be specified according to the key type by
14180Sstevel@tonic-gate 		 * C_CreateObject.
14190Sstevel@tonic-gate 		 */
14200Sstevel@tonic-gate 		case CKA_MODULUS:
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 			isModulus = 1;
14230Sstevel@tonic-gate 			/*
14240Sstevel@tonic-gate 			 * Copyin big integer attribute from template
14250Sstevel@tonic-gate 			 * to a local variable.
14260Sstevel@tonic-gate 			 */
14270Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&modulus,
14280Sstevel@tonic-gate 			    &template[i]);
14290Sstevel@tonic-gate 			if (rv != CKR_OK)
14300Sstevel@tonic-gate 				goto fail_cleanup;
14310Sstevel@tonic-gate 
14320Sstevel@tonic-gate 			/*
14330Sstevel@tonic-gate 			 * Modulus length needs to be between min key length and
14340Sstevel@tonic-gate 			 * max key length.
14350Sstevel@tonic-gate 			 */
14360Sstevel@tonic-gate 			if ((modulus.big_value_len <
14370Sstevel@tonic-gate 			    MIN_RSA_KEYLENGTH_IN_BYTES) ||
14380Sstevel@tonic-gate 			    (modulus.big_value_len >
14390Sstevel@tonic-gate 			    MAX_RSA_KEYLENGTH_IN_BYTES)) {
14400Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
14410Sstevel@tonic-gate 				goto fail_cleanup;
14420Sstevel@tonic-gate 			}
14430Sstevel@tonic-gate 			break;
14440Sstevel@tonic-gate 
14450Sstevel@tonic-gate 		case CKA_PUBLIC_EXPONENT:
14460Sstevel@tonic-gate 			isPubExpo = 1;
14470Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&pubexpo,
14480Sstevel@tonic-gate 			    &template[i]);
14490Sstevel@tonic-gate 			if (rv != CKR_OK)
14500Sstevel@tonic-gate 				goto fail_cleanup;
14510Sstevel@tonic-gate 			break;
14520Sstevel@tonic-gate 
14530Sstevel@tonic-gate 		case CKA_PRIME:
14540Sstevel@tonic-gate 			isPrime = 1;
14550Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&prime,
14560Sstevel@tonic-gate 			    &template[i]);
14570Sstevel@tonic-gate 			if (rv != CKR_OK)
14580Sstevel@tonic-gate 				goto fail_cleanup;
14590Sstevel@tonic-gate 			break;
14600Sstevel@tonic-gate 
14610Sstevel@tonic-gate 		case CKA_SUBPRIME:
14620Sstevel@tonic-gate 			isSubprime = 1;
14630Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&subprime,
14640Sstevel@tonic-gate 			    &template[i]);
14650Sstevel@tonic-gate 			if (rv != CKR_OK)
14660Sstevel@tonic-gate 				goto fail_cleanup;
14670Sstevel@tonic-gate 			break;
14680Sstevel@tonic-gate 
14690Sstevel@tonic-gate 		case CKA_BASE:
14700Sstevel@tonic-gate 			isBase = 1;
14710Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&base,
14720Sstevel@tonic-gate 			    &template[i]);
14730Sstevel@tonic-gate 			if (rv != CKR_OK)
14740Sstevel@tonic-gate 				goto fail_cleanup;
14750Sstevel@tonic-gate 			break;
14760Sstevel@tonic-gate 
14770Sstevel@tonic-gate 		case CKA_VALUE:
14780Sstevel@tonic-gate 			isValue = 1;
14790Sstevel@tonic-gate 			if (mode == SOFT_CREATE_OBJ) {
14800Sstevel@tonic-gate 				if ((template[i].ulValueLen == 0) ||
14810Sstevel@tonic-gate 				    (template[i].pValue == NULL)) {
14820Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
14830Sstevel@tonic-gate 					goto fail_cleanup;
14845697Smcpowers 				}
14850Sstevel@tonic-gate 			}
14860Sstevel@tonic-gate 
14870Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&value,
14880Sstevel@tonic-gate 			    &template[i]);
14890Sstevel@tonic-gate 			if (rv != CKR_OK)
14900Sstevel@tonic-gate 				goto fail_cleanup;
14910Sstevel@tonic-gate 			break;
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 		case CKA_MODULUS_BITS:
14940Sstevel@tonic-gate 			isModulusBits = 1;
14957512SAnthony.Scarpino@Sun.COM 			rv = get_ulong_attr_from_template(&modulus_bits,
14960Sstevel@tonic-gate 			    &template[i]);
14977512SAnthony.Scarpino@Sun.COM 			if (rv != CKR_OK)
14987512SAnthony.Scarpino@Sun.COM 				goto fail_cleanup;
14990Sstevel@tonic-gate 			break;
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 		case CKA_LABEL:
15020Sstevel@tonic-gate 			isLabel = 1;
15030Sstevel@tonic-gate 			rv = get_string_from_template(&string_tmp,
15040Sstevel@tonic-gate 			    &template[i]);
15050Sstevel@tonic-gate 			if (rv != CKR_OK)
15060Sstevel@tonic-gate 				goto fail_cleanup;
15070Sstevel@tonic-gate 			break;
15080Sstevel@tonic-gate 
15094219Smcpowers 		case CKA_EC_PARAMS:
15104219Smcpowers 			isECParam = 1;
15115697Smcpowers 			rv = get_string_from_template(&param_tmp, &template[i]);
15124219Smcpowers 			if (rv != CKR_OK)
15134219Smcpowers 				goto fail_cleanup;
15144219Smcpowers 			break;
15154219Smcpowers 
15164219Smcpowers 		case CKA_EC_POINT:
15174219Smcpowers 			isECPoint = 1;
15185697Smcpowers 			rv = get_bigint_attr_from_template(&point,
15194219Smcpowers 			    &template[i]);
15204219Smcpowers 			if (rv != CKR_OK)
15214219Smcpowers 				goto fail_cleanup;
15224219Smcpowers 			break;
15234219Smcpowers 
15240Sstevel@tonic-gate 		default:
15250Sstevel@tonic-gate 			rv = soft_parse_common_attrs(&template[i],
15260Sstevel@tonic-gate 			    &object_type);
15270Sstevel@tonic-gate 			if (rv != CKR_OK)
15280Sstevel@tonic-gate 				goto fail_cleanup;
15290Sstevel@tonic-gate 			break;
15300Sstevel@tonic-gate 		}
15310Sstevel@tonic-gate 	} /* For */
15320Sstevel@tonic-gate 
15330Sstevel@tonic-gate 	/* Allocate storage for Public Key Object. */
15340Sstevel@tonic-gate 	pbk = calloc(1, sizeof (public_key_obj_t));
15350Sstevel@tonic-gate 	if (pbk == NULL) {
15360Sstevel@tonic-gate 		rv = CKR_HOST_MEMORY;
15370Sstevel@tonic-gate 		goto fail_cleanup;
15380Sstevel@tonic-gate 	}
15390Sstevel@tonic-gate 
15400Sstevel@tonic-gate 	new_object->object_class_u.public_key = pbk;
15410Sstevel@tonic-gate 	new_object->class = CKO_PUBLIC_KEY;
15420Sstevel@tonic-gate 
15430Sstevel@tonic-gate 	if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
15440Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCOMPLETE;
15450Sstevel@tonic-gate 		goto fail_cleanup;
15460Sstevel@tonic-gate 	}
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate 	if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
15490Sstevel@tonic-gate 		keytype = key_type;
15500Sstevel@tonic-gate 	}
15510Sstevel@tonic-gate 
15520Sstevel@tonic-gate 	if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
15530Sstevel@tonic-gate 		/*
15540Sstevel@tonic-gate 		 * The key type specified in the template does not
15550Sstevel@tonic-gate 		 * match the implied key type based on the mechanism.
15560Sstevel@tonic-gate 		 */
15570Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
15580Sstevel@tonic-gate 		goto fail_cleanup;
15590Sstevel@tonic-gate 	}
15600Sstevel@tonic-gate 
15610Sstevel@tonic-gate 	new_object->key_type = keytype;
15620Sstevel@tonic-gate 
15630Sstevel@tonic-gate 	/* Supported key types of the Public Key Object */
15640Sstevel@tonic-gate 	switch (keytype) {
15650Sstevel@tonic-gate 
15660Sstevel@tonic-gate 	case CKK_RSA:
15670Sstevel@tonic-gate 		if (mode == SOFT_CREATE_OBJ) {
15680Sstevel@tonic-gate 			if (isModulusBits || isPrime || isSubprime ||
15690Sstevel@tonic-gate 			    isBase || isValue) {
15700Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
15710Sstevel@tonic-gate 				goto fail_cleanup;
15720Sstevel@tonic-gate 			}
15730Sstevel@tonic-gate 
15740Sstevel@tonic-gate 			if (isModulus && isPubExpo) {
15750Sstevel@tonic-gate 				/*
1576*9830SDina.Nimeh@Sun.COM 				 * Derive modulus_bits attribute from modulus.
1577*9830SDina.Nimeh@Sun.COM 				 * Save modulus_bits integer value to the
1578*9830SDina.Nimeh@Sun.COM 				 * designated place in the public key object.
1579*9830SDina.Nimeh@Sun.COM 				 */
1580*9830SDina.Nimeh@Sun.COM 				n.malloced = 0;
1581*9830SDina.Nimeh@Sun.COM #ifdef  __sparcv9
1582*9830SDina.Nimeh@Sun.COM 				if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1583*9830SDina.Nimeh@Sun.COM 				    modulus.big_value_len)) != BIG_OK) {
1584*9830SDina.Nimeh@Sun.COM #else   /* !__sparcv9 */
1585*9830SDina.Nimeh@Sun.COM 				if (big_init(&n, CHARLEN2BIGNUMLEN(
1586*9830SDina.Nimeh@Sun.COM 				    modulus.big_value_len)) != BIG_OK) {
1587*9830SDina.Nimeh@Sun.COM #endif  /* __sparcv9 */
1588*9830SDina.Nimeh@Sun.COM 					rv = CKR_HOST_MEMORY;
1589*9830SDina.Nimeh@Sun.COM 					big_finish(&n);
1590*9830SDina.Nimeh@Sun.COM 					goto fail_cleanup;
1591*9830SDina.Nimeh@Sun.COM 				}
1592*9830SDina.Nimeh@Sun.COM 				bytestring2bignum(&n, modulus.big_value,
1593*9830SDina.Nimeh@Sun.COM 				    modulus.big_value_len);
1594*9830SDina.Nimeh@Sun.COM 
1595*9830SDina.Nimeh@Sun.COM 				modulus_bits = big_bitlength(&n);
1596*9830SDina.Nimeh@Sun.COM 				KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1597*9830SDina.Nimeh@Sun.COM 				big_finish(&n);
1598*9830SDina.Nimeh@Sun.COM 
1599*9830SDina.Nimeh@Sun.COM 				/*
1600*9830SDina.Nimeh@Sun.COM 				 * After modulus_bits has been computed,
1601*9830SDina.Nimeh@Sun.COM 				 * it is safe to move modulus and pubexpo
1602*9830SDina.Nimeh@Sun.COM 				 * big integer attribute value to the
16030Sstevel@tonic-gate 				 * designated place in the public key object.
16040Sstevel@tonic-gate 				 */
16050Sstevel@tonic-gate 				copy_bigint_attr(&modulus,
16060Sstevel@tonic-gate 				    KEY_PUB_RSA_MOD(pbk));
16070Sstevel@tonic-gate 
16080Sstevel@tonic-gate 				copy_bigint_attr(&pubexpo,
16090Sstevel@tonic-gate 				    KEY_PUB_RSA_PUBEXPO(pbk));
16100Sstevel@tonic-gate 			} else {
16110Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
16120Sstevel@tonic-gate 				goto fail_cleanup;
16130Sstevel@tonic-gate 			}
16140Sstevel@tonic-gate 		} else {
16159536SDina.Nimeh@Sun.COM 			/* mode is SOFT_GEN_KEY */
16169536SDina.Nimeh@Sun.COM 
16170Sstevel@tonic-gate 			if (isModulus || isPrime || isSubprime ||
16180Sstevel@tonic-gate 			    isBase || isValue) {
16190Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
16200Sstevel@tonic-gate 				goto fail_cleanup;
16210Sstevel@tonic-gate 			}
16220Sstevel@tonic-gate 
16239536SDina.Nimeh@Sun.COM 
16249536SDina.Nimeh@Sun.COM 			if (isModulusBits) {
16250Sstevel@tonic-gate 				/*
16260Sstevel@tonic-gate 				 * Copy big integer attribute value to the
16270Sstevel@tonic-gate 				 * designated place in the public key object.
16280Sstevel@tonic-gate 				 */
16290Sstevel@tonic-gate 				KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
16300Sstevel@tonic-gate 			} else {
16310Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
16320Sstevel@tonic-gate 				goto fail_cleanup;
16330Sstevel@tonic-gate 			}
16349536SDina.Nimeh@Sun.COM 
16359536SDina.Nimeh@Sun.COM 			/*
16369536SDina.Nimeh@Sun.COM 			 * Use PKCS#11 default 0x010001 for public exponent
16379536SDina.Nimeh@Sun.COM 			 * if not not specified in attribute template.
16389536SDina.Nimeh@Sun.COM 			 */
16399536SDina.Nimeh@Sun.COM 			if (!isPubExpo) {
16409536SDina.Nimeh@Sun.COM 				isPubExpo = 1;
16419536SDina.Nimeh@Sun.COM 				rv = get_bigint_attr_from_template(&pubexpo,
16429536SDina.Nimeh@Sun.COM 				    &defpubexpo);
16439536SDina.Nimeh@Sun.COM 				if (rv != CKR_OK)
16449536SDina.Nimeh@Sun.COM 					goto fail_cleanup;
16459536SDina.Nimeh@Sun.COM 			}
16469536SDina.Nimeh@Sun.COM 			/*
16479536SDina.Nimeh@Sun.COM 			 * Copy big integer attribute value to the
16489536SDina.Nimeh@Sun.COM 			 * designated place in the public key object.
16499536SDina.Nimeh@Sun.COM 			 */
16509536SDina.Nimeh@Sun.COM 			copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
16510Sstevel@tonic-gate 		}
16520Sstevel@tonic-gate 
16530Sstevel@tonic-gate 		break;
16540Sstevel@tonic-gate 
16550Sstevel@tonic-gate 	case CKK_DSA:
16560Sstevel@tonic-gate 		if (mode == SOFT_CREATE_OBJ) {
16570Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo) {
16580Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
16590Sstevel@tonic-gate 				goto fail_cleanup;
16600Sstevel@tonic-gate 			}
16610Sstevel@tonic-gate 
16620Sstevel@tonic-gate 			if (isPrime && isSubprime && isBase && isValue) {
16630Sstevel@tonic-gate 				copy_bigint_attr(&value,
16640Sstevel@tonic-gate 				    KEY_PUB_DSA_VALUE(pbk));
16650Sstevel@tonic-gate 			} else {
16660Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
16670Sstevel@tonic-gate 				goto fail_cleanup;
16680Sstevel@tonic-gate 			}
16690Sstevel@tonic-gate 		} else {
16700Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo ||
16710Sstevel@tonic-gate 			    isValue) {
16720Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
16730Sstevel@tonic-gate 				goto fail_cleanup;
16740Sstevel@tonic-gate 			}
16750Sstevel@tonic-gate 
16760Sstevel@tonic-gate 			if (!(isPrime && isSubprime && isBase)) {
16770Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
16780Sstevel@tonic-gate 				goto fail_cleanup;
16790Sstevel@tonic-gate 			}
16800Sstevel@tonic-gate 		}
16810Sstevel@tonic-gate 
16820Sstevel@tonic-gate 		copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate 		copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
16850Sstevel@tonic-gate 
16860Sstevel@tonic-gate 		copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
16870Sstevel@tonic-gate 
16880Sstevel@tonic-gate 		break;
16890Sstevel@tonic-gate 
16900Sstevel@tonic-gate 	case CKK_DH:
16910Sstevel@tonic-gate 		if (mode == SOFT_CREATE_OBJ) {
16920Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo ||
16930Sstevel@tonic-gate 			    isSubprime) {
16940Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
16950Sstevel@tonic-gate 				goto fail_cleanup;
16960Sstevel@tonic-gate 			}
16970Sstevel@tonic-gate 
16980Sstevel@tonic-gate 			if (isPrime && isBase && isValue) {
16990Sstevel@tonic-gate 				copy_bigint_attr(&value,
17000Sstevel@tonic-gate 				    KEY_PUB_DH_VALUE(pbk));
17010Sstevel@tonic-gate 			} else {
17020Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
17030Sstevel@tonic-gate 				goto fail_cleanup;
17040Sstevel@tonic-gate 			}
17050Sstevel@tonic-gate 		} else {
17060Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo ||
17070Sstevel@tonic-gate 			    isSubprime || isValue) {
17080Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
17090Sstevel@tonic-gate 				goto fail_cleanup;
17100Sstevel@tonic-gate 			}
17110Sstevel@tonic-gate 
17120Sstevel@tonic-gate 			if (!(isPrime && isBase)) {
17130Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
17140Sstevel@tonic-gate 				goto fail_cleanup;
17150Sstevel@tonic-gate 			}
17160Sstevel@tonic-gate 		}
17170Sstevel@tonic-gate 
17180Sstevel@tonic-gate 		copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
17190Sstevel@tonic-gate 
17200Sstevel@tonic-gate 		copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
17210Sstevel@tonic-gate 
17220Sstevel@tonic-gate 		break;
17230Sstevel@tonic-gate 
17240Sstevel@tonic-gate 	case CKK_X9_42_DH:
17250Sstevel@tonic-gate 		if (mode == SOFT_CREATE_OBJ) {
17260Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo) {
17270Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
17280Sstevel@tonic-gate 				goto fail_cleanup;
17290Sstevel@tonic-gate 			}
17300Sstevel@tonic-gate 
17310Sstevel@tonic-gate 			if (isPrime && isSubprime && isBase && isValue) {
17320Sstevel@tonic-gate 				copy_bigint_attr(&value,
17330Sstevel@tonic-gate 				    KEY_PUB_DH942_VALUE(pbk));
17340Sstevel@tonic-gate 			} else {
17350Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
17360Sstevel@tonic-gate 				goto fail_cleanup;
17370Sstevel@tonic-gate 			}
17380Sstevel@tonic-gate 		} else {
17390Sstevel@tonic-gate 			if (isModulusBits || isModulus || isPubExpo ||
17400Sstevel@tonic-gate 			    isValue) {
17410Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
17420Sstevel@tonic-gate 				goto fail_cleanup;
17430Sstevel@tonic-gate 			}
17440Sstevel@tonic-gate 
17450Sstevel@tonic-gate 			if (!(isPrime && isSubprime && isBase)) {
17460Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
17470Sstevel@tonic-gate 				goto fail_cleanup;
17480Sstevel@tonic-gate 			}
17490Sstevel@tonic-gate 		}
17500Sstevel@tonic-gate 
17510Sstevel@tonic-gate 		copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
17520Sstevel@tonic-gate 
17530Sstevel@tonic-gate 		copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
17540Sstevel@tonic-gate 
17550Sstevel@tonic-gate 		copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
17560Sstevel@tonic-gate 
17570Sstevel@tonic-gate 		break;
17580Sstevel@tonic-gate 
17594219Smcpowers 	case CKK_EC:
17605697Smcpowers 		if (mode == SOFT_CREATE_OBJ) {
17615697Smcpowers 			if (isModulusBits || isModulus || isPubExpo ||
17625697Smcpowers 			    isPrime || isSubprime || isBase || isValue) {
17635697Smcpowers 				rv = CKR_TEMPLATE_INCONSISTENT;
17645697Smcpowers 				goto fail_cleanup;
17655697Smcpowers 
17665697Smcpowers 			} else if (!isECParam || !isECPoint) {
17675697Smcpowers 				rv = CKR_TEMPLATE_INCOMPLETE;
17685697Smcpowers 				goto fail_cleanup;
17695697Smcpowers 			}
17705697Smcpowers 		} else {
17715697Smcpowers 			if (isModulusBits || isModulus || isPubExpo ||
17725697Smcpowers 			    isPrime || isSubprime || isBase || isValue) {
17735697Smcpowers 				rv = CKR_TEMPLATE_INCONSISTENT;
17745697Smcpowers 				goto fail_cleanup;
17755697Smcpowers 
17765697Smcpowers 			} else if (!isECParam) {
17775697Smcpowers 				rv = CKR_TEMPLATE_INCOMPLETE;
17785697Smcpowers 				goto fail_cleanup;
17795697Smcpowers 			}
17805697Smcpowers 		}
17815697Smcpowers 
17825697Smcpowers 		if (isECPoint) {
17835697Smcpowers 			copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
17845697Smcpowers 		}
17855697Smcpowers 		rv = soft_add_extra_attr(&param_tmp, new_object);
17865697Smcpowers 		if (rv != CKR_OK)
17874219Smcpowers 			goto fail_cleanup;
17885697Smcpowers 		string_attr_cleanup(&param_tmp);
17894219Smcpowers 		break;
17904219Smcpowers 
17910Sstevel@tonic-gate 	default:
17920Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
17930Sstevel@tonic-gate 		goto fail_cleanup;
17940Sstevel@tonic-gate 	}
17950Sstevel@tonic-gate 
17960Sstevel@tonic-gate 	/* Set up object. */
17970Sstevel@tonic-gate 	new_object->object_type = object_type;
17980Sstevel@tonic-gate 	new_object->bool_attr_mask = attr_mask;
17990Sstevel@tonic-gate 	if (isLabel) {
18000Sstevel@tonic-gate 		rv = soft_add_extra_attr(&string_tmp, new_object);
18010Sstevel@tonic-gate 		if (rv != CKR_OK)
18020Sstevel@tonic-gate 			goto fail_cleanup;
18030Sstevel@tonic-gate 		string_attr_cleanup(&string_tmp);
18040Sstevel@tonic-gate 	}
18050Sstevel@tonic-gate 
18060Sstevel@tonic-gate 	return (rv);
18070Sstevel@tonic-gate 
18080Sstevel@tonic-gate fail_cleanup:
18090Sstevel@tonic-gate 	/*
18100Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
18110Sstevel@tonic-gate 	 */
18120Sstevel@tonic-gate 	bigint_attr_cleanup(&modulus);
18130Sstevel@tonic-gate 	bigint_attr_cleanup(&pubexpo);
18140Sstevel@tonic-gate 	bigint_attr_cleanup(&prime);
18150Sstevel@tonic-gate 	bigint_attr_cleanup(&subprime);
18160Sstevel@tonic-gate 	bigint_attr_cleanup(&base);
18170Sstevel@tonic-gate 	bigint_attr_cleanup(&value);
18185697Smcpowers 	bigint_attr_cleanup(&point);
18190Sstevel@tonic-gate 	string_attr_cleanup(&string_tmp);
18205697Smcpowers 	string_attr_cleanup(&param_tmp);
18210Sstevel@tonic-gate 
18220Sstevel@tonic-gate 	/*
18230Sstevel@tonic-gate 	 * cleanup the storage allocated inside the object itself.
18240Sstevel@tonic-gate 	 */
18250Sstevel@tonic-gate 	soft_cleanup_object(new_object);
18260Sstevel@tonic-gate 
18270Sstevel@tonic-gate 	return (rv);
18280Sstevel@tonic-gate }
18290Sstevel@tonic-gate 
18300Sstevel@tonic-gate 
18310Sstevel@tonic-gate /*
18320Sstevel@tonic-gate  * Build a Private Key Object.
18330Sstevel@tonic-gate  *
18340Sstevel@tonic-gate  * - Parse the object's template, and when an error is detected such as
18350Sstevel@tonic-gate  *   invalid attribute type, invalid attribute value, etc., return
18360Sstevel@tonic-gate  *   with appropriate return value.
18370Sstevel@tonic-gate  * - Set up attribute mask field in the object for the supplied common
18380Sstevel@tonic-gate  *   attributes that have boolean type.
18390Sstevel@tonic-gate  * - Build the attribute_info struct to hold the value of each supplied
18400Sstevel@tonic-gate  *   attribute that has byte array type. Link attribute_info structs
18410Sstevel@tonic-gate  *   together to form the extra attribute list of the object.
18420Sstevel@tonic-gate  * - Allocate storage for the Private Key object.
18430Sstevel@tonic-gate  * - Build the Private Key object according to the key type. Allocate
18440Sstevel@tonic-gate  *   storage to hold the big integer value for the supplied attributes
18450Sstevel@tonic-gate  *   that are required for a certain key type.
18460Sstevel@tonic-gate  *
18470Sstevel@tonic-gate  */
18480Sstevel@tonic-gate CK_RV
18490Sstevel@tonic-gate soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
18500Sstevel@tonic-gate 	soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
18510Sstevel@tonic-gate {
18520Sstevel@tonic-gate 	ulong_t		i;
18530Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = (CK_KEY_TYPE)~0UL;
18540Sstevel@tonic-gate 	uint64_t	attr_mask = PRIVATE_KEY_DEFAULT;
18550Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
18560Sstevel@tonic-gate 	int		isLabel = 0;
18574219Smcpowers 	int		isECParam = 0;
18580Sstevel@tonic-gate 	/* Must set flags unless mode == SOFT_UNWRAP_KEY */
18590Sstevel@tonic-gate 	int		isModulus = 0;
18600Sstevel@tonic-gate 	int		isPriExpo = 0;
18610Sstevel@tonic-gate 	int		isPrime = 0;
18620Sstevel@tonic-gate 	int		isSubprime = 0;
18630Sstevel@tonic-gate 	int		isBase = 0;
18640Sstevel@tonic-gate 	/* Must set flags if mode == SOFT_GEN_KEY */
18650Sstevel@tonic-gate 	int		isValue = 0;
18660Sstevel@tonic-gate 	/* Must not set flags */
18670Sstevel@tonic-gate 	int		isValueBits = 0;
18680Sstevel@tonic-gate 	CK_ULONG	value_bits = 0;
18690Sstevel@tonic-gate 
18700Sstevel@tonic-gate 	/* Private Key RSA optional */
18710Sstevel@tonic-gate 	int		isPubExpo = 0;
18720Sstevel@tonic-gate 	int		isPrime1 = 0;
18730Sstevel@tonic-gate 	int		isPrime2 = 0;
18740Sstevel@tonic-gate 	int		isExpo1 = 0;
18750Sstevel@tonic-gate 	int		isExpo2 = 0;
18760Sstevel@tonic-gate 	int		isCoef = 0;
18770Sstevel@tonic-gate 
18780Sstevel@tonic-gate 	biginteger_t	modulus;
18790Sstevel@tonic-gate 	biginteger_t	priexpo;
18800Sstevel@tonic-gate 	biginteger_t	prime;
18810Sstevel@tonic-gate 	biginteger_t	subprime;
18820Sstevel@tonic-gate 	biginteger_t	base;
18830Sstevel@tonic-gate 	biginteger_t	value;
18840Sstevel@tonic-gate 
18850Sstevel@tonic-gate 	biginteger_t	pubexpo;
18860Sstevel@tonic-gate 	biginteger_t	prime1;
18870Sstevel@tonic-gate 	biginteger_t	prime2;
18880Sstevel@tonic-gate 	biginteger_t	expo1;
18890Sstevel@tonic-gate 	biginteger_t	expo2;
18900Sstevel@tonic-gate 	biginteger_t	coef;
18910Sstevel@tonic-gate 	CK_ATTRIBUTE	string_tmp;
18925697Smcpowers 	CK_ATTRIBUTE	param_tmp;
18930Sstevel@tonic-gate 	BIGNUM	x, q;
18940Sstevel@tonic-gate 
18950Sstevel@tonic-gate 	private_key_obj_t *pvk;
18960Sstevel@tonic-gate 	uchar_t	object_type = 0;
18970Sstevel@tonic-gate 
18980Sstevel@tonic-gate 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
18990Sstevel@tonic-gate 	(void) memset(&modulus, 0x0, sizeof (biginteger_t));
19000Sstevel@tonic-gate 	(void) memset(&priexpo, 0x0, sizeof (biginteger_t));
19010Sstevel@tonic-gate 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
19020Sstevel@tonic-gate 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
19030Sstevel@tonic-gate 	(void) memset(&base, 0x0, sizeof (biginteger_t));
19040Sstevel@tonic-gate 	(void) memset(&value, 0x0, sizeof (biginteger_t));
19050Sstevel@tonic-gate 	(void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
19060Sstevel@tonic-gate 	(void) memset(&prime1, 0x0, sizeof (biginteger_t));
19070Sstevel@tonic-gate 	(void) memset(&prime2, 0x0, sizeof (biginteger_t));
19080Sstevel@tonic-gate 	(void) memset(&expo1, 0x0, sizeof (biginteger_t));
19090Sstevel@tonic-gate 	(void) memset(&expo2, 0x0, sizeof (biginteger_t));
19100Sstevel@tonic-gate 	(void) memset(&coef, 0x0, sizeof (biginteger_t));
19110Sstevel@tonic-gate 	string_tmp.pValue = NULL;
19125697Smcpowers 	param_tmp.pValue = NULL;
19130Sstevel@tonic-gate 	x.malloced = 0;
19140Sstevel@tonic-gate 	q.malloced = 0;
19150Sstevel@tonic-gate 
19160Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
19170Sstevel@tonic-gate 
19180Sstevel@tonic-gate 		/* Private Key Object Attributes */
19190Sstevel@tonic-gate 		switch (template[i].type) {
19200Sstevel@tonic-gate 		/* common key attributes */
19210Sstevel@tonic-gate 		case CKA_KEY_TYPE:
19220Sstevel@tonic-gate 			keytype = *((CK_KEY_TYPE*)template[i].pValue);
19230Sstevel@tonic-gate 			break;
19240Sstevel@tonic-gate 
19250Sstevel@tonic-gate 		case CKA_ID:
19260Sstevel@tonic-gate 		case CKA_START_DATE:
19270Sstevel@tonic-gate 		case CKA_END_DATE:
19280Sstevel@tonic-gate 
19290Sstevel@tonic-gate 		/* common private key attribute */
19300Sstevel@tonic-gate 		case CKA_SUBJECT:
19310Sstevel@tonic-gate 			/*
19320Sstevel@tonic-gate 			 * Allocate storage to hold the attribute
19330Sstevel@tonic-gate 			 * value with byte array type, and add it to
19340Sstevel@tonic-gate 			 * the extra attribute list of the object.
19350Sstevel@tonic-gate 			 */
19360Sstevel@tonic-gate 			rv = soft_add_extra_attr(&template[i],
19370Sstevel@tonic-gate 			    new_object);
19380Sstevel@tonic-gate 			if (rv != CKR_OK) {
19390Sstevel@tonic-gate 				goto fail_cleanup;
19400Sstevel@tonic-gate 			}
19410Sstevel@tonic-gate 			break;
19420Sstevel@tonic-gate 
19430Sstevel@tonic-gate 		/*
19440Sstevel@tonic-gate 		 * The following key related attribute types must
19450Sstevel@tonic-gate 		 * not be specified by C_CreateObject or C_GenerateKey(Pair).
19460Sstevel@tonic-gate 		 */
19470Sstevel@tonic-gate 		case CKA_LOCAL:
19480Sstevel@tonic-gate 		case CKA_KEY_GEN_MECHANISM:
19490Sstevel@tonic-gate 		case CKA_AUTH_PIN_FLAGS:
19500Sstevel@tonic-gate 		case CKA_ALWAYS_SENSITIVE:
19510Sstevel@tonic-gate 		case CKA_NEVER_EXTRACTABLE:
19520Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
19530Sstevel@tonic-gate 			goto fail_cleanup;
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate 		/* Key related boolean attributes */
19560Sstevel@tonic-gate 		case CKA_DERIVE:
19570Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19580Sstevel@tonic-gate 				attr_mask |= DERIVE_BOOL_ON;
19590Sstevel@tonic-gate 			break;
19600Sstevel@tonic-gate 
19610Sstevel@tonic-gate 		case CKA_SENSITIVE:
19620Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19630Sstevel@tonic-gate 				attr_mask |= SENSITIVE_BOOL_ON;
19640Sstevel@tonic-gate 			break;
19650Sstevel@tonic-gate 
19660Sstevel@tonic-gate 		case CKA_SECONDARY_AUTH:
19670Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue) {
19680Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
19690Sstevel@tonic-gate 				goto fail_cleanup;
19700Sstevel@tonic-gate 			}
19710Sstevel@tonic-gate 			break;
19720Sstevel@tonic-gate 
19730Sstevel@tonic-gate 		case CKA_DECRYPT:
19740Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19750Sstevel@tonic-gate 				attr_mask |= DECRYPT_BOOL_ON;
19760Sstevel@tonic-gate 			else
19770Sstevel@tonic-gate 				attr_mask &= ~DECRYPT_BOOL_ON;
19780Sstevel@tonic-gate 			break;
19790Sstevel@tonic-gate 
19800Sstevel@tonic-gate 		case CKA_SIGN:
19810Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19820Sstevel@tonic-gate 				attr_mask |= SIGN_BOOL_ON;
19830Sstevel@tonic-gate 			else
19840Sstevel@tonic-gate 				attr_mask &= ~SIGN_BOOL_ON;
19850Sstevel@tonic-gate 			break;
19860Sstevel@tonic-gate 
19870Sstevel@tonic-gate 		case CKA_SIGN_RECOVER:
19880Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19890Sstevel@tonic-gate 				attr_mask |= SIGN_RECOVER_BOOL_ON;
19900Sstevel@tonic-gate 			else
19910Sstevel@tonic-gate 				attr_mask &= ~SIGN_RECOVER_BOOL_ON;
19920Sstevel@tonic-gate 			break;
19930Sstevel@tonic-gate 
19940Sstevel@tonic-gate 		case CKA_UNWRAP:
19950Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
19960Sstevel@tonic-gate 				attr_mask |= UNWRAP_BOOL_ON;
19970Sstevel@tonic-gate 			else
19980Sstevel@tonic-gate 				attr_mask &= ~UNWRAP_BOOL_ON;
19990Sstevel@tonic-gate 			break;
20000Sstevel@tonic-gate 
20010Sstevel@tonic-gate 		case CKA_EXTRACTABLE:
20020Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
20030Sstevel@tonic-gate 				attr_mask |= EXTRACTABLE_BOOL_ON;
20040Sstevel@tonic-gate 			else
20050Sstevel@tonic-gate 				attr_mask &= ~EXTRACTABLE_BOOL_ON;
20060Sstevel@tonic-gate 			break;
20070Sstevel@tonic-gate 
20080Sstevel@tonic-gate 		case CKA_MODIFIABLE:
20090Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
20100Sstevel@tonic-gate 				attr_mask |= NOT_MODIFIABLE_BOOL_ON;
20110Sstevel@tonic-gate 			break;
20120Sstevel@tonic-gate 
20130Sstevel@tonic-gate 		/*
20140Sstevel@tonic-gate 		 * The following key related attribute types must
20150Sstevel@tonic-gate 		 * be specified according to the key type by
20160Sstevel@tonic-gate 		 * C_CreateObject.
20170Sstevel@tonic-gate 		 */
20180Sstevel@tonic-gate 		case CKA_MODULUS:
20190Sstevel@tonic-gate 
20200Sstevel@tonic-gate 			isModulus = 1;
20210Sstevel@tonic-gate 			/*
20220Sstevel@tonic-gate 			 * Copyin big integer attribute from template
20230Sstevel@tonic-gate 			 * to a local variable.
20240Sstevel@tonic-gate 			 */
20250Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&modulus,
20260Sstevel@tonic-gate 			    &template[i]);
20270Sstevel@tonic-gate 			if (rv != CKR_OK)
20280Sstevel@tonic-gate 				goto fail_cleanup;
20290Sstevel@tonic-gate 
20300Sstevel@tonic-gate 			/*
20310Sstevel@tonic-gate 			 * Modulus length needs to be between min key length and
20320Sstevel@tonic-gate 			 * max key length.
20330Sstevel@tonic-gate 			 */
20340Sstevel@tonic-gate 			if ((modulus.big_value_len <
20350Sstevel@tonic-gate 			    MIN_RSA_KEYLENGTH_IN_BYTES) ||
20360Sstevel@tonic-gate 			    (modulus.big_value_len >
20370Sstevel@tonic-gate 			    MAX_RSA_KEYLENGTH_IN_BYTES)) {
20380Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
20390Sstevel@tonic-gate 				goto fail_cleanup;
20400Sstevel@tonic-gate 			}
20410Sstevel@tonic-gate 			break;
20420Sstevel@tonic-gate 
20430Sstevel@tonic-gate 		case CKA_PUBLIC_EXPONENT:
20440Sstevel@tonic-gate 
20450Sstevel@tonic-gate 			isPubExpo = 1;
20460Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&pubexpo,
20470Sstevel@tonic-gate 			    &template[i]);
20480Sstevel@tonic-gate 			if (rv != CKR_OK)
20490Sstevel@tonic-gate 				goto fail_cleanup;
20500Sstevel@tonic-gate 			break;
20510Sstevel@tonic-gate 
20520Sstevel@tonic-gate 		case CKA_PRIVATE_EXPONENT:
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate 			isPriExpo = 1;
20550Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&priexpo,
20560Sstevel@tonic-gate 			    &template[i]);
20570Sstevel@tonic-gate 			if (rv != CKR_OK)
20580Sstevel@tonic-gate 				goto fail_cleanup;
20590Sstevel@tonic-gate 			break;
20600Sstevel@tonic-gate 
20610Sstevel@tonic-gate 		case CKA_PRIME_1:
20620Sstevel@tonic-gate 			isPrime1 = 1;
20630Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&prime1,
20640Sstevel@tonic-gate 			    &template[i]);
20650Sstevel@tonic-gate 			if (rv != CKR_OK)
20660Sstevel@tonic-gate 				goto fail_cleanup;
20670Sstevel@tonic-gate 			break;
20680Sstevel@tonic-gate 
20690Sstevel@tonic-gate 		case CKA_PRIME_2:
20700Sstevel@tonic-gate 			isPrime2 = 1;
20710Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&prime2,
20720Sstevel@tonic-gate 			    &template[i]);
20730Sstevel@tonic-gate 			if (rv != CKR_OK)
20740Sstevel@tonic-gate 				goto fail_cleanup;
20750Sstevel@tonic-gate 			break;
20760Sstevel@tonic-gate 
20770Sstevel@tonic-gate 		case CKA_EXPONENT_1:
20780Sstevel@tonic-gate 			isExpo1 = 1;
20790Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&expo1,
20800Sstevel@tonic-gate 			    &template[i]);
20810Sstevel@tonic-gate 			if (rv != CKR_OK)
20820Sstevel@tonic-gate 				goto fail_cleanup;
20830Sstevel@tonic-gate 			break;
20840Sstevel@tonic-gate 
20850Sstevel@tonic-gate 		case CKA_EXPONENT_2:
20860Sstevel@tonic-gate 			isExpo2 = 1;
20870Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&expo2,
20880Sstevel@tonic-gate 			    &template[i]);
20890Sstevel@tonic-gate 			if (rv != CKR_OK)
20900Sstevel@tonic-gate 				goto fail_cleanup;
20910Sstevel@tonic-gate 			break;
20920Sstevel@tonic-gate 
20930Sstevel@tonic-gate 		case CKA_COEFFICIENT:
20940Sstevel@tonic-gate 			isCoef = 1;
20950Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&coef,
20960Sstevel@tonic-gate 			    &template[i]);
20970Sstevel@tonic-gate 			if (rv != CKR_OK)
20980Sstevel@tonic-gate 				goto fail_cleanup;
20990Sstevel@tonic-gate 			break;
21000Sstevel@tonic-gate 
21010Sstevel@tonic-gate 		case CKA_PRIME:
21020Sstevel@tonic-gate 			isPrime = 1;
21030Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&prime,
21040Sstevel@tonic-gate 			    &template[i]);
21050Sstevel@tonic-gate 			if (rv != CKR_OK)
21060Sstevel@tonic-gate 				goto fail_cleanup;
21070Sstevel@tonic-gate 			break;
21080Sstevel@tonic-gate 
21090Sstevel@tonic-gate 		case CKA_SUBPRIME:
21100Sstevel@tonic-gate 			isSubprime = 1;
21110Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&subprime,
21120Sstevel@tonic-gate 			    &template[i]);
21130Sstevel@tonic-gate 			if (rv != CKR_OK)
21140Sstevel@tonic-gate 				goto fail_cleanup;
21150Sstevel@tonic-gate 			break;
21160Sstevel@tonic-gate 
21170Sstevel@tonic-gate 		case CKA_BASE:
21180Sstevel@tonic-gate 			isBase = 1;
21190Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&base,
21200Sstevel@tonic-gate 			    &template[i]);
21210Sstevel@tonic-gate 			if (rv != CKR_OK)
21220Sstevel@tonic-gate 				goto fail_cleanup;
21230Sstevel@tonic-gate 			break;
21240Sstevel@tonic-gate 
21250Sstevel@tonic-gate 		case CKA_VALUE:
21260Sstevel@tonic-gate 			isValue = 1;
21270Sstevel@tonic-gate 			if (mode == SOFT_CREATE_OBJ) {
21280Sstevel@tonic-gate 				if ((template[i].ulValueLen == 0) ||
21290Sstevel@tonic-gate 				    (template[i].pValue == NULL)) {
21300Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
21310Sstevel@tonic-gate 					goto fail_cleanup;
21320Sstevel@tonic-gate 				}
21330Sstevel@tonic-gate 			}
21340Sstevel@tonic-gate 
21350Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&value,
21360Sstevel@tonic-gate 			    &template[i]);
21370Sstevel@tonic-gate 			if (rv != CKR_OK)
21380Sstevel@tonic-gate 				goto fail_cleanup;
21390Sstevel@tonic-gate 			break;
21400Sstevel@tonic-gate 
21410Sstevel@tonic-gate 		case CKA_VALUE_BITS:
21420Sstevel@tonic-gate 			isValueBits = 1;
21437512SAnthony.Scarpino@Sun.COM 			rv = get_ulong_attr_from_template(&value_bits,
21440Sstevel@tonic-gate 			    &template[i]);
21457512SAnthony.Scarpino@Sun.COM 			if (rv != CKR_OK)
21467512SAnthony.Scarpino@Sun.COM 				goto fail_cleanup;
21470Sstevel@tonic-gate 			break;
21480Sstevel@tonic-gate 
21490Sstevel@tonic-gate 		case CKA_LABEL:
21500Sstevel@tonic-gate 			isLabel = 1;
21510Sstevel@tonic-gate 			rv = get_string_from_template(&string_tmp,
21520Sstevel@tonic-gate 			    &template[i]);
21530Sstevel@tonic-gate 			if (rv != CKR_OK)
21540Sstevel@tonic-gate 				goto fail_cleanup;
21550Sstevel@tonic-gate 			break;
21560Sstevel@tonic-gate 
21574219Smcpowers 		case CKA_EC_PARAMS:
21584219Smcpowers 			isECParam = 1;
21595697Smcpowers 			rv = get_string_from_template(&param_tmp,
21604219Smcpowers 			    &template[i]);
21614219Smcpowers 			if (rv != CKR_OK)
21624219Smcpowers 				goto fail_cleanup;
21634219Smcpowers 			break;
21644219Smcpowers 
21650Sstevel@tonic-gate 		default:
21660Sstevel@tonic-gate 			rv = soft_parse_common_attrs(&template[i],
21670Sstevel@tonic-gate 			    &object_type);
21680Sstevel@tonic-gate 			if (rv != CKR_OK)
21690Sstevel@tonic-gate 				goto fail_cleanup;
21700Sstevel@tonic-gate 			break;
21710Sstevel@tonic-gate 
21720Sstevel@tonic-gate 		}
21730Sstevel@tonic-gate 	} /* For */
21740Sstevel@tonic-gate 
21750Sstevel@tonic-gate 	/* Allocate storage for Private Key Object. */
21760Sstevel@tonic-gate 	pvk = calloc(1, sizeof (private_key_obj_t));
21770Sstevel@tonic-gate 	if (pvk == NULL) {
21780Sstevel@tonic-gate 		rv = CKR_HOST_MEMORY;
21790Sstevel@tonic-gate 		goto fail_cleanup;
21800Sstevel@tonic-gate 	}
21810Sstevel@tonic-gate 
21820Sstevel@tonic-gate 	new_object->object_class_u.private_key = pvk;
21830Sstevel@tonic-gate 	new_object->class = CKO_PRIVATE_KEY;
21840Sstevel@tonic-gate 
21850Sstevel@tonic-gate 	if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
21860Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCOMPLETE;
21870Sstevel@tonic-gate 		goto fail_cleanup;
21880Sstevel@tonic-gate 	}
21890Sstevel@tonic-gate 
21900Sstevel@tonic-gate 	if (mode == SOFT_GEN_KEY) {
21910Sstevel@tonic-gate 		/*
21920Sstevel@tonic-gate 		 * The key type is not specified in the application's
21930Sstevel@tonic-gate 		 * template, so we use the implied key type based on
21940Sstevel@tonic-gate 		 * the mechanism.
21950Sstevel@tonic-gate 		 */
21960Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
21970Sstevel@tonic-gate 			keytype = key_type;
21980Sstevel@tonic-gate 		}
21990Sstevel@tonic-gate 
22000Sstevel@tonic-gate 		/* If still unspecified, template is incomplete */
22010Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
22020Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
22030Sstevel@tonic-gate 			goto fail_cleanup;
22040Sstevel@tonic-gate 		}
22050Sstevel@tonic-gate 
22060Sstevel@tonic-gate 		/*
22070Sstevel@tonic-gate 		 * The key type specified in the template does not
22080Sstevel@tonic-gate 		 * match the implied key type based on the mechanism.
22090Sstevel@tonic-gate 		 */
22100Sstevel@tonic-gate 		if (keytype != key_type) {
22110Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
22120Sstevel@tonic-gate 			goto fail_cleanup;
22130Sstevel@tonic-gate 		}
22140Sstevel@tonic-gate 	}
22150Sstevel@tonic-gate 
22160Sstevel@tonic-gate 	if (mode == SOFT_UNWRAP_KEY) {
22170Sstevel@tonic-gate 		/*
22180Sstevel@tonic-gate 		 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
22190Sstevel@tonic-gate 		 * implied by the mechanism (key_type), so if it is not
22200Sstevel@tonic-gate 		 * specified from the attribute template (keytype), it is
22210Sstevel@tonic-gate 		 * incomplete.
22220Sstevel@tonic-gate 		 */
22230Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
22240Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
22250Sstevel@tonic-gate 			goto fail_cleanup;
22260Sstevel@tonic-gate 		}
22270Sstevel@tonic-gate 	}
22280Sstevel@tonic-gate 
22290Sstevel@tonic-gate 	new_object->key_type = keytype;
22300Sstevel@tonic-gate 
22310Sstevel@tonic-gate 	/* Supported key types of the Private Key Object */
22320Sstevel@tonic-gate 	switch (keytype) {
22330Sstevel@tonic-gate 	case CKK_RSA:
22340Sstevel@tonic-gate 		if (isPrime || isSubprime || isBase || isValue ||
22350Sstevel@tonic-gate 		    isValueBits) {
22360Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
22370Sstevel@tonic-gate 			goto fail_cleanup;
22380Sstevel@tonic-gate 		}
22390Sstevel@tonic-gate 
22400Sstevel@tonic-gate 		if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
22410Sstevel@tonic-gate 			if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
22420Sstevel@tonic-gate 			    isPrime2 || isExpo1 || isExpo2 || isCoef) {
22430Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
22440Sstevel@tonic-gate 				goto fail_cleanup;
22450Sstevel@tonic-gate 			} else
22460Sstevel@tonic-gate 				break;
22470Sstevel@tonic-gate 		}
22480Sstevel@tonic-gate 
22490Sstevel@tonic-gate 		if (isModulus && isPriExpo) {
22500Sstevel@tonic-gate 			/*
22510Sstevel@tonic-gate 			 * Copy big integer attribute value to the
22520Sstevel@tonic-gate 			 * designated place in the Private Key object.
22530Sstevel@tonic-gate 			 */
22540Sstevel@tonic-gate 			copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
22550Sstevel@tonic-gate 
22560Sstevel@tonic-gate 			copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
22570Sstevel@tonic-gate 		} else {
22580Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
22590Sstevel@tonic-gate 			goto fail_cleanup;
22600Sstevel@tonic-gate 		}
22610Sstevel@tonic-gate 
22620Sstevel@tonic-gate 		/* The following attributes are optional. */
22630Sstevel@tonic-gate 		if (isPubExpo) {
22640Sstevel@tonic-gate 			copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
22650Sstevel@tonic-gate 		}
22660Sstevel@tonic-gate 
22670Sstevel@tonic-gate 		if (isPrime1) {
22680Sstevel@tonic-gate 			copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
22690Sstevel@tonic-gate 		}
22700Sstevel@tonic-gate 
22710Sstevel@tonic-gate 		if (isPrime2) {
22720Sstevel@tonic-gate 			copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
22730Sstevel@tonic-gate 		}
22740Sstevel@tonic-gate 
22750Sstevel@tonic-gate 		if (isExpo1) {
22760Sstevel@tonic-gate 			copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
22770Sstevel@tonic-gate 		}
22780Sstevel@tonic-gate 
22790Sstevel@tonic-gate 		if (isExpo2) {
22800Sstevel@tonic-gate 			copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
22810Sstevel@tonic-gate 		}
22820Sstevel@tonic-gate 
22830Sstevel@tonic-gate 		if (isCoef) {
22840Sstevel@tonic-gate 			copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
22850Sstevel@tonic-gate 		}
22860Sstevel@tonic-gate 		break;
22870Sstevel@tonic-gate 
22880Sstevel@tonic-gate 	case CKK_DSA:
22890Sstevel@tonic-gate 		if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
22900Sstevel@tonic-gate 		    isPrime2 || isExpo1 || isExpo2 || isCoef ||
22910Sstevel@tonic-gate 		    isValueBits) {
22920Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
22930Sstevel@tonic-gate 			goto fail_cleanup;
22940Sstevel@tonic-gate 		}
22950Sstevel@tonic-gate 
22960Sstevel@tonic-gate 		if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
22970Sstevel@tonic-gate 			if (isPrime || isSubprime || isBase || isValue) {
22980Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
22990Sstevel@tonic-gate 				goto fail_cleanup;
23000Sstevel@tonic-gate 			} else
23010Sstevel@tonic-gate 				break;
23020Sstevel@tonic-gate 		}
23030Sstevel@tonic-gate 
23040Sstevel@tonic-gate 		if (isPrime && isSubprime && isBase && isValue) {
23050Sstevel@tonic-gate 			/*
23060Sstevel@tonic-gate 			 * The private value x must be less than subprime q.
23076557Sfr41279 			 * Size for big_init is in BIG_CHUNK_TYPE words.
23080Sstevel@tonic-gate 			 */
23090Sstevel@tonic-gate #ifdef	__sparcv9
23106557Sfr41279 			if (big_init(&x,
23116557Sfr41279 			    (int)CHARLEN2BIGNUMLEN(value.big_value_len))
23126557Sfr41279 			    != BIG_OK) {
23130Sstevel@tonic-gate #else	/* !__sparcv9 */
23146557Sfr41279 			if (big_init(&x,
23156557Sfr41279 			    CHARLEN2BIGNUMLEN(value.big_value_len))
23166557Sfr41279 			    != BIG_OK) {
23175697Smcpowers #endif	/* __sparcv9 */
23180Sstevel@tonic-gate 				rv = CKR_HOST_MEMORY;
23190Sstevel@tonic-gate 				goto fail_cleanup;
23200Sstevel@tonic-gate 			}
23210Sstevel@tonic-gate #ifdef	__sparcv9
23226557Sfr41279 			if (big_init(&q,
23236557Sfr41279 			    (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
23246557Sfr41279 			    != BIG_OK) {
23250Sstevel@tonic-gate #else	/* !__sparcv9 */
23266557Sfr41279 			if (big_init(&q,
23276557Sfr41279 			    CHARLEN2BIGNUMLEN(subprime.big_value_len))
23286557Sfr41279 			    != BIG_OK) {
23295697Smcpowers #endif	/* __sparcv9 */
23300Sstevel@tonic-gate 				rv = CKR_HOST_MEMORY;
23310Sstevel@tonic-gate 				goto fail_cleanup;
23320Sstevel@tonic-gate 			}
23330Sstevel@tonic-gate 			bytestring2bignum(&x, value.big_value,
23340Sstevel@tonic-gate 			    value.big_value_len);
23350Sstevel@tonic-gate 			bytestring2bignum(&q, subprime.big_value,
23360Sstevel@tonic-gate 			    subprime.big_value_len);
23370Sstevel@tonic-gate 
23380Sstevel@tonic-gate 			if (big_cmp_abs(&x, &q) > 0) {
23390Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
23400Sstevel@tonic-gate 				goto fail_cleanup;
23410Sstevel@tonic-gate 			}
23420Sstevel@tonic-gate 
23430Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
23440Sstevel@tonic-gate 
23450Sstevel@tonic-gate 			copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
23460Sstevel@tonic-gate 
23470Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
23480Sstevel@tonic-gate 
23490Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
23500Sstevel@tonic-gate 		} else {
23510Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
23520Sstevel@tonic-gate 			goto fail_cleanup;
23530Sstevel@tonic-gate 		}
23540Sstevel@tonic-gate 		break;
23550Sstevel@tonic-gate 
23560Sstevel@tonic-gate 	case CKK_DH:
23570Sstevel@tonic-gate 		if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
23580Sstevel@tonic-gate 		    isPrime2 || isExpo1 || isExpo2 || isCoef ||
23590Sstevel@tonic-gate 		    isSubprime) {
23600Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
23610Sstevel@tonic-gate 			goto fail_cleanup;
23620Sstevel@tonic-gate 		}
23630Sstevel@tonic-gate 
23640Sstevel@tonic-gate 		/* CKA_VALUE_BITS is for key gen but not unwrap */
23650Sstevel@tonic-gate 		if (mode == SOFT_GEN_KEY)
23660Sstevel@tonic-gate 			KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
23670Sstevel@tonic-gate 			    value_bits : 0;
23680Sstevel@tonic-gate 		else if (mode == SOFT_UNWRAP_KEY) {
23690Sstevel@tonic-gate 			if (isValueBits) {
23700Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
23710Sstevel@tonic-gate 				goto fail_cleanup;
23720Sstevel@tonic-gate 			}
23730Sstevel@tonic-gate 		}
23740Sstevel@tonic-gate 
23750Sstevel@tonic-gate 		if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
23760Sstevel@tonic-gate 			if (isPrime || isBase || isValue) {
23770Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
23780Sstevel@tonic-gate 				goto fail_cleanup;
23790Sstevel@tonic-gate 			} else
23800Sstevel@tonic-gate 				break;
23810Sstevel@tonic-gate 		}
23820Sstevel@tonic-gate 
23830Sstevel@tonic-gate 		if (isValueBits) {
23840Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
23850Sstevel@tonic-gate 			goto fail_cleanup;
23860Sstevel@tonic-gate 		}
23870Sstevel@tonic-gate 
23880Sstevel@tonic-gate 		if (isPrime && isBase && isValue) {
23890Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
23900Sstevel@tonic-gate 
23910Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
23920Sstevel@tonic-gate 
23930Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
23940Sstevel@tonic-gate 		} else {
23950Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
23960Sstevel@tonic-gate 			goto fail_cleanup;
23970Sstevel@tonic-gate 		}
23980Sstevel@tonic-gate 		break;
23990Sstevel@tonic-gate 
24000Sstevel@tonic-gate 	case CKK_X9_42_DH:
24010Sstevel@tonic-gate 		if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
24020Sstevel@tonic-gate 		    isPrime2 || isExpo1 || isExpo2 || isCoef ||
24030Sstevel@tonic-gate 		    isValueBits) {
24040Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
24050Sstevel@tonic-gate 			goto fail_cleanup;
24060Sstevel@tonic-gate 		}
24070Sstevel@tonic-gate 
24080Sstevel@tonic-gate 		if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
24090Sstevel@tonic-gate 			if (isPrime || isSubprime || isBase || isValue) {
24100Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
24110Sstevel@tonic-gate 				goto fail_cleanup;
24120Sstevel@tonic-gate 			} else
24130Sstevel@tonic-gate 				break;
24140Sstevel@tonic-gate 		}
24150Sstevel@tonic-gate 
24160Sstevel@tonic-gate 		if (isPrime && isSubprime && isBase && isValue) {
24170Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
24180Sstevel@tonic-gate 
24190Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
24200Sstevel@tonic-gate 
24210Sstevel@tonic-gate 			copy_bigint_attr(&subprime,
24225697Smcpowers 			    KEY_PRI_DH942_SUBPRIME(pvk));
24230Sstevel@tonic-gate 
24240Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
24250Sstevel@tonic-gate 		} else {
24260Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
24270Sstevel@tonic-gate 			goto fail_cleanup;
24280Sstevel@tonic-gate 		}
24290Sstevel@tonic-gate 		break;
24300Sstevel@tonic-gate 
24314219Smcpowers 	case CKK_EC:
24324219Smcpowers 		if (isModulus || isPubExpo || isPrime ||
24334219Smcpowers 		    isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
24345697Smcpowers 		    isValueBits || isBase) {
24354219Smcpowers 			rv = CKR_TEMPLATE_INCONSISTENT;
24364219Smcpowers 			goto fail_cleanup;
24374219Smcpowers 
24385697Smcpowers 		} else if (isECParam) {
24395697Smcpowers 			rv = soft_add_extra_attr(&param_tmp, new_object);
24405697Smcpowers 			if (rv != CKR_OK)
24415697Smcpowers 				goto fail_cleanup;
24425697Smcpowers 			string_attr_cleanup(&param_tmp);
24435697Smcpowers 		}
24445697Smcpowers 		if (isValue) {
24455697Smcpowers 			copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
24465697Smcpowers 		}
24474219Smcpowers 		break;
24484219Smcpowers 
24490Sstevel@tonic-gate 	default:
24500Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
24510Sstevel@tonic-gate 		goto fail_cleanup;
24520Sstevel@tonic-gate 	}
24530Sstevel@tonic-gate 
24540Sstevel@tonic-gate 	/* Set up object. */
24550Sstevel@tonic-gate 	new_object->object_type = object_type;
24560Sstevel@tonic-gate 	new_object->bool_attr_mask = attr_mask;
24570Sstevel@tonic-gate 	if (isLabel) {
24580Sstevel@tonic-gate 		rv = soft_add_extra_attr(&string_tmp, new_object);
24590Sstevel@tonic-gate 		if (rv != CKR_OK)
24600Sstevel@tonic-gate 			goto fail_cleanup;
24610Sstevel@tonic-gate 		string_attr_cleanup(&string_tmp);
24620Sstevel@tonic-gate 	}
24630Sstevel@tonic-gate 	big_finish(&x);
24640Sstevel@tonic-gate 	big_finish(&q);
24650Sstevel@tonic-gate 
24660Sstevel@tonic-gate 	return (rv);
24670Sstevel@tonic-gate 
24680Sstevel@tonic-gate fail_cleanup:
24690Sstevel@tonic-gate 	/*
24700Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
24710Sstevel@tonic-gate 	 */
24720Sstevel@tonic-gate 	bigint_attr_cleanup(&modulus);
24730Sstevel@tonic-gate 	bigint_attr_cleanup(&priexpo);
24740Sstevel@tonic-gate 	bigint_attr_cleanup(&prime);
24750Sstevel@tonic-gate 	bigint_attr_cleanup(&subprime);
24760Sstevel@tonic-gate 	bigint_attr_cleanup(&base);
24770Sstevel@tonic-gate 	bigint_attr_cleanup(&value);
24780Sstevel@tonic-gate 	bigint_attr_cleanup(&pubexpo);
24790Sstevel@tonic-gate 	bigint_attr_cleanup(&prime1);
24800Sstevel@tonic-gate 	bigint_attr_cleanup(&prime2);
24810Sstevel@tonic-gate 	bigint_attr_cleanup(&expo1);
24820Sstevel@tonic-gate 	bigint_attr_cleanup(&expo2);
24830Sstevel@tonic-gate 	bigint_attr_cleanup(&coef);
24840Sstevel@tonic-gate 	string_attr_cleanup(&string_tmp);
24855697Smcpowers 	string_attr_cleanup(&param_tmp);
24860Sstevel@tonic-gate 	big_finish(&x);
24870Sstevel@tonic-gate 	big_finish(&q);
24880Sstevel@tonic-gate 
24890Sstevel@tonic-gate 	/*
24900Sstevel@tonic-gate 	 * cleanup the storage allocated inside the object itself.
24910Sstevel@tonic-gate 	 */
24920Sstevel@tonic-gate 	soft_cleanup_object(new_object);
24930Sstevel@tonic-gate 
24940Sstevel@tonic-gate 	return (rv);
24950Sstevel@tonic-gate }
24960Sstevel@tonic-gate 
24970Sstevel@tonic-gate 
24980Sstevel@tonic-gate /*
24990Sstevel@tonic-gate  * Build a Secret Key Object.
25000Sstevel@tonic-gate  *
25010Sstevel@tonic-gate  * - Parse the object's template, and when an error is detected such as
25020Sstevel@tonic-gate  *   invalid attribute type, invalid attribute value, etc., return
25030Sstevel@tonic-gate  *   with appropriate return value.
25040Sstevel@tonic-gate  * - Set up attribute mask field in the object for the supplied common
25050Sstevel@tonic-gate  *   attributes that have boolean type.
25060Sstevel@tonic-gate  * - Build the attribute_info struct to hold the value of each supplied
25070Sstevel@tonic-gate  *   attribute that has byte array type. Link attribute_info structs
25080Sstevel@tonic-gate  *   together to form the extra attribute list of the object.
25090Sstevel@tonic-gate  * - Allocate storage for the Secret Key object.
25100Sstevel@tonic-gate  * - Build the Secret Key object. Allocate storage to hold the big integer
25110Sstevel@tonic-gate  *   value for the attribute CKA_VALUE that is required for all the key
25120Sstevel@tonic-gate  *   types supported by secret key object.
25130Sstevel@tonic-gate  * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
25140Sstevel@tonic-gate  *
25150Sstevel@tonic-gate  */
25160Sstevel@tonic-gate CK_RV
25170Sstevel@tonic-gate soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
25180Sstevel@tonic-gate 	soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
25190Sstevel@tonic-gate 	CK_KEY_TYPE key_type)
25200Sstevel@tonic-gate {
25210Sstevel@tonic-gate 
25220Sstevel@tonic-gate 	ulong_t		i;
25230Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = (CK_KEY_TYPE)~0UL;
25240Sstevel@tonic-gate 	uint64_t	attr_mask = SECRET_KEY_DEFAULT;
25250Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
25260Sstevel@tonic-gate 	int		isLabel = 0;
25270Sstevel@tonic-gate 	/* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
25280Sstevel@tonic-gate 	int		isValue = 0;
25290Sstevel@tonic-gate 	/* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
25300Sstevel@tonic-gate 	int		isValueLen = 0;
25310Sstevel@tonic-gate 
25320Sstevel@tonic-gate 	CK_ATTRIBUTE	string_tmp;
25330Sstevel@tonic-gate 
25340Sstevel@tonic-gate 	secret_key_obj_t  *sck;
25350Sstevel@tonic-gate 	uchar_t	object_type = 0;
25360Sstevel@tonic-gate 
25370Sstevel@tonic-gate 	string_tmp.pValue = NULL;
25380Sstevel@tonic-gate 
25390Sstevel@tonic-gate 	/* Allocate storage for Secret Key Object. */
25400Sstevel@tonic-gate 	sck = calloc(1, sizeof (secret_key_obj_t));
25410Sstevel@tonic-gate 	if (sck == NULL) {
25420Sstevel@tonic-gate 		rv = CKR_HOST_MEMORY;
25430Sstevel@tonic-gate 		goto fail_cleanup;
25440Sstevel@tonic-gate 	}
25450Sstevel@tonic-gate 
25460Sstevel@tonic-gate 	new_object->object_class_u.secret_key = sck;
25470Sstevel@tonic-gate 	new_object->class = CKO_SECRET_KEY;
25480Sstevel@tonic-gate 
25490Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
25500Sstevel@tonic-gate 
25510Sstevel@tonic-gate 		/* Secret Key Object Attributes */
25520Sstevel@tonic-gate 		switch (template[i].type) {
25530Sstevel@tonic-gate 
25540Sstevel@tonic-gate 		/* common key attributes */
25550Sstevel@tonic-gate 		case CKA_KEY_TYPE:
25560Sstevel@tonic-gate 			keytype = *((CK_KEY_TYPE*)template[i].pValue);
25570Sstevel@tonic-gate 			break;
25580Sstevel@tonic-gate 
25590Sstevel@tonic-gate 		case CKA_ID:
25600Sstevel@tonic-gate 		case CKA_START_DATE:
25610Sstevel@tonic-gate 		case CKA_END_DATE:
25620Sstevel@tonic-gate 			/*
25630Sstevel@tonic-gate 			 * Allocate storage to hold the attribute
25640Sstevel@tonic-gate 			 * value with byte array type, and add it to
25650Sstevel@tonic-gate 			 * the extra attribute list of the object.
25660Sstevel@tonic-gate 			 */
25670Sstevel@tonic-gate 			rv = soft_add_extra_attr(&template[i],
25680Sstevel@tonic-gate 			    new_object);
25690Sstevel@tonic-gate 			if (rv != CKR_OK) {
25700Sstevel@tonic-gate 				goto fail_cleanup;
25710Sstevel@tonic-gate 			}
25720Sstevel@tonic-gate 			break;
25730Sstevel@tonic-gate 
25740Sstevel@tonic-gate 		/*
25750Sstevel@tonic-gate 		 * The following key related attribute types must
25760Sstevel@tonic-gate 		 * not be specified by C_CreateObject and C_GenerateKey.
25770Sstevel@tonic-gate 		 */
25780Sstevel@tonic-gate 		case CKA_LOCAL:
25790Sstevel@tonic-gate 		case CKA_KEY_GEN_MECHANISM:
25800Sstevel@tonic-gate 		case CKA_ALWAYS_SENSITIVE:
25810Sstevel@tonic-gate 		case CKA_NEVER_EXTRACTABLE:
25820Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
25830Sstevel@tonic-gate 			goto fail_cleanup;
25840Sstevel@tonic-gate 
25850Sstevel@tonic-gate 		/* Key related boolean attributes */
25860Sstevel@tonic-gate 		case CKA_DERIVE:
25870Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
25880Sstevel@tonic-gate 				attr_mask |= DERIVE_BOOL_ON;
25890Sstevel@tonic-gate 			break;
25900Sstevel@tonic-gate 
25910Sstevel@tonic-gate 		case CKA_SENSITIVE:
25920Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
25930Sstevel@tonic-gate 				attr_mask |= SENSITIVE_BOOL_ON;
25940Sstevel@tonic-gate 			break;
25950Sstevel@tonic-gate 
25960Sstevel@tonic-gate 		case CKA_ENCRYPT:
25970Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
25980Sstevel@tonic-gate 				attr_mask |= ENCRYPT_BOOL_ON;
25990Sstevel@tonic-gate 			else
26000Sstevel@tonic-gate 				attr_mask &= ~ENCRYPT_BOOL_ON;
26010Sstevel@tonic-gate 			break;
26020Sstevel@tonic-gate 
26030Sstevel@tonic-gate 		case CKA_DECRYPT:
26040Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26050Sstevel@tonic-gate 				attr_mask |= DECRYPT_BOOL_ON;
26060Sstevel@tonic-gate 			else
26070Sstevel@tonic-gate 				attr_mask &= ~DECRYPT_BOOL_ON;
26080Sstevel@tonic-gate 			break;
26090Sstevel@tonic-gate 
26100Sstevel@tonic-gate 		case CKA_SIGN:
26110Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26120Sstevel@tonic-gate 				attr_mask |= SIGN_BOOL_ON;
26130Sstevel@tonic-gate 			else
26140Sstevel@tonic-gate 				attr_mask &= ~SIGN_BOOL_ON;
26150Sstevel@tonic-gate 			break;
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 		case CKA_VERIFY:
26180Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26190Sstevel@tonic-gate 				attr_mask |= VERIFY_BOOL_ON;
26200Sstevel@tonic-gate 			else
26210Sstevel@tonic-gate 				attr_mask &= ~VERIFY_BOOL_ON;
26220Sstevel@tonic-gate 			break;
26230Sstevel@tonic-gate 
26240Sstevel@tonic-gate 		case CKA_WRAP:
26250Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26260Sstevel@tonic-gate 				attr_mask |= WRAP_BOOL_ON;
26270Sstevel@tonic-gate 			else
26280Sstevel@tonic-gate 				attr_mask &= ~WRAP_BOOL_ON;
26290Sstevel@tonic-gate 			break;
26300Sstevel@tonic-gate 
26310Sstevel@tonic-gate 		case CKA_UNWRAP:
26320Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26330Sstevel@tonic-gate 				attr_mask |= UNWRAP_BOOL_ON;
26340Sstevel@tonic-gate 			else
26350Sstevel@tonic-gate 				attr_mask &= ~UNWRAP_BOOL_ON;
26360Sstevel@tonic-gate 			break;
26370Sstevel@tonic-gate 
26380Sstevel@tonic-gate 		case CKA_EXTRACTABLE:
26390Sstevel@tonic-gate 			if (*(CK_BBOOL *)template[i].pValue)
26400Sstevel@tonic-gate 				attr_mask |= EXTRACTABLE_BOOL_ON;
26410Sstevel@tonic-gate 			else
26420Sstevel@tonic-gate 				attr_mask &= ~EXTRACTABLE_BOOL_ON;
26430Sstevel@tonic-gate 			break;
26440Sstevel@tonic-gate 
26450Sstevel@tonic-gate 		case CKA_MODIFIABLE:
26460Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
26470Sstevel@tonic-gate 				attr_mask |= NOT_MODIFIABLE_BOOL_ON;
26480Sstevel@tonic-gate 			break;
26490Sstevel@tonic-gate 
26500Sstevel@tonic-gate 		case CKA_VALUE:
26510Sstevel@tonic-gate 			isValue = 1;
26520Sstevel@tonic-gate 			if (mode == SOFT_CREATE_OBJ) {
26530Sstevel@tonic-gate 				if ((template[i].ulValueLen == 0) ||
26540Sstevel@tonic-gate 				    (template[i].pValue == NULL)) {
26550Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
26560Sstevel@tonic-gate 					goto fail_cleanup;
26570Sstevel@tonic-gate 				}
26580Sstevel@tonic-gate 			}
26590Sstevel@tonic-gate 
26600Sstevel@tonic-gate 			/*
26610Sstevel@tonic-gate 			 * Copyin attribute from template
26620Sstevel@tonic-gate 			 * to a local variable.
26630Sstevel@tonic-gate 			 */
26640Sstevel@tonic-gate 			rv = get_bigint_attr_from_template((biginteger_t *)sck,
26650Sstevel@tonic-gate 			    &template[i]);
26660Sstevel@tonic-gate 			if (rv != CKR_OK)
26670Sstevel@tonic-gate 				goto fail_cleanup;
26680Sstevel@tonic-gate 			break;
26690Sstevel@tonic-gate 
26700Sstevel@tonic-gate 		case CKA_VALUE_LEN:
26710Sstevel@tonic-gate 			isValueLen = 1;
26727512SAnthony.Scarpino@Sun.COM 			rv = get_ulong_attr_from_template(&sck->sk_value_len,
26730Sstevel@tonic-gate 			    &template[i]);
26747512SAnthony.Scarpino@Sun.COM 			if (rv != CKR_OK)
26757512SAnthony.Scarpino@Sun.COM 				goto fail_cleanup;
26760Sstevel@tonic-gate 			break;
26770Sstevel@tonic-gate 
26780Sstevel@tonic-gate 		case CKA_LABEL:
26790Sstevel@tonic-gate 			isLabel = 1;
26800Sstevel@tonic-gate 			rv = get_string_from_template(&string_tmp,
26810Sstevel@tonic-gate 			    &template[i]);
26820Sstevel@tonic-gate 			if (rv != CKR_OK)
26830Sstevel@tonic-gate 				goto fail_cleanup;
26840Sstevel@tonic-gate 			break;
26850Sstevel@tonic-gate 
26860Sstevel@tonic-gate 		default:
26870Sstevel@tonic-gate 			rv = soft_parse_common_attrs(&template[i],
26880Sstevel@tonic-gate 			    &object_type);
26890Sstevel@tonic-gate 			if (rv != CKR_OK)
26900Sstevel@tonic-gate 				goto fail_cleanup;
26910Sstevel@tonic-gate 			break;
26920Sstevel@tonic-gate 
26930Sstevel@tonic-gate 		}
26940Sstevel@tonic-gate 	} /* For */
26950Sstevel@tonic-gate 
26960Sstevel@tonic-gate 	switch (mode) {
26970Sstevel@tonic-gate 	case SOFT_CREATE_OBJ:
26980Sstevel@tonic-gate 	case SOFT_CREATE_OBJ_INT:
26990Sstevel@tonic-gate 	case SOFT_DERIVE_KEY_DH:
27000Sstevel@tonic-gate 		/*
27010Sstevel@tonic-gate 		 * The key type must be specified in the application's
27020Sstevel@tonic-gate 		 * template. Otherwise, returns error.
27030Sstevel@tonic-gate 		 */
27040Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
27050Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
27060Sstevel@tonic-gate 			goto fail_cleanup;
27070Sstevel@tonic-gate 		}
27080Sstevel@tonic-gate 		break;
27090Sstevel@tonic-gate 
27100Sstevel@tonic-gate 	case SOFT_GEN_KEY:
27110Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
27120Sstevel@tonic-gate 			/*
27130Sstevel@tonic-gate 			 * The key type is not specified in the application's
27140Sstevel@tonic-gate 			 * template, so we use the implied key type based on
27150Sstevel@tonic-gate 			 * the mechanism.
27160Sstevel@tonic-gate 			 */
27170Sstevel@tonic-gate 			keytype = key_type;
27180Sstevel@tonic-gate 		} else {
27190Sstevel@tonic-gate 			if (keytype != key_type) {
27200Sstevel@tonic-gate 				/*
27210Sstevel@tonic-gate 				 * The key type specified in the template
27220Sstevel@tonic-gate 				 * does not match the implied key type based
27230Sstevel@tonic-gate 				 * on the mechanism.
27240Sstevel@tonic-gate 				 */
27250Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
27260Sstevel@tonic-gate 				goto fail_cleanup;
27270Sstevel@tonic-gate 			}
27280Sstevel@tonic-gate 		}
27290Sstevel@tonic-gate 
27300Sstevel@tonic-gate 		/*
27310Sstevel@tonic-gate 		 * If a key_len is passed as a parameter, it has to
27320Sstevel@tonic-gate 		 * match the one found in the template.
27330Sstevel@tonic-gate 		 */
27340Sstevel@tonic-gate 		if (key_len > 0) {
27350Sstevel@tonic-gate 			if (isValueLen && sck->sk_value_len != key_len) {
27360Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
27370Sstevel@tonic-gate 				goto fail_cleanup;
27380Sstevel@tonic-gate 			}
27390Sstevel@tonic-gate 			isValueLen = 1;
27400Sstevel@tonic-gate 			sck->sk_value_len = key_len;
27410Sstevel@tonic-gate 		}
27420Sstevel@tonic-gate 		break;
27430Sstevel@tonic-gate 
27440Sstevel@tonic-gate 	case SOFT_UNWRAP_KEY:
27450Sstevel@tonic-gate 		/*
27460Sstevel@tonic-gate 		 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
27470Sstevel@tonic-gate 		 * implied by the mechanism (key_type), so if it is not
27480Sstevel@tonic-gate 		 * specified from the attribute template (keytype), it is
27490Sstevel@tonic-gate 		 * incomplete.
27500Sstevel@tonic-gate 		 */
27510Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
27520Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
27530Sstevel@tonic-gate 			goto fail_cleanup;
27540Sstevel@tonic-gate 		}
27550Sstevel@tonic-gate 		break;
27560Sstevel@tonic-gate 
27570Sstevel@tonic-gate 	case SOFT_DERIVE_KEY_OTHER:
27580Sstevel@tonic-gate 		/*
27590Sstevel@tonic-gate 		 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
27600Sstevel@tonic-gate 		 * key type is optional.
27610Sstevel@tonic-gate 		 */
27620Sstevel@tonic-gate 		if (keytype == (CK_KEY_TYPE)~0UL) {
27630Sstevel@tonic-gate 			keytype = key_type;
27640Sstevel@tonic-gate 		}
27650Sstevel@tonic-gate 		break;
27660Sstevel@tonic-gate 	}
27670Sstevel@tonic-gate 
27680Sstevel@tonic-gate 	switch (mode) {
27690Sstevel@tonic-gate 	case SOFT_CREATE_OBJ:
27700Sstevel@tonic-gate 	case SOFT_CREATE_OBJ_INT:
27710Sstevel@tonic-gate 		switch (keytype) {
27720Sstevel@tonic-gate 		case CKK_RC4:
27730Sstevel@tonic-gate 			if (!isValue) {
27740Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
27750Sstevel@tonic-gate 				goto fail_cleanup;
27760Sstevel@tonic-gate 			}
27770Sstevel@tonic-gate 			if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
27780Sstevel@tonic-gate 			    (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
27790Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
27800Sstevel@tonic-gate 				goto fail_cleanup;
27810Sstevel@tonic-gate 			}
27820Sstevel@tonic-gate 			break;
27830Sstevel@tonic-gate 
27840Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
27850Sstevel@tonic-gate 			if (!isValue) {
27860Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
27870Sstevel@tonic-gate 				goto fail_cleanup;
27880Sstevel@tonic-gate 			}
27890Sstevel@tonic-gate 			break;
27900Sstevel@tonic-gate 
27910Sstevel@tonic-gate 		case CKK_AES:
27920Sstevel@tonic-gate 			if (!isValue) {
27930Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
27940Sstevel@tonic-gate 				goto fail_cleanup;
27950Sstevel@tonic-gate 			}
27960Sstevel@tonic-gate 			if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
27970Sstevel@tonic-gate 			    (sck->sk_value_len != AES_192_KEY_BYTES) &&
27980Sstevel@tonic-gate 			    (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
27990Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
28000Sstevel@tonic-gate 				goto fail_cleanup;
28010Sstevel@tonic-gate 			}
28020Sstevel@tonic-gate 			break;
28030Sstevel@tonic-gate 
2804676Sizick 		case CKK_BLOWFISH:
2805676Sizick 			if (!isValue) {
2806676Sizick 				rv = CKR_TEMPLATE_INCOMPLETE;
2807676Sizick 				goto fail_cleanup;
2808676Sizick 			}
2809676Sizick 			if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2810676Sizick 			    (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2811676Sizick 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
2812676Sizick 				goto fail_cleanup;
2813676Sizick 			}
2814676Sizick 
2815676Sizick 			break;
2816676Sizick 
28170Sstevel@tonic-gate 		case CKK_DES:
28180Sstevel@tonic-gate 			if (!isValue) {
28190Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
28200Sstevel@tonic-gate 				goto fail_cleanup;
28210Sstevel@tonic-gate 			}
28220Sstevel@tonic-gate 			if (sck->sk_value_len != DES_KEYSIZE) {
28230Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
28240Sstevel@tonic-gate 				goto fail_cleanup;
28250Sstevel@tonic-gate 			}
28260Sstevel@tonic-gate 			break;
28270Sstevel@tonic-gate 
28280Sstevel@tonic-gate 		case CKK_DES2:
28290Sstevel@tonic-gate 			if (!isValue) {
28300Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
28310Sstevel@tonic-gate 				goto fail_cleanup;
28320Sstevel@tonic-gate 			}
28330Sstevel@tonic-gate 			if (sck->sk_value_len != DES2_KEYSIZE) {
28340Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
28350Sstevel@tonic-gate 				goto fail_cleanup;
28360Sstevel@tonic-gate 			}
28370Sstevel@tonic-gate 			break;
28380Sstevel@tonic-gate 
28390Sstevel@tonic-gate 		case CKK_DES3:
28400Sstevel@tonic-gate 			if (!isValue) {
28410Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
28420Sstevel@tonic-gate 				goto fail_cleanup;
28430Sstevel@tonic-gate 			}
28440Sstevel@tonic-gate 			if (sck->sk_value_len != DES3_KEYSIZE) {
28450Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
28460Sstevel@tonic-gate 				goto fail_cleanup;
28470Sstevel@tonic-gate 			}
28480Sstevel@tonic-gate 			break;
28490Sstevel@tonic-gate 
28500Sstevel@tonic-gate 		default:
28510Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
28520Sstevel@tonic-gate 			goto fail_cleanup;
28530Sstevel@tonic-gate 		}
28540Sstevel@tonic-gate 
28550Sstevel@tonic-gate 		if (isValueLen) {
28560Sstevel@tonic-gate 			/*
28570Sstevel@tonic-gate 			 * Templates for internal object creation come from
28580Sstevel@tonic-gate 			 * applications calls to C_DeriveKey(), for which it
28590Sstevel@tonic-gate 			 * is OKey to pass a CKA_VALUE_LEN attribute, as
28600Sstevel@tonic-gate 			 * long as it does not conflict with the length of the
28610Sstevel@tonic-gate 			 * CKA_VALUE attribute.
28620Sstevel@tonic-gate 			 */
28630Sstevel@tonic-gate 			if ((mode != SOFT_CREATE_OBJ_INT) ||
28640Sstevel@tonic-gate 			    ((key_len > 0) && sck->sk_value_len != key_len)) {
28650Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
28660Sstevel@tonic-gate 				goto fail_cleanup;
28670Sstevel@tonic-gate 			}
28680Sstevel@tonic-gate 		}
28690Sstevel@tonic-gate 		break;
28700Sstevel@tonic-gate 
28710Sstevel@tonic-gate 	case SOFT_GEN_KEY:
28720Sstevel@tonic-gate 		/* CKA_VALUE must not be specified */
28730Sstevel@tonic-gate 		if (isValue) {
28740Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
28750Sstevel@tonic-gate 			goto fail_cleanup;
28760Sstevel@tonic-gate 		}
28770Sstevel@tonic-gate 
28780Sstevel@tonic-gate 		switch (keytype) {
28790Sstevel@tonic-gate 		/*
28800Sstevel@tonic-gate 		 * CKA_VALUE_LEN must be specified by C_GenerateKey
28810Sstevel@tonic-gate 		 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
28820Sstevel@tonic-gate 		 */
28830Sstevel@tonic-gate 		case CKK_RC4:
28840Sstevel@tonic-gate 			if (!isValueLen) {
28859341SAnthony.Scarpino@Sun.COM 				rv = CKR_TEMPLATE_INCOMPLETE;
28860Sstevel@tonic-gate 				goto fail_cleanup;
28870Sstevel@tonic-gate 			}
28889341SAnthony.Scarpino@Sun.COM 			;
28890Sstevel@tonic-gate 			if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
28905697Smcpowers 			    (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
28910Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
28920Sstevel@tonic-gate 				goto fail_cleanup;
28930Sstevel@tonic-gate 			}
28940Sstevel@tonic-gate 			break;
28950Sstevel@tonic-gate 
28960Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
28970Sstevel@tonic-gate 			/* arbitrary key length - no length checking */
28980Sstevel@tonic-gate 			if (!isValueLen) {
28999341SAnthony.Scarpino@Sun.COM 				rv = CKR_TEMPLATE_INCOMPLETE;
29000Sstevel@tonic-gate 				goto fail_cleanup;
29010Sstevel@tonic-gate 			}
29020Sstevel@tonic-gate 			break;
29030Sstevel@tonic-gate 
29040Sstevel@tonic-gate 		case CKK_AES:
29050Sstevel@tonic-gate 			if (!isValueLen) {
29069341SAnthony.Scarpino@Sun.COM 				rv = CKR_TEMPLATE_INCOMPLETE;
29070Sstevel@tonic-gate 				goto fail_cleanup;
29080Sstevel@tonic-gate 			}
29090Sstevel@tonic-gate 
29100Sstevel@tonic-gate 			if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
29110Sstevel@tonic-gate 			    (sck->sk_value_len != AES_192_KEY_BYTES) &&
29120Sstevel@tonic-gate 			    (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
29130Sstevel@tonic-gate 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
29140Sstevel@tonic-gate 				goto fail_cleanup;
29150Sstevel@tonic-gate 			}
29160Sstevel@tonic-gate 
29170Sstevel@tonic-gate 			break;
29180Sstevel@tonic-gate 
2919676Sizick 		case CKK_BLOWFISH:
2920676Sizick 			if (!isValueLen) {
29219341SAnthony.Scarpino@Sun.COM 				rv = CKR_TEMPLATE_INCOMPLETE;
2922676Sizick 				goto fail_cleanup;
2923676Sizick 			}
2924676Sizick 			if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2925676Sizick 			    (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2926676Sizick 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
2927676Sizick 				goto fail_cleanup;
2928676Sizick 			}
2929676Sizick 
2930676Sizick 			break;
2931676Sizick 
29320Sstevel@tonic-gate 		case CKK_DES:
29330Sstevel@tonic-gate 		case CKK_DES2:
29340Sstevel@tonic-gate 		case CKK_DES3:
29350Sstevel@tonic-gate 			/* CKA_VALUE_LEN attribute does not apply to DES<n> */
29360Sstevel@tonic-gate 			if (isValueLen) {
29370Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
29380Sstevel@tonic-gate 				goto fail_cleanup;
29390Sstevel@tonic-gate 			}
29400Sstevel@tonic-gate 			break;
29410Sstevel@tonic-gate 
29420Sstevel@tonic-gate 		default:
29430Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
29440Sstevel@tonic-gate 			goto fail_cleanup;
29450Sstevel@tonic-gate 		}
29460Sstevel@tonic-gate 		break;
29470Sstevel@tonic-gate 
29480Sstevel@tonic-gate 	case SOFT_UNWRAP_KEY:
29490Sstevel@tonic-gate 		/*
29500Sstevel@tonic-gate 		 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
29510Sstevel@tonic-gate 		 * CKA_VALUE_LEN can be be specified; however v2.20 has this
29520Sstevel@tonic-gate 		 * restriction removed, perhaps because it makes it hard to
29530Sstevel@tonic-gate 		 * determine variable-length key sizes.  This case statement
29540Sstevel@tonic-gate 		 * complied with v2.20.
29550Sstevel@tonic-gate 		 */
29560Sstevel@tonic-gate 		if (isValue) {
29570Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
29580Sstevel@tonic-gate 			goto fail_cleanup;
29590Sstevel@tonic-gate 		}
29600Sstevel@tonic-gate 
29610Sstevel@tonic-gate 		switch (keytype) {
29620Sstevel@tonic-gate 		/*
29630Sstevel@tonic-gate 		 * CKA_VALUE_LEN is optional
29640Sstevel@tonic-gate 		 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
29650Sstevel@tonic-gate 		 * and the unwrapping mech is *_CBC_PAD.
29660Sstevel@tonic-gate 		 *
29670Sstevel@tonic-gate 		 * CKA_VALUE_LEN is required
29680Sstevel@tonic-gate 		 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
29690Sstevel@tonic-gate 		 * and the unwrapping mech is *_ECB or *_CBC.
29700Sstevel@tonic-gate 		 *
29710Sstevel@tonic-gate 		 * since mech is not known at this point, CKA_VALUE_LEN is
29720Sstevel@tonic-gate 		 * treated as optional and the caller needs to enforce it.
29730Sstevel@tonic-gate 		 */
29740Sstevel@tonic-gate 		case CKK_RC4:
29750Sstevel@tonic-gate 			if (isValueLen) {
29760Sstevel@tonic-gate 				if ((sck->sk_value_len <
29770Sstevel@tonic-gate 				    ARCFOUR_MIN_KEY_BYTES) ||
29780Sstevel@tonic-gate 				    (sck->sk_value_len >
29790Sstevel@tonic-gate 				    ARCFOUR_MAX_KEY_BYTES)) {
29800Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
29810Sstevel@tonic-gate 					goto fail_cleanup;
29820Sstevel@tonic-gate 				}
29830Sstevel@tonic-gate 			}
29840Sstevel@tonic-gate 			break;
29850Sstevel@tonic-gate 
29860Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
29870Sstevel@tonic-gate 			/* arbitrary key length - no length checking */
29880Sstevel@tonic-gate 			break;
29890Sstevel@tonic-gate 
29900Sstevel@tonic-gate 		case CKK_AES:
29910Sstevel@tonic-gate 			if (isValueLen) {
29920Sstevel@tonic-gate 				if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
29930Sstevel@tonic-gate 				    (sck->sk_value_len != AES_192_KEY_BYTES) &&
29940Sstevel@tonic-gate 				    (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
29950Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
29960Sstevel@tonic-gate 					goto fail_cleanup;
29970Sstevel@tonic-gate 				}
29980Sstevel@tonic-gate 			}
29990Sstevel@tonic-gate 			break;
30000Sstevel@tonic-gate 
3001676Sizick 		case CKK_BLOWFISH:
3002676Sizick 			if (isValueLen &&
3003676Sizick 			    ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
30045697Smcpowers 			    (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
30055697Smcpowers 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
30065697Smcpowers 				goto fail_cleanup;
30075697Smcpowers 			}
3008676Sizick 			break;
3009676Sizick 
30100Sstevel@tonic-gate 		case CKK_DES:
30110Sstevel@tonic-gate 		case CKK_DES2:
30120Sstevel@tonic-gate 		case CKK_DES3:
30130Sstevel@tonic-gate 			/* CKA_VALUE_LEN attribute does not apply to DES<n> */
30140Sstevel@tonic-gate 			if (isValueLen) {
30150Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
30160Sstevel@tonic-gate 				goto fail_cleanup;
30170Sstevel@tonic-gate 			}
30180Sstevel@tonic-gate 			break;
30190Sstevel@tonic-gate 
30200Sstevel@tonic-gate 		default:
30210Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
30220Sstevel@tonic-gate 			goto fail_cleanup;
30230Sstevel@tonic-gate 		}
30240Sstevel@tonic-gate 		break;
30250Sstevel@tonic-gate 
30260Sstevel@tonic-gate 	case SOFT_DERIVE_KEY_DH:
30270Sstevel@tonic-gate 		/* CKA_VALUE must not be specified */
30280Sstevel@tonic-gate 		if (isValue) {
30290Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
30300Sstevel@tonic-gate 			goto fail_cleanup;
30310Sstevel@tonic-gate 		}
30320Sstevel@tonic-gate 
30330Sstevel@tonic-gate 		switch (keytype) {
30340Sstevel@tonic-gate 		/*
30350Sstevel@tonic-gate 		 * CKA_VALUE_LEN is optional
30360Sstevel@tonic-gate 		 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
30370Sstevel@tonic-gate 		 */
30380Sstevel@tonic-gate 		case CKK_RC4:
30390Sstevel@tonic-gate 			if (isValueLen) {
30400Sstevel@tonic-gate 				if ((sck->sk_value_len <
30410Sstevel@tonic-gate 				    ARCFOUR_MIN_KEY_BYTES) ||
30420Sstevel@tonic-gate 				    (sck->sk_value_len >
30430Sstevel@tonic-gate 				    ARCFOUR_MAX_KEY_BYTES)) {
30440Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
30450Sstevel@tonic-gate 					goto fail_cleanup;
30460Sstevel@tonic-gate 				}
30470Sstevel@tonic-gate 			}
30480Sstevel@tonic-gate 			break;
30490Sstevel@tonic-gate 
30500Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
30510Sstevel@tonic-gate 			/* arbitrary key length - no length checking */
30520Sstevel@tonic-gate 			break;
30530Sstevel@tonic-gate 
30540Sstevel@tonic-gate 		case CKK_AES:
30550Sstevel@tonic-gate 			if (isValueLen) {
30560Sstevel@tonic-gate 				if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
30570Sstevel@tonic-gate 				    (sck->sk_value_len != AES_192_KEY_BYTES) &&
30580Sstevel@tonic-gate 				    (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
30590Sstevel@tonic-gate 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
30600Sstevel@tonic-gate 					goto fail_cleanup;
30610Sstevel@tonic-gate 				}
30620Sstevel@tonic-gate 			}
30630Sstevel@tonic-gate 
30640Sstevel@tonic-gate 			break;
30650Sstevel@tonic-gate 
3066676Sizick 		case CKK_BLOWFISH:
3067676Sizick 			if (isValueLen &&
3068676Sizick 			    ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
30695697Smcpowers 			    (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
30705697Smcpowers 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
30715697Smcpowers 				goto fail_cleanup;
30725697Smcpowers 			}
3073676Sizick 			break;
3074676Sizick 
30750Sstevel@tonic-gate 		case CKK_DES:
30760Sstevel@tonic-gate 		case CKK_DES2:
30770Sstevel@tonic-gate 		case CKK_DES3:
30780Sstevel@tonic-gate 			/* CKA_VALUE_LEN attribute does not apply to DES<n> */
30790Sstevel@tonic-gate 			if (isValueLen) {
30800Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
30810Sstevel@tonic-gate 				goto fail_cleanup;
30820Sstevel@tonic-gate 			}
30830Sstevel@tonic-gate 			break;
30840Sstevel@tonic-gate 
30850Sstevel@tonic-gate 		default:
30860Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
30870Sstevel@tonic-gate 			goto fail_cleanup;
30880Sstevel@tonic-gate 		}
30890Sstevel@tonic-gate 		break;
30900Sstevel@tonic-gate 
30910Sstevel@tonic-gate 	case SOFT_DERIVE_KEY_OTHER:
30920Sstevel@tonic-gate 		/* CKA_VALUE must not be specified */
30930Sstevel@tonic-gate 		if (isValue) {
30940Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
30950Sstevel@tonic-gate 			goto fail_cleanup;
30960Sstevel@tonic-gate 		}
30970Sstevel@tonic-gate 
30980Sstevel@tonic-gate 		switch (keytype) {
30990Sstevel@tonic-gate 		/*
31000Sstevel@tonic-gate 		 * CKA_VALUE_LEN is an optional attribute for
31010Sstevel@tonic-gate 		 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
31020Sstevel@tonic-gate 		 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
31030Sstevel@tonic-gate 		 */
31040Sstevel@tonic-gate 		case CKK_RC4:
31050Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
31060Sstevel@tonic-gate 		case CKK_AES:
3107676Sizick 		case CKK_BLOWFISH:
31080Sstevel@tonic-gate 			/*
31090Sstevel@tonic-gate 			 * No need to check key length value here, it will be
31100Sstevel@tonic-gate 			 * validated later in soft_key_derive_check_length().
31110Sstevel@tonic-gate 			 */
31120Sstevel@tonic-gate 			break;
31130Sstevel@tonic-gate 
31140Sstevel@tonic-gate 		case CKK_DES:
31150Sstevel@tonic-gate 		case CKK_DES2:
31160Sstevel@tonic-gate 		case CKK_DES3:
31170Sstevel@tonic-gate 			/* CKA_VALUE_LEN attribute does not apply to DES<n> */
31180Sstevel@tonic-gate 			if (isValueLen) {
31190Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCONSISTENT;
31200Sstevel@tonic-gate 				goto fail_cleanup;
31210Sstevel@tonic-gate 			}
31220Sstevel@tonic-gate 			break;
31230Sstevel@tonic-gate 
31240Sstevel@tonic-gate 		default:
31250Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
31260Sstevel@tonic-gate 			goto fail_cleanup;
31270Sstevel@tonic-gate 		}
31280Sstevel@tonic-gate 		break;
31290Sstevel@tonic-gate 	}
31300Sstevel@tonic-gate 
31310Sstevel@tonic-gate 	/* Set up object. */
31320Sstevel@tonic-gate 	new_object->key_type = keytype;
31330Sstevel@tonic-gate 	new_object->object_type = object_type;
31340Sstevel@tonic-gate 	new_object->bool_attr_mask = attr_mask;
31350Sstevel@tonic-gate 	if (isLabel) {
31360Sstevel@tonic-gate 		rv = soft_add_extra_attr(&string_tmp, new_object);
31370Sstevel@tonic-gate 		if (rv != CKR_OK)
31380Sstevel@tonic-gate 			goto fail_cleanup;
31390Sstevel@tonic-gate 		string_attr_cleanup(&string_tmp);
31400Sstevel@tonic-gate 	}
31410Sstevel@tonic-gate 	return (rv);
31420Sstevel@tonic-gate 
31430Sstevel@tonic-gate fail_cleanup:
31440Sstevel@tonic-gate 	/*
31450Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
31460Sstevel@tonic-gate 	 */
31470Sstevel@tonic-gate 	bigint_attr_cleanup((biginteger_t *)sck);
31480Sstevel@tonic-gate 	string_attr_cleanup(&string_tmp);
31490Sstevel@tonic-gate 
31500Sstevel@tonic-gate 	/*
31510Sstevel@tonic-gate 	 * cleanup the storage allocated inside the object itself.
31520Sstevel@tonic-gate 	 */
31530Sstevel@tonic-gate 	soft_cleanup_object(new_object);
31540Sstevel@tonic-gate 
31550Sstevel@tonic-gate 	return (rv);
31560Sstevel@tonic-gate }
31570Sstevel@tonic-gate 
31580Sstevel@tonic-gate 
31590Sstevel@tonic-gate /*
31600Sstevel@tonic-gate  * Build a Domain Parameter Object.
31610Sstevel@tonic-gate  *
31620Sstevel@tonic-gate  * - Parse the object's template, and when an error is detected such as
31630Sstevel@tonic-gate  *   invalid attribute type, invalid attribute value, etc., return
31640Sstevel@tonic-gate  *   with appropriate return value.
31650Sstevel@tonic-gate  * - Allocate storage for the Domain Parameter object.
31660Sstevel@tonic-gate  * - Build the Domain Parameter object according to the key type. Allocate
31670Sstevel@tonic-gate  *   storage to hold the big integer value for the supplied attributes
31680Sstevel@tonic-gate  *   that are required for a certain key type.
31690Sstevel@tonic-gate  *
31700Sstevel@tonic-gate  */
31710Sstevel@tonic-gate CK_RV
31720Sstevel@tonic-gate soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
31730Sstevel@tonic-gate 	CK_ULONG ulAttrNum, soft_object_t *new_object)
31740Sstevel@tonic-gate {
31750Sstevel@tonic-gate 
31760Sstevel@tonic-gate 	ulong_t		i;
31770Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = (CK_KEY_TYPE)~0UL;
31780Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
31790Sstevel@tonic-gate 	int		isLabel = 0;
31800Sstevel@tonic-gate 	/* Must set flags */
31810Sstevel@tonic-gate 	int		isPrime = 0;
31820Sstevel@tonic-gate 	int		isSubprime = 0;
31830Sstevel@tonic-gate 	int		isBase = 0;
31840Sstevel@tonic-gate 	/* Must not set flags */
31850Sstevel@tonic-gate 	int		isPrimeBits = 0;
31860Sstevel@tonic-gate 	int		isSubPrimeBits = 0;
31870Sstevel@tonic-gate 
31880Sstevel@tonic-gate 	biginteger_t	prime;
31890Sstevel@tonic-gate 	biginteger_t	subprime;
31900Sstevel@tonic-gate 	biginteger_t	base;
31910Sstevel@tonic-gate 	CK_ATTRIBUTE	string_tmp;
31920Sstevel@tonic-gate 
31930Sstevel@tonic-gate 	domain_obj_t	*dom;
31940Sstevel@tonic-gate 	uchar_t	object_type = 0;
31950Sstevel@tonic-gate 
31960Sstevel@tonic-gate 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
31970Sstevel@tonic-gate 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
31980Sstevel@tonic-gate 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
31990Sstevel@tonic-gate 	(void) memset(&base, 0x0, sizeof (biginteger_t));
32000Sstevel@tonic-gate 	string_tmp.pValue = NULL;
32010Sstevel@tonic-gate 
32020Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
32030Sstevel@tonic-gate 
32040Sstevel@tonic-gate 		/* Domain Parameters Object Attributes */
32050Sstevel@tonic-gate 		switch (template[i].type) {
32060Sstevel@tonic-gate 
32070Sstevel@tonic-gate 		/* common domain parameter attribute */
32080Sstevel@tonic-gate 		case CKA_KEY_TYPE:
32090Sstevel@tonic-gate 			keytype = *((CK_KEY_TYPE*)template[i].pValue);
32100Sstevel@tonic-gate 			break;
32110Sstevel@tonic-gate 
32120Sstevel@tonic-gate 		/*
32130Sstevel@tonic-gate 		 * The following common domain parameter attribute
32140Sstevel@tonic-gate 		 * must not be specified by C_CreateObject.
32150Sstevel@tonic-gate 		 */
32160Sstevel@tonic-gate 		case CKA_LOCAL:
32170Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
32180Sstevel@tonic-gate 			goto fail_cleanup;
32190Sstevel@tonic-gate 
32200Sstevel@tonic-gate 		/*
32210Sstevel@tonic-gate 		 * The following domain parameter attributes must be
32220Sstevel@tonic-gate 		 * specified according to the key type by
32230Sstevel@tonic-gate 		 * C_CreateObject.
32240Sstevel@tonic-gate 		 */
32250Sstevel@tonic-gate 		case CKA_PRIME:
32260Sstevel@tonic-gate 			isPrime = 1;
32270Sstevel@tonic-gate 			/*
32280Sstevel@tonic-gate 			 * Copyin big integer attribute from template
32290Sstevel@tonic-gate 			 * to a local variable.
32300Sstevel@tonic-gate 			 */
32310Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&prime,
32320Sstevel@tonic-gate 			    &template[i]);
32330Sstevel@tonic-gate 			if (rv != CKR_OK)
32340Sstevel@tonic-gate 				goto fail_cleanup;
32350Sstevel@tonic-gate 			break;
32360Sstevel@tonic-gate 
32370Sstevel@tonic-gate 		case CKA_SUBPRIME:
32380Sstevel@tonic-gate 			isSubprime = 1;
32390Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&subprime,
32400Sstevel@tonic-gate 			    &template[i]);
32410Sstevel@tonic-gate 			if (rv != CKR_OK)
32420Sstevel@tonic-gate 				goto fail_cleanup;
32430Sstevel@tonic-gate 			break;
32440Sstevel@tonic-gate 
32450Sstevel@tonic-gate 		case CKA_BASE:
32460Sstevel@tonic-gate 			isBase = 1;
32470Sstevel@tonic-gate 			rv = get_bigint_attr_from_template(&base,
32480Sstevel@tonic-gate 			    &template[i]);
32490Sstevel@tonic-gate 			if (rv != CKR_OK)
32500Sstevel@tonic-gate 				goto fail_cleanup;
32510Sstevel@tonic-gate 			break;
32520Sstevel@tonic-gate 
32530Sstevel@tonic-gate 		case CKA_PRIME_BITS:
32540Sstevel@tonic-gate 			isPrimeBits = 1;
32550Sstevel@tonic-gate 			break;
32560Sstevel@tonic-gate 
32570Sstevel@tonic-gate 		case CKA_SUB_PRIME_BITS:
32580Sstevel@tonic-gate 			isSubPrimeBits = 1;
32590Sstevel@tonic-gate 			break;
32600Sstevel@tonic-gate 
32610Sstevel@tonic-gate 		case CKA_LABEL:
32620Sstevel@tonic-gate 			isLabel = 1;
32630Sstevel@tonic-gate 			rv = get_string_from_template(&string_tmp,
32640Sstevel@tonic-gate 			    &template[i]);
32650Sstevel@tonic-gate 			if (rv != CKR_OK)
32660Sstevel@tonic-gate 				goto fail_cleanup;
32670Sstevel@tonic-gate 			break;
32680Sstevel@tonic-gate 
32690Sstevel@tonic-gate 		default:
32700Sstevel@tonic-gate 			rv = soft_parse_common_attrs(&template[i],
32710Sstevel@tonic-gate 			    &object_type);
32720Sstevel@tonic-gate 			if (rv != CKR_OK)
32730Sstevel@tonic-gate 				goto fail_cleanup;
32740Sstevel@tonic-gate 			break;
32750Sstevel@tonic-gate 
32760Sstevel@tonic-gate 		}
32770Sstevel@tonic-gate 	} /* For */
32780Sstevel@tonic-gate 
32790Sstevel@tonic-gate 	/* Allocate storage for Domain Parameters Object. */
32800Sstevel@tonic-gate 	dom = calloc(1, sizeof (domain_obj_t));
32810Sstevel@tonic-gate 	if (dom == NULL) {
32820Sstevel@tonic-gate 		rv = CKR_HOST_MEMORY;
32830Sstevel@tonic-gate 		goto fail_cleanup;
32840Sstevel@tonic-gate 	}
32850Sstevel@tonic-gate 
32860Sstevel@tonic-gate 	new_object->object_class_u.domain = dom;
32870Sstevel@tonic-gate 	new_object->class = CKO_DOMAIN_PARAMETERS;
32880Sstevel@tonic-gate 
32890Sstevel@tonic-gate 	if (keytype == (CK_KEY_TYPE)~0UL) {
32900Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCOMPLETE;
32910Sstevel@tonic-gate 		goto fail_cleanup;
32920Sstevel@tonic-gate 	}
32930Sstevel@tonic-gate 
32940Sstevel@tonic-gate 	new_object->key_type = keytype;
32950Sstevel@tonic-gate 
32960Sstevel@tonic-gate 	/* Supported key types of the Domain Parameters Object */
32970Sstevel@tonic-gate 	switch (keytype) {
32980Sstevel@tonic-gate 	case CKK_DSA:
32990Sstevel@tonic-gate 		if (isPrimeBits || isSubPrimeBits) {
33000Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
33010Sstevel@tonic-gate 			goto fail_cleanup;
33020Sstevel@tonic-gate 		}
33030Sstevel@tonic-gate 
33040Sstevel@tonic-gate 		if (isPrime && isSubprime && isBase) {
33050Sstevel@tonic-gate 			/*
33060Sstevel@tonic-gate 			 * Copy big integer attribute value to the
33070Sstevel@tonic-gate 			 * designated place in the domain parameter
33080Sstevel@tonic-gate 			 * object.
33090Sstevel@tonic-gate 			 */
33100Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
33110Sstevel@tonic-gate 
33120Sstevel@tonic-gate 			copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
33130Sstevel@tonic-gate 
33140Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
33150Sstevel@tonic-gate 		} else {
33160Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
33170Sstevel@tonic-gate 			goto fail_cleanup;
33180Sstevel@tonic-gate 		}
33190Sstevel@tonic-gate 		break;
33200Sstevel@tonic-gate 
33210Sstevel@tonic-gate 	case CKK_DH:
33220Sstevel@tonic-gate 		if (isPrimeBits || isSubprime || isSubPrimeBits) {
33230Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
33240Sstevel@tonic-gate 			goto fail_cleanup;
33250Sstevel@tonic-gate 		}
33260Sstevel@tonic-gate 
33270Sstevel@tonic-gate 		if (isPrime && isBase) {
33280Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
33290Sstevel@tonic-gate 
33300Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
33310Sstevel@tonic-gate 		} else {
33320Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
33330Sstevel@tonic-gate 			goto fail_cleanup;
33340Sstevel@tonic-gate 		}
33350Sstevel@tonic-gate 		break;
33360Sstevel@tonic-gate 
33370Sstevel@tonic-gate 	case CKK_X9_42_DH:
33380Sstevel@tonic-gate 		if (isPrimeBits || isSubPrimeBits) {
33390Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCONSISTENT;
33400Sstevel@tonic-gate 			goto fail_cleanup;
33410Sstevel@tonic-gate 		}
33420Sstevel@tonic-gate 
33430Sstevel@tonic-gate 		if (isPrime && isSubprime && isBase) {
33440Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
33450Sstevel@tonic-gate 
33460Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
33470Sstevel@tonic-gate 
33480Sstevel@tonic-gate 			copy_bigint_attr(&subprime,
33495697Smcpowers 			    KEY_DOM_DH942_SUBPRIME(dom));
33500Sstevel@tonic-gate 		} else {
33510Sstevel@tonic-gate 			rv = CKR_TEMPLATE_INCOMPLETE;
33520Sstevel@tonic-gate 			goto fail_cleanup;
33530Sstevel@tonic-gate 		}
33540Sstevel@tonic-gate 		break;
33550Sstevel@tonic-gate 
33560Sstevel@tonic-gate 	default:
33570Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
33580Sstevel@tonic-gate 		goto fail_cleanup;
33590Sstevel@tonic-gate 	}
33600Sstevel@tonic-gate 
33610Sstevel@tonic-gate 	new_object->object_type = object_type;
33620Sstevel@tonic-gate 
33630Sstevel@tonic-gate 	if (isLabel) {
33640Sstevel@tonic-gate 		rv = soft_add_extra_attr(&string_tmp, new_object);
33650Sstevel@tonic-gate 		if (rv != CKR_OK)
33660Sstevel@tonic-gate 			goto fail_cleanup;
33670Sstevel@tonic-gate 		string_attr_cleanup(&string_tmp);
33680Sstevel@tonic-gate 	}
33690Sstevel@tonic-gate 
33700Sstevel@tonic-gate 	return (rv);
33710Sstevel@tonic-gate 
33720Sstevel@tonic-gate fail_cleanup:
33730Sstevel@tonic-gate 	/*
33740Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
33750Sstevel@tonic-gate 	 */
33760Sstevel@tonic-gate 	bigint_attr_cleanup(&prime);
33770Sstevel@tonic-gate 	bigint_attr_cleanup(&subprime);
33780Sstevel@tonic-gate 	bigint_attr_cleanup(&base);
33790Sstevel@tonic-gate 	string_attr_cleanup(&string_tmp);
33800Sstevel@tonic-gate 
33810Sstevel@tonic-gate 	/*
33820Sstevel@tonic-gate 	 * cleanup the storage allocated inside the object itself.
33830Sstevel@tonic-gate 	 */
33840Sstevel@tonic-gate 	soft_cleanup_object(new_object);
33850Sstevel@tonic-gate 
33860Sstevel@tonic-gate 	return (rv);
33870Sstevel@tonic-gate }
33880Sstevel@tonic-gate 
33890Sstevel@tonic-gate /*
33900Sstevel@tonic-gate  * Build a Certificate Object
33910Sstevel@tonic-gate  *
33920Sstevel@tonic-gate  * - Parse the object's template, and when an error is detected such as
33930Sstevel@tonic-gate  *   invalid attribute type, invalid attribute value, etc., return
33940Sstevel@tonic-gate  *   with appropriate return value.
33950Sstevel@tonic-gate  * - Allocate storage for the Certificate object
33960Sstevel@tonic-gate  */
33970Sstevel@tonic-gate static CK_RV
33980Sstevel@tonic-gate soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
33990Sstevel@tonic-gate 	CK_ULONG ulAttrNum, soft_object_t *new_object,
34000Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE cert_type)
34010Sstevel@tonic-gate {
34020Sstevel@tonic-gate 	uint64_t	attr_mask = 0;
34030Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
34040Sstevel@tonic-gate 	CK_ULONG	i;
34050Sstevel@tonic-gate 	int		owner_set = 0;
34060Sstevel@tonic-gate 	int		value_set = 0;
34070Sstevel@tonic-gate 	int		subject_set = 0;
34080Sstevel@tonic-gate 	certificate_obj_t *cert;
34090Sstevel@tonic-gate 	/* certificate type defaults to the value given as a parameter */
34100Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = cert_type;
34110Sstevel@tonic-gate 	CK_ATTRIBUTE	string_tmp;
34120Sstevel@tonic-gate 	int		isLabel = 0;
34130Sstevel@tonic-gate 	uchar_t		object_type = 0;
34140Sstevel@tonic-gate 
34150Sstevel@tonic-gate 	/*
34160Sstevel@tonic-gate 	 * Look for the certificate type attribute and do some
34170Sstevel@tonic-gate 	 * sanity checking before creating the structures.
34180Sstevel@tonic-gate 	 */
34190Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
34200Sstevel@tonic-gate 		/* Certificate Object Attributes */
34210Sstevel@tonic-gate 		switch (template[i].type) {
34220Sstevel@tonic-gate 			case CKA_CERTIFICATE_TYPE:
34230Sstevel@tonic-gate 				certtype =
34240Sstevel@tonic-gate 				    *((CK_CERTIFICATE_TYPE*)template[i].pValue);
34250Sstevel@tonic-gate 				break;
34260Sstevel@tonic-gate 			case CKA_SUBJECT:
34270Sstevel@tonic-gate 				subject_set = 1;
34280Sstevel@tonic-gate 				break;
34290Sstevel@tonic-gate 			case CKA_OWNER:
34300Sstevel@tonic-gate 				owner_set = 1;
34310Sstevel@tonic-gate 				break;
34320Sstevel@tonic-gate 			case CKA_VALUE:
34330Sstevel@tonic-gate 				value_set = 1;
34340Sstevel@tonic-gate 				break;
34350Sstevel@tonic-gate 		}
34360Sstevel@tonic-gate 	}
34370Sstevel@tonic-gate 
34380Sstevel@tonic-gate 	/* The certificate type MUST be specified */
34390Sstevel@tonic-gate 	if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
34400Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCOMPLETE);
34410Sstevel@tonic-gate 
34420Sstevel@tonic-gate 	/*
34430Sstevel@tonic-gate 	 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
34440Sstevel@tonic-gate 	 * must be present at creation time.
34450Sstevel@tonic-gate 	 */
34460Sstevel@tonic-gate 	if (certtype == CKC_X_509 &&
34470Sstevel@tonic-gate 	    (!subject_set || !value_set))
34480Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCOMPLETE);
34490Sstevel@tonic-gate 
34500Sstevel@tonic-gate 	/*
34510Sstevel@tonic-gate 	 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
34520Sstevel@tonic-gate 	 * must be present at creation time.
34530Sstevel@tonic-gate 	 */
34540Sstevel@tonic-gate 	if (certtype == CKC_X_509_ATTR_CERT &&
34550Sstevel@tonic-gate 	    (!owner_set || !value_set))
34560Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCOMPLETE);
34570Sstevel@tonic-gate 
34580Sstevel@tonic-gate 	string_tmp.pValue = NULL;
34590Sstevel@tonic-gate 	cert = calloc(1, sizeof (certificate_obj_t));
34600Sstevel@tonic-gate 	if (cert == NULL) {
34610Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
34620Sstevel@tonic-gate 	}
34630Sstevel@tonic-gate 	cert->certificate_type = certtype;
34640Sstevel@tonic-gate 
34650Sstevel@tonic-gate 	for (i = 0; i < ulAttrNum; i++) {
34660Sstevel@tonic-gate 		/* Certificate Object Attributes */
34670Sstevel@tonic-gate 		switch (certtype) {
34680Sstevel@tonic-gate 			case CKC_X_509:
34690Sstevel@tonic-gate 			switch (template[i].type) {
34700Sstevel@tonic-gate 				case CKA_SUBJECT:
34710Sstevel@tonic-gate 					rv = get_cert_attr_from_template(
34725697Smcpowers 					    &cert->cert_type_u.x509.subject,
34735697Smcpowers 					    &template[i]);
34740Sstevel@tonic-gate 					break;
34750Sstevel@tonic-gate 				case CKA_VALUE:
34760Sstevel@tonic-gate 					rv = get_cert_attr_from_template(
34775697Smcpowers 					    &cert->cert_type_u.x509.value,
34785697Smcpowers 					    &template[i]);
34790Sstevel@tonic-gate 					break;
34800Sstevel@tonic-gate 				case CKA_LABEL:
34810Sstevel@tonic-gate 					isLabel = 1;
34820Sstevel@tonic-gate 					rv = get_string_from_template(
34835697Smcpowers 					    &string_tmp,
34845697Smcpowers 					    &template[i]);
34850Sstevel@tonic-gate 					if (rv != CKR_OK)
34860Sstevel@tonic-gate 						goto fail_cleanup;
34870Sstevel@tonic-gate 					break;
34880Sstevel@tonic-gate 				case CKA_ID:
34890Sstevel@tonic-gate 				case CKA_ISSUER:
34900Sstevel@tonic-gate 				case CKA_SERIAL_NUMBER:
34910Sstevel@tonic-gate 					rv = soft_add_extra_attr(&template[i],
34925697Smcpowers 					    new_object);
34930Sstevel@tonic-gate 					break;
34940Sstevel@tonic-gate 				case CKA_MODIFIABLE:
34950Sstevel@tonic-gate 					if ((*(CK_BBOOL *)template[i].pValue) ==
34960Sstevel@tonic-gate 					    B_FALSE)
34970Sstevel@tonic-gate 						attr_mask |=
34980Sstevel@tonic-gate 						    NOT_MODIFIABLE_BOOL_ON;
34990Sstevel@tonic-gate 					break;
35000Sstevel@tonic-gate 				case CKA_CERTIFICATE_TYPE:
35010Sstevel@tonic-gate 					break;
35020Sstevel@tonic-gate 				default:
35035697Smcpowers 					rv = soft_parse_common_attrs(
35045697Smcpowers 					    &template[i], &object_type);
35055697Smcpowers 					if (rv != CKR_OK)
35065697Smcpowers 						goto fail_cleanup;
35070Sstevel@tonic-gate 			}
35080Sstevel@tonic-gate 			break;
35090Sstevel@tonic-gate 			case CKC_X_509_ATTR_CERT:
35100Sstevel@tonic-gate 			switch (template[i].type) {
35110Sstevel@tonic-gate 				case CKA_OWNER:
35120Sstevel@tonic-gate 					rv = get_cert_attr_from_template(
35130Sstevel@tonic-gate 					    &cert->cert_type_u.x509_attr.owner,
35140Sstevel@tonic-gate 					    &template[i]);
35150Sstevel@tonic-gate 					break;
35160Sstevel@tonic-gate 				case CKA_VALUE:
35170Sstevel@tonic-gate 					rv = get_cert_attr_from_template(
35180Sstevel@tonic-gate 					    &cert->cert_type_u.x509_attr.value,
35190Sstevel@tonic-gate 					    &template[i]);
35200Sstevel@tonic-gate 					break;
35210Sstevel@tonic-gate 				case CKA_LABEL:
35220Sstevel@tonic-gate 					isLabel = 1;
35230Sstevel@tonic-gate 					rv = get_string_from_template(
35245697Smcpowers 					    &string_tmp, &template[i]);
35250Sstevel@tonic-gate 					if (rv != CKR_OK)
35260Sstevel@tonic-gate 						goto fail_cleanup;
35270Sstevel@tonic-gate 					break;
35280Sstevel@tonic-gate 				case CKA_SERIAL_NUMBER:
35290Sstevel@tonic-gate 				case CKA_AC_ISSUER:
35300Sstevel@tonic-gate 				case CKA_ATTR_TYPES:
35310Sstevel@tonic-gate 					rv = soft_add_extra_attr(&template[i],
35325697Smcpowers 					    new_object);
35330Sstevel@tonic-gate 					break;
35340Sstevel@tonic-gate 
35350Sstevel@tonic-gate 				case CKA_MODIFIABLE:
35360Sstevel@tonic-gate 					if ((*(CK_BBOOL *)template[i].pValue) ==
35370Sstevel@tonic-gate 					    B_FALSE)
35380Sstevel@tonic-gate 						attr_mask |=
35390Sstevel@tonic-gate 						    NOT_MODIFIABLE_BOOL_ON;
35400Sstevel@tonic-gate 					break;
35410Sstevel@tonic-gate 				case CKA_CERTIFICATE_TYPE:
35420Sstevel@tonic-gate 					break;
35430Sstevel@tonic-gate 				default:
35445697Smcpowers 					rv = soft_parse_common_attrs(
35455697Smcpowers 					    &template[i], &object_type);
35465697Smcpowers 					if (rv != CKR_OK)
35475697Smcpowers 						goto fail_cleanup;
35485697Smcpowers 					break;
35490Sstevel@tonic-gate 			}
35500Sstevel@tonic-gate 			break;
35510Sstevel@tonic-gate 			default:
35520Sstevel@tonic-gate 				rv = CKR_TEMPLATE_INCOMPLETE;
35530Sstevel@tonic-gate 				break;
35540Sstevel@tonic-gate 		}
35550Sstevel@tonic-gate 	}
35560Sstevel@tonic-gate 
35570Sstevel@tonic-gate 	if (rv == CKR_OK) {
35580Sstevel@tonic-gate 		new_object->object_class_u.certificate = cert;
35590Sstevel@tonic-gate 		new_object->class = CKO_CERTIFICATE;
35600Sstevel@tonic-gate 		new_object->object_type = object_type;
35610Sstevel@tonic-gate 		new_object->cert_type = certtype;
35620Sstevel@tonic-gate 		new_object->bool_attr_mask = attr_mask;
35630Sstevel@tonic-gate 		if (isLabel) {
35640Sstevel@tonic-gate 			rv = soft_add_extra_attr(&string_tmp, new_object);
35650Sstevel@tonic-gate 			if (rv != CKR_OK)
35660Sstevel@tonic-gate 				goto fail_cleanup;
35670Sstevel@tonic-gate 			string_attr_cleanup(&string_tmp);
35680Sstevel@tonic-gate 		}
35690Sstevel@tonic-gate 	}
35700Sstevel@tonic-gate 
35710Sstevel@tonic-gate fail_cleanup:
35720Sstevel@tonic-gate 	if (rv != CKR_OK) {
35730Sstevel@tonic-gate 		soft_cleanup_cert_object(new_object);
35740Sstevel@tonic-gate 	}
35750Sstevel@tonic-gate 	return (rv);
35760Sstevel@tonic-gate }
35770Sstevel@tonic-gate 
35780Sstevel@tonic-gate 
35790Sstevel@tonic-gate /*
35800Sstevel@tonic-gate  * Validate the attribute types in the object's template. Then,
35810Sstevel@tonic-gate  * call the appropriate build function according to the class of
35820Sstevel@tonic-gate  * the object specified in the template.
35830Sstevel@tonic-gate  *
35840Sstevel@tonic-gate  * Note: The following classes of objects are supported:
35850Sstevel@tonic-gate  * - CKO_PUBLIC_KEY
35860Sstevel@tonic-gate  * - CKO_PRIVATE_KEY
35870Sstevel@tonic-gate  * - CKO_SECRET_KEY
35880Sstevel@tonic-gate  * - CKO_DOMAIN_PARAMETERS
35890Sstevel@tonic-gate  * - CKO_CERTIFICATE
35900Sstevel@tonic-gate  *
35910Sstevel@tonic-gate  */
35920Sstevel@tonic-gate CK_RV
35930Sstevel@tonic-gate soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
35940Sstevel@tonic-gate 	soft_object_t *new_object)
35950Sstevel@tonic-gate {
35960Sstevel@tonic-gate 
35970Sstevel@tonic-gate 	CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
35980Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
35990Sstevel@tonic-gate 
36000Sstevel@tonic-gate 	if (template == NULL) {
36010Sstevel@tonic-gate 		return (CKR_ARGUMENTS_BAD);
36020Sstevel@tonic-gate 	}
36030Sstevel@tonic-gate 
36040Sstevel@tonic-gate 	/* Validate the attribute type in the template. */
36050Sstevel@tonic-gate 	rv = soft_validate_attr(template, ulAttrNum, &class);
36060Sstevel@tonic-gate 	if (rv != CKR_OK)
36070Sstevel@tonic-gate 		return (rv);
36080Sstevel@tonic-gate 	/*
36090Sstevel@tonic-gate 	 * CKA_CLASS is a mandatory attribute for C_CreateObject
36100Sstevel@tonic-gate 	 */
36110Sstevel@tonic-gate 	if (class == (CK_OBJECT_CLASS)~0UL)
36120Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCOMPLETE);
36130Sstevel@tonic-gate 
36140Sstevel@tonic-gate 	/*
36150Sstevel@tonic-gate 	 * Call the appropriate function based on the supported class
36160Sstevel@tonic-gate 	 * of the object.
36170Sstevel@tonic-gate 	 */
36180Sstevel@tonic-gate 	switch (class) {
36190Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
36200Sstevel@tonic-gate 		rv = soft_build_public_key_object(template, ulAttrNum,
36210Sstevel@tonic-gate 		    new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
36220Sstevel@tonic-gate 		break;
36230Sstevel@tonic-gate 
36240Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
36250Sstevel@tonic-gate 		rv = soft_build_private_key_object(template, ulAttrNum,
36260Sstevel@tonic-gate 		    new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
36270Sstevel@tonic-gate 		break;
36280Sstevel@tonic-gate 
36290Sstevel@tonic-gate 	case CKO_SECRET_KEY:
36300Sstevel@tonic-gate 		rv = soft_build_secret_key_object(template, ulAttrNum,
36310Sstevel@tonic-gate 		    new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
36320Sstevel@tonic-gate 		break;
36330Sstevel@tonic-gate 
36340Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
36350Sstevel@tonic-gate 		rv = soft_build_domain_parameters_object(template, ulAttrNum,
36360Sstevel@tonic-gate 		    new_object);
36370Sstevel@tonic-gate 		break;
36380Sstevel@tonic-gate 
36390Sstevel@tonic-gate 	case CKO_CERTIFICATE:
36400Sstevel@tonic-gate 		rv = soft_build_certificate_object(template, ulAttrNum,
36415697Smcpowers 		    new_object, (CK_CERTIFICATE_TYPE)~0UL);
36420Sstevel@tonic-gate 		break;
36430Sstevel@tonic-gate 
36440Sstevel@tonic-gate 	case CKO_DATA:
36450Sstevel@tonic-gate 	case CKO_HW_FEATURE:
36460Sstevel@tonic-gate 	case CKO_VENDOR_DEFINED:
36470Sstevel@tonic-gate 	default:
36480Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_VALUE_INVALID);
36490Sstevel@tonic-gate 	}
36500Sstevel@tonic-gate 
36510Sstevel@tonic-gate 	return (rv);
36520Sstevel@tonic-gate }
36530Sstevel@tonic-gate 
36540Sstevel@tonic-gate /*
36550Sstevel@tonic-gate  * Validate the attribute types in the object's template. Then,
36560Sstevel@tonic-gate  * call the appropriate build function according to the class of
36570Sstevel@tonic-gate  * the object specified in the template.
36580Sstevel@tonic-gate  *
36590Sstevel@tonic-gate  */
36600Sstevel@tonic-gate CK_RV
36610Sstevel@tonic-gate soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
36620Sstevel@tonic-gate 	soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
36630Sstevel@tonic-gate 	CK_ULONG key_len, CK_ULONG mode)
36640Sstevel@tonic-gate {
36650Sstevel@tonic-gate 
36660Sstevel@tonic-gate 	CK_RV 		rv = CKR_OK;
36670Sstevel@tonic-gate 	CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
36680Sstevel@tonic-gate 
36690Sstevel@tonic-gate 	/* Validate the attribute type in the template. */
36700Sstevel@tonic-gate 	if ((template != NULL) && (ulAttrNum != 0)) {
36710Sstevel@tonic-gate 		rv = soft_validate_attr(template, ulAttrNum, &temp_class);
36720Sstevel@tonic-gate 		if (rv != CKR_OK)
36730Sstevel@tonic-gate 			return (rv);
36740Sstevel@tonic-gate 	}
36750Sstevel@tonic-gate 
36760Sstevel@tonic-gate 	/*
36770Sstevel@tonic-gate 	 * If either the class from the parameter list ("class") or
36780Sstevel@tonic-gate 	 * the class from the template ("temp_class") is not specified,
36790Sstevel@tonic-gate 	 * try to use the other one.
36800Sstevel@tonic-gate 	 */
36810Sstevel@tonic-gate 	if (temp_class == (CK_OBJECT_CLASS)~0UL) {
36820Sstevel@tonic-gate 		temp_class = class;
36830Sstevel@tonic-gate 	} else if (class == (CK_OBJECT_CLASS)~0UL) {
36840Sstevel@tonic-gate 		class = temp_class;
36850Sstevel@tonic-gate 	}
36860Sstevel@tonic-gate 
36870Sstevel@tonic-gate 	/* If object class is still not specified, template is incomplete. */
36880Sstevel@tonic-gate 	if (class == (CK_OBJECT_CLASS)~0UL)
36890Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCOMPLETE);
36900Sstevel@tonic-gate 
36910Sstevel@tonic-gate 	/* Class should match if specified in both parameters and template. */
36920Sstevel@tonic-gate 	if (class != temp_class)
36930Sstevel@tonic-gate 		return (CKR_TEMPLATE_INCONSISTENT);
36940Sstevel@tonic-gate 
36950Sstevel@tonic-gate 	/*
36960Sstevel@tonic-gate 	 * Call the appropriate function based on the supported class
36970Sstevel@tonic-gate 	 * of the object.
36980Sstevel@tonic-gate 	 */
36990Sstevel@tonic-gate 	switch (class) {
37000Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
37010Sstevel@tonic-gate 
37020Sstevel@tonic-gate 		/* Unwrapping public keys is not supported. */
37030Sstevel@tonic-gate 		if (mode == SOFT_UNWRAP_KEY) {
37040Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_VALUE_INVALID;
37050Sstevel@tonic-gate 			break;
37060Sstevel@tonic-gate 		}
37070Sstevel@tonic-gate 
37080Sstevel@tonic-gate 		rv = soft_build_public_key_object(template, ulAttrNum,
37090Sstevel@tonic-gate 		    new_object, mode, key_type);
37100Sstevel@tonic-gate 		break;
37110Sstevel@tonic-gate 
37120Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
37130Sstevel@tonic-gate 
37140Sstevel@tonic-gate 		rv = soft_build_private_key_object(template, ulAttrNum,
37150Sstevel@tonic-gate 		    new_object, mode, key_type);
37160Sstevel@tonic-gate 		break;
37170Sstevel@tonic-gate 
37180Sstevel@tonic-gate 	case CKO_SECRET_KEY:
37190Sstevel@tonic-gate 
37200Sstevel@tonic-gate 		rv = soft_build_secret_key_object(template, ulAttrNum,
37210Sstevel@tonic-gate 		    new_object, mode, key_len, key_type);
37220Sstevel@tonic-gate 		break;
37230Sstevel@tonic-gate 
37240Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
37250Sstevel@tonic-gate 
37260Sstevel@tonic-gate 		/* Unwrapping domain parameters is not supported. */
37270Sstevel@tonic-gate 		if (mode == SOFT_UNWRAP_KEY) {
37280Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_VALUE_INVALID;
37290Sstevel@tonic-gate 			break;
37300Sstevel@tonic-gate 		}
37310Sstevel@tonic-gate 
37320Sstevel@tonic-gate 		rv = soft_build_domain_parameters_object(template, ulAttrNum,
37330Sstevel@tonic-gate 		    new_object);
37340Sstevel@tonic-gate 		break;
37350Sstevel@tonic-gate 
37360Sstevel@tonic-gate 	case CKO_DATA:
37370Sstevel@tonic-gate 	case CKO_CERTIFICATE:
37380Sstevel@tonic-gate 	case CKO_HW_FEATURE:
37390Sstevel@tonic-gate 	case CKO_VENDOR_DEFINED:
37400Sstevel@tonic-gate 	default:
37410Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_VALUE_INVALID);
37420Sstevel@tonic-gate 	}
37430Sstevel@tonic-gate 
37440Sstevel@tonic-gate 	return (rv);
37450Sstevel@tonic-gate }
37460Sstevel@tonic-gate 
37470Sstevel@tonic-gate 
37480Sstevel@tonic-gate /*
37490Sstevel@tonic-gate  * Get the value of a requested attribute that is common to all supported
37500Sstevel@tonic-gate  * classes (i.e. public key, private key, secret key, domain parameters,
37510Sstevel@tonic-gate  * and certificate classes).
37520Sstevel@tonic-gate  */
37530Sstevel@tonic-gate CK_RV
37540Sstevel@tonic-gate soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
37550Sstevel@tonic-gate     uchar_t object_type)
37560Sstevel@tonic-gate {
37570Sstevel@tonic-gate 
37580Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
37590Sstevel@tonic-gate 
37600Sstevel@tonic-gate 	switch (template->type) {
37610Sstevel@tonic-gate 
37620Sstevel@tonic-gate 	case CKA_CLASS:
37630Sstevel@tonic-gate 		return (get_ulong_attr_from_object(object_p->class,
37640Sstevel@tonic-gate 		    template));
37650Sstevel@tonic-gate 
37660Sstevel@tonic-gate 	/* default boolean attributes */
37670Sstevel@tonic-gate 	case CKA_TOKEN:
37680Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_BBOOL);
37690Sstevel@tonic-gate 		if (template->pValue == NULL) {
37700Sstevel@tonic-gate 			return (CKR_OK);
37710Sstevel@tonic-gate 		}
37720Sstevel@tonic-gate 		if (object_type & TOKEN_OBJECT)
37730Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_TRUE;
37740Sstevel@tonic-gate 		else
37750Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_FALSE;
37760Sstevel@tonic-gate 		break;
37770Sstevel@tonic-gate 
37780Sstevel@tonic-gate 	case CKA_PRIVATE:
37790Sstevel@tonic-gate 
37800Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_BBOOL);
37810Sstevel@tonic-gate 		if (template->pValue == NULL) {
37820Sstevel@tonic-gate 			return (CKR_OK);
37830Sstevel@tonic-gate 		}
37840Sstevel@tonic-gate 		if (object_type & PRIVATE_OBJECT)
37850Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_TRUE;
37860Sstevel@tonic-gate 		else
37870Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_FALSE;
37880Sstevel@tonic-gate 		break;
37890Sstevel@tonic-gate 
37900Sstevel@tonic-gate 	case CKA_MODIFIABLE:
37910Sstevel@tonic-gate 		template->ulValueLen = sizeof (CK_BBOOL);
37920Sstevel@tonic-gate 		if (template->pValue == NULL) {
37930Sstevel@tonic-gate 			return (CKR_OK);
37940Sstevel@tonic-gate 		}
37950Sstevel@tonic-gate 		if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
37960Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_FALSE;
37970Sstevel@tonic-gate 		else
37980Sstevel@tonic-gate 			*((CK_BBOOL *)template->pValue) = B_TRUE;
37990Sstevel@tonic-gate 		break;
38000Sstevel@tonic-gate 
38010Sstevel@tonic-gate 	case CKA_LABEL:
38020Sstevel@tonic-gate 		return (get_extra_attr_from_object(object_p,
38030Sstevel@tonic-gate 		    template));
38040Sstevel@tonic-gate 
38050Sstevel@tonic-gate 	default:
38060Sstevel@tonic-gate 		/*
38070Sstevel@tonic-gate 		 * The specified attribute for the object is invalid.
38080Sstevel@tonic-gate 		 * (the object does not possess such an attribute.)
38090Sstevel@tonic-gate 		 */
38100Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
38110Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_TYPE_INVALID);
38120Sstevel@tonic-gate 	}
38130Sstevel@tonic-gate 
38140Sstevel@tonic-gate 	return (rv);
38150Sstevel@tonic-gate }
38160Sstevel@tonic-gate 
38170Sstevel@tonic-gate /*
38180Sstevel@tonic-gate  * Get the value of a requested attribute that is common to all key objects
38190Sstevel@tonic-gate  * (i.e. public key, private key and secret key).
38200Sstevel@tonic-gate  */
38210Sstevel@tonic-gate CK_RV
38220Sstevel@tonic-gate soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
38230Sstevel@tonic-gate {
38240Sstevel@tonic-gate 
38250Sstevel@tonic-gate 	switch (template->type) {
38260Sstevel@tonic-gate 
38270Sstevel@tonic-gate 	case CKA_KEY_TYPE:
38280Sstevel@tonic-gate 		return (get_ulong_attr_from_object(object_p->key_type,
38290Sstevel@tonic-gate 		    template));
38300Sstevel@tonic-gate 
38310Sstevel@tonic-gate 	case CKA_ID:
38320Sstevel@tonic-gate 	case CKA_START_DATE:
38330Sstevel@tonic-gate 	case CKA_END_DATE:
38340Sstevel@tonic-gate 		/*
38350Sstevel@tonic-gate 		 * The above extra attributes have byte array type.
38360Sstevel@tonic-gate 		 */
38370Sstevel@tonic-gate 		return (get_extra_attr_from_object(object_p,
38380Sstevel@tonic-gate 		    template));
38390Sstevel@tonic-gate 
38400Sstevel@tonic-gate 	/* Key related boolean attributes */
38410Sstevel@tonic-gate 	case CKA_LOCAL:
38420Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38430Sstevel@tonic-gate 		    LOCAL_BOOL_ON, template));
38440Sstevel@tonic-gate 
38450Sstevel@tonic-gate 	case CKA_DERIVE:
38460Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38470Sstevel@tonic-gate 		    DERIVE_BOOL_ON, template));
38480Sstevel@tonic-gate 
38490Sstevel@tonic-gate 	case CKA_KEY_GEN_MECHANISM:
38500Sstevel@tonic-gate 		return (get_ulong_attr_from_object(object_p->mechanism,
38510Sstevel@tonic-gate 		    template));
38520Sstevel@tonic-gate 
38530Sstevel@tonic-gate 	default:
38540Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_TYPE_INVALID);
38550Sstevel@tonic-gate 	}
38560Sstevel@tonic-gate }
38570Sstevel@tonic-gate 
38580Sstevel@tonic-gate /*
38590Sstevel@tonic-gate  * Get the value of a requested attribute of a Public Key Object.
38600Sstevel@tonic-gate  *
38610Sstevel@tonic-gate  * Rule: All the attributes in the public key object can be revealed.
38620Sstevel@tonic-gate  */
38630Sstevel@tonic-gate CK_RV
38640Sstevel@tonic-gate soft_get_public_key_attribute(soft_object_t *object_p,
38650Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
38660Sstevel@tonic-gate {
38670Sstevel@tonic-gate 
38680Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
38690Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
38700Sstevel@tonic-gate 
38710Sstevel@tonic-gate 	switch (template->type) {
38720Sstevel@tonic-gate 
38730Sstevel@tonic-gate 	case CKA_SUBJECT:
38745697Smcpowers 	case CKA_EC_PARAMS:
38750Sstevel@tonic-gate 		/*
38760Sstevel@tonic-gate 		 * The above extra attributes have byte array type.
38770Sstevel@tonic-gate 		 */
38780Sstevel@tonic-gate 		return (get_extra_attr_from_object(object_p,
38790Sstevel@tonic-gate 		    template));
38800Sstevel@tonic-gate 
38810Sstevel@tonic-gate 	/* Key related boolean attributes */
38820Sstevel@tonic-gate 	case CKA_ENCRYPT:
38830Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38840Sstevel@tonic-gate 		    ENCRYPT_BOOL_ON, template));
38850Sstevel@tonic-gate 
38860Sstevel@tonic-gate 	case CKA_VERIFY:
38870Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38880Sstevel@tonic-gate 		    VERIFY_BOOL_ON, template));
38890Sstevel@tonic-gate 
38900Sstevel@tonic-gate 	case CKA_VERIFY_RECOVER:
38910Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38920Sstevel@tonic-gate 		    VERIFY_RECOVER_BOOL_ON, template));
38930Sstevel@tonic-gate 
38940Sstevel@tonic-gate 	case CKA_WRAP:
38950Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
38960Sstevel@tonic-gate 		    WRAP_BOOL_ON, template));
38970Sstevel@tonic-gate 
38980Sstevel@tonic-gate 	case CKA_TRUSTED:
38990Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
39000Sstevel@tonic-gate 		    TRUSTED_BOOL_ON, template));
39010Sstevel@tonic-gate 
39020Sstevel@tonic-gate 	case CKA_MODULUS:
39030Sstevel@tonic-gate 		/*
39040Sstevel@tonic-gate 		 * This attribute is valid only for RSA public key
39050Sstevel@tonic-gate 		 * object.
39060Sstevel@tonic-gate 		 */
39070Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
39080Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39090Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(object_p), template));
39100Sstevel@tonic-gate 		} else {
39110Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39120Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39130Sstevel@tonic-gate 		}
39140Sstevel@tonic-gate 
39150Sstevel@tonic-gate 	case CKA_PUBLIC_EXPONENT:
39160Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
39170Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39180Sstevel@tonic-gate 			    OBJ_PUB_RSA_PUBEXPO(object_p), template));
39190Sstevel@tonic-gate 		} else {
39200Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39210Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39220Sstevel@tonic-gate 		}
39230Sstevel@tonic-gate 
39240Sstevel@tonic-gate 	case CKA_MODULUS_BITS:
39250Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
39260Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
39270Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD_BITS(object_p), template));
39280Sstevel@tonic-gate 		} else {
39290Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39300Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39310Sstevel@tonic-gate 		}
39320Sstevel@tonic-gate 
39330Sstevel@tonic-gate 	case CKA_PRIME:
39340Sstevel@tonic-gate 		switch (keytype) {
39350Sstevel@tonic-gate 		case CKK_DSA:
39360Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39370Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(object_p), template));
39380Sstevel@tonic-gate 
39390Sstevel@tonic-gate 		case CKK_DH:
39400Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39410Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(object_p), template));
39420Sstevel@tonic-gate 
39430Sstevel@tonic-gate 		case CKK_X9_42_DH:
39440Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39450Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(object_p), template));
39460Sstevel@tonic-gate 
39470Sstevel@tonic-gate 		default:
39480Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39490Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39500Sstevel@tonic-gate 		}
39510Sstevel@tonic-gate 
39520Sstevel@tonic-gate 	case CKA_SUBPRIME:
39530Sstevel@tonic-gate 		switch (keytype) {
39540Sstevel@tonic-gate 		case CKK_DSA:
39550Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39560Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(object_p), template));
39570Sstevel@tonic-gate 
39580Sstevel@tonic-gate 		case CKK_X9_42_DH:
39590Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39600Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(object_p), template));
39610Sstevel@tonic-gate 
39620Sstevel@tonic-gate 		default:
39630Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39640Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39650Sstevel@tonic-gate 		}
39660Sstevel@tonic-gate 
39670Sstevel@tonic-gate 	case CKA_BASE:
39680Sstevel@tonic-gate 		switch (keytype) {
39690Sstevel@tonic-gate 		case CKK_DSA:
39700Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39710Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(object_p), template));
39720Sstevel@tonic-gate 
39730Sstevel@tonic-gate 		case CKK_DH:
39740Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39750Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(object_p), template));
39760Sstevel@tonic-gate 
39770Sstevel@tonic-gate 		case CKK_X9_42_DH:
39780Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39790Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(object_p), template));
39800Sstevel@tonic-gate 
39810Sstevel@tonic-gate 		default:
39820Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
39830Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
39840Sstevel@tonic-gate 		}
39850Sstevel@tonic-gate 
39864219Smcpowers 	case CKA_EC_POINT:
39875697Smcpowers 		return (get_bigint_attr_from_object(
39885697Smcpowers 		    OBJ_PUB_EC_POINT(object_p), template));
39894219Smcpowers 
39900Sstevel@tonic-gate 	case CKA_VALUE:
39910Sstevel@tonic-gate 		switch (keytype) {
39920Sstevel@tonic-gate 		case CKK_DSA:
39930Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39940Sstevel@tonic-gate 			    OBJ_PUB_DSA_VALUE(object_p), template));
39950Sstevel@tonic-gate 
39960Sstevel@tonic-gate 		case CKK_DH:
39970Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
39980Sstevel@tonic-gate 			    OBJ_PUB_DH_VALUE(object_p), template));
39990Sstevel@tonic-gate 
40000Sstevel@tonic-gate 		case CKK_X9_42_DH:
40010Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
40020Sstevel@tonic-gate 			    OBJ_PUB_DH942_VALUE(object_p), template));
40030Sstevel@tonic-gate 
40040Sstevel@tonic-gate 		default:
40050Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
40060Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
40070Sstevel@tonic-gate 		}
40080Sstevel@tonic-gate 
40090Sstevel@tonic-gate 	default:
40100Sstevel@tonic-gate 		/*
40110Sstevel@tonic-gate 		 * First, get the value of the request attribute defined
40120Sstevel@tonic-gate 		 * in the list of common key attributes. If the request
40130Sstevel@tonic-gate 		 * attribute is not found in that list, then get the
40140Sstevel@tonic-gate 		 * attribute from the list of common attributes.
40150Sstevel@tonic-gate 		 */
40160Sstevel@tonic-gate 		rv = soft_get_common_key_attrs(object_p, template);
40170Sstevel@tonic-gate 		if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
40180Sstevel@tonic-gate 			rv = soft_get_common_attrs(object_p, template,
40190Sstevel@tonic-gate 			    object_p->object_type);
40200Sstevel@tonic-gate 		}
40210Sstevel@tonic-gate 		break;
40220Sstevel@tonic-gate 	}
40230Sstevel@tonic-gate 
40240Sstevel@tonic-gate 	return (rv);
40250Sstevel@tonic-gate }
40260Sstevel@tonic-gate 
40270Sstevel@tonic-gate 
40280Sstevel@tonic-gate /*
40290Sstevel@tonic-gate  * Get the value of a requested attribute of a Private Key Object.
40300Sstevel@tonic-gate  *
40310Sstevel@tonic-gate  * Rule: All the attributes in the private key object can be revealed
40320Sstevel@tonic-gate  *       except those marked with footnote number "7" when the object
40330Sstevel@tonic-gate  *       has its CKA_SENSITIVE attribute set to TRUE or its
40340Sstevel@tonic-gate  *       CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
40350Sstevel@tonic-gate  */
40360Sstevel@tonic-gate CK_RV
40370Sstevel@tonic-gate soft_get_private_key_attribute(soft_object_t *object_p,
40380Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
40390Sstevel@tonic-gate {
40400Sstevel@tonic-gate 
40410Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
40420Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
40430Sstevel@tonic-gate 
40440Sstevel@tonic-gate 
40450Sstevel@tonic-gate 	/*
40460Sstevel@tonic-gate 	 * If the following specified attributes for the private key
40470Sstevel@tonic-gate 	 * object cannot be revealed because the object is sensitive
40480Sstevel@tonic-gate 	 * or unextractable, then the ulValueLen is set to -1.
40490Sstevel@tonic-gate 	 */
40500Sstevel@tonic-gate 	if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
40510Sstevel@tonic-gate 	    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
40520Sstevel@tonic-gate 
40530Sstevel@tonic-gate 		switch (template->type) {
40540Sstevel@tonic-gate 		case CKA_PRIVATE_EXPONENT:
40550Sstevel@tonic-gate 		case CKA_PRIME_1:
40560Sstevel@tonic-gate 		case CKA_PRIME_2:
40570Sstevel@tonic-gate 		case CKA_EXPONENT_1:
40580Sstevel@tonic-gate 		case CKA_EXPONENT_2:
40590Sstevel@tonic-gate 		case CKA_COEFFICIENT:
40600Sstevel@tonic-gate 		case CKA_VALUE:
40610Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
40620Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_SENSITIVE);
40630Sstevel@tonic-gate 		}
40640Sstevel@tonic-gate 	}
40650Sstevel@tonic-gate 
40660Sstevel@tonic-gate 	switch (template->type) {
40670Sstevel@tonic-gate 
40680Sstevel@tonic-gate 	case CKA_SUBJECT:
40695697Smcpowers 	case CKA_EC_PARAMS:
40700Sstevel@tonic-gate 		/*
40710Sstevel@tonic-gate 		 * The above extra attributes have byte array type.
40720Sstevel@tonic-gate 		 */
40730Sstevel@tonic-gate 		return (get_extra_attr_from_object(object_p,
40740Sstevel@tonic-gate 		    template));
40750Sstevel@tonic-gate 
40760Sstevel@tonic-gate 	/* Key related boolean attributes */
40770Sstevel@tonic-gate 	case CKA_SENSITIVE:
40780Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40790Sstevel@tonic-gate 		    SENSITIVE_BOOL_ON, template));
40800Sstevel@tonic-gate 
40810Sstevel@tonic-gate 	case CKA_SECONDARY_AUTH:
40820Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40830Sstevel@tonic-gate 		    SECONDARY_AUTH_BOOL_ON, template));
40840Sstevel@tonic-gate 
40850Sstevel@tonic-gate 	case CKA_DECRYPT:
40860Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40870Sstevel@tonic-gate 		    DECRYPT_BOOL_ON, template));
40880Sstevel@tonic-gate 
40890Sstevel@tonic-gate 	case CKA_SIGN:
40900Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40910Sstevel@tonic-gate 		    SIGN_BOOL_ON, template));
40920Sstevel@tonic-gate 
40930Sstevel@tonic-gate 	case CKA_SIGN_RECOVER:
40940Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40950Sstevel@tonic-gate 		    SIGN_RECOVER_BOOL_ON, template));
40960Sstevel@tonic-gate 
40970Sstevel@tonic-gate 	case CKA_UNWRAP:
40980Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
40990Sstevel@tonic-gate 		    UNWRAP_BOOL_ON, template));
41000Sstevel@tonic-gate 
41010Sstevel@tonic-gate 	case CKA_EXTRACTABLE:
41020Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
41030Sstevel@tonic-gate 		    EXTRACTABLE_BOOL_ON, template));
41040Sstevel@tonic-gate 
41050Sstevel@tonic-gate 	case CKA_ALWAYS_SENSITIVE:
41060Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
41070Sstevel@tonic-gate 		    ALWAYS_SENSITIVE_BOOL_ON, template));
41080Sstevel@tonic-gate 
41090Sstevel@tonic-gate 	case CKA_NEVER_EXTRACTABLE:
41100Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
41110Sstevel@tonic-gate 		    NEVER_EXTRACTABLE_BOOL_ON, template));
41120Sstevel@tonic-gate 
41130Sstevel@tonic-gate 	case CKA_MODULUS:
41140Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41150Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41160Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(object_p), template));
41170Sstevel@tonic-gate 		} else {
41180Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41190Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41200Sstevel@tonic-gate 			break;
41210Sstevel@tonic-gate 		}
41220Sstevel@tonic-gate 
41230Sstevel@tonic-gate 	case CKA_PUBLIC_EXPONENT:
41240Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41250Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41260Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(object_p), template));
41270Sstevel@tonic-gate 		} else {
41280Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41290Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41300Sstevel@tonic-gate 			break;
41310Sstevel@tonic-gate 		}
41320Sstevel@tonic-gate 
41330Sstevel@tonic-gate 	case CKA_PRIVATE_EXPONENT:
41340Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41350Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41360Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(object_p), template));
41370Sstevel@tonic-gate 		} else {
41380Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41390Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41400Sstevel@tonic-gate 			break;
41410Sstevel@tonic-gate 		}
41420Sstevel@tonic-gate 
41430Sstevel@tonic-gate 	case CKA_PRIME_1:
41440Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41450Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41460Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(object_p), template));
41470Sstevel@tonic-gate 		} else {
41480Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41490Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41500Sstevel@tonic-gate 			break;
41510Sstevel@tonic-gate 		}
41520Sstevel@tonic-gate 
41530Sstevel@tonic-gate 	case CKA_PRIME_2:
41540Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41550Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41560Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(object_p), template));
41570Sstevel@tonic-gate 		} else {
41580Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41590Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41600Sstevel@tonic-gate 			break;
41610Sstevel@tonic-gate 		}
41620Sstevel@tonic-gate 
41630Sstevel@tonic-gate 	case CKA_EXPONENT_1:
41640Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41650Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41660Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(object_p), template));
41670Sstevel@tonic-gate 		} else {
41680Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41690Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41700Sstevel@tonic-gate 			break;
41710Sstevel@tonic-gate 		}
41720Sstevel@tonic-gate 
41730Sstevel@tonic-gate 	case CKA_EXPONENT_2:
41740Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41750Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41760Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(object_p), template));
41770Sstevel@tonic-gate 		} else {
41780Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41790Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41800Sstevel@tonic-gate 			break;
41810Sstevel@tonic-gate 		}
41820Sstevel@tonic-gate 
41830Sstevel@tonic-gate 	case CKA_COEFFICIENT:
41840Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
41850Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
41860Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(object_p), template));
41870Sstevel@tonic-gate 		} else {
41880Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41890Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
41900Sstevel@tonic-gate 			break;
41910Sstevel@tonic-gate 		}
41920Sstevel@tonic-gate 
41930Sstevel@tonic-gate 	case CKA_VALUE_BITS:
41940Sstevel@tonic-gate 		if (keytype == CKK_DH) {
41950Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
41960Sstevel@tonic-gate 			    OBJ_PRI_DH_VAL_BITS(object_p), template));
41970Sstevel@tonic-gate 		} else {
41980Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
41990Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
42000Sstevel@tonic-gate 			break;
42010Sstevel@tonic-gate 		}
42020Sstevel@tonic-gate 
42030Sstevel@tonic-gate 	case CKA_PRIME:
42040Sstevel@tonic-gate 		switch (keytype) {
42050Sstevel@tonic-gate 		case CKK_DSA:
42060Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42070Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(object_p), template));
42080Sstevel@tonic-gate 
42090Sstevel@tonic-gate 		case CKK_DH:
42100Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42110Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(object_p), template));
42120Sstevel@tonic-gate 
42130Sstevel@tonic-gate 		case CKK_X9_42_DH:
42140Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42150Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(object_p), template));
42160Sstevel@tonic-gate 
42170Sstevel@tonic-gate 		default:
42180Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
42190Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
42200Sstevel@tonic-gate 		}
42210Sstevel@tonic-gate 
42220Sstevel@tonic-gate 	case CKA_SUBPRIME:
42230Sstevel@tonic-gate 		switch (keytype) {
42240Sstevel@tonic-gate 		case CKK_DSA:
42250Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42260Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(object_p), template));
42270Sstevel@tonic-gate 
42280Sstevel@tonic-gate 		case CKK_X9_42_DH:
42290Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42300Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(object_p), template));
42310Sstevel@tonic-gate 
42320Sstevel@tonic-gate 		default:
42330Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
42340Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
42350Sstevel@tonic-gate 		}
42360Sstevel@tonic-gate 
42370Sstevel@tonic-gate 	case CKA_BASE:
42380Sstevel@tonic-gate 		switch (keytype) {
42390Sstevel@tonic-gate 		case CKK_DSA:
42400Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42410Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(object_p), template));
42420Sstevel@tonic-gate 
42430Sstevel@tonic-gate 		case CKK_DH:
42440Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42450Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(object_p), template));
42460Sstevel@tonic-gate 
42470Sstevel@tonic-gate 		case CKK_X9_42_DH:
42480Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42490Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(object_p), template));
42500Sstevel@tonic-gate 
42510Sstevel@tonic-gate 		default:
42520Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
42530Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
42540Sstevel@tonic-gate 		}
42550Sstevel@tonic-gate 
42560Sstevel@tonic-gate 	case CKA_VALUE:
42570Sstevel@tonic-gate 		switch (keytype) {
42580Sstevel@tonic-gate 		case CKK_DSA:
42590Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42600Sstevel@tonic-gate 			    OBJ_PRI_DSA_VALUE(object_p), template));
42610Sstevel@tonic-gate 
42620Sstevel@tonic-gate 		case CKK_DH:
42630Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42640Sstevel@tonic-gate 			    OBJ_PRI_DH_VALUE(object_p), template));
42650Sstevel@tonic-gate 
42660Sstevel@tonic-gate 		case CKK_X9_42_DH:
42670Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
42680Sstevel@tonic-gate 			    OBJ_PRI_DH942_VALUE(object_p), template));
42690Sstevel@tonic-gate 
42704219Smcpowers 		case CKK_EC:
42714219Smcpowers 			return (get_bigint_attr_from_object(
42724219Smcpowers 			    OBJ_PRI_EC_VALUE(object_p), template));
42734219Smcpowers 
42740Sstevel@tonic-gate 		default:
42750Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
42760Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
42770Sstevel@tonic-gate 		}
42780Sstevel@tonic-gate 
42790Sstevel@tonic-gate 	default:
42800Sstevel@tonic-gate 		/*
42810Sstevel@tonic-gate 		 * First, get the value of the request attribute defined
42820Sstevel@tonic-gate 		 * in the list of common key attributes. If the request
42830Sstevel@tonic-gate 		 * attribute is not found in that list, then get the
42840Sstevel@tonic-gate 		 * attribute from the list of common attributes.
42850Sstevel@tonic-gate 		 */
42860Sstevel@tonic-gate 		rv = soft_get_common_key_attrs(object_p, template);
42870Sstevel@tonic-gate 		if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
42880Sstevel@tonic-gate 			rv = soft_get_common_attrs(object_p, template,
42890Sstevel@tonic-gate 			    object_p->object_type);
42900Sstevel@tonic-gate 		}
42910Sstevel@tonic-gate 		break;
42920Sstevel@tonic-gate 	}
42930Sstevel@tonic-gate 
42940Sstevel@tonic-gate 	return (rv);
42950Sstevel@tonic-gate }
42960Sstevel@tonic-gate 
42970Sstevel@tonic-gate 
42980Sstevel@tonic-gate /*
42990Sstevel@tonic-gate  * Get the value of a requested attribute of a Secret Key Object.
43000Sstevel@tonic-gate  *
43010Sstevel@tonic-gate  * Rule: All the attributes in the secret key object can be revealed
43020Sstevel@tonic-gate  *       except those marked with footnote number "7" when the object
43030Sstevel@tonic-gate  *       has its CKA_SENSITIVE attribute set to TRUE or its
43040Sstevel@tonic-gate  *       CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
43050Sstevel@tonic-gate  */
43060Sstevel@tonic-gate CK_RV
43070Sstevel@tonic-gate soft_get_secret_key_attribute(soft_object_t *object_p,
43080Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
43090Sstevel@tonic-gate {
43100Sstevel@tonic-gate 
43110Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
43120Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
43130Sstevel@tonic-gate 
43140Sstevel@tonic-gate 	switch (template->type) {
43150Sstevel@tonic-gate 
43160Sstevel@tonic-gate 	/* Key related boolean attributes */
43170Sstevel@tonic-gate 	case CKA_SENSITIVE:
43180Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43190Sstevel@tonic-gate 		    SENSITIVE_BOOL_ON, template));
43200Sstevel@tonic-gate 
43210Sstevel@tonic-gate 	case CKA_ENCRYPT:
43220Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43230Sstevel@tonic-gate 		    ENCRYPT_BOOL_ON, template));
43240Sstevel@tonic-gate 
43250Sstevel@tonic-gate 	case CKA_DECRYPT:
43260Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43270Sstevel@tonic-gate 		    DECRYPT_BOOL_ON, template));
43280Sstevel@tonic-gate 
43290Sstevel@tonic-gate 	case CKA_SIGN:
43300Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43310Sstevel@tonic-gate 		    SIGN_BOOL_ON, template));
43320Sstevel@tonic-gate 
43330Sstevel@tonic-gate 	case CKA_VERIFY:
43340Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43350Sstevel@tonic-gate 		    VERIFY_BOOL_ON, template));
43360Sstevel@tonic-gate 
43370Sstevel@tonic-gate 	case CKA_WRAP:
43380Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43390Sstevel@tonic-gate 		    WRAP_BOOL_ON, template));
43400Sstevel@tonic-gate 
43410Sstevel@tonic-gate 	case CKA_UNWRAP:
43420Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43430Sstevel@tonic-gate 		    UNWRAP_BOOL_ON, template));
43440Sstevel@tonic-gate 
43450Sstevel@tonic-gate 	case CKA_EXTRACTABLE:
43460Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43470Sstevel@tonic-gate 		    EXTRACTABLE_BOOL_ON, template));
43480Sstevel@tonic-gate 
43490Sstevel@tonic-gate 	case CKA_ALWAYS_SENSITIVE:
43500Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43510Sstevel@tonic-gate 		    ALWAYS_SENSITIVE_BOOL_ON, template));
43520Sstevel@tonic-gate 
43530Sstevel@tonic-gate 	case CKA_NEVER_EXTRACTABLE:
43540Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
43550Sstevel@tonic-gate 		    NEVER_EXTRACTABLE_BOOL_ON, template));
43560Sstevel@tonic-gate 
43570Sstevel@tonic-gate 	case CKA_VALUE:
43580Sstevel@tonic-gate 	case CKA_VALUE_LEN:
43590Sstevel@tonic-gate 		/*
43600Sstevel@tonic-gate 		 * If the specified attribute for the secret key object
43610Sstevel@tonic-gate 		 * cannot be revealed because the object is sensitive
43620Sstevel@tonic-gate 		 * or unextractable, then the ulValueLen is set to -1.
43630Sstevel@tonic-gate 		 */
43640Sstevel@tonic-gate 		if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
43650Sstevel@tonic-gate 		    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
43660Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
43670Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_SENSITIVE);
43680Sstevel@tonic-gate 		}
43690Sstevel@tonic-gate 
43700Sstevel@tonic-gate 		switch (keytype) {
43710Sstevel@tonic-gate 		case CKK_RC4:
43720Sstevel@tonic-gate 		case CKK_GENERIC_SECRET:
43730Sstevel@tonic-gate 		case CKK_RC5:
43740Sstevel@tonic-gate 		case CKK_DES:
43750Sstevel@tonic-gate 		case CKK_DES2:
43760Sstevel@tonic-gate 		case CKK_DES3:
43770Sstevel@tonic-gate 		case CKK_CDMF:
43780Sstevel@tonic-gate 		case CKK_AES:
4379676Sizick 		case CKK_BLOWFISH:
43800Sstevel@tonic-gate 			if (template->type == CKA_VALUE_LEN) {
43810Sstevel@tonic-gate 				return (get_ulong_attr_from_object(
43820Sstevel@tonic-gate 				    OBJ_SEC_VALUE_LEN(object_p),
43830Sstevel@tonic-gate 				    template));
43840Sstevel@tonic-gate 			} else {
43850Sstevel@tonic-gate 				return (get_bigint_attr_from_object(
43860Sstevel@tonic-gate 				    (biginteger_t *)OBJ_SEC(object_p),
43870Sstevel@tonic-gate 				    template));
43880Sstevel@tonic-gate 			}
43890Sstevel@tonic-gate 		default:
43900Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
43910Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
43920Sstevel@tonic-gate 			break;
43930Sstevel@tonic-gate 		}
43940Sstevel@tonic-gate 		break;
43950Sstevel@tonic-gate 
43960Sstevel@tonic-gate 	default:
43970Sstevel@tonic-gate 		/*
43980Sstevel@tonic-gate 		 * First, get the value of the request attribute defined
43990Sstevel@tonic-gate 		 * in the list of common key attributes. If the request
44000Sstevel@tonic-gate 		 * attribute is not found in that list, then get the
44010Sstevel@tonic-gate 		 * attribute from the list of common attributes.
44020Sstevel@tonic-gate 		 */
44030Sstevel@tonic-gate 		rv = soft_get_common_key_attrs(object_p, template);
44040Sstevel@tonic-gate 		if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
44050Sstevel@tonic-gate 			rv = soft_get_common_attrs(object_p, template,
44060Sstevel@tonic-gate 			    object_p->object_type);
44070Sstevel@tonic-gate 		}
44080Sstevel@tonic-gate 		break;
44090Sstevel@tonic-gate 	}
44100Sstevel@tonic-gate 
44110Sstevel@tonic-gate 	return (rv);
44120Sstevel@tonic-gate }
44130Sstevel@tonic-gate 
44140Sstevel@tonic-gate 
44150Sstevel@tonic-gate /*
44160Sstevel@tonic-gate  * Get the value of a requested attribute of a Domain Parameters Object.
44170Sstevel@tonic-gate  *
44180Sstevel@tonic-gate  * Rule: All the attributes in the domain parameters object can be revealed.
44190Sstevel@tonic-gate  */
44200Sstevel@tonic-gate CK_RV
44210Sstevel@tonic-gate soft_get_domain_parameters_attribute(soft_object_t *object_p,
44220Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
44230Sstevel@tonic-gate {
44240Sstevel@tonic-gate 
44250Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
44260Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
44270Sstevel@tonic-gate 
44280Sstevel@tonic-gate 	switch (template->type) {
44290Sstevel@tonic-gate 
44300Sstevel@tonic-gate 	case CKA_KEY_TYPE:
44310Sstevel@tonic-gate 		return (get_ulong_attr_from_object(keytype,
44320Sstevel@tonic-gate 		    template));
44330Sstevel@tonic-gate 
44340Sstevel@tonic-gate 	case CKA_LOCAL:
44350Sstevel@tonic-gate 		return (get_bool_attr_from_object(object_p,
44360Sstevel@tonic-gate 		    LOCAL_BOOL_ON, template));
44370Sstevel@tonic-gate 
44380Sstevel@tonic-gate 	case CKA_PRIME:
44390Sstevel@tonic-gate 		switch (keytype) {
44400Sstevel@tonic-gate 		case CKK_DSA:
44410Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44420Sstevel@tonic-gate 			    OBJ_DOM_DSA_PRIME(object_p), template));
44430Sstevel@tonic-gate 
44440Sstevel@tonic-gate 		case CKK_DH:
44450Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44460Sstevel@tonic-gate 			    OBJ_DOM_DH_PRIME(object_p), template));
44470Sstevel@tonic-gate 
44480Sstevel@tonic-gate 		case CKK_X9_42_DH:
44490Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44500Sstevel@tonic-gate 			    OBJ_DOM_DH942_PRIME(object_p), template));
44510Sstevel@tonic-gate 
44520Sstevel@tonic-gate 		default:
44530Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
44540Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
44550Sstevel@tonic-gate 		}
44560Sstevel@tonic-gate 
44570Sstevel@tonic-gate 	case CKA_SUBPRIME:
44580Sstevel@tonic-gate 		switch (keytype) {
44590Sstevel@tonic-gate 		case CKK_DSA:
44600Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44610Sstevel@tonic-gate 			    OBJ_DOM_DSA_SUBPRIME(object_p), template));
44620Sstevel@tonic-gate 
44630Sstevel@tonic-gate 		case CKK_X9_42_DH:
44640Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44650Sstevel@tonic-gate 			    OBJ_DOM_DH942_SUBPRIME(object_p), template));
44660Sstevel@tonic-gate 
44670Sstevel@tonic-gate 		default:
44680Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
44690Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
44700Sstevel@tonic-gate 		}
44710Sstevel@tonic-gate 
44720Sstevel@tonic-gate 	case CKA_BASE:
44730Sstevel@tonic-gate 		switch (keytype) {
44740Sstevel@tonic-gate 		case CKK_DSA:
44750Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44760Sstevel@tonic-gate 			    OBJ_DOM_DSA_BASE(object_p), template));
44770Sstevel@tonic-gate 
44780Sstevel@tonic-gate 		case CKK_DH:
44790Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44800Sstevel@tonic-gate 			    OBJ_DOM_DH_BASE(object_p), template));
44810Sstevel@tonic-gate 
44820Sstevel@tonic-gate 		case CKK_X9_42_DH:
44830Sstevel@tonic-gate 			return (get_bigint_attr_from_object(
44840Sstevel@tonic-gate 			    OBJ_DOM_DH942_BASE(object_p), template));
44850Sstevel@tonic-gate 
44860Sstevel@tonic-gate 		default:
44870Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
44880Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
44890Sstevel@tonic-gate 		}
44900Sstevel@tonic-gate 
44910Sstevel@tonic-gate 	case CKA_PRIME_BITS:
44920Sstevel@tonic-gate 		switch (keytype) {
44930Sstevel@tonic-gate 		case CKK_DSA:
44940Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
44950Sstevel@tonic-gate 			    OBJ_DOM_DSA_PRIME_BITS(object_p), template));
44960Sstevel@tonic-gate 
44970Sstevel@tonic-gate 		case CKK_DH:
44980Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
44990Sstevel@tonic-gate 			    OBJ_DOM_DH_PRIME_BITS(object_p), template));
45000Sstevel@tonic-gate 
45010Sstevel@tonic-gate 		case CKK_X9_42_DH:
45020Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
45030Sstevel@tonic-gate 			    OBJ_DOM_DH942_PRIME_BITS(object_p), template));
45040Sstevel@tonic-gate 
45050Sstevel@tonic-gate 		default:
45060Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
45070Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
45080Sstevel@tonic-gate 		}
45090Sstevel@tonic-gate 
45100Sstevel@tonic-gate 	case CKA_SUB_PRIME_BITS:
45110Sstevel@tonic-gate 		switch (keytype) {
45120Sstevel@tonic-gate 		case CKK_X9_42_DH:
45130Sstevel@tonic-gate 			return (get_ulong_attr_from_object(
45140Sstevel@tonic-gate 			    OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
45150Sstevel@tonic-gate 
45160Sstevel@tonic-gate 		default:
45170Sstevel@tonic-gate 			template->ulValueLen = (CK_ULONG)-1;
45180Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_TYPE_INVALID);
45190Sstevel@tonic-gate 		}
45200Sstevel@tonic-gate 
45210Sstevel@tonic-gate 	default:
45220Sstevel@tonic-gate 		/*
45230Sstevel@tonic-gate 		 * Get the value of a common attribute.
45240Sstevel@tonic-gate 		 */
45250Sstevel@tonic-gate 		rv = soft_get_common_attrs(object_p, template,
45260Sstevel@tonic-gate 		    object_p->object_type);
45270Sstevel@tonic-gate 		break;
45280Sstevel@tonic-gate 	}
45290Sstevel@tonic-gate 
45300Sstevel@tonic-gate 	return (rv);
45310Sstevel@tonic-gate }
45320Sstevel@tonic-gate 
45330Sstevel@tonic-gate /*
45340Sstevel@tonic-gate  * Get certificate attributes from an object.
45350Sstevel@tonic-gate  * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
45360Sstevel@tonic-gate  * does not exist in the certificate.
45370Sstevel@tonic-gate  */
45380Sstevel@tonic-gate CK_RV
45390Sstevel@tonic-gate soft_get_certificate_attribute(soft_object_t *object_p,
45400Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template)
45410Sstevel@tonic-gate {
45420Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
45430Sstevel@tonic-gate 	cert_attr_t src;
45440Sstevel@tonic-gate 
45450Sstevel@tonic-gate 	switch (template->type) {
45460Sstevel@tonic-gate 		case CKA_SUBJECT:
45470Sstevel@tonic-gate 			if (certtype == CKC_X_509) {
45480Sstevel@tonic-gate 				return (get_cert_attr_from_object(
45495697Smcpowers 				    X509_CERT_SUBJECT(object_p), template));
45500Sstevel@tonic-gate 			}
45510Sstevel@tonic-gate 			break;
45520Sstevel@tonic-gate 		case CKA_VALUE:
45530Sstevel@tonic-gate 			if (certtype == CKC_X_509) {
45545697Smcpowers 				return (get_cert_attr_from_object(
45555697Smcpowers 				    X509_CERT_VALUE(object_p), template));
45560Sstevel@tonic-gate 			} else if (certtype == CKC_X_509_ATTR_CERT) {
45575697Smcpowers 				return (get_cert_attr_from_object(
45585697Smcpowers 				    X509_ATTR_CERT_VALUE(object_p), template));
45590Sstevel@tonic-gate 			}
45600Sstevel@tonic-gate 			break;
45610Sstevel@tonic-gate 		case CKA_OWNER:
45620Sstevel@tonic-gate 			if (certtype == CKC_X_509_ATTR_CERT) {
45630Sstevel@tonic-gate 				return (get_cert_attr_from_object(
45645697Smcpowers 				    X509_ATTR_CERT_OWNER(object_p), template));
45650Sstevel@tonic-gate 			}
45660Sstevel@tonic-gate 			break;
45670Sstevel@tonic-gate 		case CKA_CERTIFICATE_TYPE:
45680Sstevel@tonic-gate 			src.value = (CK_BYTE *)&certtype;
45690Sstevel@tonic-gate 			src.length = sizeof (certtype);
45700Sstevel@tonic-gate 			return (get_cert_attr_from_object(&src, template));
45710Sstevel@tonic-gate 			break;
45720Sstevel@tonic-gate 		case CKA_TRUSTED:
45730Sstevel@tonic-gate 			return (get_bool_attr_from_object(object_p,
45745697Smcpowers 			    TRUSTED_BOOL_ON, template));
45750Sstevel@tonic-gate 		case CKA_ID:
45760Sstevel@tonic-gate 		case CKA_ISSUER:
45770Sstevel@tonic-gate 		case CKA_SERIAL_NUMBER:
45780Sstevel@tonic-gate 		case CKA_AC_ISSUER:
45790Sstevel@tonic-gate 		case CKA_ATTR_TYPES:
45800Sstevel@tonic-gate 			return (get_extra_attr_from_object(object_p,
4581676Sizick 			    template));
45820Sstevel@tonic-gate 			break;
45830Sstevel@tonic-gate 		default:
45840Sstevel@tonic-gate 			return (soft_get_common_attrs(object_p, template,
45855697Smcpowers 			    object_p->object_type));
45860Sstevel@tonic-gate 			break;
45870Sstevel@tonic-gate 	}
45880Sstevel@tonic-gate 
45890Sstevel@tonic-gate 	/*
45900Sstevel@tonic-gate 	 * If we got this far, then the combination of certificate type
45910Sstevel@tonic-gate 	 * and requested attribute is invalid.
45920Sstevel@tonic-gate 	 */
45930Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
45940Sstevel@tonic-gate }
45950Sstevel@tonic-gate 
45960Sstevel@tonic-gate CK_RV
45970Sstevel@tonic-gate soft_set_certificate_attribute(soft_object_t *object_p,
45980Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
45990Sstevel@tonic-gate {
46000Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
46010Sstevel@tonic-gate 
46020Sstevel@tonic-gate 	switch (template->type) {
46030Sstevel@tonic-gate 		case CKA_SUBJECT:
46040Sstevel@tonic-gate 			if (certtype == CKC_X_509) {
46050Sstevel@tonic-gate 				/* SUBJECT attr cannot be modified. */
46060Sstevel@tonic-gate 				return (CKR_ATTRIBUTE_READ_ONLY);
46070Sstevel@tonic-gate 			}
46080Sstevel@tonic-gate 			break;
46090Sstevel@tonic-gate 		case CKA_OWNER:
46100Sstevel@tonic-gate 			if (certtype == CKC_X_509_ATTR_CERT) {
46110Sstevel@tonic-gate 				/* OWNER attr cannot be modified. */
46120Sstevel@tonic-gate 				return (CKR_ATTRIBUTE_READ_ONLY);
46130Sstevel@tonic-gate 			}
46140Sstevel@tonic-gate 			break;
46150Sstevel@tonic-gate 		case CKA_VALUE:
46160Sstevel@tonic-gate 			/* VALUE attr cannot be modified. */
46170Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
46180Sstevel@tonic-gate 			break;
46190Sstevel@tonic-gate 		case CKA_ID:
46200Sstevel@tonic-gate 		case CKA_ISSUER:
46210Sstevel@tonic-gate 			if (certtype == CKC_X_509) {
46220Sstevel@tonic-gate 				return (set_extra_attr_to_object(object_p,
46235697Smcpowers 				    template->type, template));
46240Sstevel@tonic-gate 			}
46250Sstevel@tonic-gate 			break;
46260Sstevel@tonic-gate 		case CKA_AC_ISSUER:
46270Sstevel@tonic-gate 		case CKA_ATTR_TYPES:
46280Sstevel@tonic-gate 			if (certtype == CKC_X_509_ATTR_CERT) {
46290Sstevel@tonic-gate 				return (set_extra_attr_to_object(object_p,
46305697Smcpowers 				    template->type, template));
46310Sstevel@tonic-gate 			}
46320Sstevel@tonic-gate 			break;
46330Sstevel@tonic-gate 		case CKA_SERIAL_NUMBER:
46340Sstevel@tonic-gate 		case CKA_LABEL:
46350Sstevel@tonic-gate 			return (set_extra_attr_to_object(object_p,
46365697Smcpowers 			    template->type, template));
46370Sstevel@tonic-gate 			break;
46380Sstevel@tonic-gate 		default:
46390Sstevel@tonic-gate 			return (soft_set_common_storage_attribute(
46400Sstevel@tonic-gate 			    object_p, template, copy));
46410Sstevel@tonic-gate 			break;
46420Sstevel@tonic-gate 	}
46430Sstevel@tonic-gate 
46440Sstevel@tonic-gate 	/*
46450Sstevel@tonic-gate 	 * If we got this far, then the combination of certificate type
46460Sstevel@tonic-gate 	 * and requested attribute is invalid.
46470Sstevel@tonic-gate 	 */
46480Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
46490Sstevel@tonic-gate }
46500Sstevel@tonic-gate 
46510Sstevel@tonic-gate /*
46520Sstevel@tonic-gate  * Call the appropriate get attribute function according to the class
46530Sstevel@tonic-gate  * of object.
46540Sstevel@tonic-gate  *
46550Sstevel@tonic-gate  * The caller of this function holds the lock on the object.
46560Sstevel@tonic-gate  */
46570Sstevel@tonic-gate CK_RV
46580Sstevel@tonic-gate soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
46590Sstevel@tonic-gate {
46600Sstevel@tonic-gate 
46610Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
46620Sstevel@tonic-gate 	CK_OBJECT_CLASS class = object_p->class;
46630Sstevel@tonic-gate 
46640Sstevel@tonic-gate 	switch (class) {
46650Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
46660Sstevel@tonic-gate 		rv = soft_get_public_key_attribute(object_p, template);
46670Sstevel@tonic-gate 		break;
46680Sstevel@tonic-gate 
46690Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
46700Sstevel@tonic-gate 		rv = soft_get_private_key_attribute(object_p, template);
46710Sstevel@tonic-gate 		break;
46720Sstevel@tonic-gate 
46730Sstevel@tonic-gate 	case CKO_SECRET_KEY:
46740Sstevel@tonic-gate 		rv = soft_get_secret_key_attribute(object_p, template);
46750Sstevel@tonic-gate 		break;
46760Sstevel@tonic-gate 
46770Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
46780Sstevel@tonic-gate 		rv = soft_get_domain_parameters_attribute(object_p, template);
46790Sstevel@tonic-gate 		break;
46800Sstevel@tonic-gate 
46810Sstevel@tonic-gate 	case CKO_CERTIFICATE:
46820Sstevel@tonic-gate 		rv = soft_get_certificate_attribute(object_p, template);
46830Sstevel@tonic-gate 		break;
46840Sstevel@tonic-gate 
46850Sstevel@tonic-gate 	default:
46860Sstevel@tonic-gate 		/*
46870Sstevel@tonic-gate 		 * If the specified attribute for the object is invalid
46880Sstevel@tonic-gate 		 * (the object does not possess such as attribute), then
46890Sstevel@tonic-gate 		 * the ulValueLen is modified to hold the value -1.
46900Sstevel@tonic-gate 		 */
46910Sstevel@tonic-gate 		template->ulValueLen = (CK_ULONG)-1;
46920Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_TYPE_INVALID);
46930Sstevel@tonic-gate 	}
46940Sstevel@tonic-gate 
46950Sstevel@tonic-gate 	return (rv);
46960Sstevel@tonic-gate 
46970Sstevel@tonic-gate }
46980Sstevel@tonic-gate 
46990Sstevel@tonic-gate CK_RV
47000Sstevel@tonic-gate soft_set_common_storage_attribute(soft_object_t *object_p,
47010Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
47020Sstevel@tonic-gate {
47030Sstevel@tonic-gate 
47040Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
47050Sstevel@tonic-gate 
47060Sstevel@tonic-gate 	switch (template->type) {
47070Sstevel@tonic-gate 
47080Sstevel@tonic-gate 	case CKA_TOKEN:
47090Sstevel@tonic-gate 		if (copy) {
47100Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
47111937Sizick 				if (!soft_keystore_status(KEYSTORE_INITIALIZED))
47120Sstevel@tonic-gate 					return (CKR_DEVICE_REMOVED);
47130Sstevel@tonic-gate 				object_p->object_type |= TOKEN_OBJECT;
47140Sstevel@tonic-gate 			}
47150Sstevel@tonic-gate 		} else {
47160Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_READ_ONLY;
47170Sstevel@tonic-gate 		}
47180Sstevel@tonic-gate 
47190Sstevel@tonic-gate 		break;
47200Sstevel@tonic-gate 
47210Sstevel@tonic-gate 	case CKA_PRIVATE:
47220Sstevel@tonic-gate 		if (copy) {
47230Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
47240Sstevel@tonic-gate 				(void) pthread_mutex_lock(&soft_giant_mutex);
47250Sstevel@tonic-gate 				if (!soft_slot.authenticated) {
47260Sstevel@tonic-gate 					/*
47270Sstevel@tonic-gate 					 * Check if this is the special case
47280Sstevel@tonic-gate 					 * when the PIN is never initialized
47290Sstevel@tonic-gate 					 * in the keystore. If true, we will
47300Sstevel@tonic-gate 					 * let it pass here and let it fail
47310Sstevel@tonic-gate 					 * with CKR_PIN_EXPIRED later on.
47320Sstevel@tonic-gate 					 */
47330Sstevel@tonic-gate 					if (!soft_slot.userpin_change_needed) {
47340Sstevel@tonic-gate 						(void) pthread_mutex_unlock(
47350Sstevel@tonic-gate 						    &soft_giant_mutex);
47360Sstevel@tonic-gate 						return (CKR_USER_NOT_LOGGED_IN);
47370Sstevel@tonic-gate 					}
47380Sstevel@tonic-gate 				}
47390Sstevel@tonic-gate 				(void) pthread_mutex_unlock(&soft_giant_mutex);
47400Sstevel@tonic-gate 				object_p->object_type |= PRIVATE_OBJECT;
47410Sstevel@tonic-gate 			}
47420Sstevel@tonic-gate 		} else {
47430Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_READ_ONLY;
47440Sstevel@tonic-gate 		}
47450Sstevel@tonic-gate 		break;
47460Sstevel@tonic-gate 
47470Sstevel@tonic-gate 	case CKA_MODIFIABLE:
47480Sstevel@tonic-gate 		if (copy) {
47490Sstevel@tonic-gate 			if ((*(CK_BBOOL *)template->pValue) == TRUE)
47500Sstevel@tonic-gate 				object_p->bool_attr_mask &=
47510Sstevel@tonic-gate 				    ~NOT_MODIFIABLE_BOOL_ON;
47520Sstevel@tonic-gate 			else
47530Sstevel@tonic-gate 				object_p->bool_attr_mask |=
47540Sstevel@tonic-gate 				    NOT_MODIFIABLE_BOOL_ON;
47550Sstevel@tonic-gate 		} else {
47560Sstevel@tonic-gate 			rv = CKR_ATTRIBUTE_READ_ONLY;
47570Sstevel@tonic-gate 		}
47580Sstevel@tonic-gate 		break;
47590Sstevel@tonic-gate 
47600Sstevel@tonic-gate 	case CKA_CLASS:
47610Sstevel@tonic-gate 		rv = CKR_ATTRIBUTE_READ_ONLY;
47620Sstevel@tonic-gate 		break;
47630Sstevel@tonic-gate 
47640Sstevel@tonic-gate 	default:
47650Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
47660Sstevel@tonic-gate 	}
47670Sstevel@tonic-gate 
47680Sstevel@tonic-gate 	return (rv);
47690Sstevel@tonic-gate }
47700Sstevel@tonic-gate 
47710Sstevel@tonic-gate /*
47720Sstevel@tonic-gate  * Set the value of an attribute that is common to all key objects
47730Sstevel@tonic-gate  * (i.e. public key, private key and secret key).
47740Sstevel@tonic-gate  */
47750Sstevel@tonic-gate CK_RV
47760Sstevel@tonic-gate soft_set_common_key_attribute(soft_object_t *object_p,
47770Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
47780Sstevel@tonic-gate {
47790Sstevel@tonic-gate 
47800Sstevel@tonic-gate 	switch (template->type) {
47810Sstevel@tonic-gate 
47820Sstevel@tonic-gate 	case CKA_LABEL:
47830Sstevel@tonic-gate 		/*
47840Sstevel@tonic-gate 		 * Only the LABEL can be modified in the common storage
47850Sstevel@tonic-gate 		 * object attributes after the object is created.
47860Sstevel@tonic-gate 		 */
47870Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
47880Sstevel@tonic-gate 		    CKA_LABEL, template));
47890Sstevel@tonic-gate 
47900Sstevel@tonic-gate 	case CKA_ID:
47910Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
47920Sstevel@tonic-gate 		    CKA_ID, template));
47930Sstevel@tonic-gate 
47940Sstevel@tonic-gate 	case CKA_START_DATE:
47950Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
47960Sstevel@tonic-gate 		    CKA_START_DATE, template));
47970Sstevel@tonic-gate 
47980Sstevel@tonic-gate 	case CKA_END_DATE:
47990Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
48000Sstevel@tonic-gate 		    CKA_END_DATE, template));
48010Sstevel@tonic-gate 
48020Sstevel@tonic-gate 	case CKA_DERIVE:
48030Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
48040Sstevel@tonic-gate 		    DERIVE_BOOL_ON, template));
48050Sstevel@tonic-gate 
48060Sstevel@tonic-gate 	case CKA_KEY_TYPE:
48070Sstevel@tonic-gate 	case CKA_LOCAL:
48080Sstevel@tonic-gate 	case CKA_KEY_GEN_MECHANISM:
48090Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_READ_ONLY);
48100Sstevel@tonic-gate 
48110Sstevel@tonic-gate 	default:
48120Sstevel@tonic-gate 		return (soft_set_common_storage_attribute(object_p,
48130Sstevel@tonic-gate 		    template, copy));
48140Sstevel@tonic-gate 
48150Sstevel@tonic-gate 	}
48160Sstevel@tonic-gate 
48170Sstevel@tonic-gate }
48180Sstevel@tonic-gate 
48190Sstevel@tonic-gate 
48200Sstevel@tonic-gate /*
48210Sstevel@tonic-gate  * Set the value of an attribute of a Public Key Object.
48220Sstevel@tonic-gate  *
48230Sstevel@tonic-gate  * Rule: The attributes marked with footnote number "8" in the PKCS11
48240Sstevel@tonic-gate  *       spec may be modified (p.88 in PKCS11 spec.).
48250Sstevel@tonic-gate  */
48260Sstevel@tonic-gate CK_RV
48270Sstevel@tonic-gate soft_set_public_key_attribute(soft_object_t *object_p,
48280Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
48290Sstevel@tonic-gate {
48300Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
48310Sstevel@tonic-gate 
48320Sstevel@tonic-gate 	switch (template->type) {
48330Sstevel@tonic-gate 
48340Sstevel@tonic-gate 	case CKA_SUBJECT:
48350Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
48360Sstevel@tonic-gate 		    CKA_SUBJECT, template));
48370Sstevel@tonic-gate 
48380Sstevel@tonic-gate 	case CKA_ENCRYPT:
48390Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
48400Sstevel@tonic-gate 		    ENCRYPT_BOOL_ON, template));
48410Sstevel@tonic-gate 
48420Sstevel@tonic-gate 	case CKA_VERIFY:
48430Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
48440Sstevel@tonic-gate 		    VERIFY_BOOL_ON, template));
48450Sstevel@tonic-gate 
48460Sstevel@tonic-gate 	case CKA_VERIFY_RECOVER:
48470Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
48480Sstevel@tonic-gate 		    VERIFY_RECOVER_BOOL_ON, template));
48490Sstevel@tonic-gate 
48500Sstevel@tonic-gate 	case CKA_WRAP:
48510Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
48520Sstevel@tonic-gate 		    WRAP_BOOL_ON, template));
48530Sstevel@tonic-gate 
48540Sstevel@tonic-gate 	case CKA_MODULUS:
48550Sstevel@tonic-gate 	case CKA_MODULUS_BITS:
48560Sstevel@tonic-gate 	case CKA_PUBLIC_EXPONENT:
48570Sstevel@tonic-gate 		if (keytype == CKK_RSA)
48580Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
48590Sstevel@tonic-gate 		break;
48600Sstevel@tonic-gate 
48610Sstevel@tonic-gate 	case CKA_SUBPRIME:
48620Sstevel@tonic-gate 		if ((keytype == CKK_DSA) ||
48630Sstevel@tonic-gate 		    (keytype == CKK_X9_42_DH))
48640Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
48650Sstevel@tonic-gate 		break;
48660Sstevel@tonic-gate 
48670Sstevel@tonic-gate 	case CKA_PRIME:
48680Sstevel@tonic-gate 	case CKA_BASE:
48690Sstevel@tonic-gate 	case CKA_VALUE:
48700Sstevel@tonic-gate 		if ((keytype == CKK_DSA) ||
48710Sstevel@tonic-gate 		    (keytype == CKK_DH) ||
48720Sstevel@tonic-gate 		    (keytype == CKK_X9_42_DH))
48730Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
48740Sstevel@tonic-gate 		break;
48750Sstevel@tonic-gate 
48760Sstevel@tonic-gate 	default:
48770Sstevel@tonic-gate 		/*
48780Sstevel@tonic-gate 		 * Set the value of a common key attribute.
48790Sstevel@tonic-gate 		 */
48800Sstevel@tonic-gate 		return (soft_set_common_key_attribute(object_p,
48810Sstevel@tonic-gate 		    template, copy));
48820Sstevel@tonic-gate 
48830Sstevel@tonic-gate 	}
48840Sstevel@tonic-gate 	/*
48850Sstevel@tonic-gate 	 * If we got this far, then the combination of key type
48860Sstevel@tonic-gate 	 * and requested attribute is invalid.
48870Sstevel@tonic-gate 	 */
48880Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
48890Sstevel@tonic-gate }
48900Sstevel@tonic-gate 
48910Sstevel@tonic-gate 
48920Sstevel@tonic-gate /*
48930Sstevel@tonic-gate  * Set the value of an attribute of a Private Key Object.
48940Sstevel@tonic-gate  *
48950Sstevel@tonic-gate  * Rule: The attributes marked with footnote number "8" in the PKCS11
48960Sstevel@tonic-gate  *       spec may be modified (p.88 in PKCS11 spec.).
48970Sstevel@tonic-gate  */
48980Sstevel@tonic-gate CK_RV
48990Sstevel@tonic-gate soft_set_private_key_attribute(soft_object_t *object_p,
49000Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
49010Sstevel@tonic-gate {
49020Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
49030Sstevel@tonic-gate 
49040Sstevel@tonic-gate 	switch (template->type) {
49050Sstevel@tonic-gate 
49060Sstevel@tonic-gate 	case CKA_SUBJECT:
49070Sstevel@tonic-gate 		return (set_extra_attr_to_object(object_p,
49080Sstevel@tonic-gate 		    CKA_SUBJECT, template));
49090Sstevel@tonic-gate 
49100Sstevel@tonic-gate 	case CKA_SENSITIVE:
49110Sstevel@tonic-gate 		/*
49120Sstevel@tonic-gate 		 * Cannot set SENSITIVE to FALSE if it is already ON.
49130Sstevel@tonic-gate 		 */
49140Sstevel@tonic-gate 		if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
49150Sstevel@tonic-gate 		    (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
49160Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49170Sstevel@tonic-gate 		}
49180Sstevel@tonic-gate 
49190Sstevel@tonic-gate 		if (*(CK_BBOOL *)template->pValue)
49200Sstevel@tonic-gate 			object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
49210Sstevel@tonic-gate 		return (CKR_OK);
49220Sstevel@tonic-gate 
49230Sstevel@tonic-gate 	case CKA_DECRYPT:
49240Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
49250Sstevel@tonic-gate 		    DECRYPT_BOOL_ON, template));
49260Sstevel@tonic-gate 
49270Sstevel@tonic-gate 	case CKA_SIGN:
49280Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
49290Sstevel@tonic-gate 		    SIGN_BOOL_ON, template));
49300Sstevel@tonic-gate 
49310Sstevel@tonic-gate 	case CKA_SIGN_RECOVER:
49320Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
49330Sstevel@tonic-gate 		    SIGN_RECOVER_BOOL_ON, template));
49340Sstevel@tonic-gate 
49350Sstevel@tonic-gate 	case CKA_UNWRAP:
49360Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
49370Sstevel@tonic-gate 		    UNWRAP_BOOL_ON, template));
49380Sstevel@tonic-gate 
49390Sstevel@tonic-gate 	case CKA_EXTRACTABLE:
49400Sstevel@tonic-gate 		/*
49410Sstevel@tonic-gate 		 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
49420Sstevel@tonic-gate 		 */
49430Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) &&
49440Sstevel@tonic-gate 		    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
49450Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49460Sstevel@tonic-gate 		}
49470Sstevel@tonic-gate 
49480Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
49490Sstevel@tonic-gate 			object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
49500Sstevel@tonic-gate 		return (CKR_OK);
49510Sstevel@tonic-gate 
49520Sstevel@tonic-gate 	case CKA_MODULUS:
49530Sstevel@tonic-gate 	case CKA_PUBLIC_EXPONENT:
49540Sstevel@tonic-gate 	case CKA_PRIVATE_EXPONENT:
49550Sstevel@tonic-gate 	case CKA_PRIME_1:
49560Sstevel@tonic-gate 	case CKA_PRIME_2:
49570Sstevel@tonic-gate 	case CKA_EXPONENT_1:
49580Sstevel@tonic-gate 	case CKA_EXPONENT_2:
49590Sstevel@tonic-gate 	case CKA_COEFFICIENT:
49600Sstevel@tonic-gate 		if (keytype == CKK_RSA) {
49610Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49620Sstevel@tonic-gate 		}
49630Sstevel@tonic-gate 		break;
49640Sstevel@tonic-gate 
49650Sstevel@tonic-gate 	case CKA_SUBPRIME:
49660Sstevel@tonic-gate 		if ((keytype == CKK_DSA) ||
49670Sstevel@tonic-gate 		    (keytype == CKK_X9_42_DH))
49680Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49690Sstevel@tonic-gate 		break;
49700Sstevel@tonic-gate 
49710Sstevel@tonic-gate 	case CKA_PRIME:
49720Sstevel@tonic-gate 	case CKA_BASE:
49730Sstevel@tonic-gate 	case CKA_VALUE:
49740Sstevel@tonic-gate 		if ((keytype == CKK_DSA) ||
49750Sstevel@tonic-gate 		    (keytype == CKK_DH) ||
49760Sstevel@tonic-gate 		    (keytype == CKK_X9_42_DH))
49770Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49780Sstevel@tonic-gate 		break;
49790Sstevel@tonic-gate 
49800Sstevel@tonic-gate 	case CKA_VALUE_BITS:
49810Sstevel@tonic-gate 		if (keytype == CKK_DH)
49820Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
49830Sstevel@tonic-gate 		break;
49840Sstevel@tonic-gate 
49850Sstevel@tonic-gate 	default:
49860Sstevel@tonic-gate 		/*
49870Sstevel@tonic-gate 		 * Set the value of a common key attribute.
49880Sstevel@tonic-gate 		 */
49890Sstevel@tonic-gate 		return (soft_set_common_key_attribute(object_p,
49900Sstevel@tonic-gate 		    template, copy));
49910Sstevel@tonic-gate 	}
49920Sstevel@tonic-gate 
49930Sstevel@tonic-gate 	/*
49940Sstevel@tonic-gate 	 * If we got this far, then the combination of key type
49950Sstevel@tonic-gate 	 * and requested attribute is invalid.
49960Sstevel@tonic-gate 	 */
49970Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
49980Sstevel@tonic-gate }
49990Sstevel@tonic-gate 
50000Sstevel@tonic-gate /*
50010Sstevel@tonic-gate  * Set the value of an attribute of a Secret Key Object.
50020Sstevel@tonic-gate  *
50030Sstevel@tonic-gate  * Rule: The attributes marked with footnote number "8" in the PKCS11
50040Sstevel@tonic-gate  *       spec may be modified (p.88 in PKCS11 spec.).
50050Sstevel@tonic-gate  */
50060Sstevel@tonic-gate CK_RV
50070Sstevel@tonic-gate soft_set_secret_key_attribute(soft_object_t *object_p,
50080Sstevel@tonic-gate 	CK_ATTRIBUTE_PTR template, boolean_t copy)
50090Sstevel@tonic-gate {
50100Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = object_p->key_type;
50110Sstevel@tonic-gate 
50120Sstevel@tonic-gate 	switch (template->type) {
50130Sstevel@tonic-gate 
50140Sstevel@tonic-gate 	case CKA_SENSITIVE:
50150Sstevel@tonic-gate 		/*
50160Sstevel@tonic-gate 		 * Cannot set SENSITIVE to FALSE if it is already ON.
50170Sstevel@tonic-gate 		 */
50180Sstevel@tonic-gate 		if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
50190Sstevel@tonic-gate 		    (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
50200Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
50210Sstevel@tonic-gate 		}
50220Sstevel@tonic-gate 
50230Sstevel@tonic-gate 		if (*(CK_BBOOL *)template->pValue)
50240Sstevel@tonic-gate 			object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
50250Sstevel@tonic-gate 		return (CKR_OK);
50260Sstevel@tonic-gate 
50270Sstevel@tonic-gate 	case CKA_ENCRYPT:
50280Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50290Sstevel@tonic-gate 		    ENCRYPT_BOOL_ON, template));
50300Sstevel@tonic-gate 
50310Sstevel@tonic-gate 	case CKA_DECRYPT:
50320Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50330Sstevel@tonic-gate 		    DECRYPT_BOOL_ON, template));
50340Sstevel@tonic-gate 
50350Sstevel@tonic-gate 	case CKA_SIGN:
50360Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50370Sstevel@tonic-gate 		    SIGN_BOOL_ON, template));
50380Sstevel@tonic-gate 
50390Sstevel@tonic-gate 	case CKA_VERIFY:
50400Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50410Sstevel@tonic-gate 		    VERIFY_BOOL_ON, template));
50420Sstevel@tonic-gate 
50430Sstevel@tonic-gate 	case CKA_WRAP:
50440Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50450Sstevel@tonic-gate 		    WRAP_BOOL_ON, template));
50460Sstevel@tonic-gate 
50470Sstevel@tonic-gate 	case CKA_UNWRAP:
50480Sstevel@tonic-gate 		return (set_bool_attr_to_object(object_p,
50490Sstevel@tonic-gate 		    UNWRAP_BOOL_ON, template));
50500Sstevel@tonic-gate 
50510Sstevel@tonic-gate 	case CKA_EXTRACTABLE:
50520Sstevel@tonic-gate 		/*
50530Sstevel@tonic-gate 		 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
50540Sstevel@tonic-gate 		 */
50550Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) &&
50560Sstevel@tonic-gate 		    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
50570Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
50580Sstevel@tonic-gate 		}
50590Sstevel@tonic-gate 
50600Sstevel@tonic-gate 		if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
50610Sstevel@tonic-gate 			object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
50620Sstevel@tonic-gate 		return (CKR_OK);
50630Sstevel@tonic-gate 
50640Sstevel@tonic-gate 	case CKA_VALUE:
50650Sstevel@tonic-gate 		return (CKR_ATTRIBUTE_READ_ONLY);
50660Sstevel@tonic-gate 
50670Sstevel@tonic-gate 	case CKA_VALUE_LEN:
50680Sstevel@tonic-gate 		if ((keytype == CKK_RC4) ||
50690Sstevel@tonic-gate 		    (keytype == CKK_GENERIC_SECRET) ||
5070676Sizick 		    (keytype == CKK_AES) ||
5071676Sizick 		    (keytype == CKK_BLOWFISH))
50720Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_READ_ONLY);
50730Sstevel@tonic-gate 		break;
50740Sstevel@tonic-gate 
50750Sstevel@tonic-gate 	default:
50760Sstevel@tonic-gate 		/*
50770Sstevel@tonic-gate 		 * Set the value of a common key attribute.
50780Sstevel@tonic-gate 		 */
50790Sstevel@tonic-gate 		return (soft_set_common_key_attribute(object_p,
50800Sstevel@tonic-gate 		    template, copy));
50810Sstevel@tonic-gate 
50820Sstevel@tonic-gate 	}
50830Sstevel@tonic-gate 	/*
50840Sstevel@tonic-gate 	 * If we got this far, then the combination of key type
50850Sstevel@tonic-gate 	 * and requested attribute is invalid.
50860Sstevel@tonic-gate 	 */
50870Sstevel@tonic-gate 	return (CKR_ATTRIBUTE_TYPE_INVALID);
50880Sstevel@tonic-gate }
50890Sstevel@tonic-gate 
50900Sstevel@tonic-gate 
50910Sstevel@tonic-gate /*
50920Sstevel@tonic-gate  * Call the appropriate set attribute function according to the class
50930Sstevel@tonic-gate  * of object.
50940Sstevel@tonic-gate  *
50950Sstevel@tonic-gate  * The caller of this function does not hold the lock on the original
50960Sstevel@tonic-gate  * object, since this function is setting the attribute on the new object
50970Sstevel@tonic-gate  * that is being modified.
50980Sstevel@tonic-gate  *
50990Sstevel@tonic-gate  * Argument copy: TRUE when called by C_CopyObject,
51000Sstevel@tonic-gate  *		  FALSE when called by C_SetAttributeValue.
51010Sstevel@tonic-gate  */
51020Sstevel@tonic-gate CK_RV
51030Sstevel@tonic-gate soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
51040Sstevel@tonic-gate     boolean_t copy)
51050Sstevel@tonic-gate {
51060Sstevel@tonic-gate 
51070Sstevel@tonic-gate 	CK_RV		rv = CKR_OK;
51080Sstevel@tonic-gate 	CK_OBJECT_CLASS	class = object_p->class;
51090Sstevel@tonic-gate 
51100Sstevel@tonic-gate 	switch (class) {
51110Sstevel@tonic-gate 
51120Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
51130Sstevel@tonic-gate 		rv = soft_set_public_key_attribute(object_p, template, copy);
51140Sstevel@tonic-gate 		break;
51150Sstevel@tonic-gate 
51160Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
51170Sstevel@tonic-gate 		rv = soft_set_private_key_attribute(object_p, template, copy);
51180Sstevel@tonic-gate 		break;
51190Sstevel@tonic-gate 
51200Sstevel@tonic-gate 	case CKO_SECRET_KEY:
51210Sstevel@tonic-gate 		rv = soft_set_secret_key_attribute(object_p, template, copy);
51220Sstevel@tonic-gate 		break;
51230Sstevel@tonic-gate 
51240Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
51250Sstevel@tonic-gate 		switch (template->type) {
51260Sstevel@tonic-gate 		case CKA_LABEL:
51270Sstevel@tonic-gate 			/*
51280Sstevel@tonic-gate 			 * Only the LABEL can be modified in the common
51290Sstevel@tonic-gate 			 * storage object attributes after the object is
51300Sstevel@tonic-gate 			 * created.
51310Sstevel@tonic-gate 			 */
51320Sstevel@tonic-gate 			return (set_extra_attr_to_object(object_p,
51330Sstevel@tonic-gate 			    CKA_LABEL, template));
51340Sstevel@tonic-gate 		default:
51350Sstevel@tonic-gate 			return (CKR_TEMPLATE_INCONSISTENT);
51360Sstevel@tonic-gate 		}
51370Sstevel@tonic-gate 	case CKO_CERTIFICATE:
51380Sstevel@tonic-gate 		rv = soft_set_certificate_attribute(object_p, template, copy);
51390Sstevel@tonic-gate 		break;
51400Sstevel@tonic-gate 
51410Sstevel@tonic-gate 	default:
51420Sstevel@tonic-gate 		/*
51430Sstevel@tonic-gate 		 * If the template specifies a value of an attribute
51440Sstevel@tonic-gate 		 * which is incompatible with other existing attributes
51450Sstevel@tonic-gate 		 * of the object, then fails with return code
51460Sstevel@tonic-gate 		 * CKR_TEMPLATE_INCONSISTENT.
51470Sstevel@tonic-gate 		 */
51480Sstevel@tonic-gate 		rv = CKR_TEMPLATE_INCONSISTENT;
51490Sstevel@tonic-gate 		break;
51500Sstevel@tonic-gate 	}
51510Sstevel@tonic-gate 
51520Sstevel@tonic-gate 	return (rv);
51530Sstevel@tonic-gate }
51540Sstevel@tonic-gate 
51550Sstevel@tonic-gate CK_RV
51567260Smcpowers soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
51570Sstevel@tonic-gate     uchar_t *value, uint32_t *value_len)
51580Sstevel@tonic-gate {
51590Sstevel@tonic-gate 	uint32_t len = 0;
51600Sstevel@tonic-gate 	switch (type) {
51610Sstevel@tonic-gate 
51620Sstevel@tonic-gate 	/* The following attributes belong to RSA */
51630Sstevel@tonic-gate 	case CKA_MODULUS:
51640Sstevel@tonic-gate #ifdef	__sparcv9
51650Sstevel@tonic-gate 		len =
51660Sstevel@tonic-gate 		    /* LINTED */
51670Sstevel@tonic-gate 		    (uint32_t)
51680Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
51690Sstevel@tonic-gate #else	/* !__sparcv9 */
51700Sstevel@tonic-gate 		len =
51710Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
51720Sstevel@tonic-gate #endif	/* __sparcv9 */
51730Sstevel@tonic-gate 
51740Sstevel@tonic-gate 		/* This attribute MUST BE set */
51750Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
51760Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
51770Sstevel@tonic-gate 		}
51780Sstevel@tonic-gate 		*value_len = len;
51790Sstevel@tonic-gate 
51800Sstevel@tonic-gate 		(void) memcpy(value,
51810Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
51820Sstevel@tonic-gate 		    *value_len);
51830Sstevel@tonic-gate 
51840Sstevel@tonic-gate 		break;
51850Sstevel@tonic-gate 
51860Sstevel@tonic-gate 	case CKA_PUBLIC_EXPONENT:
51870Sstevel@tonic-gate #ifdef	__sparcv9
51880Sstevel@tonic-gate 		len =
51890Sstevel@tonic-gate 		    /* LINTED */
51900Sstevel@tonic-gate 		    (uint32_t)
51910Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
51920Sstevel@tonic-gate #else	/* !__sparcv9 */
51930Sstevel@tonic-gate 		len =
51940Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
51950Sstevel@tonic-gate #endif	/* __sparcv9 */
51960Sstevel@tonic-gate 
51970Sstevel@tonic-gate 		/* This attribute MUST BE set */
51980Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
51990Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
52000Sstevel@tonic-gate 		}
52010Sstevel@tonic-gate 		*value_len = len;
52020Sstevel@tonic-gate 
52030Sstevel@tonic-gate 		(void) memcpy(value,
52040Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
52050Sstevel@tonic-gate 		    *value_len);
52060Sstevel@tonic-gate 
52070Sstevel@tonic-gate 		break;
52080Sstevel@tonic-gate 
52090Sstevel@tonic-gate 	/* The following attributes belong to DSA and DH */
52100Sstevel@tonic-gate 	case CKA_PRIME:
52110Sstevel@tonic-gate 
52120Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
52130Sstevel@tonic-gate #ifdef	__sparcv9
52140Sstevel@tonic-gate 			len =
52150Sstevel@tonic-gate 			    /* LINTED */
52160Sstevel@tonic-gate 			    (uint32_t)
52170Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
52180Sstevel@tonic-gate 			    big_value_len;
52190Sstevel@tonic-gate #else	/* !__sparcv9 */
52200Sstevel@tonic-gate 			len =
52210Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
52220Sstevel@tonic-gate 			    big_value_len;
52230Sstevel@tonic-gate #endif	/* __sparcv9 */
52240Sstevel@tonic-gate 		else
52250Sstevel@tonic-gate #ifdef	__sparcv9
52260Sstevel@tonic-gate 			len =
52270Sstevel@tonic-gate 			    /* LINTED */
52280Sstevel@tonic-gate 			    (uint32_t)
52290Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
52300Sstevel@tonic-gate 			    big_value_len;
52310Sstevel@tonic-gate #else	/* !__sparcv9 */
52320Sstevel@tonic-gate 			len =
52330Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
52340Sstevel@tonic-gate 			    big_value_len;
52350Sstevel@tonic-gate #endif	/* __sparcv9 */
52360Sstevel@tonic-gate 
52370Sstevel@tonic-gate 		/* This attribute MUST BE set */
52380Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
52390Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
52400Sstevel@tonic-gate 		}
52410Sstevel@tonic-gate 		*value_len = len;
52420Sstevel@tonic-gate 
52430Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
52440Sstevel@tonic-gate 			(void) memcpy(value,
52450Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
52460Sstevel@tonic-gate 			    *value_len);
52470Sstevel@tonic-gate 		else
52480Sstevel@tonic-gate 			(void) memcpy(value,
52490Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
52500Sstevel@tonic-gate 			    *value_len);
52510Sstevel@tonic-gate 
52520Sstevel@tonic-gate 		break;
52530Sstevel@tonic-gate 
52540Sstevel@tonic-gate 	case CKA_SUBPRIME:
52550Sstevel@tonic-gate #ifdef	__sparcv9
52560Sstevel@tonic-gate 		len =
52570Sstevel@tonic-gate 		    /* LINTED */
52580Sstevel@tonic-gate 		    (uint32_t)
52590Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
52600Sstevel@tonic-gate #else	/* !__sparcv9 */
52610Sstevel@tonic-gate 		len =
52620Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
52630Sstevel@tonic-gate #endif	/* __sparcv9 */
52640Sstevel@tonic-gate 
52650Sstevel@tonic-gate 		/* This attribute MUST BE set */
52660Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
52670Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
52680Sstevel@tonic-gate 		}
52690Sstevel@tonic-gate 		*value_len = len;
52700Sstevel@tonic-gate 
52710Sstevel@tonic-gate 		(void) memcpy(value,
52720Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
52730Sstevel@tonic-gate 		    *value_len);
52740Sstevel@tonic-gate 
52750Sstevel@tonic-gate 		break;
52760Sstevel@tonic-gate 
52770Sstevel@tonic-gate 	case CKA_BASE:
52780Sstevel@tonic-gate 
52790Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
52800Sstevel@tonic-gate #ifdef	__sparcv9
52810Sstevel@tonic-gate 			len =
52820Sstevel@tonic-gate 			    /* LINTED */
52830Sstevel@tonic-gate 			    (uint32_t)
52840Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
52850Sstevel@tonic-gate 			    big_value_len;
52860Sstevel@tonic-gate #else	/* !__sparcv9 */
52870Sstevel@tonic-gate 			len =
52880Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
52890Sstevel@tonic-gate 			    big_value_len;
52900Sstevel@tonic-gate #endif	/* __sparcv9 */
52910Sstevel@tonic-gate 		else
52920Sstevel@tonic-gate #ifdef	__sparcv9
52930Sstevel@tonic-gate 			len =
52940Sstevel@tonic-gate 			    /* LINTED */
52950Sstevel@tonic-gate 			    (uint32_t)
52960Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
52970Sstevel@tonic-gate 			    big_value_len;
52980Sstevel@tonic-gate #else	/* !__sparcv9 */
52990Sstevel@tonic-gate 			len =
53000Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
53010Sstevel@tonic-gate 			    big_value_len;
53020Sstevel@tonic-gate #endif	/* __sparcv9 */
53030Sstevel@tonic-gate 
53040Sstevel@tonic-gate 		/* This attribute MUST BE set */
53050Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
53060Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
53070Sstevel@tonic-gate 		}
53080Sstevel@tonic-gate 		*value_len = len;
53090Sstevel@tonic-gate 
53100Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
53110Sstevel@tonic-gate 			(void) memcpy(value,
53120Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
53130Sstevel@tonic-gate 			    *value_len);
53140Sstevel@tonic-gate 		else
53150Sstevel@tonic-gate 			(void) memcpy(value,
53160Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
53170Sstevel@tonic-gate 			    *value_len);
53180Sstevel@tonic-gate 		break;
53190Sstevel@tonic-gate 
53200Sstevel@tonic-gate 	case CKA_VALUE:
53210Sstevel@tonic-gate 
53220Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
53230Sstevel@tonic-gate #ifdef	__sparcv9
53240Sstevel@tonic-gate 			len =
53250Sstevel@tonic-gate 			    /* LINTED */
53260Sstevel@tonic-gate 			    (uint32_t)
53270Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
53280Sstevel@tonic-gate 			    big_value_len;
53290Sstevel@tonic-gate #else	/* !__sparcv9 */
53300Sstevel@tonic-gate 			len =
53310Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
53320Sstevel@tonic-gate 			    big_value_len;
53330Sstevel@tonic-gate #endif	/* __sparcv9 */
53340Sstevel@tonic-gate 		else
53350Sstevel@tonic-gate #ifdef	__sparcv9
53360Sstevel@tonic-gate 			len =
53370Sstevel@tonic-gate 			    /* LINTED */
53380Sstevel@tonic-gate 			    (uint32_t)
53390Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
53400Sstevel@tonic-gate 			    big_value_len;
53410Sstevel@tonic-gate #else	/* !__sparcv9 */
53420Sstevel@tonic-gate 			len =
53430Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
53440Sstevel@tonic-gate 			    big_value_len;
53450Sstevel@tonic-gate #endif	/* __sparcv9 */
53460Sstevel@tonic-gate 
53470Sstevel@tonic-gate 		/* This attribute MUST BE set */
53480Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
53490Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
53500Sstevel@tonic-gate 		}
53510Sstevel@tonic-gate 		*value_len = len;
53520Sstevel@tonic-gate 
53530Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
53540Sstevel@tonic-gate 			(void) memcpy(value,
53550Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
53560Sstevel@tonic-gate 			    *value_len);
53570Sstevel@tonic-gate 		else
53580Sstevel@tonic-gate 			(void) memcpy(value,
53590Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
53600Sstevel@tonic-gate 			    *value_len);
53610Sstevel@tonic-gate 
53620Sstevel@tonic-gate 		break;
53630Sstevel@tonic-gate 	}
53640Sstevel@tonic-gate 
53650Sstevel@tonic-gate 	return (CKR_OK);
53660Sstevel@tonic-gate }
53670Sstevel@tonic-gate 
53680Sstevel@tonic-gate 
53690Sstevel@tonic-gate CK_RV
53707260Smcpowers soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
53710Sstevel@tonic-gate     uchar_t *value, uint32_t *value_len)
53720Sstevel@tonic-gate {
53730Sstevel@tonic-gate 
53740Sstevel@tonic-gate 	uint32_t len = 0;
53750Sstevel@tonic-gate 
53760Sstevel@tonic-gate 	switch (type) {
53770Sstevel@tonic-gate 
53780Sstevel@tonic-gate 	/* The following attributes belong to RSA */
53790Sstevel@tonic-gate 	case CKA_MODULUS:
53800Sstevel@tonic-gate #ifdef	__sparcv9
53810Sstevel@tonic-gate 		len =
53820Sstevel@tonic-gate 		    /* LINTED */
53830Sstevel@tonic-gate 		    (uint32_t)
53840Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
53850Sstevel@tonic-gate #else	/* !__sparcv9 */
53860Sstevel@tonic-gate 		len =
53870Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
53880Sstevel@tonic-gate #endif	/* __sparcv9 */
53890Sstevel@tonic-gate 
53900Sstevel@tonic-gate 		/* This attribute MUST BE set */
53910Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
53920Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
53930Sstevel@tonic-gate 		}
53940Sstevel@tonic-gate 		*value_len = len;
53950Sstevel@tonic-gate 
53960Sstevel@tonic-gate 		(void) memcpy(value,
53970Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
53980Sstevel@tonic-gate 		    *value_len);
53990Sstevel@tonic-gate 
54000Sstevel@tonic-gate 		break;
54010Sstevel@tonic-gate 
54020Sstevel@tonic-gate 	case CKA_PRIVATE_EXPONENT:
54030Sstevel@tonic-gate #ifdef	__sparcv9
54040Sstevel@tonic-gate 		len =
54050Sstevel@tonic-gate 		    /* LINTED */
54060Sstevel@tonic-gate 		    (uint32_t)
54070Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
54080Sstevel@tonic-gate #else	/* !__sparcv9 */
54090Sstevel@tonic-gate 		len =
54100Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
54110Sstevel@tonic-gate #endif	/* __sparcv9 */
54120Sstevel@tonic-gate 
54130Sstevel@tonic-gate 		/* This attribute MUST BE set */
54140Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
54150Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
54160Sstevel@tonic-gate 		}
54170Sstevel@tonic-gate 		*value_len = len;
54180Sstevel@tonic-gate 
54190Sstevel@tonic-gate 		(void) memcpy(value,
54200Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
54210Sstevel@tonic-gate 		    *value_len);
54220Sstevel@tonic-gate 
54230Sstevel@tonic-gate 		break;
54240Sstevel@tonic-gate 
54250Sstevel@tonic-gate 	case CKA_PRIME_1:
54260Sstevel@tonic-gate #ifdef	__sparcv9
54270Sstevel@tonic-gate 		len =
54280Sstevel@tonic-gate 		    /* LINTED */
54290Sstevel@tonic-gate 		    (uint32_t)
54300Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
54310Sstevel@tonic-gate #else	/* !__sparcv9 */
54320Sstevel@tonic-gate 		len =
54330Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
54340Sstevel@tonic-gate #endif	/* __sparcv9 */
54350Sstevel@tonic-gate 
54360Sstevel@tonic-gate 		if (len > *value_len) {
54370Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
54380Sstevel@tonic-gate 		}
54390Sstevel@tonic-gate 		*value_len = len;
54400Sstevel@tonic-gate 
54410Sstevel@tonic-gate 		if (*value_len == 0) {
54420Sstevel@tonic-gate 			return (CKR_OK);
54430Sstevel@tonic-gate 		}
54440Sstevel@tonic-gate 
54450Sstevel@tonic-gate 		(void) memcpy(value,
54460Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
54470Sstevel@tonic-gate 		    *value_len);
54480Sstevel@tonic-gate 
54490Sstevel@tonic-gate 		break;
54500Sstevel@tonic-gate 
54510Sstevel@tonic-gate 	case CKA_PRIME_2:
54520Sstevel@tonic-gate #ifdef	__sparcv9
54530Sstevel@tonic-gate 		len =
54540Sstevel@tonic-gate 		    /* LINTED */
54550Sstevel@tonic-gate 		    (uint32_t)
54560Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
54570Sstevel@tonic-gate #else	/* !__sparcv9 */
54580Sstevel@tonic-gate 		len =
54590Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
54600Sstevel@tonic-gate #endif	/* __sparcv9 */
54610Sstevel@tonic-gate 
54620Sstevel@tonic-gate 		if (len > *value_len) {
54630Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
54640Sstevel@tonic-gate 		}
54650Sstevel@tonic-gate 		*value_len = len;
54660Sstevel@tonic-gate 
54670Sstevel@tonic-gate 		if (*value_len == 0) {
54680Sstevel@tonic-gate 			return (CKR_OK);
54690Sstevel@tonic-gate 		}
54700Sstevel@tonic-gate 
54710Sstevel@tonic-gate 		(void) memcpy(value,
54720Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
54730Sstevel@tonic-gate 		    *value_len);
54740Sstevel@tonic-gate 
54750Sstevel@tonic-gate 		break;
54760Sstevel@tonic-gate 
54770Sstevel@tonic-gate 	case CKA_EXPONENT_1:
54780Sstevel@tonic-gate #ifdef	__sparcv9
54790Sstevel@tonic-gate 		len =
54800Sstevel@tonic-gate 		    /* LINTED */
54810Sstevel@tonic-gate 		    (uint32_t)
54820Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
54830Sstevel@tonic-gate #else	/* !__sparcv9 */
54840Sstevel@tonic-gate 		len =
54850Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
54860Sstevel@tonic-gate #endif	/* __sparcv9 */
54870Sstevel@tonic-gate 
54880Sstevel@tonic-gate 		if (len > *value_len) {
54890Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
54900Sstevel@tonic-gate 		}
54910Sstevel@tonic-gate 		*value_len = len;
54920Sstevel@tonic-gate 
54930Sstevel@tonic-gate 		if (*value_len == 0) {
54940Sstevel@tonic-gate 			return (CKR_OK);
54950Sstevel@tonic-gate 		}
54960Sstevel@tonic-gate 
54970Sstevel@tonic-gate 		(void) memcpy(value,
54980Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
54990Sstevel@tonic-gate 		    *value_len);
55000Sstevel@tonic-gate 
55010Sstevel@tonic-gate 		break;
55020Sstevel@tonic-gate 
55030Sstevel@tonic-gate 	case CKA_EXPONENT_2:
55040Sstevel@tonic-gate #ifdef	__sparcv9
55050Sstevel@tonic-gate 		len =
55060Sstevel@tonic-gate 		    /* LINTED */
55070Sstevel@tonic-gate 		    (uint32_t)
55080Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
55090Sstevel@tonic-gate #else	/* !__sparcv9 */
55100Sstevel@tonic-gate 		len =
55110Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
55120Sstevel@tonic-gate #endif	/* __sparcv9 */
55130Sstevel@tonic-gate 
55140Sstevel@tonic-gate 		if (len > *value_len) {
55150Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
55160Sstevel@tonic-gate 		}
55170Sstevel@tonic-gate 		*value_len = len;
55180Sstevel@tonic-gate 
55190Sstevel@tonic-gate 		if (*value_len == 0) {
55200Sstevel@tonic-gate 			return (CKR_OK);
55210Sstevel@tonic-gate 		}
55220Sstevel@tonic-gate 
55230Sstevel@tonic-gate 		(void) memcpy(value,
55240Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
55250Sstevel@tonic-gate 		    *value_len);
55260Sstevel@tonic-gate 
55270Sstevel@tonic-gate 		break;
55280Sstevel@tonic-gate 
55290Sstevel@tonic-gate 	case CKA_COEFFICIENT:
55300Sstevel@tonic-gate #ifdef	__sparcv9
55310Sstevel@tonic-gate 		len =
55320Sstevel@tonic-gate 		    /* LINTED */
55330Sstevel@tonic-gate 		    (uint32_t)
55340Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
55350Sstevel@tonic-gate #else	/* !__sparcv9 */
55360Sstevel@tonic-gate 		len =
55370Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
55380Sstevel@tonic-gate #endif	/* __sparcv9 */
55390Sstevel@tonic-gate 
55400Sstevel@tonic-gate 		if (len > *value_len) {
55410Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
55420Sstevel@tonic-gate 		}
55430Sstevel@tonic-gate 		*value_len = len;
55440Sstevel@tonic-gate 
55450Sstevel@tonic-gate 		if (*value_len == 0) {
55460Sstevel@tonic-gate 			return (CKR_OK);
55470Sstevel@tonic-gate 		}
55480Sstevel@tonic-gate 
55490Sstevel@tonic-gate 		(void) memcpy(value,
55500Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
55510Sstevel@tonic-gate 		    *value_len);
55520Sstevel@tonic-gate 
55530Sstevel@tonic-gate 		break;
55540Sstevel@tonic-gate 
55550Sstevel@tonic-gate 	/* The following attributes belong to DSA and DH */
55560Sstevel@tonic-gate 	case CKA_PRIME:
55570Sstevel@tonic-gate 
55580Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
55590Sstevel@tonic-gate #ifdef	__sparcv9
55600Sstevel@tonic-gate 			len =
55610Sstevel@tonic-gate 			    /* LINTED */
55620Sstevel@tonic-gate 			    (uint32_t)
55630Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
55640Sstevel@tonic-gate 			    big_value_len;
55650Sstevel@tonic-gate #else	/* !__sparcv9 */
55660Sstevel@tonic-gate 			len =
55670Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
55680Sstevel@tonic-gate 			    big_value_len;
55690Sstevel@tonic-gate #endif	/* __sparcv9 */
55700Sstevel@tonic-gate 		else
55710Sstevel@tonic-gate #ifdef	__sparcv9
55720Sstevel@tonic-gate 			len =
55730Sstevel@tonic-gate 			    /* LINTED */
55740Sstevel@tonic-gate 			    (uint32_t)
55750Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
55760Sstevel@tonic-gate 			    big_value_len;
55770Sstevel@tonic-gate #else	/* !__sparcv9 */
55780Sstevel@tonic-gate 			len =
55790Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
55800Sstevel@tonic-gate 			    big_value_len;
55810Sstevel@tonic-gate #endif	/* __sparcv9 */
55820Sstevel@tonic-gate 
55830Sstevel@tonic-gate 		/* This attribute MUST BE set */
55840Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
55850Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
55860Sstevel@tonic-gate 		}
55870Sstevel@tonic-gate 		*value_len = len;
55880Sstevel@tonic-gate 
55890Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
55900Sstevel@tonic-gate 			(void) memcpy(value,
55910Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
55920Sstevel@tonic-gate 			    *value_len);
55930Sstevel@tonic-gate 		else
55940Sstevel@tonic-gate 			(void) memcpy(value,
55950Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
55960Sstevel@tonic-gate 			    *value_len);
55970Sstevel@tonic-gate 
55980Sstevel@tonic-gate 		break;
55990Sstevel@tonic-gate 
56000Sstevel@tonic-gate 	case CKA_SUBPRIME:
56010Sstevel@tonic-gate #ifdef	__sparcv9
56020Sstevel@tonic-gate 		len =
56030Sstevel@tonic-gate 		    /* LINTED */
56040Sstevel@tonic-gate 		    (uint32_t)
56050Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
56060Sstevel@tonic-gate #else	/* !__sparcv9 */
56070Sstevel@tonic-gate 		len =
56080Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
56090Sstevel@tonic-gate #endif	/* __sparcv9 */
56100Sstevel@tonic-gate 
56110Sstevel@tonic-gate 		/* This attribute MUST BE set */
56120Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
56130Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
56140Sstevel@tonic-gate 		}
56150Sstevel@tonic-gate 		*value_len = len;
56160Sstevel@tonic-gate 
56170Sstevel@tonic-gate 		(void) memcpy(value,
56180Sstevel@tonic-gate 		    ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
56190Sstevel@tonic-gate 		    *value_len);
56200Sstevel@tonic-gate 
56210Sstevel@tonic-gate 		break;
56220Sstevel@tonic-gate 
56230Sstevel@tonic-gate 	case CKA_BASE:
56240Sstevel@tonic-gate 
56250Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
56260Sstevel@tonic-gate #ifdef	__sparcv9
56270Sstevel@tonic-gate 			len =
56280Sstevel@tonic-gate 			    /* LINTED */
56290Sstevel@tonic-gate 			    (uint32_t)
56300Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
56310Sstevel@tonic-gate 			    big_value_len;
56320Sstevel@tonic-gate #else	/* !__sparcv9 */
56330Sstevel@tonic-gate 			len =
56340Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
56350Sstevel@tonic-gate 			    big_value_len;
56360Sstevel@tonic-gate #endif	/* __sparcv9 */
56370Sstevel@tonic-gate 		else
56380Sstevel@tonic-gate #ifdef	__sparcv9
56390Sstevel@tonic-gate 			len =
56400Sstevel@tonic-gate 			    /* LINTED */
56410Sstevel@tonic-gate 			    (uint32_t)
56420Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
56430Sstevel@tonic-gate 			    big_value_len;
56440Sstevel@tonic-gate #else	/* !__sparcv9 */
56450Sstevel@tonic-gate 			len =
56460Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
56470Sstevel@tonic-gate 			    big_value_len;
56480Sstevel@tonic-gate #endif	/* __sparcv9 */
56490Sstevel@tonic-gate 
56500Sstevel@tonic-gate 		/* This attribute MUST BE set */
56510Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
56520Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
56530Sstevel@tonic-gate 		}
56540Sstevel@tonic-gate 		*value_len = len;
56550Sstevel@tonic-gate 
56560Sstevel@tonic-gate 		if (key->key_type == CKK_DSA)
56570Sstevel@tonic-gate 			(void) memcpy(value,
56580Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
56590Sstevel@tonic-gate 			    *value_len);
56600Sstevel@tonic-gate 		else
56610Sstevel@tonic-gate 			(void) memcpy(value,
56620Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
56630Sstevel@tonic-gate 			    *value_len);
56640Sstevel@tonic-gate 		break;
56650Sstevel@tonic-gate 
56660Sstevel@tonic-gate 	case CKA_VALUE:
56670Sstevel@tonic-gate 
56687260Smcpowers 		if (key->key_type == CKK_DSA) {
56690Sstevel@tonic-gate #ifdef	__sparcv9
56700Sstevel@tonic-gate 			len =
56710Sstevel@tonic-gate 			    /* LINTED */
56720Sstevel@tonic-gate 			    (uint32_t)
56730Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
56740Sstevel@tonic-gate 			    big_value_len;
56750Sstevel@tonic-gate #else	/* !__sparcv9 */
56760Sstevel@tonic-gate 			len =
56770Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
56780Sstevel@tonic-gate 			    big_value_len;
56790Sstevel@tonic-gate #endif	/* __sparcv9 */
56807260Smcpowers 		} else if (key->key_type == CKK_DH) {
56810Sstevel@tonic-gate #ifdef	__sparcv9
56820Sstevel@tonic-gate 			len =
56830Sstevel@tonic-gate 			    /* LINTED */
56840Sstevel@tonic-gate 			    (uint32_t)
56850Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
56860Sstevel@tonic-gate 			    big_value_len;
56870Sstevel@tonic-gate #else	/* !__sparcv9 */
56880Sstevel@tonic-gate 			len =
56890Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
56900Sstevel@tonic-gate 			    big_value_len;
56910Sstevel@tonic-gate #endif	/* __sparcv9 */
56927260Smcpowers 		} else {
56937260Smcpowers #ifdef	__sparcv9
56947260Smcpowers 			len =
56957260Smcpowers 			    /* LINTED */
56967260Smcpowers 			    (uint32_t)
56977260Smcpowers 			    ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
56987260Smcpowers 			    big_value_len;
56997260Smcpowers #else	/* !__sparcv9 */
57007260Smcpowers 			len =
57017260Smcpowers 			    ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
57027260Smcpowers 			    big_value_len;
57037260Smcpowers #endif	/* __sparcv9 */
57047260Smcpowers 		}
57050Sstevel@tonic-gate 
57060Sstevel@tonic-gate 		/* This attribute MUST BE set */
57070Sstevel@tonic-gate 		if (len == 0 || len > *value_len) {
57080Sstevel@tonic-gate 			return (CKR_ATTRIBUTE_VALUE_INVALID);
57090Sstevel@tonic-gate 		}
57100Sstevel@tonic-gate 		*value_len = len;
57110Sstevel@tonic-gate 
57127260Smcpowers 		if (key->key_type == CKK_DSA) {
57130Sstevel@tonic-gate 			(void) memcpy(value,
57140Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
57150Sstevel@tonic-gate 			    *value_len);
57167260Smcpowers 		} else if (key->key_type == CKK_DH) {
57170Sstevel@tonic-gate 			(void) memcpy(value,
57180Sstevel@tonic-gate 			    ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
57190Sstevel@tonic-gate 			    *value_len);
57207260Smcpowers 		} else {
57217260Smcpowers 			(void) memcpy(value,
57227260Smcpowers 			    ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
57237260Smcpowers 			    *value_len);
57247260Smcpowers 		}
57250Sstevel@tonic-gate 
57260Sstevel@tonic-gate 		break;
57270Sstevel@tonic-gate 	}
57280Sstevel@tonic-gate 
57290Sstevel@tonic-gate 	return (CKR_OK);
57300Sstevel@tonic-gate 
57310Sstevel@tonic-gate }
57320Sstevel@tonic-gate 
57330Sstevel@tonic-gate static CK_RV
57340Sstevel@tonic-gate copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
57350Sstevel@tonic-gate {
57360Sstevel@tonic-gate 	new_bigint->big_value =
57370Sstevel@tonic-gate 	    malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
57380Sstevel@tonic-gate 
57390Sstevel@tonic-gate 	if (new_bigint->big_value == NULL) {
57400Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
57410Sstevel@tonic-gate 	}
57420Sstevel@tonic-gate 
57430Sstevel@tonic-gate 	(void) memcpy(new_bigint->big_value, old_bigint->big_value,
57440Sstevel@tonic-gate 	    (sizeof (CK_BYTE) * new_bigint->big_value_len));
57450Sstevel@tonic-gate 
57460Sstevel@tonic-gate 	return (CKR_OK);
57470Sstevel@tonic-gate }
57480Sstevel@tonic-gate 
57490Sstevel@tonic-gate static void
57500Sstevel@tonic-gate free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
57510Sstevel@tonic-gate {
57520Sstevel@tonic-gate 	if (pbk == NULL) {
57530Sstevel@tonic-gate 		return;
57540Sstevel@tonic-gate 	}
57550Sstevel@tonic-gate 
57560Sstevel@tonic-gate 	switch (key_type) {
57570Sstevel@tonic-gate 		case CKK_RSA:
57580Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
57590Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
57600Sstevel@tonic-gate 			break;
57610Sstevel@tonic-gate 		case CKK_DSA:
57620Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
57630Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
57640Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
57650Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
57660Sstevel@tonic-gate 			break;
57670Sstevel@tonic-gate 		case CKK_DH:
57680Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
57690Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
57700Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
57710Sstevel@tonic-gate 			break;
57725697Smcpowers 		case CKK_EC:
57735697Smcpowers 			bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
57745697Smcpowers 			break;
57750Sstevel@tonic-gate 		case CKK_X9_42_DH:
57760Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
57770Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
57780Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
57790Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
57800Sstevel@tonic-gate 			break;
57810Sstevel@tonic-gate 		default:
57820Sstevel@tonic-gate 			break;
57830Sstevel@tonic-gate 	}
57840Sstevel@tonic-gate 	free(pbk);
57850Sstevel@tonic-gate }
57860Sstevel@tonic-gate 
57870Sstevel@tonic-gate CK_RV
57880Sstevel@tonic-gate soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
57890Sstevel@tonic-gate     public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
57900Sstevel@tonic-gate {
57910Sstevel@tonic-gate 
57920Sstevel@tonic-gate 	public_key_obj_t *pbk;
57930Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
57940Sstevel@tonic-gate 
57950Sstevel@tonic-gate 	pbk = calloc(1, sizeof (public_key_obj_t));
57960Sstevel@tonic-gate 	if (pbk == NULL) {
57970Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
57980Sstevel@tonic-gate 	}
57990Sstevel@tonic-gate 
58000Sstevel@tonic-gate 	switch (key_type) {
58010Sstevel@tonic-gate 		case CKK_RSA:
58020Sstevel@tonic-gate 			(void) memcpy(KEY_PUB_RSA(pbk),
58035697Smcpowers 			    KEY_PUB_RSA(old_pub_key_obj_p),
58040Sstevel@tonic-gate 			    sizeof (rsa_pub_key_t));
58050Sstevel@tonic-gate 			/* copy modulus */
58060Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
58070Sstevel@tonic-gate 			    KEY_PUB_RSA_MOD(old_pub_key_obj_p));
58080Sstevel@tonic-gate 			if (rv != CKR_OK) {
58090Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58100Sstevel@tonic-gate 				return (rv);
58110Sstevel@tonic-gate 			}
58120Sstevel@tonic-gate 			/* copy public exponent */
58130Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
58140Sstevel@tonic-gate 			    KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
58150Sstevel@tonic-gate 			if (rv != CKR_OK) {
58160Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58170Sstevel@tonic-gate 				return (rv);
58180Sstevel@tonic-gate 			}
58190Sstevel@tonic-gate 			break;
58200Sstevel@tonic-gate 		case CKK_DSA:
58210Sstevel@tonic-gate 			(void) memcpy(KEY_PUB_DSA(pbk),
58220Sstevel@tonic-gate 			    KEY_PUB_DSA(old_pub_key_obj_p),
58230Sstevel@tonic-gate 			    sizeof (dsa_pub_key_t));
58240Sstevel@tonic-gate 
58250Sstevel@tonic-gate 			/* copy prime */
58260Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
58270Sstevel@tonic-gate 			    KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
58280Sstevel@tonic-gate 			if (rv != CKR_OK) {
58290Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58300Sstevel@tonic-gate 				return (rv);
58310Sstevel@tonic-gate 			}
58320Sstevel@tonic-gate 
58330Sstevel@tonic-gate 			/* copy subprime */
58340Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
58350Sstevel@tonic-gate 			    KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
58360Sstevel@tonic-gate 			if (rv != CKR_OK) {
58370Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58380Sstevel@tonic-gate 				return (rv);
58390Sstevel@tonic-gate 			}
58400Sstevel@tonic-gate 
58410Sstevel@tonic-gate 			/* copy base */
58420Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
58430Sstevel@tonic-gate 			    KEY_PUB_DSA_BASE(old_pub_key_obj_p));
58440Sstevel@tonic-gate 			if (rv != CKR_OK) {
58450Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58460Sstevel@tonic-gate 				return (rv);
58470Sstevel@tonic-gate 			}
58480Sstevel@tonic-gate 
58490Sstevel@tonic-gate 			/* copy value */
58500Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
58510Sstevel@tonic-gate 			    KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
58520Sstevel@tonic-gate 			if (rv != CKR_OK) {
58530Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58540Sstevel@tonic-gate 				return (rv);
58550Sstevel@tonic-gate 			}
58560Sstevel@tonic-gate 			break;
58570Sstevel@tonic-gate 		case CKK_DH:
58580Sstevel@tonic-gate 			(void) memcpy(KEY_PUB_DH(pbk),
58590Sstevel@tonic-gate 			    KEY_PUB_DH(old_pub_key_obj_p),
58600Sstevel@tonic-gate 			    sizeof (dh_pub_key_t));
58610Sstevel@tonic-gate 
58620Sstevel@tonic-gate 			/* copy prime */
58630Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
58640Sstevel@tonic-gate 			    KEY_PUB_DH_PRIME(old_pub_key_obj_p));
58650Sstevel@tonic-gate 			if (rv != CKR_OK) {
58660Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58670Sstevel@tonic-gate 				return (rv);
58680Sstevel@tonic-gate 			}
58690Sstevel@tonic-gate 
58700Sstevel@tonic-gate 			/* copy base */
58710Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
58720Sstevel@tonic-gate 			    KEY_PUB_DH_BASE(old_pub_key_obj_p));
58730Sstevel@tonic-gate 			if (rv != CKR_OK) {
58740Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58750Sstevel@tonic-gate 				return (rv);
58760Sstevel@tonic-gate 			}
58770Sstevel@tonic-gate 
58780Sstevel@tonic-gate 			/* copy value */
58790Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
58800Sstevel@tonic-gate 			    KEY_PUB_DH_VALUE(old_pub_key_obj_p));
58810Sstevel@tonic-gate 			if (rv != CKR_OK) {
58820Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
58830Sstevel@tonic-gate 				return (rv);
58840Sstevel@tonic-gate 			}
58850Sstevel@tonic-gate 			break;
58865697Smcpowers 		case CKK_EC:
58875697Smcpowers 			(void) memcpy(KEY_PUB_EC(pbk),
58885697Smcpowers 			    KEY_PUB_EC(old_pub_key_obj_p),
58895697Smcpowers 			    sizeof (ec_pub_key_t));
58905697Smcpowers 
58915697Smcpowers 			/* copy point */
58925697Smcpowers 			rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
58935697Smcpowers 			    KEY_PUB_EC_POINT(old_pub_key_obj_p));
58945697Smcpowers 			if (rv != CKR_OK) {
58955697Smcpowers 				free_public_key_attr(pbk, key_type);
58965697Smcpowers 				return (rv);
58975697Smcpowers 			}
58985697Smcpowers 			break;
58990Sstevel@tonic-gate 		case CKK_X9_42_DH:
59000Sstevel@tonic-gate 			(void) memcpy(KEY_PUB_DH942(pbk),
59010Sstevel@tonic-gate 			    KEY_PUB_DH942(old_pub_key_obj_p),
59020Sstevel@tonic-gate 			    sizeof (dh942_pub_key_t));
59030Sstevel@tonic-gate 
59040Sstevel@tonic-gate 			/* copy prime */
59050Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
59060Sstevel@tonic-gate 			    KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
59070Sstevel@tonic-gate 			if (rv != CKR_OK) {
59080Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
59090Sstevel@tonic-gate 				return (rv);
59100Sstevel@tonic-gate 			}
59110Sstevel@tonic-gate 
59120Sstevel@tonic-gate 			/* copy subprime */
59130Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
59140Sstevel@tonic-gate 			    KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
59150Sstevel@tonic-gate 			if (rv != CKR_OK) {
59160Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
59170Sstevel@tonic-gate 				return (rv);
59180Sstevel@tonic-gate 			}
59190Sstevel@tonic-gate 
59200Sstevel@tonic-gate 			/* copy base */
59210Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
59220Sstevel@tonic-gate 			    KEY_PUB_DH942_BASE(old_pub_key_obj_p));
59230Sstevel@tonic-gate 			if (rv != CKR_OK) {
59240Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
59250Sstevel@tonic-gate 				return (rv);
59260Sstevel@tonic-gate 			}
59270Sstevel@tonic-gate 
59280Sstevel@tonic-gate 			/* copy value */
59290Sstevel@tonic-gate 			rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
59300Sstevel@tonic-gate 			    KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
59310Sstevel@tonic-gate 			if (rv != CKR_OK) {
59320Sstevel@tonic-gate 				free_public_key_attr(pbk, key_type);
59330Sstevel@tonic-gate 				return (rv);
59340Sstevel@tonic-gate 			}
59350Sstevel@tonic-gate 			break;
59360Sstevel@tonic-gate 		default:
59370Sstevel@tonic-gate 			break;
59380Sstevel@tonic-gate 	}
59390Sstevel@tonic-gate 	*new_pub_key_obj_p = pbk;
59400Sstevel@tonic-gate 	return (rv);
59410Sstevel@tonic-gate }
59420Sstevel@tonic-gate 
59430Sstevel@tonic-gate static void
59440Sstevel@tonic-gate free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
59450Sstevel@tonic-gate {
59460Sstevel@tonic-gate 	if (pbk == NULL) {
59470Sstevel@tonic-gate 		return;
59480Sstevel@tonic-gate 	}
59490Sstevel@tonic-gate 
59500Sstevel@tonic-gate 	switch (key_type) {
59510Sstevel@tonic-gate 		case CKK_RSA:
59520Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
59530Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
59540Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
59550Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
59560Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
59570Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
59580Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
59590Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
59600Sstevel@tonic-gate 			break;
59610Sstevel@tonic-gate 		case CKK_DSA:
59620Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
59630Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
59640Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
59650Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
59660Sstevel@tonic-gate 			break;
59670Sstevel@tonic-gate 		case CKK_DH:
59680Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
59690Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
59700Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
59710Sstevel@tonic-gate 			break;
59725697Smcpowers 		case CKK_EC:
59735697Smcpowers 			bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
59745697Smcpowers 			break;
59750Sstevel@tonic-gate 		case CKK_X9_42_DH:
59760Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
59770Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
59780Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
59790Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
59800Sstevel@tonic-gate 			break;
59810Sstevel@tonic-gate 		default:
59820Sstevel@tonic-gate 			break;
59830Sstevel@tonic-gate 	}
59840Sstevel@tonic-gate 	free(pbk);
59850Sstevel@tonic-gate }
59860Sstevel@tonic-gate 
59870Sstevel@tonic-gate CK_RV
59880Sstevel@tonic-gate soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
59890Sstevel@tonic-gate     private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
59900Sstevel@tonic-gate {
59910Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
59920Sstevel@tonic-gate 	private_key_obj_t *pbk;
59930Sstevel@tonic-gate 
59940Sstevel@tonic-gate 	pbk = calloc(1, sizeof (private_key_obj_t));
59950Sstevel@tonic-gate 	if (pbk == NULL) {
59960Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
59970Sstevel@tonic-gate 	}
59980Sstevel@tonic-gate 
59990Sstevel@tonic-gate 	switch (key_type) {
60000Sstevel@tonic-gate 		case CKK_RSA:
60010Sstevel@tonic-gate 			(void) memcpy(KEY_PRI_RSA(pbk),
60020Sstevel@tonic-gate 			    KEY_PRI_RSA(old_pri_key_obj_p),
60030Sstevel@tonic-gate 			    sizeof (rsa_pri_key_t));
60040Sstevel@tonic-gate 			/* copy modulus */
60050Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
60060Sstevel@tonic-gate 			    KEY_PRI_RSA_MOD(old_pri_key_obj_p));
60070Sstevel@tonic-gate 			if (rv != CKR_OK) {
60080Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60090Sstevel@tonic-gate 				return (rv);
60100Sstevel@tonic-gate 			}
60110Sstevel@tonic-gate 			/* copy public exponent */
60120Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
60130Sstevel@tonic-gate 			    KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
60140Sstevel@tonic-gate 			if (rv != CKR_OK) {
60150Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60160Sstevel@tonic-gate 				return (rv);
60170Sstevel@tonic-gate 			}
60180Sstevel@tonic-gate 			/* copy private exponent */
60190Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
60200Sstevel@tonic-gate 			    KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
60210Sstevel@tonic-gate 			if (rv != CKR_OK) {
60220Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60230Sstevel@tonic-gate 				return (rv);
60240Sstevel@tonic-gate 			}
60250Sstevel@tonic-gate 			/* copy prime_1 */
60260Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
60270Sstevel@tonic-gate 			    KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
60280Sstevel@tonic-gate 			if (rv != CKR_OK) {
60290Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60300Sstevel@tonic-gate 				return (rv);
60310Sstevel@tonic-gate 			}
60320Sstevel@tonic-gate 			/* copy prime_2 */
60330Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
60340Sstevel@tonic-gate 			    KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
60350Sstevel@tonic-gate 			if (rv != CKR_OK) {
60360Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60370Sstevel@tonic-gate 				return (rv);
60380Sstevel@tonic-gate 			}
60390Sstevel@tonic-gate 			/* copy exponent_1 */
60400Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
60410Sstevel@tonic-gate 			    KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
60420Sstevel@tonic-gate 			if (rv != CKR_OK) {
60430Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60440Sstevel@tonic-gate 				return (rv);
60450Sstevel@tonic-gate 			}
60460Sstevel@tonic-gate 			/* copy exponent_2 */
60470Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
60480Sstevel@tonic-gate 			    KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
60490Sstevel@tonic-gate 			if (rv != CKR_OK) {
60500Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60510Sstevel@tonic-gate 				return (rv);
60520Sstevel@tonic-gate 			}
60530Sstevel@tonic-gate 			/* copy coefficient */
60540Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
60550Sstevel@tonic-gate 			    KEY_PRI_RSA_COEF(old_pri_key_obj_p));
60560Sstevel@tonic-gate 			if (rv != CKR_OK) {
60570Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60580Sstevel@tonic-gate 				return (rv);
60590Sstevel@tonic-gate 			}
60600Sstevel@tonic-gate 			break;
60610Sstevel@tonic-gate 		case CKK_DSA:
60620Sstevel@tonic-gate 			(void) memcpy(KEY_PRI_DSA(pbk),
60630Sstevel@tonic-gate 			    KEY_PRI_DSA(old_pri_key_obj_p),
60640Sstevel@tonic-gate 			    sizeof (dsa_pri_key_t));
60650Sstevel@tonic-gate 
60660Sstevel@tonic-gate 			/* copy prime */
60670Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
60680Sstevel@tonic-gate 			    KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
60690Sstevel@tonic-gate 			if (rv != CKR_OK) {
60700Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60710Sstevel@tonic-gate 				return (rv);
60720Sstevel@tonic-gate 			}
60730Sstevel@tonic-gate 
60740Sstevel@tonic-gate 			/* copy subprime */
60750Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
60760Sstevel@tonic-gate 			    KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
60770Sstevel@tonic-gate 			if (rv != CKR_OK) {
60780Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60790Sstevel@tonic-gate 				return (rv);
60800Sstevel@tonic-gate 			}
60810Sstevel@tonic-gate 
60820Sstevel@tonic-gate 			/* copy base */
60830Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
60840Sstevel@tonic-gate 			    KEY_PRI_DSA_BASE(old_pri_key_obj_p));
60850Sstevel@tonic-gate 			if (rv != CKR_OK) {
60860Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60870Sstevel@tonic-gate 				return (rv);
60880Sstevel@tonic-gate 			}
60890Sstevel@tonic-gate 
60900Sstevel@tonic-gate 			/* copy value */
60910Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
60920Sstevel@tonic-gate 			    KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
60930Sstevel@tonic-gate 			if (rv != CKR_OK) {
60940Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
60950Sstevel@tonic-gate 				return (rv);
60960Sstevel@tonic-gate 			}
60970Sstevel@tonic-gate 			break;
60980Sstevel@tonic-gate 		case CKK_DH:
60990Sstevel@tonic-gate 			(void) memcpy(KEY_PRI_DH(pbk),
61000Sstevel@tonic-gate 			    KEY_PRI_DH(old_pri_key_obj_p),
61010Sstevel@tonic-gate 			    sizeof (dh_pri_key_t));
61020Sstevel@tonic-gate 
61030Sstevel@tonic-gate 			/* copy prime */
61040Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
61050Sstevel@tonic-gate 			    KEY_PRI_DH_PRIME(old_pri_key_obj_p));
61060Sstevel@tonic-gate 			if (rv != CKR_OK) {
61070Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61080Sstevel@tonic-gate 				return (rv);
61090Sstevel@tonic-gate 			}
61100Sstevel@tonic-gate 
61110Sstevel@tonic-gate 			/* copy base */
61120Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
61130Sstevel@tonic-gate 			    KEY_PRI_DH_BASE(old_pri_key_obj_p));
61140Sstevel@tonic-gate 			if (rv != CKR_OK) {
61150Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61160Sstevel@tonic-gate 				return (rv);
61170Sstevel@tonic-gate 			}
61180Sstevel@tonic-gate 
61190Sstevel@tonic-gate 			/* copy value */
61200Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
61210Sstevel@tonic-gate 			    KEY_PRI_DH_VALUE(old_pri_key_obj_p));
61220Sstevel@tonic-gate 			if (rv != CKR_OK) {
61230Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61240Sstevel@tonic-gate 				return (rv);
61250Sstevel@tonic-gate 			}
61260Sstevel@tonic-gate 			break;
61275697Smcpowers 		case CKK_EC:
61285697Smcpowers 			(void) memcpy(KEY_PRI_EC(pbk),
61295697Smcpowers 			    KEY_PRI_EC(old_pri_key_obj_p),
61305697Smcpowers 			    sizeof (ec_pri_key_t));
61315697Smcpowers 
61325697Smcpowers 			/* copy value */
61335697Smcpowers 			rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
61345697Smcpowers 			    KEY_PRI_EC_VALUE(old_pri_key_obj_p));
61355697Smcpowers 			if (rv != CKR_OK) {
61365697Smcpowers 				free_private_key_attr(pbk, key_type);
61375697Smcpowers 				return (rv);
61385697Smcpowers 			}
61395697Smcpowers 			break;
61400Sstevel@tonic-gate 		case CKK_X9_42_DH:
61410Sstevel@tonic-gate 			(void) memcpy(KEY_PRI_DH942(pbk),
61420Sstevel@tonic-gate 			    KEY_PRI_DH942(old_pri_key_obj_p),
61430Sstevel@tonic-gate 			    sizeof (dh942_pri_key_t));
61440Sstevel@tonic-gate 
61450Sstevel@tonic-gate 			/* copy prime */
61460Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
61470Sstevel@tonic-gate 			    KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
61480Sstevel@tonic-gate 			if (rv != CKR_OK) {
61490Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61500Sstevel@tonic-gate 				return (rv);
61510Sstevel@tonic-gate 			}
61520Sstevel@tonic-gate 
61530Sstevel@tonic-gate 			/* copy subprime */
61540Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
61550Sstevel@tonic-gate 			    KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
61560Sstevel@tonic-gate 			if (rv != CKR_OK) {
61570Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61580Sstevel@tonic-gate 				return (rv);
61590Sstevel@tonic-gate 			}
61600Sstevel@tonic-gate 
61610Sstevel@tonic-gate 			/* copy base */
61620Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
61630Sstevel@tonic-gate 			    KEY_PRI_DH942_BASE(old_pri_key_obj_p));
61640Sstevel@tonic-gate 			if (rv != CKR_OK) {
61650Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61660Sstevel@tonic-gate 				return (rv);
61670Sstevel@tonic-gate 			}
61680Sstevel@tonic-gate 
61690Sstevel@tonic-gate 			/* copy value */
61700Sstevel@tonic-gate 			rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
61710Sstevel@tonic-gate 			    KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
61720Sstevel@tonic-gate 			if (rv != CKR_OK) {
61730Sstevel@tonic-gate 				free_private_key_attr(pbk, key_type);
61740Sstevel@tonic-gate 				return (rv);
61750Sstevel@tonic-gate 			}
61760Sstevel@tonic-gate 			break;
61770Sstevel@tonic-gate 		default:
61780Sstevel@tonic-gate 			break;
61790Sstevel@tonic-gate 	}
61800Sstevel@tonic-gate 	*new_pri_key_obj_p = pbk;
61810Sstevel@tonic-gate 	return (rv);
61820Sstevel@tonic-gate }
61830Sstevel@tonic-gate 
61840Sstevel@tonic-gate static void
61850Sstevel@tonic-gate free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
61860Sstevel@tonic-gate {
61870Sstevel@tonic-gate 	if (domain == NULL) {
61880Sstevel@tonic-gate 		return;
61890Sstevel@tonic-gate 	}
61900Sstevel@tonic-gate 
61910Sstevel@tonic-gate 	switch (key_type) {
61920Sstevel@tonic-gate 		case CKK_DSA:
61930Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
61940Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
61950Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
61960Sstevel@tonic-gate 			break;
61970Sstevel@tonic-gate 		case CKK_DH:
61980Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
61990Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
62000Sstevel@tonic-gate 			break;
62010Sstevel@tonic-gate 		case CKK_X9_42_DH:
62020Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
62030Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
62040Sstevel@tonic-gate 			bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
62050Sstevel@tonic-gate 			break;
62060Sstevel@tonic-gate 		default:
62070Sstevel@tonic-gate 			break;
62080Sstevel@tonic-gate 	}
62090Sstevel@tonic-gate 	free(domain);
62100Sstevel@tonic-gate }
62110Sstevel@tonic-gate 
62120Sstevel@tonic-gate CK_RV
62130Sstevel@tonic-gate soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
62140Sstevel@tonic-gate     domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
62150Sstevel@tonic-gate {
62160Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
62170Sstevel@tonic-gate 	domain_obj_t *domain;
62180Sstevel@tonic-gate 
62190Sstevel@tonic-gate 	domain = calloc(1, sizeof (domain_obj_t));
62200Sstevel@tonic-gate 	if (domain == NULL) {
62210Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
62220Sstevel@tonic-gate 	}
62230Sstevel@tonic-gate 
62240Sstevel@tonic-gate 	switch (key_type) {
62250Sstevel@tonic-gate 		case CKK_DSA:
62260Sstevel@tonic-gate 			(void) memcpy(KEY_DOM_DSA(domain),
62270Sstevel@tonic-gate 			    KEY_DOM_DSA(old_domain_obj_p),
62280Sstevel@tonic-gate 			    sizeof (dsa_dom_key_t));
62290Sstevel@tonic-gate 
62300Sstevel@tonic-gate 			/* copy prime */
62310Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
62320Sstevel@tonic-gate 			    KEY_DOM_DSA_PRIME(old_domain_obj_p));
62330Sstevel@tonic-gate 			if (rv != CKR_OK) {
62340Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62350Sstevel@tonic-gate 				return (rv);
62360Sstevel@tonic-gate 			}
62370Sstevel@tonic-gate 
62380Sstevel@tonic-gate 			/* copy subprime */
62390Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
62400Sstevel@tonic-gate 			    KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
62410Sstevel@tonic-gate 			if (rv != CKR_OK) {
62420Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62430Sstevel@tonic-gate 				return (rv);
62440Sstevel@tonic-gate 			}
62450Sstevel@tonic-gate 
62460Sstevel@tonic-gate 			/* copy base */
62470Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
62480Sstevel@tonic-gate 			    KEY_DOM_DSA_BASE(old_domain_obj_p));
62490Sstevel@tonic-gate 			if (rv != CKR_OK) {
62500Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62510Sstevel@tonic-gate 				return (rv);
62520Sstevel@tonic-gate 			}
62530Sstevel@tonic-gate 
62540Sstevel@tonic-gate 			break;
62550Sstevel@tonic-gate 		case CKK_DH:
62560Sstevel@tonic-gate 			(void) memcpy(KEY_DOM_DH(domain),
62570Sstevel@tonic-gate 			    KEY_DOM_DH(old_domain_obj_p),
62580Sstevel@tonic-gate 			    sizeof (dh_dom_key_t));
62590Sstevel@tonic-gate 
62600Sstevel@tonic-gate 			/* copy prime */
62610Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
62620Sstevel@tonic-gate 			    KEY_DOM_DH_PRIME(old_domain_obj_p));
62630Sstevel@tonic-gate 			if (rv != CKR_OK) {
62640Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62650Sstevel@tonic-gate 				return (rv);
62660Sstevel@tonic-gate 			}
62670Sstevel@tonic-gate 
62680Sstevel@tonic-gate 			/* copy base */
62690Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DH_BASE(domain),
62700Sstevel@tonic-gate 			    KEY_DOM_DH_BASE(old_domain_obj_p));
62710Sstevel@tonic-gate 			if (rv != CKR_OK) {
62720Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62730Sstevel@tonic-gate 				return (rv);
62740Sstevel@tonic-gate 			}
62750Sstevel@tonic-gate 
62760Sstevel@tonic-gate 			break;
62770Sstevel@tonic-gate 		case CKK_X9_42_DH:
62780Sstevel@tonic-gate 			(void) memcpy(KEY_DOM_DH942(domain),
62790Sstevel@tonic-gate 			    KEY_DOM_DH942(old_domain_obj_p),
62800Sstevel@tonic-gate 			    sizeof (dh942_dom_key_t));
62810Sstevel@tonic-gate 
62820Sstevel@tonic-gate 			/* copy prime */
62830Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
62840Sstevel@tonic-gate 			    KEY_DOM_DH942_PRIME(old_domain_obj_p));
62850Sstevel@tonic-gate 			if (rv != CKR_OK) {
62860Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62870Sstevel@tonic-gate 				return (rv);
62880Sstevel@tonic-gate 			}
62890Sstevel@tonic-gate 
62900Sstevel@tonic-gate 			/* copy subprime */
62910Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
62920Sstevel@tonic-gate 			    KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
62930Sstevel@tonic-gate 			if (rv != CKR_OK) {
62940Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
62950Sstevel@tonic-gate 				return (rv);
62960Sstevel@tonic-gate 			}
62970Sstevel@tonic-gate 
62980Sstevel@tonic-gate 			/* copy base */
62990Sstevel@tonic-gate 			rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
63000Sstevel@tonic-gate 			    KEY_DOM_DH942_BASE(old_domain_obj_p));
63010Sstevel@tonic-gate 			if (rv != CKR_OK) {
63020Sstevel@tonic-gate 				free_domain_attr(domain, key_type);
63030Sstevel@tonic-gate 				return (rv);
63040Sstevel@tonic-gate 			}
63050Sstevel@tonic-gate 
63060Sstevel@tonic-gate 			break;
63070Sstevel@tonic-gate 		default:
63080Sstevel@tonic-gate 			break;
63090Sstevel@tonic-gate 	}
63100Sstevel@tonic-gate 	*new_domain_obj_p = domain;
63110Sstevel@tonic-gate 	return (rv);
63120Sstevel@tonic-gate }
63130Sstevel@tonic-gate 
63140Sstevel@tonic-gate CK_RV
63150Sstevel@tonic-gate soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
63160Sstevel@tonic-gate     secret_key_obj_t **new_secret_key_obj_p)
63170Sstevel@tonic-gate {
63180Sstevel@tonic-gate 	secret_key_obj_t *sk;
63190Sstevel@tonic-gate 
63200Sstevel@tonic-gate 	sk = malloc(sizeof (secret_key_obj_t));
63210Sstevel@tonic-gate 	if (sk == NULL) {
63220Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
63230Sstevel@tonic-gate 	}
63240Sstevel@tonic-gate 	(void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
63250Sstevel@tonic-gate 
63260Sstevel@tonic-gate 	/* copy the secret key value */
63270Sstevel@tonic-gate 	sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
63280Sstevel@tonic-gate 	if (sk->sk_value == NULL) {
63290Sstevel@tonic-gate 		free(sk);
63300Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
63310Sstevel@tonic-gate 	}
63320Sstevel@tonic-gate 	(void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
63330Sstevel@tonic-gate 	    (sizeof (CK_BYTE) * sk->sk_value_len));
63340Sstevel@tonic-gate 
63350Sstevel@tonic-gate 	/*
63360Sstevel@tonic-gate 	 * Copy the pre-expanded key schedule.
63370Sstevel@tonic-gate 	 */
63380Sstevel@tonic-gate 	if (old_secret_key_obj_p->key_sched != NULL &&
63390Sstevel@tonic-gate 	    old_secret_key_obj_p->keysched_len > 0) {
63400Sstevel@tonic-gate 		sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
63410Sstevel@tonic-gate 		if (sk->key_sched == NULL) {
63420Sstevel@tonic-gate 			free(sk);
63430Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
63440Sstevel@tonic-gate 		}
63450Sstevel@tonic-gate 		sk->keysched_len = old_secret_key_obj_p->keysched_len;
63460Sstevel@tonic-gate 		(void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
63475697Smcpowers 		    sk->keysched_len);
63480Sstevel@tonic-gate 	}
63490Sstevel@tonic-gate 
63500Sstevel@tonic-gate 	*new_secret_key_obj_p = sk;
63510Sstevel@tonic-gate 
63520Sstevel@tonic-gate 	return (CKR_OK);
63530Sstevel@tonic-gate }
63540Sstevel@tonic-gate 
63550Sstevel@tonic-gate /*
63560Sstevel@tonic-gate  * If CKA_CLASS not given, guess CKA_CLASS using
63570Sstevel@tonic-gate  * attributes on template .
63580Sstevel@tonic-gate  *
63590Sstevel@tonic-gate  * Some attributes are specific to an object class.  If one or more
63600Sstevel@tonic-gate  * of these attributes are in the template, make a list of classes
63610Sstevel@tonic-gate  * that can have these attributes.  This would speed up the search later,
63620Sstevel@tonic-gate  * because we can immediately skip an object if the class of that
63637518SViswanathan.Kannappan@Sun.COM  * object can not possibly contain one of the attributes.
63640Sstevel@tonic-gate  *
63650Sstevel@tonic-gate  */
63660Sstevel@tonic-gate void
63670Sstevel@tonic-gate soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
63680Sstevel@tonic-gate     CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
63690Sstevel@tonic-gate     CK_ULONG ulCount)
63700Sstevel@tonic-gate {
63710Sstevel@tonic-gate 	ulong_t i;
63720Sstevel@tonic-gate 	int j;
63730Sstevel@tonic-gate 	boolean_t pub_found = B_FALSE,
63740Sstevel@tonic-gate 	    priv_found = B_FALSE,
63750Sstevel@tonic-gate 	    secret_found = B_FALSE,
63760Sstevel@tonic-gate 	    domain_found = B_FALSE,
63770Sstevel@tonic-gate 	    hardware_found = B_FALSE,
63780Sstevel@tonic-gate 	    cert_found = B_FALSE;
63790Sstevel@tonic-gate 	int num_pub_key_attrs, num_priv_key_attrs,
63800Sstevel@tonic-gate 	    num_secret_key_attrs, num_domain_attrs,
63810Sstevel@tonic-gate 	    num_hardware_attrs, num_cert_attrs;
63820Sstevel@tonic-gate 	int num_pclasses = 0;
63830Sstevel@tonic-gate 
63840Sstevel@tonic-gate 	for (i = 0; i < ulCount; i++) {
63850Sstevel@tonic-gate 		if (pTemplate[i].type == CKA_CLASS) {
63860Sstevel@tonic-gate 			/*
63870Sstevel@tonic-gate 			 * don't need to guess the class, it is specified.
63880Sstevel@tonic-gate 			 * Just record the class, and return.
63890Sstevel@tonic-gate 			 */
63900Sstevel@tonic-gate 			pclasses[0] =
63910Sstevel@tonic-gate 			    (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
63920Sstevel@tonic-gate 			*num_result_pclasses = 1;
63930Sstevel@tonic-gate 			return;
63940Sstevel@tonic-gate 		}
63950Sstevel@tonic-gate 	}
63960Sstevel@tonic-gate 
63970Sstevel@tonic-gate 	num_pub_key_attrs =
63980Sstevel@tonic-gate 	    sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
63990Sstevel@tonic-gate 	num_priv_key_attrs =
64000Sstevel@tonic-gate 	    sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
64010Sstevel@tonic-gate 	num_secret_key_attrs =
64020Sstevel@tonic-gate 	    sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
64030Sstevel@tonic-gate 	num_domain_attrs =
64040Sstevel@tonic-gate 	    sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
64050Sstevel@tonic-gate 	num_hardware_attrs =
64060Sstevel@tonic-gate 	    sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
64070Sstevel@tonic-gate 	num_cert_attrs =
64080Sstevel@tonic-gate 	    sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
64090Sstevel@tonic-gate 
64100Sstevel@tonic-gate 	/*
64110Sstevel@tonic-gate 	 * Get the list of objects class that might contain
64120Sstevel@tonic-gate 	 * some attributes.
64130Sstevel@tonic-gate 	 */
64140Sstevel@tonic-gate 	for (i = 0; i < ulCount; i++) {
64150Sstevel@tonic-gate 		/*
64160Sstevel@tonic-gate 		 * only check if this attribute can belong to public key object
64170Sstevel@tonic-gate 		 * class if public key object isn't already in the list
64180Sstevel@tonic-gate 		 */
64190Sstevel@tonic-gate 		if (!pub_found) {
64200Sstevel@tonic-gate 			for (j = 0; j < num_pub_key_attrs; j++) {
64210Sstevel@tonic-gate 				if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
64220Sstevel@tonic-gate 					pub_found = B_TRUE;
64230Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64240Sstevel@tonic-gate 					    CKO_PUBLIC_KEY;
64250Sstevel@tonic-gate 					break;
64260Sstevel@tonic-gate 				}
64270Sstevel@tonic-gate 			}
64280Sstevel@tonic-gate 		}
64290Sstevel@tonic-gate 
64300Sstevel@tonic-gate 		if (!priv_found) {
64310Sstevel@tonic-gate 			for (j = 0; j < num_priv_key_attrs; j++) {
64320Sstevel@tonic-gate 				if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
64330Sstevel@tonic-gate 					priv_found = B_TRUE;
64340Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64350Sstevel@tonic-gate 					    CKO_PRIVATE_KEY;
64360Sstevel@tonic-gate 					break;
64370Sstevel@tonic-gate 				}
64380Sstevel@tonic-gate 			}
64390Sstevel@tonic-gate 		}
64400Sstevel@tonic-gate 
64410Sstevel@tonic-gate 		if (!secret_found) {
64420Sstevel@tonic-gate 			for (j = 0; j < num_secret_key_attrs; j++) {
64430Sstevel@tonic-gate 				if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
64440Sstevel@tonic-gate 					secret_found = B_TRUE;
64450Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64460Sstevel@tonic-gate 					    CKO_SECRET_KEY;
64470Sstevel@tonic-gate 					break;
64480Sstevel@tonic-gate 				}
64490Sstevel@tonic-gate 			}
64500Sstevel@tonic-gate 		}
64510Sstevel@tonic-gate 
64520Sstevel@tonic-gate 		if (!domain_found) {
64530Sstevel@tonic-gate 			for (j = 0; j < num_domain_attrs; j++) {
64540Sstevel@tonic-gate 				if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
64550Sstevel@tonic-gate 					domain_found = B_TRUE;
64560Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64570Sstevel@tonic-gate 					    CKO_DOMAIN_PARAMETERS;
64580Sstevel@tonic-gate 					break;
64590Sstevel@tonic-gate 				}
64600Sstevel@tonic-gate 			}
64610Sstevel@tonic-gate 		}
64620Sstevel@tonic-gate 
64630Sstevel@tonic-gate 		if (!hardware_found) {
64640Sstevel@tonic-gate 			for (j = 0; j < num_hardware_attrs; j++) {
64650Sstevel@tonic-gate 				if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
64660Sstevel@tonic-gate 					hardware_found = B_TRUE;
64670Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64680Sstevel@tonic-gate 					    CKO_HW_FEATURE;
64690Sstevel@tonic-gate 					break;
64700Sstevel@tonic-gate 				}
64710Sstevel@tonic-gate 			}
64720Sstevel@tonic-gate 		}
64730Sstevel@tonic-gate 
64740Sstevel@tonic-gate 		if (!cert_found) {
64750Sstevel@tonic-gate 			for (j = 0; j < num_cert_attrs; j++) {
64760Sstevel@tonic-gate 				if (pTemplate[i].type == CERT_ATTRS[j]) {
64770Sstevel@tonic-gate 					cert_found = B_TRUE;
64780Sstevel@tonic-gate 					pclasses[num_pclasses++] =
64790Sstevel@tonic-gate 					    CKO_CERTIFICATE;
64800Sstevel@tonic-gate 					break;
64810Sstevel@tonic-gate 				}
64820Sstevel@tonic-gate 			}
64830Sstevel@tonic-gate 		}
64840Sstevel@tonic-gate 	}
64850Sstevel@tonic-gate 	*num_result_pclasses = num_pclasses;
64860Sstevel@tonic-gate }
64870Sstevel@tonic-gate 
64880Sstevel@tonic-gate boolean_t
64890Sstevel@tonic-gate soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
64900Sstevel@tonic-gate     CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
64910Sstevel@tonic-gate {
64920Sstevel@tonic-gate 	ulong_t i;
64930Sstevel@tonic-gate 	CK_ATTRIBUTE *tmpl_attr, *obj_attr;
64940Sstevel@tonic-gate 	cert_attr_t *cert_attr;
64950Sstevel@tonic-gate 	uint64_t attr_mask;
64960Sstevel@tonic-gate 	biginteger_t *bigint;
64970Sstevel@tonic-gate 	boolean_t compare_attr, compare_bigint, compare_boolean;
64980Sstevel@tonic-gate 	boolean_t compare_cert_val, compare_cert_type;
64990Sstevel@tonic-gate 
65000Sstevel@tonic-gate 	/*
65010Sstevel@tonic-gate 	 * Check if the class of this object match with any
65027518SViswanathan.Kannappan@Sun.COM 	 * of object classes that can possibly contain the
65030Sstevel@tonic-gate 	 * requested attributes.
65040Sstevel@tonic-gate 	 */
65050Sstevel@tonic-gate 	if (num_pclasses > 0) {
65060Sstevel@tonic-gate 		for (i = 0; i < num_pclasses; i++) {
65070Sstevel@tonic-gate 			if (obj->class == pclasses[i]) {
65080Sstevel@tonic-gate 				break;
65090Sstevel@tonic-gate 			}
65100Sstevel@tonic-gate 		}
65110Sstevel@tonic-gate 		if (i == num_pclasses) {
65120Sstevel@tonic-gate 			/*
65137518SViswanathan.Kannappan@Sun.COM 			 * this object can't possibly contain one or
65140Sstevel@tonic-gate 			 * more attributes, don't need to check this object
65150Sstevel@tonic-gate 			 */
65160Sstevel@tonic-gate 			return (B_FALSE);
65170Sstevel@tonic-gate 		}
65180Sstevel@tonic-gate 	}
65190Sstevel@tonic-gate 
65200Sstevel@tonic-gate 	/* need to examine everything */
65210Sstevel@tonic-gate 	for (i = 0; i < num_attr; i++) {
65220Sstevel@tonic-gate 		tmpl_attr = &(template[i]);
65230Sstevel@tonic-gate 		compare_attr = B_FALSE;
65240Sstevel@tonic-gate 		compare_bigint = B_FALSE;
65250Sstevel@tonic-gate 		compare_boolean = B_FALSE;
65260Sstevel@tonic-gate 		compare_cert_val = B_FALSE;
65270Sstevel@tonic-gate 		compare_cert_type = B_FALSE;
65280Sstevel@tonic-gate 		switch (tmpl_attr->type) {
65290Sstevel@tonic-gate 		/* First, check the most common attributes */
65300Sstevel@tonic-gate 		case CKA_CLASS:
65310Sstevel@tonic-gate 			if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
65320Sstevel@tonic-gate 			    obj->class) {
65330Sstevel@tonic-gate 				return (B_FALSE);
65340Sstevel@tonic-gate 			}
65350Sstevel@tonic-gate 			break;
65360Sstevel@tonic-gate 		case CKA_KEY_TYPE:
65370Sstevel@tonic-gate 			if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
65380Sstevel@tonic-gate 			    obj->key_type) {
65390Sstevel@tonic-gate 				return (B_FALSE);
65400Sstevel@tonic-gate 			}
65410Sstevel@tonic-gate 			break;
65420Sstevel@tonic-gate 		case CKA_ENCRYPT:
65430Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
65440Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65450Sstevel@tonic-gate 			break;
65460Sstevel@tonic-gate 		case CKA_DECRYPT:
65470Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
65480Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65490Sstevel@tonic-gate 			break;
65500Sstevel@tonic-gate 		case CKA_WRAP:
65510Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
65520Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65530Sstevel@tonic-gate 			break;
65540Sstevel@tonic-gate 		case CKA_UNWRAP:
65550Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
65560Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65570Sstevel@tonic-gate 			break;
65580Sstevel@tonic-gate 		case CKA_SIGN:
65590Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
65600Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65610Sstevel@tonic-gate 			break;
65620Sstevel@tonic-gate 		case CKA_SIGN_RECOVER:
65630Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
65640Sstevel@tonic-gate 			    SIGN_RECOVER_BOOL_ON;
65650Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65660Sstevel@tonic-gate 			break;
65670Sstevel@tonic-gate 		case CKA_VERIFY:
65680Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
65690Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65700Sstevel@tonic-gate 			break;
65710Sstevel@tonic-gate 		case CKA_VERIFY_RECOVER:
65720Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
65730Sstevel@tonic-gate 			    VERIFY_RECOVER_BOOL_ON;
65740Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65750Sstevel@tonic-gate 			break;
65760Sstevel@tonic-gate 		case CKA_DERIVE:
65770Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
65780Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65790Sstevel@tonic-gate 			break;
65800Sstevel@tonic-gate 		case CKA_LOCAL:
65810Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
65820Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65830Sstevel@tonic-gate 			break;
65840Sstevel@tonic-gate 		case CKA_SENSITIVE:
65850Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
65860Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65870Sstevel@tonic-gate 			break;
65880Sstevel@tonic-gate 		case CKA_SECONDARY_AUTH:
65890Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
65900Sstevel@tonic-gate 			    SECONDARY_AUTH_BOOL_ON;
65910Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65920Sstevel@tonic-gate 			break;
65930Sstevel@tonic-gate 		case CKA_TRUSTED:
65940Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
65950Sstevel@tonic-gate 			compare_boolean = B_TRUE;
65960Sstevel@tonic-gate 			break;
65970Sstevel@tonic-gate 		case CKA_EXTRACTABLE:
65980Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
65990Sstevel@tonic-gate 			    EXTRACTABLE_BOOL_ON;
66000Sstevel@tonic-gate 			compare_boolean = B_TRUE;
66010Sstevel@tonic-gate 			break;
66020Sstevel@tonic-gate 		case CKA_ALWAYS_SENSITIVE:
66030Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
66040Sstevel@tonic-gate 			    ALWAYS_SENSITIVE_BOOL_ON;
66050Sstevel@tonic-gate 			compare_boolean = B_TRUE;
66060Sstevel@tonic-gate 			break;
66070Sstevel@tonic-gate 		case CKA_NEVER_EXTRACTABLE:
66080Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
66090Sstevel@tonic-gate 			    NEVER_EXTRACTABLE_BOOL_ON;
66100Sstevel@tonic-gate 			compare_boolean = B_TRUE;
66110Sstevel@tonic-gate 			break;
66120Sstevel@tonic-gate 		case CKA_TOKEN:
66130Sstevel@tonic-gate 			attr_mask = (obj->object_type) & TOKEN_OBJECT;
66140Sstevel@tonic-gate 			compare_boolean = B_TRUE;
66150Sstevel@tonic-gate 			break;
66160Sstevel@tonic-gate 		case CKA_PRIVATE:
66170Sstevel@tonic-gate 			attr_mask = (obj->object_type) & PRIVATE_OBJECT;
66180Sstevel@tonic-gate 			compare_boolean = B_TRUE;
66190Sstevel@tonic-gate 			break;
66200Sstevel@tonic-gate 		case CKA_MODIFIABLE:
66210Sstevel@tonic-gate 		{
66220Sstevel@tonic-gate 			CK_BBOOL bval;
66230Sstevel@tonic-gate 			attr_mask = (obj->bool_attr_mask) &
66240Sstevel@tonic-gate 			    NOT_MODIFIABLE_BOOL_ON;
66250Sstevel@tonic-gate 
66260Sstevel@tonic-gate 			if (attr_mask) {
66270Sstevel@tonic-gate 				bval = FALSE;
66280Sstevel@tonic-gate 			} else {
66290Sstevel@tonic-gate 				bval = TRUE;
66300Sstevel@tonic-gate 			}
66310Sstevel@tonic-gate 			if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
66320Sstevel@tonic-gate 				return (B_FALSE);
66330Sstevel@tonic-gate 			}
66340Sstevel@tonic-gate 			break;
66350Sstevel@tonic-gate 		}
66360Sstevel@tonic-gate 		case CKA_OWNER:
66370Sstevel@tonic-gate 			/*
66380Sstevel@tonic-gate 			 * For X.509 attribute certificate object, get its
66390Sstevel@tonic-gate 			 * CKA_OWNER attribute from the x509_attr_cert_t struct.
66400Sstevel@tonic-gate 			 */
66410Sstevel@tonic-gate 			if ((obj->class == CKO_CERTIFICATE) &&
66420Sstevel@tonic-gate 			    (obj->cert_type == CKC_X_509_ATTR_CERT)) {
66430Sstevel@tonic-gate 				cert_attr = X509_ATTR_CERT_OWNER(obj);
66440Sstevel@tonic-gate 				compare_cert_val = B_TRUE;
66450Sstevel@tonic-gate 			}
66460Sstevel@tonic-gate 			break;
66470Sstevel@tonic-gate 		case CKA_SUBJECT:
66480Sstevel@tonic-gate 			/*
66490Sstevel@tonic-gate 			 * For X.509 certificate object, get its CKA_SUBJECT
66500Sstevel@tonic-gate 			 * attribute from the x509_cert_t struct (not from
66510Sstevel@tonic-gate 			 * the extra_attrlistp).
66520Sstevel@tonic-gate 			 */
66530Sstevel@tonic-gate 			if ((obj->class == CKO_CERTIFICATE) &&
66540Sstevel@tonic-gate 			    (obj->cert_type == CKC_X_509)) {
66550Sstevel@tonic-gate 				cert_attr = X509_CERT_SUBJECT(obj);
66560Sstevel@tonic-gate 				compare_cert_val = B_TRUE;
66570Sstevel@tonic-gate 				break;
66580Sstevel@tonic-gate 			}
66590Sstevel@tonic-gate 			/*FALLTHRU*/
66600Sstevel@tonic-gate 		case CKA_ID:
66610Sstevel@tonic-gate 		case CKA_START_DATE:
66620Sstevel@tonic-gate 		case CKA_END_DATE:
66630Sstevel@tonic-gate 		case CKA_KEY_GEN_MECHANISM:
66640Sstevel@tonic-gate 		case CKA_LABEL:
66650Sstevel@tonic-gate 		case CKA_ISSUER:
66660Sstevel@tonic-gate 		case CKA_SERIAL_NUMBER:
66670Sstevel@tonic-gate 		case CKA_AC_ISSUER:
66680Sstevel@tonic-gate 		case CKA_ATTR_TYPES:
66690Sstevel@tonic-gate 			/* find these attributes from extra_attrlistp */
66700Sstevel@tonic-gate 			obj_attr = get_extra_attr(tmpl_attr->type, obj);
66710Sstevel@tonic-gate 			compare_attr = B_TRUE;
66720Sstevel@tonic-gate 			break;
66730Sstevel@tonic-gate 		case CKA_CERTIFICATE_TYPE:
66740Sstevel@tonic-gate 			compare_cert_type = B_TRUE;
66750Sstevel@tonic-gate 			break;
66760Sstevel@tonic-gate 		case CKA_VALUE_LEN:
66770Sstevel@tonic-gate 			/* only secret key has this attribute */
66780Sstevel@tonic-gate 			if (obj->class == CKO_SECRET_KEY) {
66790Sstevel@tonic-gate 				if (*((CK_ULONG *)tmpl_attr->pValue) !=
66800Sstevel@tonic-gate 				    OBJ_SEC_VALUE_LEN(obj)) {
66810Sstevel@tonic-gate 					return (B_FALSE);
66820Sstevel@tonic-gate 				}
66830Sstevel@tonic-gate 			} else {
66840Sstevel@tonic-gate 				return (B_FALSE);
66850Sstevel@tonic-gate 			}
66860Sstevel@tonic-gate 			break;
66870Sstevel@tonic-gate 		case CKA_VALUE:
66880Sstevel@tonic-gate 			switch (obj->class) {
66890Sstevel@tonic-gate 			case CKO_SECRET_KEY:
66900Sstevel@tonic-gate 				/*
66910Sstevel@tonic-gate 				 * secret_key_obj_t is the same as
66920Sstevel@tonic-gate 				 * biginteger_t
66930Sstevel@tonic-gate 				 */
66940Sstevel@tonic-gate 				bigint = (biginteger_t *)OBJ_SEC(obj);
66950Sstevel@tonic-gate 				compare_bigint = B_TRUE;
66960Sstevel@tonic-gate 				break;
66970Sstevel@tonic-gate 			case CKO_PRIVATE_KEY:
66980Sstevel@tonic-gate 				if (obj->key_type == CKK_DSA) {
66990Sstevel@tonic-gate 					bigint = OBJ_PRI_DSA_VALUE(obj);
67000Sstevel@tonic-gate 				} else if (obj->key_type == CKK_DH) {
67010Sstevel@tonic-gate 					bigint = OBJ_PRI_DH_VALUE(obj);
67020Sstevel@tonic-gate 				} else if (obj->key_type == CKK_X9_42_DH) {
67030Sstevel@tonic-gate 					bigint = OBJ_PRI_DH942_VALUE(obj);
67040Sstevel@tonic-gate 				} else {
67050Sstevel@tonic-gate 					return (B_FALSE);
67060Sstevel@tonic-gate 				}
67070Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67080Sstevel@tonic-gate 				break;
67090Sstevel@tonic-gate 			case CKO_PUBLIC_KEY:
67100Sstevel@tonic-gate 				if (obj->key_type == CKK_DSA) {
67110Sstevel@tonic-gate 					bigint = OBJ_PUB_DSA_VALUE(obj);
67120Sstevel@tonic-gate 				} else if (obj->key_type == CKK_DH) {
67130Sstevel@tonic-gate 					bigint = OBJ_PUB_DH_VALUE(obj);
67140Sstevel@tonic-gate 				} else if (obj->key_type == CKK_X9_42_DH) {
67150Sstevel@tonic-gate 					bigint = OBJ_PUB_DH942_VALUE(obj);
67160Sstevel@tonic-gate 				} else {
67170Sstevel@tonic-gate 					return (B_FALSE);
67180Sstevel@tonic-gate 				}
67190Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67200Sstevel@tonic-gate 				break;
67210Sstevel@tonic-gate 			case CKO_CERTIFICATE:
67220Sstevel@tonic-gate 				if (obj->cert_type == CKC_X_509) {
67230Sstevel@tonic-gate 					cert_attr = X509_CERT_VALUE(obj);
67240Sstevel@tonic-gate 				} else if (obj->cert_type ==
67250Sstevel@tonic-gate 				    CKC_X_509_ATTR_CERT) {
67260Sstevel@tonic-gate 					cert_attr = X509_ATTR_CERT_VALUE(obj);
67270Sstevel@tonic-gate 				}
67280Sstevel@tonic-gate 				compare_cert_val = B_TRUE;
67290Sstevel@tonic-gate 				break;
67300Sstevel@tonic-gate 			default:
67310Sstevel@tonic-gate 				return (B_FALSE);
67320Sstevel@tonic-gate 			}
67330Sstevel@tonic-gate 			break;
67340Sstevel@tonic-gate 		case CKA_MODULUS:
67350Sstevel@tonic-gate 			/* only RSA public and private key have this attr */
67360Sstevel@tonic-gate 			if (obj->key_type == CKK_RSA) {
67370Sstevel@tonic-gate 				if (obj->class == CKO_PUBLIC_KEY) {
67380Sstevel@tonic-gate 					bigint = OBJ_PUB_RSA_MOD(obj);
67390Sstevel@tonic-gate 				} else if (obj->class == CKO_PRIVATE_KEY) {
67400Sstevel@tonic-gate 					bigint = OBJ_PRI_RSA_MOD(obj);
67410Sstevel@tonic-gate 				} else {
67420Sstevel@tonic-gate 					return (B_FALSE);
67430Sstevel@tonic-gate 				}
67440Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67450Sstevel@tonic-gate 			} else {
67460Sstevel@tonic-gate 				return (B_FALSE);
67470Sstevel@tonic-gate 			}
67480Sstevel@tonic-gate 			break;
67490Sstevel@tonic-gate 		case CKA_MODULUS_BITS:
67500Sstevel@tonic-gate 			/* only RSA public key has this attribute */
67510Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
67520Sstevel@tonic-gate 			    (obj->class == CKO_PUBLIC_KEY)) {
67530Sstevel@tonic-gate 				CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
67540Sstevel@tonic-gate 				if (mod_bits !=
67550Sstevel@tonic-gate 				    *((CK_ULONG *)tmpl_attr->pValue)) {
67560Sstevel@tonic-gate 					return (B_FALSE);
67570Sstevel@tonic-gate 				}
67580Sstevel@tonic-gate 			} else {
67590Sstevel@tonic-gate 				return (B_FALSE);
67600Sstevel@tonic-gate 			}
67610Sstevel@tonic-gate 			break;
67620Sstevel@tonic-gate 		case CKA_PUBLIC_EXPONENT:
67630Sstevel@tonic-gate 			/* only RSA public and private key have this attr */
67640Sstevel@tonic-gate 			if (obj->key_type == CKK_RSA) {
67650Sstevel@tonic-gate 				if (obj->class == CKO_PUBLIC_KEY) {
67660Sstevel@tonic-gate 					bigint = OBJ_PUB_RSA_PUBEXPO(obj);
67670Sstevel@tonic-gate 				} else if (obj->class == CKO_PRIVATE_KEY) {
67680Sstevel@tonic-gate 					bigint = OBJ_PRI_RSA_PUBEXPO(obj);
67690Sstevel@tonic-gate 				} else {
67700Sstevel@tonic-gate 					return (B_FALSE);
67710Sstevel@tonic-gate 				}
67720Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67730Sstevel@tonic-gate 			} else {
67740Sstevel@tonic-gate 				return (B_FALSE);
67750Sstevel@tonic-gate 			}
67760Sstevel@tonic-gate 			break;
67770Sstevel@tonic-gate 		case CKA_PRIVATE_EXPONENT:
67780Sstevel@tonic-gate 			/* only RSA private key has this attribute */
67790Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
67800Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
67810Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_PRIEXPO(obj);
67820Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67830Sstevel@tonic-gate 			} else {
67840Sstevel@tonic-gate 				return (B_FALSE);
67850Sstevel@tonic-gate 			}
67860Sstevel@tonic-gate 			break;
67870Sstevel@tonic-gate 		case CKA_PRIME_1:
67880Sstevel@tonic-gate 			/* only RSA private key has this attribute */
67890Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
67900Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
67910Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_PRIME1(obj);
67920Sstevel@tonic-gate 				compare_bigint = B_TRUE;
67930Sstevel@tonic-gate 			} else {
67940Sstevel@tonic-gate 				return (B_FALSE);
67950Sstevel@tonic-gate 			}
67960Sstevel@tonic-gate 			break;
67970Sstevel@tonic-gate 		case CKA_PRIME_2:
67980Sstevel@tonic-gate 			/* only RSA private key has this attribute */
67990Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
68000Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
68010Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_PRIME2(obj);
68020Sstevel@tonic-gate 				compare_bigint = B_TRUE;
68030Sstevel@tonic-gate 			} else {
68040Sstevel@tonic-gate 				return (B_FALSE);
68050Sstevel@tonic-gate 			}
68060Sstevel@tonic-gate 			break;
68070Sstevel@tonic-gate 		case CKA_EXPONENT_1:
68080Sstevel@tonic-gate 			/* only RSA private key has this attribute */
68090Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
68100Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
68110Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_EXPO1(obj);
68120Sstevel@tonic-gate 				compare_bigint = B_TRUE;
68130Sstevel@tonic-gate 			} else {
68140Sstevel@tonic-gate 				return (B_FALSE);
68150Sstevel@tonic-gate 			}
68160Sstevel@tonic-gate 			break;
68170Sstevel@tonic-gate 		case CKA_EXPONENT_2:
68180Sstevel@tonic-gate 			/* only RSA private key has this attribute */
68190Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
68200Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
68210Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_EXPO2(obj);
68220Sstevel@tonic-gate 				compare_bigint = B_TRUE;
68230Sstevel@tonic-gate 			} else {
68240Sstevel@tonic-gate 				return (B_FALSE);
68250Sstevel@tonic-gate 			}
68260Sstevel@tonic-gate 			break;
68270Sstevel@tonic-gate 		case CKA_COEFFICIENT:
68280Sstevel@tonic-gate 			/* only RSA private key has this attribute */
68290Sstevel@tonic-gate 			if ((obj->key_type == CKK_RSA) &&
68300Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
68310Sstevel@tonic-gate 				bigint = OBJ_PRI_RSA_COEF(obj);
68320Sstevel@tonic-gate 				compare_bigint = B_TRUE;
68330Sstevel@tonic-gate 			} else {
68340Sstevel@tonic-gate 				return (B_FALSE);
68350Sstevel@tonic-gate 			}
68360Sstevel@tonic-gate 			break;
68370Sstevel@tonic-gate 		case CKA_VALUE_BITS:
68380Sstevel@tonic-gate 			/* only Diffie-Hellman private key has this attr */
68390Sstevel@tonic-gate 			if ((obj->key_type == CKK_DH) &&
68400Sstevel@tonic-gate 			    (obj->class == CKO_PRIVATE_KEY)) {
68410Sstevel@tonic-gate 				CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
68420Sstevel@tonic-gate 				if (val_bits !=
68430Sstevel@tonic-gate 				    *((CK_ULONG *)tmpl_attr->pValue)) {
68440Sstevel@tonic-gate 					return (B_FALSE);
68450Sstevel@tonic-gate 				}
68460Sstevel@tonic-gate 			} else {
68470Sstevel@tonic-gate 				return (B_FALSE);
68480Sstevel@tonic-gate 			}
68490Sstevel@tonic-gate 			break;
68500Sstevel@tonic-gate 		case CKA_PRIME:
68510Sstevel@tonic-gate 			if (obj->class == CKO_PUBLIC_KEY) {
68520Sstevel@tonic-gate 				switch (obj->key_type) {
68530Sstevel@tonic-gate 				case CKK_DSA:
68540Sstevel@tonic-gate 					bigint = OBJ_PUB_DSA_PRIME(obj);
68550Sstevel@tonic-gate 					break;
68560Sstevel@tonic-gate 				case CKK_DH:
68570Sstevel@tonic-gate 					bigint = OBJ_PUB_DH_PRIME(obj);
68580Sstevel@tonic-gate 					break;
68590Sstevel@tonic-gate 				case CKK_X9_42_DH:
68600Sstevel@tonic-gate 					bigint = OBJ_PUB_DH942_PRIME(obj);
68610Sstevel@tonic-gate 					break;
68620Sstevel@tonic-gate 				default:
68630Sstevel@tonic-gate 					return (B_FALSE);
68640Sstevel@tonic-gate 				}
68650Sstevel@tonic-gate 			} else if (obj->class == CKO_PRIVATE_KEY) {
68660Sstevel@tonic-gate 				switch (obj->key_type) {
68670Sstevel@tonic-gate 				case CKK_DSA:
68680Sstevel@tonic-gate 					bigint = OBJ_PRI_DSA_PRIME(obj);
68690Sstevel@tonic-gate 					break;
68700Sstevel@tonic-gate 				case CKK_DH:
68710Sstevel@tonic-gate 					bigint = OBJ_PRI_DH_PRIME(obj);
68720Sstevel@tonic-gate 					break;
68730Sstevel@tonic-gate 				case CKK_X9_42_DH:
68740Sstevel@tonic-gate 					bigint = OBJ_PRI_DH942_PRIME(obj);
68750Sstevel@tonic-gate 					break;
68760Sstevel@tonic-gate 				default:
68770Sstevel@tonic-gate 					return (B_FALSE);
68780Sstevel@tonic-gate 				}
68790Sstevel@tonic-gate 			} else if (obj->class == CKO_DOMAIN_PARAMETERS) {
68800Sstevel@tonic-gate 				switch (obj->key_type) {
68810Sstevel@tonic-gate 				case CKK_DSA:
68820Sstevel@tonic-gate 					bigint = OBJ_DOM_DSA_PRIME(obj);
68830Sstevel@tonic-gate 					break;
68840Sstevel@tonic-gate 				case CKK_DH:
68850Sstevel@tonic-gate 					bigint = OBJ_DOM_DH_PRIME(obj);
68860Sstevel@tonic-gate 					break;
68870Sstevel@tonic-gate 				case CKK_X9_42_DH:
68880Sstevel@tonic-gate 					bigint = OBJ_DOM_DH942_PRIME(obj);
68890Sstevel@tonic-gate 					break;
68900Sstevel@tonic-gate 				default:
68910Sstevel@tonic-gate 					return (B_FALSE);
68920Sstevel@tonic-gate 				}
68930Sstevel@tonic-gate 			} else {
68940Sstevel@tonic-gate 				return (B_FALSE);
68950Sstevel@tonic-gate 			}
68960Sstevel@tonic-gate 			compare_bigint = B_TRUE;
68970Sstevel@tonic-gate 			break;
68980Sstevel@tonic-gate 		case CKA_SUBPRIME:
68990Sstevel@tonic-gate 			if (obj->class == CKO_PUBLIC_KEY) {
69000Sstevel@tonic-gate 				switch (obj->key_type) {
69010Sstevel@tonic-gate 				case CKK_DSA:
69020Sstevel@tonic-gate 					bigint = OBJ_PUB_DSA_SUBPRIME(obj);
69030Sstevel@tonic-gate 					break;
69040Sstevel@tonic-gate 				case CKK_X9_42_DH:
69050Sstevel@tonic-gate 					bigint = OBJ_PUB_DH942_SUBPRIME(obj);
69060Sstevel@tonic-gate 					break;
69070Sstevel@tonic-gate 				default:
69080Sstevel@tonic-gate 					return (B_FALSE);
69090Sstevel@tonic-gate 				}
69100Sstevel@tonic-gate 			} else if (obj->class == CKO_PRIVATE_KEY) {
69110Sstevel@tonic-gate 				switch (obj->key_type) {
69120Sstevel@tonic-gate 				case CKK_DSA:
69130Sstevel@tonic-gate 					bigint = OBJ_PRI_DSA_SUBPRIME(obj);
69140Sstevel@tonic-gate 					break;
69150Sstevel@tonic-gate 				case CKK_X9_42_DH:
69160Sstevel@tonic-gate 					bigint = OBJ_PRI_DH942_SUBPRIME(obj);
69170Sstevel@tonic-gate 					break;
69180Sstevel@tonic-gate 				default:
69190Sstevel@tonic-gate 					return (B_FALSE);
69200Sstevel@tonic-gate 				}
69210Sstevel@tonic-gate 			} else if (obj->class == CKO_DOMAIN_PARAMETERS) {
69220Sstevel@tonic-gate 				switch (obj->key_type) {
69230Sstevel@tonic-gate 				case CKK_DSA:
69240Sstevel@tonic-gate 					bigint = OBJ_DOM_DSA_SUBPRIME(obj);
69250Sstevel@tonic-gate 					break;
69260Sstevel@tonic-gate 				case CKK_X9_42_DH:
69270Sstevel@tonic-gate 					bigint = OBJ_DOM_DH942_SUBPRIME(obj);
69280Sstevel@tonic-gate 					break;
69290Sstevel@tonic-gate 				default:
69300Sstevel@tonic-gate 					return (B_FALSE);
69310Sstevel@tonic-gate 				}
69320Sstevel@tonic-gate 			} else {
69330Sstevel@tonic-gate 				return (B_FALSE);
69340Sstevel@tonic-gate 			}
69350Sstevel@tonic-gate 			compare_bigint = B_TRUE;
69360Sstevel@tonic-gate 			break;
69370Sstevel@tonic-gate 		case CKA_BASE:
69380Sstevel@tonic-gate 			if (obj->class == CKO_PUBLIC_KEY) {
69390Sstevel@tonic-gate 				switch (obj->key_type) {
69400Sstevel@tonic-gate 				case CKK_DSA:
69410Sstevel@tonic-gate 					bigint = OBJ_PUB_DSA_BASE(obj);
69420Sstevel@tonic-gate 					break;
69430Sstevel@tonic-gate 				case CKK_DH:
69440Sstevel@tonic-gate 					bigint = OBJ_PUB_DH_BASE(obj);
69450Sstevel@tonic-gate 					break;
69460Sstevel@tonic-gate 				case CKK_X9_42_DH:
69470Sstevel@tonic-gate 					bigint = OBJ_PUB_DH942_BASE(obj);
69480Sstevel@tonic-gate 					break;
69490Sstevel@tonic-gate 				default:
69500Sstevel@tonic-gate 					return (B_FALSE);
69510Sstevel@tonic-gate 				}
69520Sstevel@tonic-gate 			} else if (obj->class == CKO_PRIVATE_KEY) {
69530Sstevel@tonic-gate 				switch (obj->key_type) {
69540Sstevel@tonic-gate 				case CKK_DSA:
69550Sstevel@tonic-gate 					bigint = OBJ_PRI_DSA_BASE(obj);
69560Sstevel@tonic-gate 					break;
69570Sstevel@tonic-gate 				case CKK_DH:
69580Sstevel@tonic-gate 					bigint = OBJ_PRI_DH_BASE(obj);
69590Sstevel@tonic-gate 					break;
69600Sstevel@tonic-gate 				case CKK_X9_42_DH:
69610Sstevel@tonic-gate 					bigint = OBJ_PRI_DH942_BASE(obj);
69620Sstevel@tonic-gate 					break;
69630Sstevel@tonic-gate 				default:
69640Sstevel@tonic-gate 					return (B_FALSE);
69650Sstevel@tonic-gate 				}
69660Sstevel@tonic-gate 			} else if (obj->class == CKO_DOMAIN_PARAMETERS) {
69670Sstevel@tonic-gate 				switch (obj->key_type) {
69680Sstevel@tonic-gate 				case CKK_DSA:
69690Sstevel@tonic-gate 					bigint = OBJ_DOM_DSA_BASE(obj);
69700Sstevel@tonic-gate 					break;
69710Sstevel@tonic-gate 				case CKK_DH:
69720Sstevel@tonic-gate 					bigint = OBJ_DOM_DH_BASE(obj);
69730Sstevel@tonic-gate 					break;
69740Sstevel@tonic-gate 				case CKK_X9_42_DH:
69750Sstevel@tonic-gate 					bigint = OBJ_DOM_DH942_BASE(obj);
69760Sstevel@tonic-gate 					break;
69770Sstevel@tonic-gate 				default:
69780Sstevel@tonic-gate 					return (B_FALSE);
69790Sstevel@tonic-gate 				}
69800Sstevel@tonic-gate 			} else {
69810Sstevel@tonic-gate 				return (B_FALSE);
69820Sstevel@tonic-gate 			}
69830Sstevel@tonic-gate 			compare_bigint = B_TRUE;
69840Sstevel@tonic-gate 			break;
69850Sstevel@tonic-gate 		case CKA_PRIME_BITS:
69860Sstevel@tonic-gate 			if (obj->class == CKO_DOMAIN_PARAMETERS) {
69870Sstevel@tonic-gate 				CK_ULONG prime_bits;
69880Sstevel@tonic-gate 				if (obj->key_type == CKK_DSA) {
69890Sstevel@tonic-gate 					prime_bits =
69900Sstevel@tonic-gate 					    OBJ_DOM_DSA_PRIME_BITS(obj);
69910Sstevel@tonic-gate 				} else if (obj->key_type == CKK_DH) {
69920Sstevel@tonic-gate 					prime_bits =
69930Sstevel@tonic-gate 					    OBJ_DOM_DH_PRIME_BITS(obj);
69940Sstevel@tonic-gate 				} else if (obj->key_type == CKK_X9_42_DH) {
69950Sstevel@tonic-gate 					prime_bits =
69960Sstevel@tonic-gate 					    OBJ_DOM_DH942_PRIME_BITS(obj);
69970Sstevel@tonic-gate 				} else {
69980Sstevel@tonic-gate 					return (B_FALSE);
69990Sstevel@tonic-gate 				}
70000Sstevel@tonic-gate 				if (prime_bits !=
70010Sstevel@tonic-gate 				    *((CK_ULONG *)tmpl_attr->pValue)) {
70020Sstevel@tonic-gate 					return (B_FALSE);
70030Sstevel@tonic-gate 				}
70040Sstevel@tonic-gate 			} else {
70050Sstevel@tonic-gate 				return (B_FALSE);
70060Sstevel@tonic-gate 			}
70070Sstevel@tonic-gate 			break;
70080Sstevel@tonic-gate 		case CKA_SUBPRIME_BITS:
70090Sstevel@tonic-gate 			if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
70100Sstevel@tonic-gate 			    (obj->key_type == CKK_X9_42_DH)) {
70110Sstevel@tonic-gate 				CK_ULONG subprime_bits =
70120Sstevel@tonic-gate 				    OBJ_DOM_DH942_SUBPRIME_BITS(obj);
70130Sstevel@tonic-gate 				if (subprime_bits !=
70140Sstevel@tonic-gate 				    *((CK_ULONG *)tmpl_attr->pValue)) {
70150Sstevel@tonic-gate 					return (B_FALSE);
70160Sstevel@tonic-gate 				}
70170Sstevel@tonic-gate 			} else {
70180Sstevel@tonic-gate 				return (B_FALSE);
70190Sstevel@tonic-gate 			}
70200Sstevel@tonic-gate 			break;
70210Sstevel@tonic-gate 		default:
70220Sstevel@tonic-gate 			/*
70230Sstevel@tonic-gate 			 * any other attributes are currently not supported.
70240Sstevel@tonic-gate 			 * so, it's not possible for them to be in the
70250Sstevel@tonic-gate 			 * object
70260Sstevel@tonic-gate 			 */
70270Sstevel@tonic-gate 			return (B_FALSE);
70280Sstevel@tonic-gate 		}
70290Sstevel@tonic-gate 		if (compare_boolean) {
70300Sstevel@tonic-gate 			CK_BBOOL bval;
70310Sstevel@tonic-gate 
70320Sstevel@tonic-gate 			if (attr_mask) {
70330Sstevel@tonic-gate 				bval = TRUE;
70340Sstevel@tonic-gate 			} else {
70350Sstevel@tonic-gate 				bval = FALSE;
70360Sstevel@tonic-gate 			}
70370Sstevel@tonic-gate 			if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
70380Sstevel@tonic-gate 				return (B_FALSE);
70390Sstevel@tonic-gate 			}
70400Sstevel@tonic-gate 		} else if (compare_bigint) {
70410Sstevel@tonic-gate 			if (bigint == NULL) {
70420Sstevel@tonic-gate 				return (B_FALSE);
70430Sstevel@tonic-gate 			}
70440Sstevel@tonic-gate 			if (tmpl_attr->ulValueLen != bigint->big_value_len) {
70450Sstevel@tonic-gate 				return (B_FALSE);
70460Sstevel@tonic-gate 			}
70470Sstevel@tonic-gate 			if (memcmp(tmpl_attr->pValue, bigint->big_value,
70480Sstevel@tonic-gate 			    tmpl_attr->ulValueLen) != 0) {
70490Sstevel@tonic-gate 				return (B_FALSE);
70500Sstevel@tonic-gate 			}
70510Sstevel@tonic-gate 		} else if (compare_attr) {
70520Sstevel@tonic-gate 			if (obj_attr == NULL) {
70530Sstevel@tonic-gate 				/*
70540Sstevel@tonic-gate 				 * The attribute type is valid, and its value
70550Sstevel@tonic-gate 				 * has not been initialized in the object. In
70560Sstevel@tonic-gate 				 * this case, it only matches the template's
70570Sstevel@tonic-gate 				 * attribute if the template's value length
70580Sstevel@tonic-gate 				 * is 0.
70590Sstevel@tonic-gate 				 */
70600Sstevel@tonic-gate 				if (tmpl_attr->ulValueLen != 0)
70610Sstevel@tonic-gate 					return (B_FALSE);
70620Sstevel@tonic-gate 			} else {
70630Sstevel@tonic-gate 				if (tmpl_attr->ulValueLen !=
70640Sstevel@tonic-gate 				    obj_attr->ulValueLen) {
70650Sstevel@tonic-gate 					return (B_FALSE);
70660Sstevel@tonic-gate 				}
70670Sstevel@tonic-gate 				if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
70680Sstevel@tonic-gate 				    tmpl_attr->ulValueLen) != 0) {
70690Sstevel@tonic-gate 					return (B_FALSE);
70700Sstevel@tonic-gate 				}
70710Sstevel@tonic-gate 			}
70720Sstevel@tonic-gate 		} else if (compare_cert_val) {
70730Sstevel@tonic-gate 			if (cert_attr == NULL) {
70740Sstevel@tonic-gate 				/* specific attribute not found */
70750Sstevel@tonic-gate 				return (B_FALSE);
70760Sstevel@tonic-gate 			}
70770Sstevel@tonic-gate 			if (tmpl_attr->ulValueLen != cert_attr->length) {
70780Sstevel@tonic-gate 				return (B_FALSE);
70790Sstevel@tonic-gate 			}
70800Sstevel@tonic-gate 			if (memcmp(tmpl_attr->pValue, cert_attr->value,
70810Sstevel@tonic-gate 			    tmpl_attr->ulValueLen) != 0) {
70820Sstevel@tonic-gate 				return (B_FALSE);
70830Sstevel@tonic-gate 			}
70840Sstevel@tonic-gate 		} else if (compare_cert_type) {
70850Sstevel@tonic-gate 			if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
70860Sstevel@tonic-gate 			    tmpl_attr->ulValueLen) != 0) {
70870Sstevel@tonic-gate 				return (B_FALSE);
70880Sstevel@tonic-gate 			}
70890Sstevel@tonic-gate 		}
70900Sstevel@tonic-gate 	}
70910Sstevel@tonic-gate 	return (B_TRUE);
70920Sstevel@tonic-gate }
70930Sstevel@tonic-gate 
70940Sstevel@tonic-gate CK_ATTRIBUTE_PTR
70950Sstevel@tonic-gate get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
70960Sstevel@tonic-gate {
70970Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR tmp;
70980Sstevel@tonic-gate 
70990Sstevel@tonic-gate 	tmp = obj->extra_attrlistp;
71000Sstevel@tonic-gate 	while (tmp != NULL) {
71010Sstevel@tonic-gate 		if (tmp->attr.type == type) {
71020Sstevel@tonic-gate 			return (&(tmp->attr));
71030Sstevel@tonic-gate 		}
71040Sstevel@tonic-gate 		tmp = tmp->next;
71050Sstevel@tonic-gate 	}
71060Sstevel@tonic-gate 	/* if get there, the specified attribute is not found */
71070Sstevel@tonic-gate 	return (NULL);
71080Sstevel@tonic-gate }
7109