/*
* 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
*
* PKCS11 token KMF Plugin
*
*/
#include <stdio.h> /* debugging only */
#include <errno.h>
#include <values.h>
#include <kmfapiP.h>
#include <ber_der.h>
#include <fcntl.h>
#include <sha1.h>
#include <bignum.h>
#include <cryptoutil.h>
#include <security/cryptoki.h>
typedef struct _objlist {
} OBJLIST;
static KMF_RETURN
static CK_RV
static KMF_RETURN
static KMF_RETURN
int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
void
KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
static
{
1, /* Version */
NULL, /* ImportCRL */
NULL, /* DeleteCRL */
NULL, /* ListCRL */
NULL, /* FindCRL */
NULL, /* FindCertInCRL */
NULL /* Finalize */
};
{
return (&pk11token_plugin_table);
}
{
char *label;
return (KMF_ERR_BAD_PARAMETER);
}
/* "readonly" is optional. Default is TRUE */
return (rv);
}
static KMF_RETURN
{
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
}
if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
return (KMF_ERR_AUTH_FAILED);
}
}
return (KMF_OK);
}
static KMF_RETURN
{
/* Is this a certificate object ? */
return (KMF_ERR_INTERNAL);
}
return (ckrv);
} else {
int i = 0;
/* What attributes are available and how big are they? */
i++;
i++;
i++;
i++;
i++;
/*
* Query the object with NULL values in the pValue spot
* so we know how much space to allocate for each field.
*/
return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
}
/*
* For PKCS#11 CKC_X_509 certificate objects,
* the following attributes must be defined.
* CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
* CKA_VALUE.
*/
if (subject_len == 0 || issuer_len == 0 ||
return (KMF_ERR_INTERNAL);
}
/* Only fetch the value field if we are saving the data */
int i = 0;
rv = KMF_ERR_MEMORY;
goto errout;
}
i++;
/* re-query the object with room for the value attr */
templ, i);
goto errout;
}
}
}
}
if (subject)
if (value)
if (kmfcert) {
}
}
return (rv);
}
static void
{
}
}
/*
* The caller should make sure that the templ->pValue is NULL since
* it will be overwritten below.
*/
static KMF_RETURN
{
return (KMF_ERR_INTERNAL);
}
if (templ->ulValueLen > 0) {
return (KMF_ERR_MEMORY);
return (KMF_ERR_INTERNAL);
}
}
return (KMF_OK);
}
/*
* This is tricky because we cannot reliably compare DER encodings
* because RDNs may have their AV-pairs in different orders even
* if the values are the same. You must compare individual
* AV pairs for the RDNs.
*
* RETURN: 0 for a match, non-zero for a non-match.
*/
static KMF_RETURN
{
if (issuer->numberOfRDNs > 0) {
certattr.ulValueLen = 0;
kmf_free_dn(&dn);
}
}
return (rv);
}
if (subject->numberOfRDNs > 0) {
certattr.ulValueLen = 0;
kmf_free_dn(&dn);
}
}
}
return (rv);
}
/*
* delete "curr" node from the "newlist".
*/
static void
{
/* first node in the list */
} else {
}
}
/*
* search_certs
*
* Because this code is shared by the FindCert and
* DeleteCert functions, put it in a separate routine
* to save some work and make code easier to debug and
* read.
*/
static KMF_RETURN
{
int i;
i = 0;
i++;
}
if (private) {
}
return (rv);
}
return (rv);
}
i++;
}
(*numobj) = 0;
goto cleanup;
break;
/*
*
* If no match, move on to the next one
*/
continue;
rv = KMF_ERR_MEMORY;
break;
}
} else {
} else {
rv = KMF_ERR_MEMORY;
break;
}
}
(*numobj)++;
}
*numobj = 0;
}
} else {
if (validity == KMF_ALL_CERTS) {
} else {
uint32_t i = 0;
/*
* Now check to see if any found certificate is expired
* or valid.
*/
(void) memset(&tmp_kmf_cert, 0,
sizeof (KMF_X509_DER_CERT));
&tmp_kmf_cert);
goto cleanup1;
}
if (validity == KMF_NONEXPIRED_CERTS) {
num_ok_certs++;
} else if (rv ==
/*
* expired - remove it from list
*/
} else {
goto cleanup1;
}
}
if (validity == KMF_EXPIRED_CERTS) {
if (rv == KMF_ERR_VALIDITY_PERIOD) {
num_ok_certs++;
/*
* valid - remove it from list
*/
} else {
goto cleanup1;
}
}
i++;
}
*numobj = num_ok_certs;
}
}
*numobj = 0;
}
return (rv);
}
/*
* The caller may pass a NULL value for kmf_cert below and the function will
* just return the number of certs found (in num_certs).
*/
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
if (*num_certs > 0)
want_certs = *num_certs;
else
*num_certs = 0;
/* Get the optional returned certificate list */
numattr);
/* Get optional search criteria attributes */
}
}
return (rv);
}
/* Start searching */
int i = 0;
&kmf_cert[i]);
i++;
}
}
if (*num_certs == 0)
return (rv);
}
/*ARGSUSED*/
void
{
}
}
}
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
case KMF_RSA:
sizeof (ckObjClass));
sizeof (ckKeyType));
/* Get the length of the fields */
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_MEMORY);
return (KMF_ERR_MEMORY);
}
/* Now get the values */
return (KMF_ERR_BAD_PARAMETER);
}
/*
* This is the KEY algorithm, not the
* signature algorithm.
*/
/* Encode the RSA Key Data */
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_ENCODING);
}
return (KMF_ERR_ENCODING);
}
}
break;
case KMF_DSA:
sizeof (ckObjClass));
sizeof (ckKeyType));
/* Get the length of the fields */
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_MEMORY);
}
/* Now get the values */
return (KMF_ERR_BAD_PARAMETER);
}
/*
* This is the KEY algorithm, not the
* signature algorithm.
*/
/* Encode the DSA Algorithm Parameters */
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_ENCODING);
}
return (KMF_ERR_ENCODING);
}
/* Encode the DSA Key Value */
return (KMF_ERR_MEMORY);
}
return (KMF_ERR_ENCODING);
}
return (KMF_ERR_ENCODING);
}
break;
case KMF_ECDSA:
/* The EC_PARAMS are the PubKey algorithm parameters */
if (PubKeyParams == NULL)
return (KMF_ERR_MEMORY);
if (EncodedKey == NULL) {
return (KMF_ERR_MEMORY);
}
/* Get the length of the fields */
ecdsaTemplate, 2);
return (KMF_ERR_BAD_PARAMETER);
}
/* The params are to be used as algorithm parameters */
/*
* The EC_POINT is to be used as the subject pub key.
*/
/* Use the EC_PUBLIC_KEY OID */
break;
default:
return (KMF_ERR_BAD_PARAMETER);
}
/* Now, build an SPKI structure for the final encoding step */
if (PubKeyParams != NULL) {
} else {
}
if (EncodedKey != NULL) {
} else {
}
/* Finally, encode the entire SPKI record */
if (EncodedKey) {
}
if (PubKeyParams) {
}
return (ret);
}
static KMF_RETURN
{
int i;
return (KMF_ERR_INTERNAL); /* should not happen */
return (KMF_ERR_INTERNAL); /* should not happen */
return (KMF_ERR_INTERNAL); /* should not happen */
/*
* The data *must* be a DER encoded X.509 certificate.
* Convert it to a CSSM cert and then parse the fields so
* the PKCS#11 attributes can be filled in correctly.
*/
return (KMF_ERR_ENCODING);
}
/*
* Encode fields into PKCS#11 attributes.
*/
/* Get the subject name */
} else {
goto cleanup;
}
/* Encode the issuer */
} else {
goto cleanup;
}
/* Encode serial number */
} else {
/*
* RFC3280 says to gracefully handle certs with serial numbers
* of 0.
*/
nullserno = '\0';
serno_len = 1;
}
/* Generate an ID from the SPKI data */
&Id);
goto cleanup;
}
i = 0;
sizeof (certtype));
i++;
}
/*
* The cert object handle is actually "leaked" here. If the app
* really wants to clean up the data space, it will have to call
* KMF_DeleteCert and specify the softtoken keystore.
*/
/* Report authentication failures to the caller */
if (ckrv == CKR_USER_NOT_LOGGED_IN ||
ckrv == CKR_PIN_INCORRECT ||
ckrv == CKR_PIN_INVALID ||
ckrv == CKR_PIN_EXPIRED ||
ckrv == CKR_PIN_LOCKED ||
else
}
if (signed_cert_ptr) {
}
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED);
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
/* label attribute is optional */
return (rv);
}
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED);
return (KMF_ERR_NO_TOKEN_SELECTED);
/*
* Get the input cert filename attribute, check if it is a valid
* certificate and auto-detect the file format of it.
*/
return (KMF_ERR_BAD_PARAMETER);
return (rv);
/* Read in the CERT file */
return (rv);
}
/* The label attribute is optional */
/*
* If the input certificate is in PEM format, we need to convert
* it to DER first.
*/
if (format == KMF_FORMAT_PEM) {
int derlen;
goto out;
}
}
return (rv);
}
out:
}
}
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
/* Get the search criteria attributes. They are all optional. */
}
}
/*
* Start searching for certificates that match the criteria and
* delete them.
*/
break;
}
}
}
out:
return (rv);
}
static CK_RV
{
0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
0x78, 0x47, 0xb0, 0xd5};
0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
{ CKA_TOKEN, &true, sizeof (true)},
{ CKA_PRIVATE, &false, sizeof (false)},
{ CKA_VERIFY, &true, sizeof (true) },
};
sizeof (CK_ATTRIBUTE))
sizeof (CK_ATTRIBUTE))
{CKA_TOKEN, &true, sizeof (true)},
{CKA_PRIVATE, &true, sizeof (true)},
{CKA_SIGN, &true, sizeof (true)},
};
sizeof (CK_ATTRIBUTE))
sizeof (CK_ATTRIBUTE))
(sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
(sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
return (KMF_ERR_KEYGEN_FAILED);
}
return (ckrv);
}
static CK_RV
{
numpubattr++;
&modulusBits, sizeof (modulusBits));
numpubattr++;
numpubattr++;
} else {
numpubattr++;
}
&true, sizeof (true));
numpubattr++;
&true, sizeof (true));
numpubattr++;
&true, sizeof (true));
numpubattr++;
numpriattr++;
sizeof (true));
numpriattr++;
sizeof (true));
numpriattr++;
sizeof (true));
numpriattr++;
sizeof (true));
numpriattr++;
return (ckrv);
}
return (ckrv);
}
static CK_RV
{
numpubattr = 0;
numpubattr++;
numpubattr++;
numpubattr++;
ontoken ? &true : &false, sizeof (true));
numpubattr++;
&true, sizeof (true));
numpubattr++;
&false, sizeof (false));
numpubattr++;
numpriattr = 0;
&privateKey, sizeof (privateKey));
numpriattr++;
numpriattr++;
ontoken ? &true : &false, sizeof (true));
numpriattr++;
&true, sizeof (true));
numpriattr++;
&true, sizeof (true));
numpriattr++;
&true, sizeof (true));
numpriattr++;
return (ckrv);
}
return (ckrv);
}
int numattr,
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
/* "storekey" is optional. Default is TRUE */
return (KMF_ERR_BAD_PARAMETER);
return (rv);
/* keytype is optional. KMF_RSA is default */
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
if (rv == KMF_ERR_ATTR_NOT_FOUND)
/* Default modulusBits = 1024 */
return (KMF_ERR_BAD_PARAMETER);
/* Generate the RSA keypair */
return (KMF_ERR_BAD_PARAMETER);
/* Get the Modulus field to use as input for creating the ID */
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_MEMORY);
return (KMF_ERR_BAD_PARAMETER);
}
/* Generate the DSA keypair */
return (KMF_ERR_BAD_PARAMETER);
/* Get the Public Value to use as input for creating the ID */
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_MEMORY);
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
/* Get the EC_POINT to use as input for creating the ID */
return (KMF_ERR_BAD_PARAMETER);
}
return (KMF_ERR_MEMORY);
return (KMF_ERR_BAD_PARAMETER);
}
} else {
return (KMF_ERR_BAD_PARAMETER);
}
/* Set the CKA_LABEL if one was indicated */
goto cleanup;
}
rv = KMF_ERR_MEMORY;
goto cleanup;
}
goto cleanup;
}
rv = KMF_ERR_MEMORY;
goto cleanup;
}
} else {
}
/* Now, assign a CKA_ID value so it can be searched */
/* ID_Input was assigned above in the RSA or DSA keygen section */
goto cleanup;
}
goto cleanup;
}
goto cleanup;
}
if (pubKey != CK_INVALID_HANDLE)
if (priKey != CK_INVALID_HANDLE)
}
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_KEY_CLASS);
/* "destroy" is optional. Default is TRUE */
if (destroy) {
return (KMF_ERR_BAD_PARAMETER);
return (rv);
}
}
/* Report authentication failures to the caller */
else
}
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
/* These functions are available to the plugin from libkmf */
if (AlgId == KMF_ALGID_NONE)
return (KMF_ERR_BAD_PARAMETER);
/* Get the PKCS11 signing key type and mechtype */
return (KMF_ERR_BAD_PARAMETER);
(mechtype == CKM_RSA_PKCS));
if (rv)
return (rv);
/*
* FIPS 186-3 says that when signing with DSA
* the hash must be truncated to the size of the
* subprime.
*/
&subprime, 1);
return (KMF_ERR_INTERNAL);
}
}
/* the mechtype from the 'get_pk11_info' refers to the signing */
mechanism.ulParameterLen = 0;
return (KMF_ERR_INTERNAL);
}
return (KMF_ERR_INTERNAL);
}
return (KMF_OK);
}
{
return (KMF_ERR_MEMORY);
}
}
return (KMF_OK);
}
static CK_RV
{
return (rv);
}
static CK_RV
char **outlabel)
{
} else {
}
return (rv);
}
static CK_RV
{
if (class == CKO_PUBLIC_KEY) {
*keyclass = KMF_ASYM_PUB;
} else if (class == CKO_PRIVATE_KEY) {
*keyclass = KMF_ASYM_PRI;
} else if (class == CKO_SECRET_KEY) {
}
} else {
}
return (rv);
}
{
/* Get the key handle */
return (KMF_ERR_BAD_PARAMETER);
/* Get the optional encoded format */
/* Decode the signer cert so we can get the SPKI data */
return (KMF_ERR_BAD_PARAMETER);
&SignerCert)) != KMF_OK)
return (rv);
/* Get the public key info from the signer certificate */
/* Generate an ID from the SPKI data */
goto errout;
}
/* Get the credential and login */
return (KMF_ERR_BAD_PARAMETER);
return (rv);
}
/* Start searching */
goto errout;
}
goto errout;
}
if (obj_count == 0) {
goto errout;
}
} else {
}
/*
* The key->keyalg value is needed if we need to convert the key
* to raw key. However, the key->keyalg value will not be set if
* this function is not called thru the kmf_find_prikey_by_cert()
* framework function. To be safe, we will get the keytype from
* the key object and set key->keyalg value here.
*/
&keytype);
} else {
}
else {
/* For asymmetric keys, we only support RSA and DSA */
goto errout;
}
}
}
if (SignerCert != NULL) {
}
return (rv);
}
{
int i, blocks;
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
if (AlgId == KMF_ALGID_NONE)
return (KMF_ERR_BAD_PARAMETER);
/* Map the Algorithm ID to a PKCS#11 mechanism */
return (KMF_ERR_BAD_PARAMETER);
mechanism.ulParameterLen = 0;
sizeof (CK_ULONG));
/* Get the modulus length */
return (KMF_ERR_INTERNAL);
}
/* Compute the number of times to do single-part decryption */
for (i = 0; i < blocks; i++) {
return (KMF_ERR_INTERNAL);
}
return (KMF_ERR_INTERNAL);
}
}
return (KMF_OK);
}
static void
{
}
static KMF_RETURN
{
attr.ulValueLen = 0;
/* Mask this error so the caller can continue */
if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
return (KMF_OK);
else
return (KMF_ERR_INTERNAL);
}
return (KMF_ERR_MEMORY);
return (KMF_ERR_INTERNAL);
}
}
return (KMF_OK);
}
static KMF_RETURN
{
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 }
};
int i;
return (KMF_ERR_BAD_PARAMETER);
/* Tell the caller know why the key data cannot be retrieved. */
if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
return (KMF_ERR_SENSITIVE_KEY);
else if (ckrv == CKR_KEY_UNEXTRACTABLE)
return (KMF_ERR_UNEXTRACTABLE_KEY);
else
return (KMF_ERR_INTERNAL);
}
/* Allocate memory for each attribute. */
for (i = 0; i < count; i++) {
rsa_pri_attrs[i].ulValueLen == 0) {
rsa_pri_attrs[i].ulValueLen = 0;
continue;
}
if ((rsa_pri_attrs[i].pValue =
rv = KMF_ERR_MEMORY;
goto end;
}
}
/* Now that we have space, really get the attributes */
goto end;
}
i = 0;
/* Now get the optional parameters */
goto end;
goto end;
goto end;
goto end;
goto end;
goto end;
end:
for (i = 0; i < count; i++) {
}
}
return (rv);
}
/*
* This function calculates the pubkey value from the prime,
* base and private key values of a DSA key.
*/
static KMF_RETURN
{
BIGNUM p, g, x, y;
rv = KMF_ERR_MEMORY;
return (rv);
}
rv = KMF_ERR_MEMORY;
goto ret1;
}
rv = KMF_ERR_MEMORY;
goto ret2;
}
rv = KMF_ERR_MEMORY;
goto ret3;
}
goto ret3;
}
rv = KMF_ERR_MEMORY;
goto ret4;
}
ret4:
big_finish(&y);
ret3:
big_finish(&x);
ret2:
big_finish(&g);
ret1:
big_finish(&p);
return (rv);
}
static KMF_RETURN
{
{ CKA_EC_PARAMS, NULL, 0},
};
int i;
/* Tell the caller know why the key data cannot be retrieved. */
if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
return (KMF_ERR_SENSITIVE_KEY);
else if (ckrv == CKR_KEY_UNEXTRACTABLE)
return (KMF_ERR_UNEXTRACTABLE_KEY);
return (KMF_ERR_INTERNAL);
}
for (i = 0; i < count; i++) {
ec_attrs[i].ulValueLen == 0) {
ec_attrs[i].ulValueLen = 0;
continue;
}
rv = KMF_ERR_MEMORY;
goto end;
}
}
goto end;
}
end:
for (i = 0; i < count; i++) {
}
}
return (rv);
}
static KMF_RETURN
{
{ CKA_SUBPRIME, NULL, 0 },
};
int i;
/* Tell the caller know why the key data cannot be retrieved. */
if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
return (KMF_ERR_SENSITIVE_KEY);
else if (ckrv == CKR_KEY_UNEXTRACTABLE)
return (KMF_ERR_UNEXTRACTABLE_KEY);
return (KMF_ERR_INTERNAL);
}
/* Allocate memory for each attribute. */
for (i = 0; i < count; i++) {
dsa_pri_attrs[i].ulValueLen == 0) {
dsa_pri_attrs[i].ulValueLen = 0;
continue;
}
if ((dsa_pri_attrs[i].pValue =
rv = KMF_ERR_MEMORY;
goto end;
}
}
goto end;
}
/* Fill in all the temp variables. They are all required. */
i = 0;
/* Compute the public key value and store it */
end:
for (i = 0; i < count; i++) {
}
}
return (rv);
}
static KMF_RETURN
{
/* find the key length first */
if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
return (KMF_ERR_SENSITIVE_KEY);
} else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
return (KMF_ERR_UNEXTRACTABLE_KEY);
} else {
return (KMF_ERR_INTERNAL);
}
}
/* Allocate memory for pValue */
return (KMF_ERR_MEMORY);
}
/* get the key data */
return (KMF_ERR_INTERNAL);
}
return (rv);
}
static KMF_RETURN
{
return (KMF_ERR_MEMORY);
/*
* If sensitive or non-extractable, mark them as such
* but return "OK" status so the keys get counted
* when doing FindKey operations.
*/
if (rv == KMF_ERR_SENSITIVE_KEY) {
} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
}
} else {
}
}
return (rv);
}
static KMF_RETURN
{
switch (keyalg) {
case KMF_RSA:
break;
case KMF_DSA:
break;
case KMF_ECDSA:
break;
case KMF_AES:
break;
case KMF_RC4:
break;
case KMF_DES:
break;
case KMF_DES3:
break;
case KMF_GENERIC_SECRET:
break;
default:
return (KMF_ERR_BAD_KEY_TYPE);
}
return (KMF_OK);
}
static int
{
int len, i;
return (-1);
return (KMF_ERR_MEMORY);
return (KMF_ERR_MEMORY);
return (-1);
}
i = 0;
do {
return (0);
}
{
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
if (*numkeys > 0)
else
/* keyclass is optional */
if (keyclass == KMF_ASYM_PUB) {
} else if (keyclass == KMF_ASYM_PRI) {
} else if (keyclass == KMF_SYMMETRIC) {
}
return (rv);
i = 0;
if (is_token) {
i++;
}
if (keyclass != KMF_KEYCLASS_NONE) {
i++;
}
i++;
}
/* keytype is optional */
if (keytype != 0) {
return (KMF_ERR_BAD_KEY_TYPE);
}
i++;
}
/*
* ID String parameter is assumed to be of form:
* XX:XX:XX:XX:XX ... :XX
* where XX is a hex number.
*
* We must convert this back to binary in order to
* use it in a search.
*/
i++;
} else {
return (rv);
}
}
/* is_private is optional */
(void *)&is_private, NULL);
if (is_private) {
i++;
}
/*
* Authenticate if the object is a token object,
* a private or secred key, or if the user passed in credentials.
*/
return (rv);
}
/* it is okay to have "keys" contains NULL */
1, &obj_count);
&keytype);
goto end;
goto end;
if (keyclass == KMF_KEYCLASS_NONE) {
goto end;
} else {
}
} else if (keytype ==
}
}
n++;
} else {
break;
}
}
/* "numkeys" indicates the number that were actually found */
*numkeys = n;
}
if (format == KMF_FORMAT_RAWKEY ||
format == KMF_FORMAT_PEM) {
/* Convert keys to "rawkey" format */
for (i = 0; i < (*numkeys); i++) {
&rkey);
} else {
break;
}
}
}
} else {
}
}
end:
/* Report authentication failures to the caller */
if (ckrv == CKR_USER_NOT_LOGGED_IN ||
ckrv == CKR_PIN_INCORRECT ||
ckrv == CKR_PIN_INVALID ||
ckrv == CKR_PIN_EXPIRED ||
ckrv == CKR_PIN_LOCKED ||
else
} else if ((*numkeys) == 0) {
}
return (rv);
}
static char *
{
newtime[8] = 0;
/* memory returned must be freed by the caller */
}
static KMF_RETURN
{
int i;
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
else
return (KMF_ERR_BAD_PARAMETER);
return (rv);
}
/*
* If the caller did not specify a label, see if the raw key
* came with one (possible if it came from a PKCS#12 file).
*/
}
i = 0;
goto cleanup;
}
goto cleanup;
}
goto cleanup;
}
i++;
goto cleanup;
}
goto cleanup;
}
i++;
}
/*
* This makes some potentially dangerous assumptions:
* 1. that the startdate in the parameter block is
* properly formatted as YYYYMMDD
* 2. That the CK_DATE structure is always the same.
*/
sizeof (startdate));
i++;
}
sizeof (enddate));
i++;
}
goto cleanup;
}
/*
* Only set the KeyUsage stuff if the KU extension was present.
*/
if (kufound) {
i++;
i++;
i++;
sizeof (CK_BBOOL));
i++;
}
i++;
}
i++;
}
i++;
i++;
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
}
/* Report authentication failures to the caller */
if (ckrv == CKR_USER_NOT_LOGGED_IN ||
ckrv == CKR_PIN_INCORRECT ||
ckrv == CKR_PIN_INVALID ||
ckrv == CKR_PIN_EXPIRED ||
ckrv == CKR_PIN_LOCKED ||
else
}
kmf_free_data(&id);
return (rv);
}
{
int i = 0;
return (KMF_ERR_UNINITIALIZED);
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
(void *)&is_sensitive, NULL);
return (KMF_ERR_BAD_PARAMETER);
(void *)&is_not_extractable, NULL);
return (KMF_ERR_BAD_PARAMETER);
/*
* For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
*
* For a generic secret key, because it may not be supported in
* C_GenerateKey() for some PKCS11 providers, we will handle it
* differently.
*/
if (keytype == KMF_GENERIC_SECRET) {
goto out;
else
goto setup;
}
NULL, &attrkeylen);
numattr);
} else {
attrkeylen = 0;
}
goto out;
}
goto out;
}
/*
* This may override what the user gave on the
* command line.
*/
} else {
/*
* If keydata was not given, key length must be
* provided.
*/
&keylen, &keylen_size);
if (rv == KMF_ERR_ATTR_NOT_FOUND &&
/* keylength is not required for DES and 3DES */
return (KMF_ERR_BAD_PARAMETER);
}
if ((keylen % 8) != 0) {
return (KMF_ERR_BAD_KEY_SIZE);
}
/*
* Only set CKA_VALUE_LEN if the key data was not given and
* we are creating an RC4 or AES key.
*/
sizeof (secKeyLen));
i++;
}
/* Other keytypes */
keyGenMech.ulParameterLen = 0;
switch (keytype) {
case KMF_AES:
break;
case KMF_RC4:
break;
case KMF_DES:
break;
case KMF_DES3:
break;
default:
return (KMF_ERR_BAD_KEY_TYPE);
}
i++;
}
i++;
i++;
i++;
}
if (is_sensitive == B_TRUE) {
} else {
}
i++;
if (is_not_extractable == B_TRUE) {
} else {
}
i++;
i++;
i++;
i++;
i++;
i++;
i++;
return (KMF_ERR_BAD_PARAMETER);
return (rv);
}
/* If the key data was given, use C_CreateObject */
} else {
&keyhandle);
}
if (ckrv == CKR_USER_NOT_LOGGED_IN ||
ckrv == CKR_PIN_INCORRECT ||
ckrv == CKR_PIN_INVALID ||
ckrv == CKR_PIN_EXPIRED ||
ckrv == CKR_PIN_LOCKED ||
else
goto out;
}
out:
return (rv);
}
{
return (KMF_ERR_UNINITIALIZED);
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_KEY_CLASS);
/*
* If the key is already in "raw" format, copy the data
* to the new record if possible.
*/
return (KMF_ERR_BAD_KEYHANDLE);
return (KMF_ERR_SENSITIVE_KEY);
if (rawkey->not_extractable)
return (KMF_ERR_UNEXTRACTABLE_KEY);
return (KMF_ERR_GETKEYVALUE_FAILED);
return (KMF_ERR_MEMORY);
} else {
}
return (rv);
}
{
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
/*
* If a slot wasn't given, the user must pass
* a token label so we can find the slot here.
*/
numattr);
if (tokenlabel == NULL)
return (KMF_ERR_BAD_PARAMETER);
return (rv);
}
goto end;
}
if (rv == CKR_PIN_INCORRECT ||
rv == CKR_PIN_INVALID ||
rv == CKR_PIN_EXPIRED ||
rv == CKR_PIN_LOCKED)
else
goto end;
}
if (rv == CKR_PIN_INCORRECT ||
rv == CKR_PIN_INVALID ||
rv == CKR_PIN_EXPIRED ||
rv == CKR_PIN_LOCKED)
else
}
end:
(void) C_CloseSession(session);
return (ret);
}
static KMF_RETURN
{
int i;
int nread;
int freebuf = 0;
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
(void *)&is_sensitive, NULL);
return (KMF_ERR_BAD_PARAMETER);
(void *)&is_not_extractable, NULL);
return (KMF_ERR_BAD_PARAMETER);
NULL, &attrkeylen);
numattr);
} else {
}
/*
* If the key data was not given, key length must
* be provided.
*/
return (KMF_ERR_BAD_PARAMETER);
/*
* Check the key size.
*/
if ((keylen % 8) != 0) {
return (KMF_ERR_BAD_KEY_SIZE);
} else {
}
/*
* Generate a random number with the key size first.
*/
return (KMF_ERR_MEMORY);
freebuf = 1;
break;
}
if (random_fd < 0) {
goto out;
}
goto out;
}
}
/*
* Authenticate into the token and call C_CreateObject to generate
* a generic secret token key.
*/
goto out;
}
i = 0;
i++;
i++;
i++;
i++;
}
if (is_sensitive == B_TRUE) {
} else {
}
i++;
if (is_not_extractable == B_TRUE) {
} else {
}
i++;
i++;
i++;
i++;
if (ckrv == CKR_USER_NOT_LOGGED_IN ||
ckrv == CKR_PIN_INCORRECT ||
ckrv == CKR_PIN_INVALID ||
ckrv == CKR_PIN_EXPIRED ||
ckrv == CKR_PIN_LOCKED ||
else
}
out:
if (random_fd != -1)
return (rv);
}
int numattr,
{
return (KMF_ERR_UNINITIALIZED);
return (KMF_ERR_NO_TOKEN_SELECTED);
return (KMF_ERR_BAD_PARAMETER);
return (rv);
numattr);
numattr);
}
return (KMF_ERR_ATTR_NOT_FOUND);
/* Copy the key object to the token */
return (KMF_ERR_INTERNAL);
}
/* Replace the object handle with the new token-based one */
return (KMF_ERR_INTERNAL);
}
} else {
}
return (rv);
}
{
int i;
return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
return (KMF_ERR_NO_TOKEN_SELECTED);
/* First get the required attributes */
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_BAD_PARAMETER);
numattr);
return (KMF_ERR_BAD_PARAMETER);
/* Find all the certificates that match the searching criteria */
i = 0;
i++;
i++;
i++;
}
i++;
}
i++;
}
i++;
}
sizeof (KMF_X509_DER_CERT));
return (KMF_ERR_MEMORY);
sizeof (KMF_X509_DER_CERT));
certlist, sizeof (KMF_X509_DER_CERT));
i++;
return (rv);
}
} else {
return (rv);
}
/* For each certificate, find the matching private key */
numkeys = 0;
for (i = 0; i < numcerts; i++) {
int j = 0;
j++;
j++;
j++;
sizeof (KMF_DATA));
j++;
j++;
numkeys++;
numkeys * sizeof (KMF_KEY_HANDLE));
rv = KMF_ERR_MEMORY;
goto out;
}
} else if (rv == KMF_ERR_KEY_NOT_FOUND) {
/* it is OK if a key is not found */
}
}
goto out;
out:
for (i = 0; i < numcerts; i++)
}
for (i = 0; i < numkeys; i++)
}
return (rv);
}