2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * If it isn't set or is set to the empty string use the 2N/A * default location. We need to check for the empty string 2N/A * because some users "unset" environment variables by giving 2N/A * them no value, this isn't the same thing as removing it 2N/A * from the environment. 2N/A * Alternate path not specified, 2N/A /* check for comment sign */ 2N/A /* skip the rest of the line */ 2N/A while (*s !=
'\n' && *s !=
'\r' && s <
end)
2N/A f = s;
/* mark the beginning. */ 2N/A /* Find the end of the line and null terminate it. */ 2N/A while (*s !=
'\n' && *s !=
'\r' && s <
end) s++;
2N/A /* Strip trailing whitespace */ 2N/A /* If we reached the end, return NULL */ 2N/A * Open the keystore description file in the specified mode. 2N/A * The KMS token is considered "initialized" if the file with the token 2N/A * configuration information is present. 2N/A * The PK12 file is only established once the user has enrolled 2N/A * and is thus considered having a PIN set. 2N/A /* Remove trailing CR */ 2N/A /* see if this entry already exists */ 2N/A /* It's a dup, don't add it */ 2N/A * If its a dup that was already marked for deletion, 2N/A * Read each line and add it as a label node. 2N/A * We don't need to clear the label list because 2N/A * "add_label_node" checks for dups. 2N/A /* Re-stat to get current times */ 2N/A /* if nothing to read or the timestamp hasnt changed, return */ 2N/A * The caller MUST provide a CKA_LABEL when deleting. 2N/A * Retrieve a data unit associated with the label. 2N/A /* Find the data unit that holds the key */ 2N/A /* If it doesn't start with the expected prefix, return */ 2N/A * Decode as follows: 2N/A * CK_OBJECT_CLASS (2 bytes) 2N/A * CK_KEY_TYPE (2 bytes) 2N/A * CKA_VALUE_LEN (4 bytes) 2N/A * CK_CERTIFICATE_TYPE (2 bytes - not used) 2N/A * CK_MECHANISM_TYPE (4 bytes) 2N/A * boolean attributes (3 bytes) 2N/A * extra attributes (1 byte) 2N/A * non-boolean attributes 2N/A "%02lx%02lx%02x00%04lx%06llx00",
2N/A /* We didn't get the full set of attributes */ 2N/A * Create a new PKCS#11 object record for the KMSAgent_Key. 2N/A }
else {
/* Can only be one of the decrypt-only states. */ 2N/A * Decode the DataUnit description field to find various 2N/A * object attributes. 2N/A * Set the template keytype and class according to the 2N/A * data parsed from the description. 2N/A * Retrieve a key from KMS. We can't use "RetrieveKey" because 2N/A * we don't know the key id. Instead get all keys associated 2N/A * with our data unit (there should be only 1. 2N/A /* No keys available. CKR_OK is still valid status */ 2N/A /* No keys is a valid response */ 2N/A * Make sure the key is in a useable state. 2N/A * If an object is not in the list, reload it from KMS. 2N/A /* Search object list for matching object */ 2N/A /* Skip nodes that are marked for deletion */ 2N/A * Fetch KMS key and prepend it to the 2N/A * token object list for the slot. 2N/A * If the keystore directory doesn't exist, create it. 2N/A /* First, try to load existing profile */ 2N/A * kms_update_label_file 2N/A * KMS doesn't provide an API to allow one to query for available 2N/A * data units (which map 1-1 to keys). To allow for PKCS11 to 2N/A * query for a list of available objects, we keep a local list 2N/A * and update it when an object is added or deleted. 2N/A /* Open the label file with a WRITE lock, but for READ/WRITE access */ 2N/A /* Re-read the label file and merge the list. */ 2N/A /* merge the label list */ 2N/A /* Truncate the file in preparation for updating it */ 2N/A /* remove nodes marked for deletion */ 2N/A /* get the next one */ 2N/A /* remove and free the old node data */ 2N/A /* Update the last mtime */ 2N/A * Destroy a key in the KMS by disassociating an entire data unit. 2N/A * The KMSAgent API does not have an interface for destroying an 2N/A * The caller MUST provide a CKA_LABEL when deleting. 2N/A * Remove the label from the label list and update 2N/A * the file that tracks active keys. 2N/A /* Mark it for deletion */ 2N/A /* rewrite the list of labels to disk */ 2N/A /* Ignore error here */ 2N/A * Encode as follows: 2N/A * CK_OBJECT_CLASS (2 bytes) 2N/A * CK_KEY_TYPE (2 bytes) 2N/A * CKA_VALUE_LEN (4 bytes) 2N/A * CK_CERTIFICATE_TYPE (2 bytes - not used) 2N/A * CK_MECHANISM_TYPE (4 bytes) 2N/A * boolean attributes (3 bytes) 2N/A * extra attributes (1 byte) 2N/A * non-boolean attributes 2N/A "%02lx%02lx%02x00%04lx%06x00",
2N/A * The caller MUST provide a CKA_LABEL for storing in the KMS. 2N/A /* Encode attributes in Description */ 2N/A * If the DataUnit exists, check to see if it has any keys. 2N/A * If it has no keys, then it is OK to continue. 2N/A * This would be better if there were PKCS#11 2N/A * error codes for duplicate objects or 2N/A * something like that. 2N/A /* If no keys associated with data unit, continue */ 2N/A * Clean up the old data unit. 2N/A * KMS Agent only creates AES-256 keys, so ignore what the user 2N/A * requested at this point. 2N/A * Add the label to the local list of available objects