/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include "metaGlobal.h"
#include "metaAttrMasters.h"
static void
/*
* get_master_attributes_by_object
*
* Returns an (statically allocated) set of object attributes, as determined by
* class and keytype of the supplied object. The attributes are only
* initialized to default values.
*/
{
/* first get the class */
return (rv);
}
switch (class) {
case CKO_CERTIFICATE:
break;
case CKO_HW_FEATURE:
break;
case CKO_PUBLIC_KEY:
case CKO_PRIVATE_KEY:
case CKO_SECRET_KEY:
case CKO_DOMAIN_PARAMETERS:
break;
case CKO_DATA:
goto get_attr;
/* NOTREACHED */
break;
default:
/* should never be here */
return (CKR_ATTRIBUTE_VALUE_INVALID);
}
return (rv);
}
return (rv);
}
/*
* get_master_attributes_by_template
*
* Returns an (statically allocated) set of object attributes, as determined by
* the supplied object template. The template is only used to determine the
* default values.
*/
{
if (!found) {
return (CKR_TEMPLATE_INCOMPLETE);
}
switch (class) {
case CKO_CERTIFICATE:
break;
case CKO_HW_FEATURE:
break;
case CKO_PUBLIC_KEY:
case CKO_PRIVATE_KEY:
case CKO_SECRET_KEY:
case CKO_DOMAIN_PARAMETERS:
break;
case CKO_DATA:
/* CKO_DATA has no subtype, just pretend it is found */
default:
/* unknown object class */
return (CKR_ATTRIBUTE_VALUE_INVALID);
}
if (!found) {
return (CKR_TEMPLATE_INCOMPLETE);
}
}
/*
* get_master_template_by_type
*
* Returns an (statically allocated) set of object attributes, as determined
* by the specified class and subtype. The attributes are initialized to default
* values.
*/
{
switch (class) {
case CKO_HW_FEATURE:
switch (subtype) {
case CKO_HW_FEATURE:
master_template_size = sizeof (OBJ_HW_CLOCK);
break;
case CKH_MONOTONIC_COUNTER:
master_template_size = sizeof (OBJ_HW_MONOTONIC);
break;
default:
/* Unsupported. */
break;
}
break;
case CKO_DATA:
/* Objects of this class have no subtype. */
master_template_size = sizeof (OBJ_DATA);
break;
case CKO_CERTIFICATE:
switch (subtype) {
case CKC_X_509:
master_template_size = sizeof (OBJ_CERT_X509);
break;
case CKC_X_509_ATTR_CERT:
master_template_size = sizeof (OBJ_CERT_X509ATTR);
break;
default:
/* Unsupported. */
break;
}
break;
case CKO_PUBLIC_KEY:
switch (subtype) {
case CKK_RSA:
master_template_size = sizeof (OBJ_PUBKEY_RSA);
break;
case CKK_DSA:
master_template_size = sizeof (OBJ_PUBKEY_DSA);
break;
case CKK_EC:
master_template_size = sizeof (OBJ_PUBKEY_EC);
break;
case CKK_DH:
master_template_size = sizeof (OBJ_PUBKEY_DH);
break;
case CKK_X9_42_DH:
master_template_size = sizeof (OBJ_PUBKEY_X942DH);
break;
case CKK_KEA:
master_template_size = sizeof (OBJ_PUBKEY_KEA);
break;
default:
/* Unsupported. */
break;
}
break;
case CKO_PRIVATE_KEY:
switch (subtype) {
case CKK_RSA:
master_template_size = sizeof (OBJ_PRIVKEY_RSA);
break;
case CKK_DSA:
master_template_size = sizeof (OBJ_PRIVKEY_DSA);
break;
case CKK_EC:
master_template_size = sizeof (OBJ_PRIVKEY_EC);
break;
case CKK_DH:
master_template_size = sizeof (OBJ_PRIVKEY_DH);
break;
case CKK_X9_42_DH:
master_template_size = sizeof (OBJ_PRIVKEY_X942DH);
break;
case CKK_KEA:
master_template_size = sizeof (OBJ_PRIVKEY_KEA);
break;
default:
/* Unsupported. */
break;
}
break;
case CKO_SECRET_KEY:
/*
* The only difference between secret keys is that some
* are variable length (eg CKK_AES), while others are not
* (eg CKK_DES) -- and do not have a CKA_VALUE_LEN attribute.
*
* FUTURE(?): Consider using obj_seckey_withlen for unknown
* keytypes. This is the most likely choice, as new algorithms
* seem to support variable length keys. That's not the default
* now, because if people have implemented new key types with
* key types), then incorrect behaviour would result. It's
* easier to relax this restriction than to tighten it (which
* would introduce a regression to anyone relying on this
* working for unknown key types).
*
*/
switch (subtype) {
case CKK_DES:
case CKK_DES2:
case CKK_DES3:
case CKK_IDEA:
case CKK_CDMF:
case CKK_SKIPJACK:
case CKK_BATON:
case CKK_JUNIPER:
master_template_size = sizeof (OBJ_SECKEY);
break;
case CKK_GENERIC_SECRET:
case CKK_RC2:
case CKK_RC4:
case CKK_RC5:
case CKK_AES:
case CKK_BLOWFISH:
case CKK_CAST:
case CKK_CAST3:
case CKK_CAST128:
master_template_size = sizeof (OBJ_SECKEY_WITHLEN);
break;
default:
/* Unsupported. */
break;
}
break;
case CKO_DOMAIN_PARAMETERS:
switch (subtype) {
case CKK_DSA:
master_template_size = sizeof (OBJ_DOM_DSA);
break;
case CKK_DH:
master_template_size = sizeof (OBJ_DOM_DH);
break;
case CKK_X9_42_DH:
master_template_size = sizeof (OBJ_DOM_X942DH);
break;
default:
/* Unsupported. */
break;
}
break;
default:
/* Unsupported. */
break;
}
/* Requested object is unknown or invalid. */
if (master_template == NULL)
return (CKR_ATTRIBUTE_VALUE_INVALID);
else {
return (CKR_OK);
}
}
/*
* get_master_attributes_by_type
*
* Returns an (statically allocated) set of object attributes, as determined by
* the specified class and subtype. The attributes are initialized to default
* values.
*/
{
/* Determine the appropriate master template needed. */
return (rv);
/* Duplicate the master template. */
if (new_attributes == NULL)
return (CKR_HOST_MEMORY);
/* Set the pointer in the appropriate storage area. */
for (i = 0; i < num_new_attributes; i++) {
attr = new_attributes + i;
case (sizeof (CK_ULONG)):
break;
case (sizeof (CK_BBOOL)):
break;
default:
break;
}
}
/* Secret keys share a common template, so set the key type here. */
if (class == CKO_SECRET_KEY) {
/* Keytype / subtype is always the second attribute. */
}
return (CKR_OK);
}
/*
* get_master_attributes_by_duplication
*
* Returns an (statically allocated) set of object attributes, as copied from an
* existing set of attributes. The new attributes inherit the values from
* the old attributes.
*/
{
size_t i;
return (CKR_HOST_MEMORY);
for (i = 0; i < num_src_attrs; i++) {
/* Adjust pointers in dst so that they don't point to src. */
if (src->isMalloced) {
/*
* Continue on error, so that the cleanup
* routine doesn't see pointers to src_attrs.
*/
continue;
}
} else {
/* This shouldn't happen. */
num_src_attrs = i + 1;
break;
}
}
} else {
}
return (rv);
}
/*
* dealloc_attributes
*
* Deallocates the storage used for a set of attributes. The attribute
* values are zeroed out before being free'd.
*/
void
{
size_t i;
for (i = 0; i < num_attributes; i++) {
attr = attributes + i;
/*
* Zero-out any attribute values. We could do this just for
* attributes with isSensitive == True, but it's not much
* extra work to just do them all. [Most attributes are just
* 1 or 4 bytes]
*/
if (attr->isMalloced)
}
}
/*
* attribute_set_value
*
* Sets the value of the specified attribute. Any portion of the old value
* which will not be overwritten by the new value is zeroed out.
*/
{
return (CKR_TEMPLATE_INCOMPLETE);
return (CKR_ATTRIBUTE_VALUE_INVALID);
}
return (CKR_ATTRIBUTE_TYPE_INVALID);
}
/* Store the new value. */
/* Existing storage is sufficient to store new value. */
/* bzero() out any data that won't be overwritten. */
/* Use generic storage to avoid a malloc. */
if (attr->isMalloced) {
/*
* If app sets a large value (triggering a malloc),
* then sets a tiny value, and finally again sets
* a large value (phew!) we could end up here.
*
* FUTURE?: Store the original malloc size, so that
* we can regrow the value up to the original size.
* This might avoid some heap churn for pathologic
* applications.
*/
}
} else {
/* Need to allocate storage for the new value. */
void *newStorage;
if (newStorage == NULL)
return (CKR_HOST_MEMORY);
}
return (CKR_OK);
}
/*
* find_attribute
*
* Passes a pointer to the requested attribute, or NULL if not found.
*/
static void
{
size_t i;
/* Find the requested attribute. */
break;
}
}
}
/*
* get_template_ulong
*
* Look for the specified ulong-size attribute, and retrieve its value. The
* return value specifies if the attribute was found (or not).
*/
{
CK_ULONG i;
for (i = 0; i < num_attributes; i++) {
break;
}
}
return (found);
}
/*
* get_template_boolean
*
* Look for the specified boolean attribute, and retrieve its value. The
* return value specifies if the attribute was found (or not).
*/
{
CK_ULONG i;
for (i = 0; i < num_attributes; i++) {
else
break;
}
}
return (found);
}
/*
* set_template_boolean
*
* Look for the specified boolean attribute, and set its value.
*
* if 'local' is true, it sets the pointer to the value in the template a new
* location. There should be no memory leak created by this because we are
* only doing this to booleans which should not be malloc'ed.
*
* if 'local' is false, it sets its value.
*
* The return value specifies if the attribute was found (or not).
*/
int
{
int i;
for (i = 0; i < num_attributes; i++) {
if (local)
else
return (i);
}
}
return (-1);
}