summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2007-04-27 03:19:46 +0000
committerStef Walter <stef@memberwebs.com>2007-04-27 03:19:46 +0000
commit3d8ed01d2653c45e52821ba00ac72099a12600e1 (patch)
treead13d6df465ef1a4f143109f04c35991ddb1efba
-rw-r--r--ckcapi-cert.c520
-rw-r--r--ckcapi-object.c655
-rw-r--r--ckcapi-session.c329
-rw-r--r--ckcapi-util.c167
-rw-r--r--ckcapi-util.h46
-rw-r--r--cryptoki-capi.c1149
-rw-r--r--cryptoki-capi.dsp145
-rw-r--r--cryptoki-capi.dsw29
-rw-r--r--cryptoki-capi.h99
-rw-r--r--pkcs11/Makefile.am9
-rw-r--r--pkcs11/cryptoki.h66
-rw-r--r--pkcs11/pkcs-11v2-20a3.h119
-rw-r--r--pkcs11/pkcs11.h299
-rw-r--r--pkcs11/pkcs11f.h912
-rw-r--r--pkcs11/pkcs11t.h1685
15 files changed, 6229 insertions, 0 deletions
diff --git a/ckcapi-cert.c b/ckcapi-cert.c
new file mode 100644
index 0000000..d1b9b32
--- /dev/null
+++ b/ckcapi-cert.c
@@ -0,0 +1,520 @@
+
+
+typedef struct _CertRef
+{
+
+
+}
+CertRef;
+
+static CK_RV
+copy_static_data(CK_VOID_PTR val, CK_ULONG_PTR len,
+ CK_VOID_PTR data, DWORD cb)
+{
+ if(cb == 0)
+ return CKR_CANCEL;
+
+ if(!val)
+ {
+ *len = cb;
+ return CKR_OK;
+ }
+
+ if(cb > *len)
+ {
+ *len = cb;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ *len = cb;
+ memcpy(val, data, cb);
+ return CKR_OK;
+}
+
+static CK_RV
+cert_bool_attribute(void* obj, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR data, CK_ULONG_PTR len)
+{
+ PCCERT_CONTEXT cert = (PCCERT_CONTEXT)obj;
+ CK_BBOOL val;
+
+ ASSERT(obj);
+ ASSERT(ret);
+
+ switch(type)
+ {
+ /*
+ * Resides on the token
+ * - Always true for CAPI objects.
+ */
+ case CKA_TOKEN:
+ val = CK_TRUE;
+ break;
+
+ /*
+ * Private vs. Public object.
+ * - Always false for certificates.
+ */
+ case CKA_PRIVATE:
+ val = CK_FALSE;
+ break;
+
+ /*
+ * If object can be modified.
+ * - Currently always false. In the future with additional
+ * functionality this may change.
+ */
+ case CKA_MODIFIABLE:
+ val = CK_FALSE;
+ break;
+
+ /*
+ * Whether the certificate can be trusted for the application
+ * in which it was created.
+ * - Use CertGetCertificateChain to build up a chain
+ * for this certificate, and then look in the CERT_CHAIN_CONTEXT
+ * TrustStatus field.
+ */
+ case CKA_TRUSTED:
+ /* TODO: Implement */
+
+ default:
+ return CK_CANCEL;
+ };
+
+ return copy_static_data(data, len, &val, sizeof(CK_BBOOL));
+}
+
+static CK_RV
+cert_ulong_attribute(void* obj, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR data, CK_ULONG_PTR len)
+{
+ PCCERT_CONTEXT cert = (PCCERT_CONTEXT)obj;
+ CK_ULONG val;
+
+ ASSERT(obj);
+ ASSERT(ret);
+
+ switch(type)
+ {
+
+ /*
+ * Object class.
+ * - Always CKO_CERTIFICATE for certificates.
+ */
+ case CKA_OBJECT_CLASS:
+ val = CKO_CERTIFICATE;
+ break;
+
+ /*
+ * Type of certificate.
+ * - Always X509.
+ */
+ case CKA_CERTIFICATE_TYPE:
+ val = CKC_X_509;
+ break;
+
+ /*
+ * Whether a CA, user certificate, other.
+ * - Get certificate szOID_ENHANCED_KEY_USAGE
+ * extension or CERT_CTL_PROP_ID and look into CTL_USAGE structure.
+ */
+ case CKA_CERTIFICATE_CATEGORY:
+ /* TODO: Implement */
+
+ default:
+ return CK_CANCEL;
+ };
+
+ if(*len < sizeof(CK_ULONG))
+ {
+ *len = sizeof(CK_ULONG);
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ return copy_static_data(data, len, &val, sizeof(CK_ULONG));
+}
+
+static CK_RV
+cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type,
+ CkCapiAttrAction action, CK_ATTRIBUTE_PTR attr)
+{
+ PCCERT_CONTEXT cert = (PCCERT_CONTEXT)obj;
+ CK_VOID_PTR val;
+ CK_ULONG len;
+ size_t maxa;
+ BOOL r;
+
+
+ DWORD size = *len;
+
+ int allocated = 0;
+
+ ASSERT(obj);
+ ASSERT(ret);
+
+ /*
+ * We don't need to retrieve the full value of any of
+ * these fields if we don't have to. Just calculate
+ * the max amount to retrieve, so we can compare, or
+ * notify caller of real length.
+ */
+ maxa = attr->ulValueLen;
+ if(maxa == 0)
+ maxa = 4;
+ /* Keep dynamic allocations under a 64k. */
+ if(maxa > 0xFFFF)
+ maxa = 0xFFFF;
+
+ switch(type)
+ {
+
+ /*
+ * Description of the object.
+ * - We use CAPI's CERT_FRIENDLY_NAME_PROP_ID property,
+ * converted into UTF8.
+ * - Yes this is slow, but this is not really a property
+ * that's searched on or retrieved intensively.
+ */
+ case CKA_LABEL:
+ {
+ DWORD size = maxa * sizeof(WCHAR);
+ WCHAR* utf16;
+xxxxxx, this is wrong, second call may be needed
+ /* Get the UTF16 string, a worst case of twice as long as UTF8 */
+ WCHAR* utf16 = alloca(size);
+ r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
+ utf16, &size);
+ if(!r)
+ {
+ DWORD err = GetLastError();
+ if(err == ERROR_MORE_DATA)
+ {
+ /* Truncate long names */
+ utf16[maxa - 1] = 0;
+ r = TRUE;
+ }
+ else if (err != CRYPT_E_NOT_FOUND)
+ {
+ return ckcapi_winerr_to_ckr(err);
+ }
+ }
+
+ if(r)
+ {
+ /* Convert it */
+ if(!ckcapi_util_utf16_to_utf8(utf16, &val, &len))
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ allocated = 1;
+ }
+ else
+ {
+ /* We always like to have a decent label */
+ val = "Unnamed Certificate";
+ len = strlen(val);
+ allocated = 0;
+ }
+ }
+ break;
+
+ /*
+ * A byte array unique to this certificate. The CKA_ID of
+ * matching certificates and private keys should match.
+ * Should match the key identifier in an X.509v3 certificate.
+ *
+ * We use CAPI's CERT_KEY_IDENTIFIER_PROP_ID property directly.
+ */
+ case CKA_ID:
+ {
+ BOOL r;
+
+ val = alloca(size);
+ r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
+ val, &size);
+ if(!r)
+ {
+ DWORD err = GetLastError();
+ if(err == CRYPT_E_NOT_FOUND)
+ return CKR_CANCEL;
+ if(err != ERROR_MORE_DATA)
+ return ckcapi_winerr_to_ckr(err);
+ }
+
+ *len = size;
+ }
+ break;
+
+ /*
+ * DER-encoding of the certificate subject name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Subject field
+ * directly.
+ */
+ case CKA_SUBJECT:
+ if(cert->pCertInfo->Subject.pbData == NULL ||
+ cert->pCertInfo->Subject.cbData == 0)
+ return CKR_CANCEL;
+ val = cert->pCertInfo->Subject.pbData;
+ len = cert->pCertInfo->Subject.cbData;
+ break;
+
+ /*
+ * DER-encoding of the certificate issuer name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Issuer field
+ * directly.
+ */
+ case CKA_ISSUER:
+ if(cert->pCertInfo->Issuer.pbData == NULL ||
+ cert->pCertInfo->Issuer.cbData == 0)
+ return CKR_CANCEL;
+ val = cert->pCertInfo->Issuer.pbData;
+ len = cert->pCertInfo->Issuer.cbData;
+ break;
+
+ /*
+ * DER-encoding of the certificate serial number.
+ *
+ * TODO:
+ * BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
+ * X509_MULTI_BYTE_INTEGER,
+ * &certContext->pCertInfo->SerialNumber,
+ * co->derSerial,
+ * &size);
+ */
+ case CKA_SERIAL_NUMBER:
+ {
+ BOOL r;
+ DWORD size = *len;
+
+ r = CryptEncodeObject(X509_ASN_ENCODING, X509_MULTI_BYTE_INTEGER,
+ &cert->pCertInfo->SerialNumber, val, *len);
+ if(!r)
+ {
+ DWORD err = GetLastError();
+ if(err == ERROR_FILE_NOT_FOUND)
+ return CKR_GENERAL_ERROR;
+ if(err != ERROR_MORE_DATA)
+ return ckcapi_winerr_to_ckr(err);
+ }
+
+ len = size;
+ }
+ break;
+
+ /*
+ * BER-encoding of the full certificate.
+ *
+ * We use CAPI's CERT_CONTEXT pbCertEncoded field directly.
+ */
+ case CKA_VALUE:
+ if(cert->pbCertEncoded == NULL ||
+ cert->cbCertEncoded == 0)
+ return CKR_CANCEL;
+ val = cert->pbCertEncoded;
+ len = cert->cbCertEncoded;
+ break;
+ break;
+
+ /*
+ * If CKA_VALUE not specified, this is where the full
+ * certificate can be found.
+ *
+ * We don't support this. All our certificates are present
+ * in full.
+ */
+ case CKA_URL:
+ return CKR_CANCEL;
+
+ /*
+ * Checksum
+ * - TODO: Work out what to do here
+ */
+ case CKA_CHECKSUM:
+ break;
+
+ /*
+ * TODO: Should we support these?
+ */
+ CKA_HASH_OF_SUBJECT_PUBLIC_KEY
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY
+ break;
+
+ /* Not supported */
+
+ default:
+ break
+ };
+};
+
+static CK_RV
+cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR data, CK_ULONG_PTR len)
+{
+ PCCERT_CONTEXT cert = (PCCERT_CONTEXT)obj;
+
+ ASSERT(sizeof(CK_ULONG) == sizeof(DWORD));
+ ASSERT(obj);
+
+ switch(type)
+ {
+
+ /*
+ * Description of the object.
+ * - We use CAPI's CERT_FRIENDLY_NAME_PROP_ID property,
+ * converted into UTF8.
+ * - Yes this is slow, but this is not really a property
+ * that's searched on or retrieved intensively.
+ */
+ case CKA_LABEL:
+ {
+ WCHAR* utf16;
+
+ /* Get the UTF16 string, a worst case of twice as long as UTF8 */
+ (*len) *= sizeof(WCHAR);
+ utf16 = alloca(*len);
+ r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
+ utf16, (DWORD*)len))
+ {
+ DWORD err = GetLastError();
+ if(err == CRYPT_E_NOT_FOUND)
+ utf16 = L"Unnamed Certificate";
+ else
+ return ckcapi_winerr_to_ckr(err);
+ }
+
+ /* Convert the data into the buffer */
+ return ckcapi_util_utf16_to_utf8(utf16, data, len));
+ }
+ break;
+
+ /*
+ * A byte array unique to this certificate. The CKA_ID of
+ * matching certificates and private keys should match.
+ * Should match the key identifier in an X.509v3 certificate.
+ *
+ * We use CAPI's CERT_KEY_IDENTIFIER_PROP_ID property directly.
+ */
+ case CKA_ID:
+ {
+ if(!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID,
+ data, (DWORD*)len))
+ {
+ DWORD err = GetLastError();
+ if(err == CRYPT_E_NOT_FOUND)
+ return CKR_CANCEL;
+ return ckcapi_winerr_to_ckr(err);
+ }
+ }
+ break;
+
+ /*
+ * DER-encoding of the certificate subject name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Subject field
+ * directly.
+ */
+ case CKA_SUBJECT:
+ return copy_static_data(data, len, cert->pCertInfo->Subject.pbData,
+ cert->pCertInfo->Subject.cbData);
+
+ /*
+ * DER-encoding of the certificate issuer name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Issuer field
+ * directly.
+ */
+ case CKA_ISSUER:
+ return copy_static_data(data, len, cert->pCertInfo->Issuer.pbData,
+ cert->pCertInfo->Issuer.cbData);
+
+ /*
+ * DER-encoding of the certificate serial number.
+ *
+ * TODO:
+ * BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
+ * X509_MULTI_BYTE_INTEGER,
+ * &certContext->pCertInfo->SerialNumber,
+ * co->derSerial,
+ * &size);
+ */
+ case CKA_SERIAL_NUMBER:
+ {
+ if(!CryptEncodeObject(X509_ASN_ENCODING, X509_MULTI_BYTE_INTEGER,
+ &cert->pCertInfo->SerialNumber, data, len))
+ {
+ DWORD err = GetLastError();
+ if(err == ERROR_FILE_NOT_FOUND)
+ return CKR_GENERAL_ERROR;
+ return ckcapi_winerr_to_ckr(err);
+ }
+ }
+ break;
+
+ /*
+ * BER-encoding of the full certificate.
+ *
+ * We use CAPI's CERT_CONTEXT pbCertEncoded field directly.
+ */
+ case CKA_VALUE:
+ return copy_static_data(data, len, cert->pbCertEncoded,
+ cert->cbCertEncoded);
+
+ /*
+ * If CKA_VALUE not specified, this is where the full
+ * certificate can be found.
+ *
+ * We don't support this. All our certificates are present
+ * in full.
+ */
+ case CKA_URL:
+ break;
+
+ /*
+ * Checksum
+ * - TODO: Work out what to do here
+ */
+ case CKA_CHECKSUM:
+ break;
+
+ /*
+ * TODO: Should we support these?
+ */
+ CKA_HASH_OF_SUBJECT_PUBLIC_KEY
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY
+ break;
+
+ /* Not supported */
+
+ default:
+ break
+ };
+
+ return CKR_CANCEL;
+}
+
+static xxx
+cert_date_attribute()
+{
+ switch(type)
+ {
+
+ /*
+ * Start date for the certificate.
+ * - TODO: Work out where to get this.
+ * pCertInfo->NotBefore;
+ */
+ case CKA_START_DATE:
+ xxxx;
+ break;
+
+ /*
+ * End date for the certificate.
+ * - TODO: Work out where to get this.
+ * pCertInfo->NotBefore;
+ */
+ case CKA_END_DATE:
+ xxxx;
+ break;
+ };
+}
diff --git a/ckcapi-object.c b/ckcapi-object.c
new file mode 100644
index 0000000..531ad2f
--- /dev/null
+++ b/ckcapi-object.c
@@ -0,0 +1,655 @@
+
+#include "cryptoki-capi.h"
+
+#include <wtypes.h>
+#include <wincrypt.h>
+
+enum
+{
+ DATA_UNKNOWN = 0,
+ DATA_BOOL,
+ DATA_ULONG,
+ DATA_DATE,
+ DATA_BYTES
+};
+
+
+int
+attribute_data_type(CK_ATTRIBUTE_TYPE type)
+{
+ switch(type)
+ {
+ // CK_ULONG attribute types
+ case CKA_CLASS:
+ case CKA_CERTIFICATE_TYPE:
+ case CKA_CERTIFICATE_CATEGORY:
+ case CKA_KEY_TYPE:
+ case CKA_MODULUS_BITS:
+ case CKA_PRIME_BITS:
+ case CKA_SUBPRIME_BITS:
+ case CKA_SUB_PRIME_BITS:
+ case CKA_VALUE_BITS:
+ case CKA_VALUE_LEN:
+ case CKA_KEY_GEN_MECHANISM:
+ case CKA_HW_FEATURE_TYPE:
+ case CKA_PIXEL_X:
+ case CKA_PIXEL_Y:
+ case CKA_RESOLUTION:
+ case CKA_CHAR_ROWS:
+ case CKA_CHAR_COLUMNS:
+ case CKA_BITS_PER_PIXEL:
+ case CKA_MECHANISM_TYPE:
+ case CKA_JAVA_MIDP_SECURITY_DOMAIN:
+ return DATA_ULONG:
+
+ // CK_BBOOL attribute types
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ case CKA_TRUSTED:
+ case CKA_SENSITIVE:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ case CKA_EXTRACTABLE:
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_WRAP_WITH_TRUSTED:
+ case CKA_ALWAYS_AUTHENTICATE
+ case CKA_ENCRYPT:
+ case CKA_WRAP:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_DERIVE:
+ case CKA_LOCAL:
+ case CKA_RESET_ON_INIT:
+ case CKA_HAS_RESET:
+ case CKA_COLOR:
+ return DATA_BOOL;
+
+ // Raw or string data
+ case CKA_LABEL:
+ case CKA_APPLICATION:
+ case CKA_VALUE:
+ case CKA_OBJECT_ID:
+ case CKA_CHECK_VALUE:
+ case CKA_ISSUER:
+ case CKA_SERIAL_NUMBER:
+ case CKA_SUBJECT:
+ case CKA_ID:
+ case CKA_URL:
+ case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
+ case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
+ case CKA_AC_ISSUER:
+ case CKA_OWNER:
+ case CKA_ATTR_TYPES:
+ case CKA_MODULUS:
+ case CKA_PUBLIC_EXPONENT:
+ case CKA_PRIVATE_EXPONENT:
+ case CKA_PRIME_1:
+ case CKA_PRIME_2:
+ case CKA_EXPONENT_1:
+ case CKA_EXPONENT_2:
+ case CKA_COEFFICIENT:
+ case CKA_PRIME:
+ case CKA_SUBPRIME:
+ case CKA_BASE:
+ case CKA_ECDSA_PARAMS:
+ case CKA_EC_PARAMS:
+ case CKA_EC_POINT:
+ case CKA_CHAR_SETS:
+ case CKA_ENCODING_METHODS:
+ case CKA_MIME_TYPES:
+ case CKA_REQUIRED_CMS_ATTRIBUTES:
+ case CKA_DEFAULT_CMS_ATTRIBUTES:
+ case CKA_SUPPORTED_CMS_ATTRIBUTES:
+ return DATA_BYTES;
+
+ // CK_DATE data
+ case CKA_START_DATE:
+ case CKA_END_DATE:
+ return DATA_DATE;
+
+ // Arrays are nasty
+ case CKA_WRAP_TEMPLATE:
+ case CKA_ALLOWED_MECHANISMS:
+ case CKA_UNWRAP_TEMPLATE:
+ default:
+ return DATA_UNKNOWN;
+ };
+}
+
+CK_RV
+attribute_fill(CK_ATTRIBUTE_PTR attr, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR* val, CK_ULONG len)
+{
+ ASSERT(attr);
+ ASSERT(val);
+ ASSERT(len);
+
+ attr->type = type;
+
+ if(attr->pValue && attr->ulValueLen < len)
+ {
+ attr->ulValueLen = len;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ else if(!attr->pValue)
+ {
+ attr->ulValueLen = len;
+ return CKR_OK;
+ }
+
+ else
+ {
+ memcpy(attr->pValue, &val, len);
+ attr->ulValueLen = len;
+ return CKR_OK;
+ }
+}
+
+CK_RV
+attribute_match(CK_ATTRIBUTE_PTR attr, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR* val, CK_ULONG len)
+{
+ ASSERT(attr);
+ ASSERT(val);
+ ASSERT(len);
+
+ if(attr->pValue && attr->ulValueLen == len &&
+ memcmp(attr->pValue, &val, len);
+ return CKR_OK;
+ return CKR_CANCEL;
+}
+
+/* --------------------------------------------------------------------------
+ * CERTIFICATES
+ */
+
+static CK_RV
+cert_bool_attribute(CK_ATTRIBUTE_TYPE type, PCCERT_CONTEXT cert,
+ CK_ATTRIBUTE_PTR attr, CK_BBOOL fill)
+{
+ CK_BBOOL val;
+ switch(type)
+ {
+ /*
+ * Resides on the token
+ * - Always true for CAPI objects.
+ */
+ case CKA_TOKEN:
+ val = CK_TRUE;
+ break;
+
+ /*
+ * Private vs. Public object.
+ * - Always false for certificates.
+ */
+ case CKA_PRIVATE:
+ val = CK_FALSE;
+ break;
+
+ /*
+ * If object can be modified.
+ * - Currently always false. In the future with additional
+ * functionality this may change.
+ */
+ case CKA_MODIFIABLE:
+ val = CK_FALSE;
+ break;
+
+ /*
+ * Whether the certificate can be trusted for the application
+ * in which it was created.
+ * - Use CertGetCertificateChain to build up a chain
+ * for this certificate, and then look in the CERT_CHAIN_CONTEXT
+ * TrustStatus field.
+ */
+ case CKA_TRUSTED:
+ /* TODO: Implement */
+
+ default:
+ return CK_CANCEL;
+ };
+
+ if(fill)
+ return attribute_fill(attr, type, &val, sizeof(CK_BBOOL));
+ else
+ return attribute_match(attr, type, &val, sizeof(CK_BBOOL));
+}
+
+static CK_RV
+cert_ulong_attribute(CK_ATTRIBUTE_TYPE type, PCCERT_CONTEXT cert,
+ CK_ATTRIBUTE_PTR attr, CK_BBOOL fill)
+{
+ CK_ULONG val;
+ switch(type)
+ {
+
+ /*
+ * Object class.
+ * - Always CKO_CERTIFICATE for certificates.
+ */
+ case CKA_OBJECT_CLASS:
+ val = CKO_CERTIFICATE;
+ break;
+
+ /*
+ * Type of certificate.
+ * - Always X509.
+ */
+ case CKA_CERTIFICATE_TYPE:
+ val = CKC_X_509;
+ break;
+
+ /*
+ * Whether a CA, user certificate, other.
+ * - Get certificate szOID_ENHANCED_KEY_USAGE
+ * extension or CERT_CTL_PROP_ID and look into CTL_USAGE structure.
+ */
+ case CKA_CERTIFICATE_CATEGORY:
+ /* TODO: Implement */
+
+ default:
+ return CK_CANCEL;
+ };
+
+ if(fill)
+ return attribute_fill(attr, type, &val, sizeof(CK_ULONG));
+ else
+ return attribute_match(attr, type, &val, sizeof(CK_ULONG));
+}
+
+static CK_RV
+cert_bytes_attribute(CK_ATTRIBUTE_TYPE type, PCCERT_CONTEXT cert,
+ CK_ATTRIBUTE_PTR attr, CK_BBOOL fill)
+{
+ switch(type)
+ {
+
+ /*
+ * Description of the object.
+ * - We use CAPI's CERT_FRIENDLY_NAME_PROP_ID property,
+ * converted into UTF8.
+ */
+ case CKA_LABEL:
+ xxxxx
+ break;
+
+ /*
+ * A byte array unique to this certificate. The CKA_ID of
+ * matching certificates and private keys should match.
+ * Should match the key identifier in an X.509v3 certificate.
+ *
+ * We use CAPI's CERT_KEY_IDENTIFIER_PROP_ID property directly.
+ */
+ case CKA_ID:
+ xxxxx
+ break;
+
+ /*
+ * DER-encoding of the certificate subject name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Subject field
+ * directly.
+ */
+ case CKA_SUBJECT:
+ xxxxx
+ break;
+
+ /*
+ * DER-encoding of the certificate issuer name.
+ *
+ * We use CAPI's CERT_CONTEXT pCertInfo->Issuer field
+ * directly.
+ */
+ case CKA_ISSUER:
+ xxxxx
+ break;
+
+ /*
+ * DER-encoding of the certificate serial number.
+ *
+ * TODO:
+ * BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
+ * X509_MULTI_BYTE_INTEGER,
+ * &certContext->pCertInfo->SerialNumber,
+ * co->derSerial,
+ * &size);
+ */
+ case CKA_SERIAL_NUMBER:
+ xxxxx
+ break;
+
+ /*
+ * BER-encoding of the full certificate.
+ *
+ * We use CAPI's CERT_CONTEXT pbCertEncoded field directly.
+ */
+ case CKA_VALUE:
+ xxxxx
+ break;
+
+ /*
+ * If CKA_VALUE not specified, this is where the full
+ * certificate can be found.
+ *
+ * We don't support this. All our certificates are present
+ * in full.
+ */
+ case CKA_URL:
+ break;
+
+ /*
+ * Checksum
+ * - TODO: Work out what to do here
+ */
+ case CKA_CHECKSUM:
+ break;
+
+ /*
+ * TODO: Should we support these?
+ */
+ CKA_HASH_OF_SUBJECT_PUBLIC_KEY
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY
+ break;
+
+ /* Not supported */
+
+ default:
+ break
+ };
+};
+
+static xxx
+cert_date_attribute()
+{
+ switch(type)
+ {
+
+ /*
+ * Start date for the certificate.
+ * - TODO: Work out where to get this.
+ */
+ pCertInfo->NotBefore;
+ case CKA_START_DATE:
+ xxxx;
+ break;
+
+ /*
+ * End date for the certificate.
+ * - TODO: Work out where to get this.
+ */
+ pCertInfo->NotAfter;
+ case CKA_END_DATE:
+ xxxx;
+ break;
+ };
+}
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+static CK_RV
+cert_ulong_attribute(CK_ATTRIBUTE_TYPE type, PCCERT_CONTEXT cert,
+ CK_ATTRIBUTE_PTR attr)
+{
+ CK_ATTRIBUTE_PTR ret;
+ CK_BBOOL val;
+
+ switch(type)
+ {
+ case CKA_TOKEN:
+ val = CK_TRUE;
+ break;
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ val = CK_FALSE;
+ break;
+ };
+
+ /* If attr is initialized, just do a match */
+ if(attr.type == type)
+ {
+ if(attr->pValue && attr->ulValueLen == sizeof(CK_BBOOL) &&
+ memcmp(attr->pValue, &val, sizeof(CK_BBOOL));
+ return CKR_OK;
+ return CKR_CANCEL;
+ }
+
+ /* Otherwise fill in the value */
+ else
+ {
+ return prep_attribute(attr, type, &val, sizeof(CK_BBOOL);
+ }
+}
+
+static CK_ATTRIBUTE_PTR
+cert_load_attribute(CK_ATTRIBUTE_TYPE type, PCCERT_CONTEXT cert)
+{
+ CK_BBOOL vval = CK_FALSE;
+ CK_ULONG uval = 0;
+ CK_VOID_PTR val;
+ CK_ULONG n_val;
+
+ switch(type)
+ {
+ case CKA_CLASS:
+ uval = CKO_CERTIFICATE;
+ break;
+ case CKA_TOKEN;
+
+ }
+}
+
+static CK_BBOOL
+cert_match_attr(CK_ATTRIBUTE_PTR match, PCCERT_CONTEXT cert)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_BBOOL ret;
+
+ attr = cert_load_attribute(match->type, cert);
+ if(!attr)
+ return CK_FALSE;
+
+ ret = (attr->ulValueLen == match->ulValueLen &&
+ memcmp(attr->pValue, match->pValue, attr->ulValueLen) == 0);
+
+ free_attribute(attr);
+ return ret;
+}
+
+static CK_BBOOL
+cert_match(CK_ATTRIBUTE_PTR matches, CK_ULONG count,
+ PCCERT_CONTEXT cert)
+{
+ CK_ULONG i;
+
+ for(i = 0; i < count; ++i)
+ {
+ if(!cert_match_attr(&match[i], cert))
+ return CK_FALSE;
+ }
+
+ return CK_TRUE;
+}
+
+static CK_RV
+gather_store_certs(const char* store_name, Array* arr,
+ CK_ATTRIBUTE_PTR match, CK_ULONG count)
+{
+ PCCERT_CONTEXT cert = NULL;
+ CK_OBJECT_HANDLE obj;
+ HCERTSTORE store;
+ DWORD err;
+ CK_RV ret = CKR_OK;
+
+ store = CertOpenSystemStore((HCRYPTPROV)NULL, store_name);
+ if(store == NULL)
+ {
+ err = GetLastError();
+
+ /* Store not found, we don't care */
+ if(err == ERROR_FILE_NOT_FOUND)
+ return CKR_OK;
+
+ else
+ return ckcapi_winerr_to_ckr(err);
+ }
+
+ /* Match each certificate */
+ while((cert = CertEnumCertificatesInStore(store, cert)) != NULL)
+ {
+ if(match_cert(match, count, cert))
+ {
+ obj = register_cert(store, cert);
+ if(!obj)
+ {
+ ret = CKR_HOST_MEMORY;
+ break;
+ }
+
+ ckcapi_util_array_append(arr, obj);
+ }
+ }
+
+ ASSERT(store);
+ CertCloseStore(store, 0);
+
+ return ret;
+}
+
+/* ----------------------------------------------------------------------------
+ * FIND
+ */
+
+BOOL
+get_ulong_attribute(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE_PTR templ,
+ CK_ULONG count, CK_ULONG* val)
+{
+ CK_ULONG i;
+
+ ASSERT(val);
+ ASSERT(!count || templ);
+
+ for(i = 0; i < count; ++i)
+ {
+ if(templ[i].type == type)
+ {
+ *val = *((CK_ULONG*)templ[i].pValue);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
+
+CK_RV
+gather_objects(Array* arr, CK_ATTRIBUTE_PTR match, CK_ULONG count)
+{
+ CK_OBJECT_CLASS ocls = CK_INVALID_HANDLE;
+ CK_RV ret = CKR_OK;
+
+ get_ulong_attribute(CKA_CLASS, match, count, &ocls);
+ switch(ocls)
+ {
+ /* all different classes */
+ case CK_INVALID_HANDLE:
+ case CKO_CERTIFICATE:
+ ret = gather_certificates(arr, match, count);
+ break;
+ case CKO_PUBLIC_KEY:
+ case CKO_PRIVATE_KEY:
+ default:
+ break;
+ };
+
+ return ret;
+}
+
+void
+cleanup_find_operation(Session* sess)
+{
+ ASSERT(sess->operation_type == OPERATION_FIND);
+ if(sess->operation_data)
+ ckcapi_util_array_free((Array*)sess->operation_data, TRUE);
+ sess->operation_type = OPERATION_NONE;
+ sess->operation_data = NULL;
+ sess->operation_cancel = NULL;
+}
+
+CK_RV
+ckcapi_object_find_init(Session* sess, CK_ATTRIBUTE_PTR match,
+ CK_ULONG count)
+{
+ Array* arr;
+ CK_RV ret;
+
+ ASSERT(sess);
+ ASSERT(!count || match);
+
+ if(sess->operation_type != OPERATION_NONE)
+ return CKR_OPERATION_ACTIVE;
+
+ arr = ckcapi_util_array_new(0, 1, sizeof(CK_OBJECT_HANDLE));
+ if(!arr)
+ return CKR_HOST_MEMORY;
+
+ ret = gather_objects(arr, match, count);
+ if(ret != CKR_OK)
+ {
+ ckcapi_util_array_free(arr, TRUE);
+ return ret;
+ }
+
+ sess->operation_type = OPERATION_FIND;
+ sess->operation_data = arr;
+ sess->operation_cancel = cleanup_find_operation;
+
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_object_find(Session* sess, CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_object_count, CK_ULONG_PTR object_count)
+{
+ Array* arr;
+ size_t i;
+
+ ASSERT(sess);
+ ASSERT(object_count);
+ ASSERT(!max_object_count || objects);
+
+ if(sess->operation_type != OPERATION_FIND)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if(!max_object_count)
+ {
+ *object_count = 0;
+ return CKR_OK;
+ }
+
+ arr = (Array*)sess->operation_data;
+ *object_count = (max_object_count > arr->len ? arr->len : max_object_count);
+ for(i = 0; i < *object_count; ++i)
+ objects[i] = ckcapi_util_array_index(arr, CK_OBJECT_HANDLE, i);
+ ckcapi_util_array_remove_range(arr, 0, *object_count);
+
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_objects_find_final(Session* sess)
+{
+ ASSERT(sess);
+
+ if(sess->operation_type != OPERATION_FIND)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ cleanup_find_operation(sess);
+ return CKR_OK;
+}
+
diff --git a/ckcapi-session.c b/ckcapi-session.c
new file mode 100644
index 0000000..dc700c1
--- /dev/null
+++ b/ckcapi-session.c
@@ -0,0 +1,329 @@
+
+#include <stdlib.h>
+
+#include "cryptoki-capi.h"
+
+typedef struct _SessionList {
+ Session **list;
+ size_t lmax;
+} SessionList;
+
+/* These are protected by global_mutex */
+static SessionList the_sessions = { NULL, 0 };
+
+
+Session*
+ckcapi_session_create(void)
+{
+ Session* sess = calloc(1, sizeof(Session));
+ if(!sess)
+ return NULL;
+
+ sess->mutex = CreateMutex(NULL, FALSE, NULL);
+ if(!sess->mutex)
+ {
+ free(sess);
+ return NULL;
+ }
+
+ DBGS(sess, "created");
+ return sess;
+}
+
+CK_RV
+ckcapi_session_register(Session* sess)
+{
+ CK_ULONG id = 0;
+ CK_RV ret = CKR_OK;
+ size_t i;
+
+ ASSERT(sess);
+ ASSERT(sess->id == 0 && sess->refs == 0);
+
+ DBGS(sess, "registering new session");
+
+ ckcapi_lock_global();
+
+ /* Find a nice session identifier */
+ while(id == 0) {
+
+ /*
+ * PKCS#11 GRAY AREA: We're assuming we can reuse session
+ * handles. PKCS#11 spec says they're like file handles,
+ * and file handles get reused :)
+ */
+
+ /* Note we never put anything in array position '0' */
+ for(i = 1; i < the_sessions.lmax; ++i)
+ {
+ /* Any empty position will do */
+ if(!the_sessions.list[i])
+ {
+ id = i;
+ break;
+ }
+ }
+
+ /* Couldn't find a handle, reallocate */
+ if(id == 0)
+ {
+ Session** buf;
+ size_t oldmax, newmax;
+
+ oldmax = the_sessions.lmax;
+ newmax = oldmax + 16;
+
+ buf = realloc(the_sessions.list, newmax * sizeof(Session*));
+ if(!buf)
+ {
+ DBGS(sess, ("couldn't allocate session list, out of memory"));
+ ret = CKR_HOST_MEMORY;
+ break;
+ }
+
+ /* Choose the first of the new block as the id */
+ id = oldmax;
+
+ /* Clear new memory */
+ the_sessions.list = buf;
+ for( ; oldmax < newmax; ++oldmax)
+ buf[oldmax] = NULL;
+ the_sessions.lmax = newmax;
+
+ DBG(("allocated new session list: %d max", newmax));
+ }
+ }
+
+ if(ret == CKR_OK)
+ {
+ ASSERT(id > 0 && id < the_sessions.lmax);
+ ASSERT(the_sessions.list[id] == NULL);
+
+ /* And assign it to the session handle */
+ the_sessions.list[id] = sess;
+ sess->id = id;
+
+ /* The session list reference */
+ ASSERT(sess->refs == 0);
+ sess->refs++;
+
+ DBGS(sess, "registered sesson id");
+ }
+
+ ckcapi_unlock_global();
+
+ return ret;
+}
+
+void
+ckcapi_session_destroy(Session* sess)
+{
+ ASSERT(sess);
+ ASSERT(sess->refs == 0);
+
+ /* Ask any pending operations to cleanup */
+ if(sess->operation_type)
+ {
+ ASSERT(sess->operation_cancel);
+ (sess->operation_cancel)(sess);
+ }
+
+ ASSERT(sess->operation_type == 0);
+ ASSERT(sess->operation_data == NULL);
+ ASSERT(sess->operation_cancel == NULL);
+
+ /* And make the mutex go away */
+ ASSERT(sess->mutex != NULL);
+ CloseHandle(sess->mutex);
+
+ DBGS(sess, "destroyed");
+ free(sess);
+}
+
+static CK_RV
+find_lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id,
+ int remove, Session** sess_ret)
+{
+ Session *sess;
+ DWORD r;
+
+ ASSERT(sessions);
+ ASSERT(sess_ret);
+
+ if(id >= sessions->lmax)
+ {
+ DBG(("invalid session id: %d", id));
+ return CKR_SESSION_HANDLE_INVALID;
+ }
+
+ /* A seemingly valid id */
+ ASSERT(sessions->list);
+ sess = sessions->list[id];
+
+ if(!sess)
+ {
+ DBG(("session does not exist: %d", id));
+ return CKR_SESSION_HANDLE_INVALID;
+ }
+
+ ASSERT(sess->id == id);
+
+ /* Closing takes precedence over active operations */
+ if(!remove)
+ {
+ /*
+ * An initial check is done to make sure this session is not active.
+ * This is done outside of the lock. The real check is done later
+ * inside a lock. This is so we can return quickly without blocking
+ * in most cases.
+ */
+
+ if(sess->in_call)
+ {
+ DBGS(sess, ("an operation is already active in this session"));
+ return CKR_OPERATION_ACTIVE;
+ }
+ }
+
+ /* Lock the CallSession */
+ r = WaitForSingleObject(sess->mutex, INFINITE);
+ ASSERT(r == WAIT_OBJECT_0);
+
+ /* Do the real check */
+ if(!remove && sess->in_call)
+ {
+ ReleaseMutex(sess->mutex);
+ DBGS(sess, ("an operation is already active in this session"));
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ /* Make sure it doesn't go away */
+ ASSERT(sess->refs > 0);
+ sess->refs++;
+
+ DBGS(sess, "found and locked session");
+
+ /* And remove it if necessary */
+ if(remove)
+ {
+ sessions->list[id] = NULL;
+
+ /* The session list reference */
+ sess->refs--;
+ ASSERT(sess->refs > 0);
+
+ DBGS(sess, "removed session from list");
+ }
+ else
+ {
+ ASSERT(!sess->in_call);
+ sess->in_call = 1;
+ }
+
+ *sess_ret = sess;
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_session_find_lock_ref(CK_ULONG id, int remove, Session **sess)
+{
+ /* This must be called without any locks held */
+
+ CK_RV ret = CKR_OK;
+
+ ASSERT(sess);
+
+ if(id <= 0)
+ {
+ DBG(("invalid session id passed: %d", id));
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ ckcapi_lock_global();
+
+ ret = find_lock_ref_internal (&the_sessions, id, remove, sess);
+
+ ckcapi_unlock_global();
+
+ return ret;
+}
+
+void
+ckcapi_session_unref_unlock(Session* sess)
+{
+ /* The CallSession must be locked at this point */
+
+ int refs;
+ BOOL r;
+
+ ASSERT(sess);
+
+ ASSERT(sess->refs > 0);
+ sess->refs--;
+ refs = sess->refs;
+
+ sess->in_call = 0;
+
+ DBGS(sess, "unlocked session");
+
+ r = ReleaseMutex(sess->mutex);
+ ASSERT(r == TRUE);
+
+ /*
+ * At this point if no references are held, then we can safely
+ * delete. No other thread should be involved.
+ */
+
+ if(refs == 0)
+ ckcapi_session_destroy(sess);
+}
+
+void
+ckcapi_session_close_all()
+{
+ /* This must be called without any locks held */
+
+ SessionList sessions;
+ Session *sess;
+ size_t i;
+ CK_RV ret;
+
+ /*
+ * PKCS#11 GRAY AREA: What happens when this gets called
+ * concurrently? We don't return an error on the second call,
+ * because by the time it returns, all sessions should be closed.
+ */
+
+ ckcapi_lock_global();
+
+ /* Steal all the session data */
+ sessions.list = the_sessions.list;
+ the_sessions.list = NULL;
+ sessions.lmax = the_sessions.lmax;
+ the_sessions.lmax = 0;
+
+ if(sessions.list || sessions.lmax)
+ DBG(("closing all sessions"));
+
+ ckcapi_unlock_global();
+
+ /* Close each session in turn */
+ for(i = 1; i < sessions.lmax; ++i)
+ {
+ if(!sessions.list[i])
+ continue;
+
+ ret = find_lock_ref_internal (&sessions, i, 1, &sess);
+ ASSERT(ret == CKR_OK);
+
+ ckcapi_session_unref_unlock(sess);
+ }
+
+ /* We stole the memory above, free it now */
+ if(sessions.list)
+ {
+ free(sessions.list);
+ DBG(("freed session list"));
+ }
+}
+
diff --git a/ckcapi-util.c b/ckcapi-util.c
new file mode 100644
index 0000000..d8d182b
--- /dev/null
+++ b/ckcapi-util.c
@@ -0,0 +1,167 @@
+
+#include "cryptoki-capi-util.h"
+
+#include <string.h>
+
+
+
+
+
+#define MIN_ARRAY_SIZE 16
+
+typedef struct _RealArray
+{
+ Array pub;
+ size_t alloc;
+ size_t elt_size;
+ int zero_terminated : 1;
+ int clear : 1;
+}
+RealArray;
+
+#define array_elt_len(array, i) ((array)->elt_size * (i))
+#define array_elt_pos(array, i) (((char*)(array)->pub.data) + array_elt_len((array),(i)))
+#define array_elt_zero(array, pos, len) \
+ (memset(array_elt_pos((array), pos), 0, array_elt_len((array), len)))
+#define array_zero_terminate(array) \
+ { if ((array)->zero_terminated) \
+ array_elt_zero((array), (array)->pub.len, 1); }
+
+static unsigned int
+nearest_pow(unsigned int num)
+{
+ unsigned int n = 1;
+ while(n < num)
+ n <<= 1;
+ return n;
+}
+
+static int
+maybe_expand(RealArray *array, size_t len)
+{
+ void* mem;
+ size_t want_alloc = array_elt_len(array, array->pub.len + len +
+ array->zero_terminated);
+
+ if(want_alloc > array->alloc)
+ {
+ want_alloc = nearest_pow(want_alloc);
+ want_alloc = want_alloc > MIN_ARRAY_SIZE ? want_alloc : MIN_ARRAY_SIZE;
+
+ mem = realloc(array->pub.data, want_alloc);
+ if(!mem)
+ return 0;
+ array->pub.data = mem;
+
+ memset((char*)array->pub.data + array->alloc, 0, want_alloc - array->alloc);
+ array->alloc = want_alloc;
+ }
+
+ return 1;
+}
+
+Array*
+ckcapi_util_array_new(int zero_terminated, int clear, size_t elt_size)
+{
+ return ckcapi_util_array_sized_new(zero_terminated, clear, elt_size, 0);
+}
+
+Array*
+ckcapi_util_array_sized_new(int zero_terminated, int clear, size_t elt_size,
+ size_t reserved_size)
+{
+ RealArray *array = malloc(sizeof(RealArray));
+ if(!array)
+ return NULL;
+
+ array->pub.data = NULL;
+ array->pub.len = 0;
+ array->alloc = 0;
+ array->zero_terminated = (zero_terminated ? 1 : 0);
+ array->clear = (clear ? 1 : 0);
+ array->elt_size = elt_size;
+
+ if(array->zero_terminated || reserved_size != 0)
+ {
+ maybe_expand(array, reserved_size);
+ array_zero_terminate(array);
+ }
+
+ return (Array*)array;
+}
+
+void*
+ckcapi_util_array_free(Array* array, int free_segment)
+{
+ void* segment;
+
+ if(array == NULL)
+ return NULL;
+
+ if(free_segment)
+ {
+ free(array->data);
+ segment = NULL;
+ }
+ else
+ segment = array->data;
+
+ free(array);
+ return segment;
+}
+
+int
+ckcapi_util_array_append_vals(Array* parray, const void* data, size_t len)
+{
+ RealArray* array = (RealArray*)parray;
+ if(!maybe_expand(array, len))
+ return 0;
+
+ memcpy(array_elt_pos(array, array->pub.len), data,
+ array_elt_len(array, len));
+
+ array->pub.len += len;
+ array_zero_terminate(array);
+
+ return 1;
+}
+
+void
+ckcapi_util_array_remove_index(Array* parray, unsigned int index)
+{
+ RealArray* array = (RealArray*)parray;
+
+ if(index >= array->pub.len)
+ return;
+
+ if(index != array->pub.len - 1)
+ memmove(array_elt_pos (array, index),
+ array_elt_pos (array, index + 1),
+ array_elt_len (array, array->pub.len - index - 1));
+
+ array->pub.len -= 1;
+
+ array_elt_zero (array, array->pub.len, 1);
+}
+
+void
+ckcapi_util_array_remove_range(Array* parray, unsigned int index, size_t length)
+{
+ RealArray *array = (RealArray*)parray;
+
+ if(index >= array->pub.len)
+ return;
+ if(index + length > array->pub.len);
+ length = array->pub.len - index;
+ if(length == 0)
+ return;
+
+ if(index + length != array->pub.len)
+ memmove(array_elt_pos (array, index),
+ array_elt_pos (array, index + length),
+ (array->pub.len - (index + length)) * array->elt_size);
+
+ array->pub.len -= length;
+ array_elt_zero(array, array->pub.len, length);
+}
+
diff --git a/ckcapi-util.h b/ckcapi-util.h
new file mode 100644
index 0000000..b37ea39
--- /dev/null
+++ b/ckcapi-util.h
@@ -0,0 +1,46 @@
+
+#ifndef __CKCAPI_UTIL_H__
+#define __CKCAPI_UTIL_H__
+
+#include <stdlib.h>
+
+/* --------------------------------------------------------------------------------
+ * WINDOWS
+ */
+
+CK_RV ckcapi_util_win_to_cryptoki_err (DWORD werr);
+
+
+/* --------------------------------------------------------------------------------
+ * ARRAYS
+ */
+
+typedef struct _Array
+{
+ void* data;
+ size_t len;
+}
+Array;
+
+#define ckcapi_util_array_append(a,v) \
+ ckcapi_util_array_append_vals(a, &(v), 1)
+#define ckcapi_util_array_index(a,t,i) \
+ (((t*) (a)->data) [(i)])
+
+Array* ckcapi_util_array_new (int zero_terminated, int zero,
+ size_t element_size);
+
+Array* ckcapi_util_array_sized_new (int zero_terminated, int zero,
+ size_t element_size, size_t reserved_size);
+
+void* ckcapi_util_array_free (Array* array, int free_segment);
+
+int ckcapi_util_array_append_vals (Array* array, const void* data,
+ size_t num);
+
+void ckcapi_util_array_remove_index (Array* array, unsigned int index);
+
+void ckcapi_util_array_remove_range (Array* array, unsigned int index,
+ size_t count);
+
+#endif /* __CKCAPI_UTIL_H__ */ \ No newline at end of file
diff --git a/cryptoki-capi.c b/cryptoki-capi.c
new file mode 100644
index 0000000..b100e25
--- /dev/null
+++ b/cryptoki-capi.c
@@ -0,0 +1,1149 @@
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "cryptoki-capi.h"
+
+/* -------------------------------------------------------------------
+ * GLOBALS / DEFINES
+ */
+
+/* TODO: Use a random number */
+static CK_ULONG slot_id = 33;
+static int cryptoki_initialized = 0;
+static HANDLE global_mutex = NULL;
+
+#define CRYPTOKI_VERSION_MAJOR 2
+#define CRYPTOKI_VERSION_MINOR 11
+#define MANUFACTURER_ID "Cryptoki CAPI "
+#define LIBRARY_DESCRIPTION "Cryptoki CAPI Provider "
+#define LIBRARY_VERSION_MAJOR 1
+#define LIBRARY_VERSION_MINOR 1
+#define SLOT_DESCRIPTION "Windows CAPI Certificates and Keys "
+#define HARDWARE_VERSION_MAJOR 0
+#define HARDWARE_VERSION_MINOR 0
+#define FIRMWARE_VERSION_MAJOR 0
+#define FIRMWARE_VERSION_MINOR 0
+#define SLOT_TOKEN_SERIAL "1.0 "
+#define SLOT_TOKEN_MODEL "1.0 "
+#define MAX_PIN_LEN 256
+#define MIN_PIN_LEN 1
+
+/* -------------------------------------------------------------------
+ * MODULE GLOBAL FUNCTIONS
+ */
+
+void
+ckcapi_debug(const char* msg, ...)
+{
+ char buf[1024];
+ va_list va;
+
+ va_start(va, msg);
+ _vsnprintf(buf, 1024, msg, va);
+ va_end(va);
+
+ OutputDebugStringA(buf);
+}
+
+/* Bah humbug, MSVC doesn't have __func__ */
+#define ENTER(func) \
+ char* _func = #func; \
+ ckcapi_debug("%s: enter", _func)
+
+#define RETURN(ret) \
+ return (ckcapi_debug("%s: %d", _func, ret), ret)
+
+#define PREREQ(cond, ret) \
+ if (!(cond)) { ckcapi_debug("%s: %s failed: %d", _func, #cond, ret); return ret; }
+
+void
+ckcapi_lock_global(void)
+{
+ DWORD r;
+
+ ASSERT(global_mutex);
+
+ r = WaitForSingleObject(global_mutex, INFINITE);
+ ASSERT(r == WAIT_OBJECT_0);
+}
+
+void
+ckcapi_unlock_global(void)
+{
+ BOOL r;
+
+ ASSERT(global_mutex);
+
+ r = ReleaseMutex(global_mutex);
+ ASSERT(r);
+}
+
+CK_RV
+ckcapi_winerr_to_ckr(DWORD werr)
+{
+ switch(werr)
+ {
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return CKR_HOST_MEMORY;
+ break;
+ case NTE_NO_MEMORY:
+ return CKR_DEVICE_MEMORY;
+ break;
+ case ERROR_MORE_DATA:
+ return CKR_BUFFER_TOO_SMALL;
+ case ERROR_INVALID_PARAMETER: /* these params were derived from the */
+ case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */
+ case NTE_BAD_ALGID: /* data is bad */
+ case NTE_BAD_HASH:
+ return CKR_DATA_INVALID;
+ break;
+ case ERROR_BUSY:
+ case NTE_FAIL:
+ case NTE_BAD_UID:
+ return CKR_DEVICE_ERROR;
+ break;
+ default:
+ return CKR_GENERAL_ERROR;
+ };
+}
+
+
+/* ---------------------------------------------------------------- */
+
+static CK_RV
+CC_C_Initialize(CK_VOID_PTR init_args)
+{
+ ENTER(C_Initialize);
+ PREREQ(!cryptoki_initialized, CKR_CRYPTOKI_ALREADY_INITIALIZED);
+
+ if (init_args != NULL) {
+ CK_C_INITIALIZE_ARGS_PTR args;
+ int supplied_ok;
+
+ /* pReserved must be NULL */
+ args = init_args;
+ PREREQ(!args->pReserved, CKR_ARGUMENTS_BAD);
+
+ /* ALL supplied function pointers need to have the value either NULL or non-NULL. */
+ supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
+ args->LockMutex == NULL && args->UnlockMutex == NULL) ||
+ (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
+ args->LockMutex != NULL && args->UnlockMutex != NULL);
+ PREREQ(supplied_ok, CKR_ARGUMENTS_BAD);
+
+ /*
+ * When the CKF_OS_LOCKING_OK flag isn't set and mutex function pointers are supplied
+ * by an application, return an error. DBus must be able to use its own locks.
+ */
+ if(!(args->flags & CKF_OS_LOCKING_OK) && (args->CreateMutex != NULL))
+ RETURN(CKR_CANT_LOCK);
+ }
+
+ if(!global_mutex)
+ {
+ global_mutex = CreateMutex(NULL, FALSE, NULL);
+ if(!global_mutex)
+ RETURN(CKR_CANT_LOCK);
+ }
+
+ cryptoki_initialized = 1;
+
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_Finalize(CK_VOID_PTR pReserved)
+{
+ ENTER(C_Finalize);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ cryptoki_initialized = 0;
+
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetInfo(CK_INFO_PTR info)
+{
+ ENTER(C_GetInfo);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(info, CKR_ARGUMENTS_BAD);
+
+ ASSERT(strlen(MANUFACTURER_ID) == 32);
+ ASSERT(strlen(LIBRARY_DESCRIPTION) == 32);
+
+ info->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
+ info->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
+ info->libraryVersion.major = LIBRARY_VERSION_MAJOR;
+ info->libraryVersion.minor = LIBRARY_VERSION_MINOR;
+ info->flags = 0;
+ strncpy((char*)info->manufacturerID, MANUFACTURER_ID, 32);
+ strncpy((char*)info->libraryDescription, LIBRARY_DESCRIPTION, 32);
+
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list)
+{
+ /* This would be a strange call to receive */
+ return C_GetFunctionList(list);
+}
+
+static CK_RV
+CC_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR slot_list, CK_ULONG_PTR count)
+{
+ ENTER(C_GetSlotList);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(count, CKR_ARGUMENTS_BAD);
+
+ /* Token is always present */
+
+ /* Application only wants to know the number of slots. */
+ if(slot_list == NULL)
+ {
+ *count = 1;
+ RETURN(CKR_OK);
+ }
+
+ if((*count < 1) && (slot_list != NULL))
+ {
+ *count = 1;
+ RETURN(CKR_BUFFER_TOO_SMALL);
+ }
+
+ *count = 1;
+ slot_list[0] = slot_id;
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetSlotInfo(CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
+{
+ ENTER(C_GetSlotInfo);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(info, CKR_ARGUMENTS_BAD);
+
+ /* Make sure the slot ID is valid */
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ ASSERT(strlen(SLOT_DESCRIPTION) == 64);
+ ASSERT(strlen(MANUFACTURER_ID) == 32);
+
+ /* Provide information about the slot in the provided buffer */
+ strncpy((char*)info->slotDescription, SLOT_DESCRIPTION, 64);
+ strncpy((char*)info->manufacturerID, MANUFACTURER_ID, 32);
+ info->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
+ info->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
+ info->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
+ info->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
+
+ /* Token is always present */
+ info->flags = CKF_TOKEN_PRESENT;
+
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetTokenInfo(CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
+{
+ ENTER(C_GetTokenInfo);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(info, CKR_ARGUMENTS_BAD);
+
+ /* Make sure the slot ID is valid */
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ ASSERT(strlen(SLOT_DESCRIPTION) == 64);
+ ASSERT(strlen(MANUFACTURER_ID) == 32);
+ ASSERT(strlen(SLOT_TOKEN_MODEL) == 16);
+ ASSERT(strlen(SLOT_TOKEN_SERIAL) == 16);
+
+ /* Provide information about a token in the provided buffer */
+ strncpy((char*)info->label, SLOT_DESCRIPTION, 32);
+ strncpy((char*)info->manufacturerID, MANUFACTURER_ID, 32);
+ strncpy((char*)info->model, SLOT_TOKEN_MODEL, 16);
+ strncpy((char*)info->serialNumber, SLOT_TOKEN_SERIAL, 16);
+
+ /* Protected authentication path: Windows prompts for it's own PINs */
+ info->flags = CKF_TOKEN_INITIALIZED | CKF_PROTECTED_AUTHENTICATION_PATH;
+ info->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
+ info->ulSessionCount = CK_EFFECTIVELY_INFINITE;
+ info->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
+ info->ulRwSessionCount = CK_EFFECTIVELY_INFINITE;
+ info->ulMaxPinLen = MAX_PIN_LEN;
+ info->ulMinPinLen = MIN_PIN_LEN;
+ info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
+ info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
+ info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
+ info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
+ info->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
+ info->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
+ info->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
+ info->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
+ memset(info->utcTime, ' ', 16);
+
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetMechanismList(CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list,
+ CK_ULONG_PTR count)
+{
+ ENTER(C_GetMechanismList);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(count, CKR_ARGUMENTS_BAD);
+
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ if(mechanism_list == NULL)
+ {
+ *count = 1;
+ RETURN(CKR_OK);
+ }
+
+ if(*count < 1)
+ {
+ *count = 1;
+ RETURN(CKR_BUFFER_TOO_SMALL);
+ }
+
+ mechanism_list[0] = CKM_RSA_PKCS;
+ *count = 1;
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetMechanismInfo(CK_SLOT_ID id, CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR info)
+{
+ ENTER(C_GetMechanismInfo);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(info, CKR_ARGUMENTS_BAD);
+
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ /* unsupported mechanism */
+ if(type != CKM_RSA_PKCS)
+ RETURN(CKR_MECHANISM_INVALID);
+
+ info->ulMinKeySize = 384;
+ info->ulMaxKeySize = 16384;
+ info->flags = 0; /* TODO: Choose which we'll implement */
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_InitToken(CK_SLOT_ID slot_id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len,
+ CK_UTF8CHAR_PTR label)
+{
+ ENTER(C_InitToken);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
+{
+ ENTER(C_WaitForSlotEvent);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /*
+ * PKCS#11 GRAY AREA: What happens when we know we'll *never*
+ * have any slot events, and someone calls us without CKR_DONT_BLOCK?
+ * In case there's a thread dedicated to calling this function in a
+ * loop, we wait 1 seconds when called without CKR_DONT_BLOCK.
+ */
+
+ if(!(flags & CKF_DONT_BLOCK))
+ Sleep(1000);
+
+ RETURN(CKR_NO_EVENT);
+}
+
+static CK_RV
+CC_C_OpenSession(CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR application,
+ CK_NOTIFY notify, CK_SESSION_HANDLE_PTR session)
+{
+ Session* sess;
+ CK_RV ret;
+
+ ENTER(C_OpenSession);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ sess = ckcapi_session_create();
+ if(sess == NULL)
+ RETURN(CKR_HOST_MEMORY);
+
+ sess->notify_callback = notify;
+ sess->user_data = application;
+
+ ret = ckcapi_session_register(sess);
+ if(ret == CKR_OK)
+ {
+ /* ID should have been assigned when registering */
+ ASSERT(sess->id > 0);
+ *session = sess->id;
+ }
+ else
+ {
+ ckcapi_session_destroy(sess);
+ }
+
+ RETURN(ret);
+}
+
+static CK_RV
+CC_C_CloseSession(CK_SESSION_HANDLE session)
+{
+ Session* sess;
+ CK_RV ret;
+
+ ENTER(C_CloseSession);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* The 'remove' flag removes it from the main session list */
+ ret = ckcapi_session_find_lock_ref(session, 1, &sess);
+ if(ret == CKR_OK)
+ {
+ /* This will unref and possibly destroy the session */
+ ckcapi_session_unref_unlock(sess);
+ }
+
+ RETURN(ret);
+}
+
+static CK_RV
+CC_C_CloseAllSessions(CK_SLOT_ID id)
+{
+ ENTER(C_CloseAllSession);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ if(id != slot_id)
+ RETURN(CKR_SLOT_ID_INVALID);
+
+ ckcapi_session_close_all();
+ RETURN(CKR_OK);
+}
+
+static CK_RV
+CC_C_GetFunctionStatus(CK_SESSION_HANDLE session)
+{
+ ENTER(C_GetFunctionStatus);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ RETURN(CKR_FUNCTION_NOT_PARALLEL);
+}
+
+static CK_RV
+CC_C_CancelFunction(CK_SESSION_HANDLE session)
+{
+ ENTER(C_CancelFunction);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ RETURN(CKR_FUNCTION_NOT_PARALLEL);
+}
+
+static CK_RV
+CC_C_GetSessionInfo(CK_SESSION_HANDLE session, CK_SESSION_INFO_PTR info)
+{
+ ENTER(C_GetSessionInfo);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ // TODO: Implement
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_InitPIN(CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len)
+{
+ ENTER(C_InitPIN);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* We don't support this stuff. We don't support 'SO' logins. */
+ RETURN(CKR_USER_NOT_LOGGED_IN);
+}
+
+static CK_RV
+CC_C_SetPIN(CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR old_pin,
+ CK_ULONG old_len, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_len)
+{
+ ENTER(C_SetPIN);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Not supported, Windows takes care of this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GetOperationState(CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state,
+ CK_ULONG_PTR operation_state_len)
+{
+ ENTER(C_GetOperationState);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Nasty, no sirrr */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SetOperationState(CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state,
+ CK_ULONG operation_state_len, CK_OBJECT_HANDLE encryption_key,
+ CK_OBJECT_HANDLE authentication_key)
+{
+ ENTER(C_SetOperationState);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Nasty, no sirrr */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Login(CK_SESSION_HANDLE session, CK_USER_TYPE user_type,
+ CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
+{
+ ENTER(C_Login);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement our local concept of logged in */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Logout(CK_SESSION_HANDLE session)
+{
+ ENTER(C_Logout);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement our local concept of logged in */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_CreateObject(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR templ,
+ CK_ULONG count, CK_OBJECT_HANDLE_PTR object)
+{
+ ENTER(C_CreateObject);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to support this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_CopyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR templ, CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object)
+{
+ ENTER(C_CopyObject);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to support this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+
+static CK_RV
+CC_C_DestroyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
+{
+ ENTER(C_DestroyObject);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to support this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GetObjectSize(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ULONG_PTR size)
+{
+ ENTER(C_GetObjectSize);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR templ, CK_ULONG count)
+{
+ ENTER(C_GetAttributeValue);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR templ, CK_ULONG count)
+{
+ ENTER(C_SetAttributeValue);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_FindObjectsInit(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR templ,
+ CK_ULONG count)
+{
+ Session* sess;
+ CK_RV ret;
+
+ ENTER(C_FindObjectsInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(!count || templ, CKR_ARGUMENTS_BAD);
+
+ ret = ckcapi_session_find_lock_ref(session, 0, &sess);
+ if(ret == CKR_OK)
+ {
+ ret = ckcapi_object_find_init(sess, templ, count);
+ ckcapi_session_unref_unlock(sess);
+ }
+
+ RETURN(ret);
+}
+
+static CK_RV
+CC_C_FindObjects(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_object_count, CK_ULONG_PTR object_count)
+{
+ Session* sess;
+ CK_RV ret;
+
+ ENTER(C_FindObjects);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ PREREQ(object_count, CKR_ARGUMENTS_BAD);
+ PREREQ(!max_object_count || objects, CKR_ARGUMENTS_BAD);
+
+ ret = ckcapi_session_find_lock_ref(session, 0, &sess);
+ if(ret == CKR_OK)
+ {
+ ret = ckcapi_object_find(sess, objects, max_object_count, object_count);
+ ckcapi_session_unref_unlock(sess);
+ }
+
+ RETURN(ret);
+}
+
+static CK_RV
+CC_C_FindObjectsFinal(CK_SESSION_HANDLE session)
+{
+ Session* sess;
+ CK_RV ret;
+
+ ENTER(C_FindObjectsFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ ret = ckcapi_session_find_lock_ref(session, 0, &sess);
+ if(ret == CKR_OK)
+ {
+ ret = ckcapi_objects_find_final(sess);
+ ckcapi_session_unref_unlock(sess);
+ }
+
+ RETURN(ret);
+}
+
+static CK_RV
+CC_C_EncryptInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_EncryptInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Encrypt(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len)
+{
+ ENTER(C_Encrypt);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_EncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part,
+ CK_ULONG part_len, CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len)
+{
+ ENTER(C_EncryptUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_EncryptFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR last_encrypted_part,
+ CK_ULONG_PTR last_encrypted_part_len)
+{
+ ENTER(C_EncryptFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DecryptInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_DecryptInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Decrypt(CK_SESSION_HANDLE session, CK_BYTE_PTR encrypted_data,
+ CK_ULONG encrypted_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
+{
+ ENTER(C_Decrypt);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DecryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR encrypted_part,
+ CK_ULONG encrypted_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len)
+{
+ ENTER(C_DecryptUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DecryptFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR last_part_len)
+{
+ ENTER(C_DecryptFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DigestInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism)
+{
+ ENTER(C_DigestInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Digest(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR digest, CK_ULONG_PTR digest_len)
+{
+ ENTER(C_Digest);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DigestUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
+{
+ ENTER(C_DigestUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DigestKey(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
+{
+ ENTER(C_DigestKey);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DigestFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len)
+{
+ ENTER(C_DigestFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_SignInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Sign(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
+{
+ ENTER(C_Sign);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
+{
+ ENTER(C_SignUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ ENTER(C_SignFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignRecoverInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_SignRecoverInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignRecover(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
+{
+ ENTER(C_SignRecover);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: Implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_VerifyInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_VerifyInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_Verify(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR signature, CK_ULONG signature_len)
+{
+ ENTER(C_Verify);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_VerifyUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
+{
+ ENTER(C_VerifyUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_VerifyFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
+ CK_ULONG signature_len)
+{
+ ENTER(C_VerifyFinal);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_VerifyRecoverInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ ENTER(C_VerifyRecoverInit);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_VerifyRecover(CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
+ CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
+{
+ ENTER(C_VerifyRecover);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DigestEncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part,
+ CK_ULONG part_len, CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len)
+{
+ ENTER(C_DigestEncryptUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DecryptDigestUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR encrypted_part,
+ CK_ULONG encrypted_part_len, CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ ENTER(C_DecryptDigestUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SignEncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part,
+ CK_ULONG part_len, CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len)
+{
+ ENTER(C_SignEncryptUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DecryptVerifyUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR encrypted_part,
+ CK_ULONG encrypted_part_len, CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ ENTER(C_DecryptVerifyUpdate);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GenerateKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR templ, CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ ENTER(C_GenerateKey);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Let key generation happen via Windows interfaces */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GenerateKeyPair(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR public_key_template, CK_ULONG public_key_attribute_count,
+ CK_ATTRIBUTE_PTR private_key_template, CK_ULONG private_key_attribute_count,
+ CK_OBJECT_HANDLE_PTR public_key, CK_OBJECT_HANDLE_PTR private_key)
+{
+ ENTER(C_GenerateKeyPair);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Let key generation happen via Windows interfaces */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_WrapKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key,
+ CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len)
+{
+ ENTER(C_WrapKey);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_UnwrapKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key,
+ CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR templ,
+ CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
+{
+ ENTER(C_UnwrapKey);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* TODO: See if we need to implement this */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_DeriveKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR templ,
+ CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
+{
+ ENTER(C_DeriveKey);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /* Can't do this with RSA */
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_SeedRandom(CK_SESSION_HANDLE session, CK_BYTE_PTR seed, CK_ULONG seed_len)
+{
+ ENTER(C_SeedRandom);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /*
+ * TODO: Perhaps at some point in the future we may want
+ * to see if we can hook into the Windows RNG
+ */
+
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static CK_RV
+CC_C_GenerateRandom(CK_SESSION_HANDLE session, CK_BYTE_PTR random_data,
+ CK_ULONG random_len)
+{
+ ENTER(C_GenerateRandom);
+ PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ /*
+ * TODO: Perhaps at some point in the future we may want
+ * to see if we can hook into the Windows RNG
+ */
+
+ RETURN(CKR_FUNCTION_NOT_SUPPORTED);
+}
+
+static struct CK_FUNCTION_LIST functionList = {
+ { 2, 11 }, /* version */
+ CC_C_Initialize,
+ CC_C_Finalize,
+ CC_C_GetInfo,
+ CC_C_GetFunctionList,
+ CC_C_GetSlotList,
+ CC_C_GetSlotInfo,
+ CC_C_GetTokenInfo,
+ CC_C_GetMechanismList,
+ CC_C_GetMechanismInfo,
+ CC_C_InitToken,
+ CC_C_InitPIN,
+ CC_C_SetPIN,
+ CC_C_OpenSession,
+ CC_C_CloseSession,
+ CC_C_CloseAllSessions,
+ CC_C_GetSessionInfo,
+ CC_C_GetOperationState,
+ CC_C_SetOperationState,
+ CC_C_Login,
+ CC_C_Logout,
+ CC_C_CreateObject,
+ CC_C_CopyObject,
+ CC_C_DestroyObject,
+ CC_C_GetObjectSize,
+ CC_C_GetAttributeValue,
+ CC_C_SetAttributeValue,
+ CC_C_FindObjectsInit,
+ CC_C_FindObjects,
+ CC_C_FindObjectsFinal,
+ CC_C_EncryptInit,
+ CC_C_Encrypt,
+ CC_C_EncryptUpdate,
+ CC_C_EncryptFinal,
+ CC_C_DecryptInit,
+ CC_C_Decrypt,
+ CC_C_DecryptUpdate,
+ CC_C_DecryptFinal,
+ CC_C_DigestInit,
+ CC_C_Digest,
+ CC_C_DigestUpdate,
+ CC_C_DigestKey,
+ CC_C_DigestFinal,
+ CC_C_SignInit,
+ CC_C_Sign,
+ CC_C_SignUpdate,
+ CC_C_SignFinal,
+ CC_C_SignRecoverInit,
+ CC_C_SignRecover,
+ CC_C_VerifyInit,
+ CC_C_Verify,
+ CC_C_VerifyUpdate,
+ CC_C_VerifyFinal,
+ CC_C_VerifyRecoverInit,
+ CC_C_VerifyRecover,
+ CC_C_DigestEncryptUpdate,
+ CC_C_DecryptDigestUpdate,
+ CC_C_SignEncryptUpdate,
+ CC_C_DecryptVerifyUpdate,
+ CC_C_GenerateKey,
+ CC_C_GenerateKeyPair,
+ CC_C_WrapKey,
+ CC_C_UnwrapKey,
+ CC_C_DeriveKey,
+ CC_C_SeedRandom,
+ CC_C_GenerateRandom,
+ CC_C_GetFunctionStatus,
+ CC_C_CancelFunction,
+ CC_C_WaitForSlotEvent
+};
+
+__declspec(dllexport) CK_RV
+C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list)
+{
+ if(!list)
+ return CKR_ARGUMENTS_BAD;
+
+ *list = &functionList;
+ return CKR_OK;
+}
diff --git a/cryptoki-capi.dsp b/cryptoki-capi.dsp
new file mode 100644
index 0000000..6f93ed3
--- /dev/null
+++ b/cryptoki-capi.dsp
@@ -0,0 +1,145 @@
+# Microsoft Developer Studio Project File - Name="cryptoki_capi" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=cryptoki_capi - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cryptoki-capi.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cryptoki-capi.mak" CFG="cryptoki_capi - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cryptoki_capi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "cryptoki_capi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cryptoki_capi - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOKI_CAPI_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOKI_CAPI_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "cryptoki_capi - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOKI_CAPI_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOKI_CAPI_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "cryptoki_capi - Win32 Release"
+# Name "cryptoki_capi - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=".\ckcapi-object.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ckcapi-util.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\cryptoki-capi-session.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\cryptoki-capi.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=".\cryptoki-capi-util.h"
+# End Source File
+# Begin Source File
+
+SOURCE=".\cryptoki-capi.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\pkcs11\cryptoki.h
+# End Source File
+# Begin Source File
+
+SOURCE=".\pkcs11\pkcs-11v2-20a3.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\pkcs11\pkcs11.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pkcs11\pkcs11f.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pkcs11\pkcs11t.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/cryptoki-capi.dsw b/cryptoki-capi.dsw
new file mode 100644
index 0000000..7f71040
--- /dev/null
+++ b/cryptoki-capi.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "cryptoki_capi"=".\cryptoki_capi.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/cryptoki-capi.h b/cryptoki-capi.h
new file mode 100644
index 0000000..a5dc9d5
--- /dev/null
+++ b/cryptoki-capi.h
@@ -0,0 +1,99 @@
+#ifndef CRYPTOKI_CAPI_H
+#define CRYPTOKI_CAPI_H
+
+#ifndef ASSERT
+#include "assert.h"
+#define ASSERT assert
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#define _WIN32_WINNT 0x400
+#include <windows.h>
+
+#define CRYPTOKI_EXPORTS
+#include "pkcs11/cryptoki.h"
+
+#include "cryptoki-capi-util.h"
+
+struct _Object;
+struct _Session;
+
+/* ------------------------------------------------------------------
+ * cryptoki-capi.c
+ */
+
+#define DBG(args) \
+ ckcapi_debug args
+
+void ckcapi_debug(const char* msg, ...);
+void ckcapi_lock_global(void);
+void ckcapi_unlock_global(void);
+CK_RV ckcapi_winerr_to_ckr (DWORD werr);
+
+/* ------------------------------------------------------------------
+ * cryptoki-capi-session.c
+ */
+
+/* For operation_type in Session */
+enum
+{
+ OPERATION_NONE = 0,
+ OPERATION_FIND = 1,
+};
+
+typedef void (*SessionCancel) (struct _Session* sess);
+
+typedef struct _Session
+{
+ CK_ULONG id; /* Unique ID for this session */
+ int in_call; /* Whether this session is use in PKCS#11 function */
+
+ int operation_type; /* Whether an operation is happening or not */
+ void* operation_data; /* Data for this operation */
+ SessionCancel operation_cancel; /* Callback to cancel operation when necessary */
+
+ CK_NOTIFY notify_callback; /* Application specified callback */
+ CK_VOID_PTR user_data; /* Argument for above */
+
+ int refs; /* Reference count */
+ HANDLE mutex; /* Mutex for protecting this structure */
+}
+Session;
+
+#define DBGS(sess, msg) \
+ ckcapi_debug("S%d: %s", (sess) ? (sess)->id : 0, (msg))
+
+Session* ckcapi_session_create(void);
+void ckcapi_session_destroy(Session* sess);
+CK_RV ckcapi_session_register(Session* sess);
+CK_RV ckcapi_session_find_lock_ref(CK_ULONG id, int remove, Session **sess);
+void ckcapi_session_unref_unlock(Session* sess);
+void ckcapi_session_close_all();
+
+
+/* ------------------------------------------------------------------
+ * cryptoki-capi-object.c
+ */
+
+typedef struct _Object
+{
+ CK_ULONG id; /* Unique ID for this object */
+
+ CK_ATTRIBUTE_PTR attrs; /* All the attributes of this object */
+ CK_ULONG n_attrs; /* Number of attributes */
+}
+Object;
+
+/*
+Object* ckcapi_object_create(Session* sess, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs);
+void ckcapi_object_destroy(Session* sess, Object* obj);
+*/
+
+CK_RV ckcapi_object_find_init (Session* sess, CK_ATTRIBUTE_PTR templ, CK_ULONG count);
+CK_RV ckcapi_object_find (Session* sess, CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_object_count, CK_ULONG_PTR object_count);
+CK_RV ckcapi_objects_find_final (Session* sess);
+
+
+#endif /* CRYPTOKI_CAPI_H */
+
diff --git a/pkcs11/Makefile.am b/pkcs11/Makefile.am
new file mode 100644
index 0000000..b3598ba
--- /dev/null
+++ b/pkcs11/Makefile.am
@@ -0,0 +1,9 @@
+
+EXTRA_DIST = \
+ cryptoki.h \
+ pkcs11.h \
+ pkcs11f.h \
+ pkcs11t.h \
+ pkcs-11v2-20a3.h
+
+
diff --git a/pkcs11/cryptoki.h b/pkcs11/cryptoki.h
new file mode 100644
index 0000000..f457b3e
--- /dev/null
+++ b/pkcs11/cryptoki.h
@@ -0,0 +1,66 @@
+/* cryptoki.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This is a sample file containing the top level include directives
+ * for building Win32 Cryptoki libraries and applications.
+ */
+
+#ifndef ___CRYPTOKI_H_INC___
+#define ___CRYPTOKI_H_INC___
+
+#pragma pack(push, cryptoki, 1)
+
+/* Specifies that the function is a DLL entry point. */
+#define CK_IMPORT_SPEC __declspec(dllimport)
+
+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
+ * not define it in applications.
+ */
+#ifdef CRYPTOKI_EXPORTS
+/* Specified that the function is an exported DLL entry point. */
+#define CK_EXPORT_SPEC __declspec(dllexport)
+#else
+#define CK_EXPORT_SPEC CK_IMPORT_SPEC
+#endif
+
+/* Ensures the calling convention for Win32 builds */
+#define CK_CALL_SPEC __cdecl
+
+#define CK_PTR *
+
+#define CK_DEFINE_FUNCTION(returnType, name) \
+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION(returnType, name) \
+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+ returnType (CK_CALL_SPEC CK_PTR name)
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#include "pkcs11.h"
+
+#pragma pack(pop, cryptoki)
+
+#endif /* ___CRYPTOKI_H_INC___ */
diff --git a/pkcs11/pkcs-11v2-20a3.h b/pkcs11/pkcs-11v2-20a3.h
new file mode 100644
index 0000000..fbce2c1
--- /dev/null
+++ b/pkcs11/pkcs-11v2-20a3.h
@@ -0,0 +1,119 @@
+/* pkcs-11v2-20a3.h include file for the PKCS #11 Version 2.20 Amendment 3
+ document. */
+
+/* $Revision: 1.3 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki) Version 2.20 Amendment 3" in all material mentioning or
+ * referencing this software.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This file is preferably included after inclusion of pkcs11.h */
+
+#ifndef _PKCS_11V2_20A3_H_
+#define _PKCS_11V2_20A3_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Key types */
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_CAMELLIA 0x00000025
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_ARIA 0x00000026
+
+
+/* Mask-generating functions */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKG_MGF1_SHA224 0x00000005
+
+
+/* Mechanism Identifiers */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224 0x00000255
+#define CKM_SHA224_HMAC 0x00000256
+#define CKM_SHA224_HMAC_GENERAL 0x00000257
+
+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_KEY_DERIVATION 0x00000396
+
+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_RSA_PKCS 0x00000046
+#define CKM_SHA224_RSA_PKCS_PSS 0x00000047
+
+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_AES_CTR 0x00001086
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_CAMELLIA_KEY_GEN 0x00000550
+#define CKM_CAMELLIA_ECB 0x00000551
+#define CKM_CAMELLIA_CBC 0x00000552
+#define CKM_CAMELLIA_MAC 0x00000553
+#define CKM_CAMELLIA_MAC_GENERAL 0x00000554
+#define CKM_CAMELLIA_CBC_PAD 0x00000555
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557
+#define CKM_CAMELLIA_CTR 0x00000558
+
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_ARIA_KEY_GEN 0x00000560
+#define CKM_ARIA_ECB 0x00000561
+#define CKM_ARIA_CBC 0x00000562
+#define CKM_ARIA_MAC 0x00000563
+#define CKM_ARIA_MAC_GENERAL 0x00000564
+#define CKM_ARIA_CBC_PAD 0x00000565
+#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566
+#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567
+
+
+/* Mechanism parameters */
+
+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_AES_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_CAMELLIA_CTR_PARAMS;
+
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkcs11/pkcs11.h b/pkcs11/pkcs11.h
new file mode 100644
index 0000000..6c61220
--- /dev/null
+++ b/pkcs11/pkcs11.h
@@ -0,0 +1,299 @@
+/* pkcs11.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 6 platform-specific macros must be defined. These
+ * macros are described below, and typical definitions for them
+ * are also given. Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 6 macros, the packing convention
+ * for Cryptoki structures should be set. The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this. You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object. It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
+ * an exportable Cryptoki library function definition out of a
+ * return type and a function name. It should be used in the
+ * following fashion to define the exposed Cryptoki functions in
+ * a Cryptoki library:
+ *
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * )
+ * {
+ * ...
+ * }
+ *
+ * If you're using Microsoft Developer Studio 5.0 to define a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllexport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to define a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name. It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name. It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV. It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h. */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points. That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points. A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library. This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkcs11/pkcs11f.h b/pkcs11/pkcs11f.h
new file mode 100644
index 0000000..a479384
--- /dev/null
+++ b/pkcs11/pkcs11f.h
@@ -0,0 +1,912 @@
+/* pkcs11f.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This header file contains pretty much everything about all the */
+/* Cryptoki function prototypes. Because this information is */
+/* used for more than just declaring function prototypes, the */
+/* order of the functions appearing herein is important, and */
+/* should not be altered. */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
+ * cast to CK_C_INITIALIZE_ARGS_PTR
+ * and dereferenced */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens? */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA). */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session
+ * handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen
+ * mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
+ * for pub.
+ * key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
+ * attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
+ * for priv.
+ * key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
+ * attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
+ * key
+ * handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
+ * priv. key
+ * handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Functions added in for Cryptoki Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
diff --git a/pkcs11/pkcs11t.h b/pkcs11/pkcs11t.h
new file mode 100644
index 0000000..b1a231a
--- /dev/null
+++ b/pkcs11/pkcs11t.h
@@ -0,0 +1,1685 @@
+/* pkcs11t.h include file for PKCS #11. */
+/* $Revision: 1.6 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file. */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+#endif
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0
+
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ /* hardwareVersion and firmwareVersion are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+ * changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sess. now open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+
+ /* hardwareVersion, firmwareVersion, and time are new for
+ * v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001 /* has random #
+ * generator */
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
+ * write-
+ * protected */
+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
+ * login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
+ * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN 0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. This flag is deprecated in v2.11 and
+ onwards. */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0
+/* Normal user */
+#define CKU_USER 1
+/* Context specific (added in v2.20) */
+#define CKU_CONTEXT_SPECIFIC 2
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0
+#define CKS_RO_USER_FUNCTIONS 1
+#define CKS_RW_PUBLIC_SESSION 2
+#define CKS_RW_USER_FUNCTIONS 3
+#define CKS_RW_SO_FUNCTIONS 4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+/* CKO_MECHANISM is new for v2.20 */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_MECHANISM 0x00000007
+#define CKO_VENDOR_DEFINED 0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+/* CKH_USER_INTERFACE is new for v2.20 */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_USER_INTERFACE 0x00000003
+#define CKH_VENDOR_DEFINED 0x80000000
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000
+#define CKK_DSA 0x00000001
+#define CKK_DH 0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA 0x00000003
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
+#define CKK_KEA 0x00000005
+
+#define CKK_GENERIC_SECRET 0x00000010
+#define CKK_RC2 0x00000011
+#define CKK_RC4 0x00000012
+#define CKK_DES 0x00000013
+#define CKK_DES2 0x00000014
+#define CKK_DES3 0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST 0x00000016
+#define CKK_CAST3 0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5 0x00000018
+#define CKK_CAST128 0x00000018
+#define CKK_RC5 0x00000019
+#define CKK_IDEA 0x0000001A
+#define CKK_SKIPJACK 0x0000001B
+#define CKK_BATON 0x0000001C
+#define CKK_JUNIPER 0x0000001D
+#define CKK_CDMF 0x0000001E
+#define CKK_AES 0x0000001F
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKK_BLOWFISH 0x00000020
+#define CKK_TWOFISH 0x00000021
+
+#define CKK_VENDOR_DEFINED 0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
+/* CKC_WTLS is new for v2.20 */
+#define CKC_X_509 0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_WTLS 0x00000002
+#define CKC_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+ consists of an array of values. */
+#define CKF_ARRAY_ATTRIBUTE 0x40000000
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000
+#define CKA_TOKEN 0x00000001
+#define CKA_PRIVATE 0x00000002
+#define CKA_LABEL 0x00000003
+#define CKA_APPLICATION 0x00000010
+#define CKA_VALUE 0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID 0x00000012
+
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED 0x00000086
+
+/* CKA_CERTIFICATE_CATEGORY ...
+ * CKA_CHECK_VALUE are new for v2.20 */
+#define CKA_CERTIFICATE_CATEGORY 0x00000087
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
+#define CKA_URL 0x00000089
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
+#define CKA_CHECK_VALUE 0x00000090
+
+#define CKA_KEY_TYPE 0x00000100
+#define CKA_SUBJECT 0x00000101
+#define CKA_ID 0x00000102
+#define CKA_SENSITIVE 0x00000103
+#define CKA_ENCRYPT 0x00000104
+#define CKA_DECRYPT 0x00000105
+#define CKA_WRAP 0x00000106
+#define CKA_UNWRAP 0x00000107
+#define CKA_SIGN 0x00000108
+#define CKA_SIGN_RECOVER 0x00000109
+#define CKA_VERIFY 0x0000010A
+#define CKA_VERIFY_RECOVER 0x0000010B
+#define CKA_DERIVE 0x0000010C
+#define CKA_START_DATE 0x00000110
+#define CKA_END_DATE 0x00000111
+#define CKA_MODULUS 0x00000120
+#define CKA_MODULUS_BITS 0x00000121
+#define CKA_PUBLIC_EXPONENT 0x00000122
+#define CKA_PRIVATE_EXPONENT 0x00000123
+#define CKA_PRIME_1 0x00000124
+#define CKA_PRIME_2 0x00000125
+#define CKA_EXPONENT_1 0x00000126
+#define CKA_EXPONENT_2 0x00000127
+#define CKA_COEFFICIENT 0x00000128
+#define CKA_PRIME 0x00000130
+#define CKA_SUBPRIME 0x00000131
+#define CKA_BASE 0x00000132
+
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUBPRIME_BITS 0x00000134
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
+/* (To retain backwards-compatibility) */
+
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
+
+#define CKA_MODIFIABLE 0x00000170
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS 0x00000180
+#define CKA_EC_PARAMS 0x00000180
+
+#define CKA_EC_POINT 0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * are new for v2.10. Deprecated in v2.11 and onwards. */
+#define CKA_SECONDARY_AUTH 0x00000200
+#define CKA_AUTH_PIN_FLAGS 0x00000201
+
+/* CKA_ALWAYS_AUTHENTICATE ...
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
+
+#define CKA_WRAP_WITH_TRUSTED 0x00000210
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
+
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
+
+/* The following attributes are new for v2.20 */
+#define CKA_PIXEL_X 0x00000400
+#define CKA_PIXEL_Y 0x00000401
+#define CKA_RESOLUTION 0x00000402
+#define CKA_CHAR_ROWS 0x00000403
+#define CKA_CHAR_COLUMNS 0x00000404
+#define CKA_COLOR 0x00000405
+#define CKA_BITS_PER_PIXEL 0x00000406
+#define CKA_CHAR_SETS 0x00000480
+#define CKA_ENCODING_METHODS 0x00000481
+#define CKA_MIME_TYPES 0x00000482
+#define CKA_MECHANISM_TYPE 0x00000500
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
+
+#define CKA_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+
+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
+#define CKM_RSA_PKCS 0x00000001
+#define CKM_RSA_9796 0x00000002
+#define CKM_RSA_X_509 0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0. They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS 0x00000004
+#define CKM_MD5_RSA_PKCS 0x00000005
+#define CKM_SHA1_RSA_PKCS 0x00000006
+
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+#define CKM_RSA_PKCS_PSS 0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_RSA_PKCS 0x00000040
+#define CKM_SHA384_RSA_PKCS 0x00000041
+#define CKM_SHA512_RSA_PKCS 0x00000042
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
+
+#define CKM_RC2_KEY_GEN 0x00000100
+#define CKM_RC2_ECB 0x00000101
+#define CKM_RC2_CBC 0x00000102
+#define CKM_RC2_MAC 0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL 0x00000104
+#define CKM_RC2_CBC_PAD 0x00000105
+
+#define CKM_RC4_KEY_GEN 0x00000110
+#define CKM_RC4 0x00000111
+#define CKM_DES_KEY_GEN 0x00000120
+#define CKM_DES_ECB 0x00000121
+#define CKM_DES_CBC 0x00000122
+#define CKM_DES_MAC 0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL 0x00000124
+#define CKM_DES_CBC_PAD 0x00000125
+
+#define CKM_DES2_KEY_GEN 0x00000130
+#define CKM_DES3_KEY_GEN 0x00000131
+#define CKM_DES3_ECB 0x00000132
+#define CKM_DES3_CBC 0x00000133
+#define CKM_DES3_MAC 0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#define CKM_CDMF_KEY_GEN 0x00000140
+#define CKM_CDMF_ECB 0x00000141
+#define CKM_CDMF_CBC 0x00000142
+#define CKM_CDMF_MAC 0x00000143
+#define CKM_CDMF_MAC_GENERAL 0x00000144
+#define CKM_CDMF_CBC_PAD 0x00000145
+
+/* the following four DES mechanisms are new for v2.20 */
+#define CKM_DES_OFB64 0x00000150
+#define CKM_DES_OFB8 0x00000151
+#define CKM_DES_CFB64 0x00000152
+#define CKM_DES_CFB8 0x00000153
+
+#define CKM_MD2 0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
+
+#define CKM_MD5 0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
+
+#define CKM_SHA_1 0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256 0x00000250
+#define CKM_SHA256_HMAC 0x00000251
+#define CKM_SHA256_HMAC_GENERAL 0x00000252
+#define CKM_SHA384 0x00000260
+#define CKM_SHA384_HMAC 0x00000261
+#define CKM_SHA384_HMAC_GENERAL 0x00000262
+#define CKM_SHA512 0x00000270
+#define CKM_SHA512_HMAC 0x00000271
+#define CKM_SHA512_HMAC_GENERAL 0x00000272
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN 0x00000300
+#define CKM_CAST_ECB 0x00000301
+#define CKM_CAST_CBC 0x00000302
+#define CKM_CAST_MAC 0x00000303
+#define CKM_CAST_MAC_GENERAL 0x00000304
+#define CKM_CAST_CBC_PAD 0x00000305
+#define CKM_CAST3_KEY_GEN 0x00000310
+#define CKM_CAST3_ECB 0x00000311
+#define CKM_CAST3_CBC 0x00000312
+#define CKM_CAST3_MAC 0x00000313
+#define CKM_CAST3_MAC_GENERAL 0x00000314
+#define CKM_CAST3_CBC_PAD 0x00000315
+#define CKM_CAST5_KEY_GEN 0x00000320
+#define CKM_CAST128_KEY_GEN 0x00000320
+#define CKM_CAST5_ECB 0x00000321
+#define CKM_CAST128_ECB 0x00000321
+#define CKM_CAST5_CBC 0x00000322
+#define CKM_CAST128_CBC 0x00000322
+#define CKM_CAST5_MAC 0x00000323
+#define CKM_CAST128_MAC 0x00000323
+#define CKM_CAST5_MAC_GENERAL 0x00000324
+#define CKM_CAST128_MAC_GENERAL 0x00000324
+#define CKM_CAST5_CBC_PAD 0x00000325
+#define CKM_CAST128_CBC_PAD 0x00000325
+#define CKM_RC5_KEY_GEN 0x00000330
+#define CKM_RC5_ECB 0x00000331
+#define CKM_RC5_CBC 0x00000332
+#define CKM_RC5_MAC 0x00000333
+#define CKM_RC5_MAC_GENERAL 0x00000334
+#define CKM_RC5_CBC_PAD 0x00000335
+#define CKM_IDEA_KEY_GEN 0x00000340
+#define CKM_IDEA_ECB 0x00000341
+#define CKM_IDEA_CBC 0x00000342
+#define CKM_IDEA_MAC 0x00000343
+#define CKM_IDEA_MAC_GENERAL 0x00000344
+#define CKM_IDEA_CBC_PAD 0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
+#define CKM_XOR_BASE_AND_DATA 0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
+/* CKM_TLS_PRF is new for v2.20 */
+#define CKM_TLS_PRF 0x00000378
+
+#define CKM_SSL3_MD5_MAC 0x00000380
+#define CKM_SSL3_SHA1_MAC 0x00000381
+#define CKM_MD5_KEY_DERIVATION 0x00000390
+#define CKM_MD2_KEY_DERIVATION 0x00000391
+#define CKM_SHA1_KEY_DERIVATION 0x00000392
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_KEY_DERIVATION 0x00000393
+#define CKM_SHA384_KEY_DERIVATION 0x00000394
+#define CKM_SHA512_KEY_DERIVATION 0x00000395
+
+#define CKM_PBE_MD2_DES_CBC 0x000003A0
+#define CKM_PBE_MD5_DES_CBC 0x000003A1
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
+#define CKM_PBE_SHA1_RC4_128 0x000003A6
+#define CKM_PBE_SHA1_RC4_40 0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+
+/* WTLS mechanisms are new for v2.20 */
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
+#define CKM_WTLS_PRF 0x000003D3
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
+
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* CKM_CMS_SIG is new for v2.20 */
+#define CKM_CMS_SIG 0x00000500
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN 0x00001000
+#define CKM_SKIPJACK_ECB64 0x00001001
+#define CKM_SKIPJACK_CBC64 0x00001002
+#define CKM_SKIPJACK_OFB64 0x00001003
+#define CKM_SKIPJACK_CFB64 0x00001004
+#define CKM_SKIPJACK_CFB32 0x00001005
+#define CKM_SKIPJACK_CFB16 0x00001006
+#define CKM_SKIPJACK_CFB8 0x00001007
+#define CKM_SKIPJACK_WRAP 0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
+#define CKM_SKIPJACK_RELAYX 0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
+#define CKM_KEA_KEY_DERIVE 0x00001011
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
+#define CKM_BATON_KEY_GEN 0x00001030
+#define CKM_BATON_ECB128 0x00001031
+#define CKM_BATON_ECB96 0x00001032
+#define CKM_BATON_CBC128 0x00001033
+#define CKM_BATON_COUNTER 0x00001034
+#define CKM_BATON_SHUFFLE 0x00001035
+#define CKM_BATON_WRAP 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
+
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
+#define CKM_ECDH1_DERIVE 0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
+#define CKM_ECMQV_DERIVE 0x00001052
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060
+#define CKM_JUNIPER_ECB128 0x00001061
+#define CKM_JUNIPER_CBC128 0x00001062
+#define CKM_JUNIPER_COUNTER 0x00001063
+#define CKM_JUNIPER_SHUFFLE 0x00001064
+#define CKM_JUNIPER_WRAP 0x00001065
+#define CKM_FASTHASH 0x00001070
+
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
+#define CKM_AES_KEY_GEN 0x00001080
+#define CKM_AES_ECB 0x00001081
+#define CKM_AES_CBC 0x00001082
+#define CKM_AES_MAC 0x00001083
+#define CKM_AES_MAC_GENERAL 0x00001084
+#define CKM_AES_CBC_PAD 0x00001085
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKM_BLOWFISH_KEY_GEN 0x00001090
+#define CKM_BLOWFISH_CBC 0x00001091
+#define CKM_TWOFISH_KEY_GEN 0x00001092
+#define CKM_TWOFISH_CBC 0x00001093
+
+
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
+
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
+
+#define CKM_VENDOR_DEFINED 0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001 /* performed by HW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+ * and CKF_DERIVE are new for v2.0. They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT 0x00000100
+#define CKF_DECRYPT 0x00000200
+#define CKF_DIGEST 0x00000400
+#define CKF_SIGN 0x00000800
+#define CKF_SIGN_RECOVER 0x00001000
+#define CKF_VERIFY 0x00002000
+#define CKF_VERIFY_RECOVER 0x00004000
+#define CKF_GENERATE 0x00008000
+#define CKF_GENERATE_KEY_PAIR 0x00010000
+#define CKF_WRAP 0x00020000
+#define CKF_UNWRAP 0x00040000
+#define CKF_DERIVE 0x00080000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
+
+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000
+#define CKR_CANCEL 0x00000001
+#define CKR_HOST_MEMORY 0x00000002
+#define CKR_SLOT_ID_INVALID 0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR 0x00000005
+#define CKR_FUNCTION_FAILED 0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD 0x00000007
+#define CKR_NO_EVENT 0x00000008
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
+#define CKR_CANT_LOCK 0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
+#define CKR_DATA_INVALID 0x00000020
+#define CKR_DATA_LEN_RANGE 0x00000021
+#define CKR_DEVICE_ERROR 0x00000030
+#define CKR_DEVICE_MEMORY 0x00000031
+#define CKR_DEVICE_REMOVED 0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
+#define CKR_FUNCTION_CANCELED 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE 0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED 0x00000064
+#define CKR_KEY_CHANGED 0x00000065
+#define CKR_KEY_NEEDED 0x00000066
+#define CKR_KEY_INDIGESTIBLE 0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+
+#define CKR_MECHANISM_INVALID 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
+#define CKR_OPERATION_ACTIVE 0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
+#define CKR_PIN_INCORRECT 0x000000A0
+#define CKR_PIN_INVALID 0x000000A1
+#define CKR_PIN_LEN_RANGE 0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED 0x000000A3
+#define CKR_PIN_LOCKED 0x000000A4
+
+#define CKR_SESSION_CLOSED 0x000000B0
+#define CKR_SESSION_COUNT 0x000000B1
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
+#define CKR_SESSION_READ_ONLY 0x000000B5
+#define CKR_SESSION_EXISTS 0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
+
+#define CKR_SIGNATURE_INVALID 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
+#define CKR_USER_NOT_LOGGED_IN 0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
+#define CKR_USER_TYPE_INVALID 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
+#define CKR_USER_TOO_MANY_TYPES 0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG 0x00000121
+
+/* These are new to v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+
+/* These are new to v2.0 */
+#define CKR_BUFFER_TOO_SMALL 0x00000150
+#define CKR_SAVED_STATE_INVALID 0x00000160
+#define CKR_INFORMATION_SENSITIVE 0x00000170
+#define CKR_STATE_UNSAVEABLE 0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
+#define CKR_MUTEX_BAD 0x000001A0
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+
+/* This is new to v2.20 */
+#define CKR_FUNCTION_REJECTED 0x00000200
+
+#define CKR_VENDOR_DEFINED 0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK 0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
+ * are new for v2.20 */
+#define CKG_MGF1_SHA1 0x00000001
+#define CKG_MGF1_SHA256 0x00000002
+#define CKG_MGF1_SHA384 0x00000003
+#define CKG_MGF1_SHA512 0x00000004
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+/* CK_EC_KDF_TYPE is new for v2.11. */
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL 0x00000001
+#define CKD_SHA1_KDF 0x00000002
+
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* The following X9.42 DH key derivation functions are defined
+ (besides CKD_NULL already defined : */
+#define CKD_SHA1_KDF_ASN1 0x00000003
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
+
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[8];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
+typedef struct CK_TLS_PRF_PARAMS {
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+/* WTLS is new for version 2.20 */
+typedef struct CK_WTLS_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hMacSecret;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+/* CMS is new for version 2.20 */
+typedef struct CK_CMS_SIG_PARAMS {
+ CK_OBJECT_HANDLE certificateHandle;
+ CK_MECHANISM_PTR pSigningMechanism;
+ CK_MECHANISM_PTR pDigestMechanism;
+ CK_UTF8CHAR_PTR pContentType;
+ CK_BYTE_PTR pRequestedAttributes;
+ CK_ULONG ulRequestedAttributesLen;
+ CK_BYTE_PTR pRequiredAttributes;
+ CK_ULONG ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+#endif