diff options
-rw-r--r-- | pkcs11.c | 1106 | ||||
-rw-r--r-- | schema.sql | 59 |
2 files changed, 373 insertions, 792 deletions
@@ -6,7 +6,7 @@ * libhal library connecting to the Cryptech FPGA cores. * * Author: Rob Austein - * Copyright (c) 2015, NORDUnet A/S + * Copyright (c) 2015-2016, NORDUnet A/S * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -153,17 +153,17 @@ typedef struct p11_session { CK_VOID_PTR application; /* Application data */ sqlite3_stmt *find_query; /* FindObject*() query state */ int find_query_done; /* find_query has terminated */ - const hal_hash_descriptor_t - *digest_descriptor, /* Hash for C_Digest*() */ - *sign_digest_descriptor, /* Hash for C_Sign*() */ - *verify_digest_descriptor; /* Hash for C_Verify*() */ + hal_digest_algorithm_t + digest_algorithm, /* Hash algorithm for C_Digest*() */ + sign_digest_algorithm, /* Hash algorithm for C_Sign*() */ + verify_digest_algorithm; /* Hash algorithm for C_Verify*() */ CK_OBJECT_HANDLE - sign_key_handle, /* Key for C_Sign*() */ - verify_key_handle; /* Key for C_Verify() */ - hal_hash_state_t - *digest_state, /* Hash state for C_Digest*() */ - *sign_digest_state, /* Hash state for C_Sign*() */ - *verify_digest_state; /* Hash state for C_Verify*() */ + sign_key_handle, /* Private key for C_Sign*() */ + verify_key_handle; /* Public key for C_Verify() */ + hal_hash_handle_t + digest_handle, /* Hash state for C_Digest*() */ + sign_digest_handle, /* Hash state for C_Sign*() */ + verify_digest_handle; /* Hash state for C_Verify*() */ } p11_session_t; /* @@ -505,6 +505,28 @@ static int ec_curve_oid_to_name(const uint8_t * const oid, const size_t oid_len, return 1; } +/* + * Extract libhal-compatible client and session identifiers from a session. + * + * libhal's session identifiers are deliberately chosen to be in the same + * numeric range as PKCS #11's, so we can just use them directly. + * + * libhal's client identifiers are multiplexing extension handled elsewhere, + * for our purposes using constant client identifier of zero will do. + */ + +static inline hal_client_handle_t p11_session_hal_client(const p11_session_t * const session) +{ + hal_client_handle_t handle = {0}; + return handle; +} + +static inline hal_session_handle_t p11_session_hal_session(const p11_session_t * const session) +{ + hal_session_handle_t handle = {session->handle}; + return handle; +} + /* @@ -1173,302 +1195,99 @@ static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session, } /* - * Store a private key. - * - * Write the key as DER, encrypt that using AES key wrap, and store - * the result as an SQL blob. - * - * We jump through a few minor hoops to let us do all the encoding and - * wrapping in place in a single buffer. + * Construct libhal type code for a key object. */ -static int p11_object_set_generic_private_key(const CK_OBJECT_HANDLE object_handle, - const void * const key, - const size_t key_der_len, - hal_error_t (*to_der)(const void * const, uint8_t *, size_t *, const size_t)) +static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle, + hal_key_type_t *pkey_type) { - static const char select_kek[] = - " SELECT kek FROM global"; - - static const char update_format[] = - " UPDATE %s_object SET private_key = ?1" - " WHERE %s_object_id = (SELECT %s_object_id FROM object WHERE object_handle = ?2)"; + static const char update_pkey_type[] = + " UPDATE object SET hal_pkey_type = ?2 WHERE object_handle = ?1"; - uint8_t wrapbuf[hal_aes_keywrap_ciphertext_length(key_der_len)]; - const char *flavor = is_token_handle(object_handle) ? "token" : "session"; - size_t der_len, wrapbuf_len = sizeof(wrapbuf); - sqlite3_stmt *q = NULL; - int ok = 0; + assert(pkey_type != NULL); - assert(to_der); - - if (!sql_check_ok(sql_prepare(&q, select_kek)) || - !sql_check_row(sqlite3_step(q)) || - sqlite3_column_type(q, 0) == SQLITE_NULL || - !hal_check(to_der(key, wrapbuf + 8, &der_len, sizeof(wrapbuf) - 8)) || - !hal_check(hal_aes_keywrap(NULL, - sqlite3_column_blob(q, 0), - sqlite3_column_bytes(q, 0), - wrapbuf+8, der_len, wrapbuf, &wrapbuf_len)) || - !sql_check_ok(sql_finalize_and_clear(&q)) || - !sql_check_ok(sql_prepare(&q, update_format, flavor, flavor, flavor)) || - !sql_check_ok(sqlite3_bind_blob( q, 1, wrapbuf, wrapbuf_len, NULL)) || - !sql_check_ok(sqlite3_bind_int64(q, 2, object_handle)) || - !sql_check_done(sqlite3_step(q))) - goto fail; - - ok = 1; + CK_OBJECT_CLASS cka_class; + CK_KEY_TYPE cka_key_type; - fail: - memset(wrapbuf, 0, sizeof(wrapbuf)); - sqlite3_finalize(q); - return ok; -} + if (!p11_attribute_get_ulong(object_handle, CKA_CLASS, &cka_class) || + !p11_attribute_get_ulong(object_handle, CKA_KEY_TYPE, &cka_key_type)) + return 0; + + else if (cka_class == CKO_PRIVATE_KEY && cka_key_type == CKK_RSA) + *pkey_type = HAL_KEY_TYPE_RSA_PRIVATE; -/* - * Store an RSA private key. - * - * Use p11_object_set_generic_private_key() to wrap the PKCS #1.5 - * RSAPrivateKey encoding of the private key. - */ + else if (cka_class == CKO_PRIVATE_KEY && cka_key_type == CKK_EC) + *pkey_type = HAL_KEY_TYPE_EC_PRIVATE; -static hal_error_t p11_object_encode_rsa_key(const void * const key, - uint8_t * der, - size_t *der_len, - const size_t der_max) -{ - return hal_rsa_private_key_to_der(key, der, der_len, der_max); -} + else if (cka_class == CKO_PUBLIC_KEY && cka_key_type == CKK_RSA) + *pkey_type = HAL_KEY_TYPE_RSA_PUBLIC; -static int p11_object_set_rsa_private_key(const CK_OBJECT_HANDLE object_handle, - const hal_rsa_key_t * const key) -{ - return p11_object_set_generic_private_key(object_handle, - key, - hal_rsa_private_key_to_der_len(key), - p11_object_encode_rsa_key); -} + else if (cka_class == CKO_PUBLIC_KEY && cka_key_type == CKK_EC) + *pkey_type = HAL_KEY_TYPE_EC_PUBLIC; -/* - * Store an EC private key. - * - * Use p11_object_set_generic_private_key() to wrap the RFC 5915 - * ECPrivateKey encoding of the private key. - */ + else + *pkey_type = HAL_KEY_TYPE_NONE; -static hal_error_t p11_object_encode_ec_key(const void * const key, - uint8_t * der, - size_t *der_len, - const size_t der_max) -{ - return hal_ecdsa_private_key_to_der(key, der, der_len, der_max); -} + sqlite3_stmt *q = NULL; -static int p11_object_set_ec_private_key(const CK_OBJECT_HANDLE object_handle, - const hal_ecdsa_key_t * const key) -{ - return p11_object_set_generic_private_key(object_handle, - key, - hal_ecdsa_private_key_to_der_len(key), - p11_object_encode_ec_key); + return (sql_check_ok(sql_prepare(&q, update_pkey_type)) && + sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && + sql_check_ok(sqlite3_bind_int64(q, 2, *pkey_type)) && + sql_check_done(sqlite3_step(q)) && + sql_check_ok(sqlite3_finalize(q))); } /* - * Fetch a private key. - * - * Retrieve SQL blob from the object, unwrap that to get the DER - * encoding, load the key from that. - * - * If the key isn't set, we return success with null key. + * Fetch the libhal pkey handle for a key object. */ -static int p11_object_get_generic_private_key(const CK_OBJECT_HANDLE object_handle, - void **key, - uint8_t *keybuf, const size_t keybuf_len, - hal_error_t (*from_der)(void **, void *, - const size_t, const uint8_t * const, const size_t)) +static int p11_object_get_pkey_handle(const p11_session_t * const session, + const CK_OBJECT_HANDLE object_handle, + hal_pkey_handle_t *pkey_handle) { static const char select_format[] = - " SELECT kek, private_key FROM global, %s_object NATURAL JOIN object WHERE object_handle = ?1"; + " SELECT value, hal_pkey_type FROM %s_attribute NATURAL JOIN object" + " WHERE object_handle = ?1 AND type = %u"; const char *flavor = is_token_handle(object_handle) ? "token" : "session"; + + hal_key_type_t pkey_type; sqlite3_stmt *q = NULL; int ok; - assert(key != NULL && keybuf != NULL); + assert(pkey_handle != NULL); - /* - * Pull everything we need from the database. - */ + ok = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_ID)) && + sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && + sql_check_row(sqlite3_step(q))); - if (!sql_check_ok(sql_prepare(&q, select_format, flavor)) || - !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) || - !sql_check_row(sqlite3_step(q)) || - sqlite3_column_type(q, 0) == SQLITE_NULL) { - ok = 0; - } + if (!ok) + goto fail; - else if (sqlite3_column_type(q, 1) == SQLITE_NULL) { - *key = NULL; - ok = 1; - } + switch (sqlite3_column_type(q, 1)) { - else { - const uint8_t * const kek = sqlite3_column_blob(q, 0); - const uint8_t * const pkey = sqlite3_column_blob(q, 1); - const size_t kek_len = sqlite3_column_bytes(q, 0); - const size_t pkey_len = sqlite3_column_bytes(q, 1); - size_t wrapbuf_len = pkey_len; - uint8_t wrapbuf[pkey_len]; + case SQLITE_INTEGER: + pkey_type = (hal_key_type_t) sqlite3_column_int64(q, 1); + break; - ok = (hal_check(hal_aes_keyunwrap(NULL, kek, kek_len, pkey, pkey_len, wrapbuf, &wrapbuf_len)) && - hal_check(from_der(key, keybuf, keybuf_len, wrapbuf, wrapbuf_len))); + case SQLITE_NULL: + ok = p11_object_pkey_type(object_handle, &pkey_type); + if (!ok) + goto fail; + break; - memset(wrapbuf, 0, sizeof(wrapbuf)); + default: + ok = 0; + goto fail; } - if (!ok || *key == NULL) - memset(keybuf, 0, keybuf_len); - - sqlite3_finalize(q); - return ok; -} - -/* - * Fetch an RSA private key. - * - * Use p11_object_get_generic_private_key() to unwrap the DER encoding - * of a PKCS #1.5 RSAPrivateKey object. - */ - -static hal_error_t p11_object_decode_rsa_key(void **key_, - void *keybuf, const size_t keybuf_len, - const uint8_t * const der, const size_t der_len) -{ - assert(key_ != NULL); - hal_rsa_key_t *key = NULL; - hal_error_t err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len); - *key_ = key; - return err; -} - -static int p11_object_get_rsa_private_key(const CK_OBJECT_HANDLE object_handle, - hal_rsa_key_t **key, - uint8_t *keybuf, const size_t keybuf_len) -{ - assert(key != NULL); - void *key_ = NULL; - int ok = p11_object_get_generic_private_key(object_handle, &key_, keybuf, keybuf_len, p11_object_decode_rsa_key); - *key = key_; - return ok; -} - -/* - * Fetch an EC private key. - * - * Use p11_object_get_generic_private_key() to unwrap the DER encoding - * of an RFC 5915 ECPrivateKey object. - */ - -static hal_error_t p11_object_decode_ec_key(void **key_, - void *keybuf, const size_t keybuf_len, - const uint8_t * const der, const size_t der_len) -{ - assert(key_ != NULL); - hal_ecdsa_key_t *key = NULL; - hal_error_t err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len); - *key_ = key; - return err; -} - -static int p11_object_get_ec_private_key(const CK_OBJECT_HANDLE object_handle, - hal_ecdsa_key_t **key, - uint8_t *keybuf, const size_t keybuf_len) -{ - assert(key != NULL); - void *key_ = NULL; - int ok = p11_object_get_generic_private_key(object_handle, &key_, keybuf, keybuf_len, p11_object_decode_ec_key); - *key = key_; - return ok; -} - -#warning Revisit return semantics of p11_object_get_*_private_key() and p11_object_*_rsa_public_key() - -/* - * Fetch an RSA public key. - * - * Public keys aren't stored separately the way that private keys are, - * so we're looking for the public components so we can load them into - * a key object. - */ - -static int p11_object_get_rsa_public_key(const CK_OBJECT_HANDLE object_handle, - hal_rsa_key_t **key, - uint8_t *keybuf, const size_t keybuf_len) -{ - static const char select_format[] = - " WITH a (type, value) " - " AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)" - " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u"; - - const char *flavor = is_token_handle(object_handle) ? "token" : "session"; - sqlite3_stmt *q = NULL; - - assert(key != NULL && keybuf != NULL); - - const int ok = (sql_check_ok(sql_prepare(&q, select_format, flavor, - CKA_MODULUS, CKA_PUBLIC_EXPONENT)) && - sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && - sql_check_row(sqlite3_step(q)) && - sqlite3_column_type(q, 0) == SQLITE_BLOB && - sqlite3_column_type(q, 1) == SQLITE_BLOB && - hal_check(hal_rsa_key_load_public(key, keybuf, keybuf_len, - sqlite3_column_blob( q, 0), - sqlite3_column_bytes(q, 0), - sqlite3_column_blob( q, 1), - sqlite3_column_bytes(q, 1)))); - - sqlite3_finalize(q); - return ok; -} - -/* - * Fetch an EC public key. - * - * Public keys aren't stored separately the way that private keys are, - * so we're looking for the public components so we can load them into - * a key object. - */ - -static int p11_object_get_ec_public_key(const CK_OBJECT_HANDLE object_handle, - hal_ecdsa_key_t **key, - uint8_t *keybuf, const size_t keybuf_len) -{ - static const char select_format[] = - " WITH a (type, value) " - " AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)" - " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u"; - - const char *flavor = is_token_handle(object_handle) ? "token" : "session"; - sqlite3_stmt *q = NULL; - hal_curve_name_t curve; - - assert(key != NULL && keybuf != NULL); - - const int ok = (sql_check_ok(sql_prepare(&q, select_format, flavor, - CKA_EC_PARAMS, CKA_EC_POINT)) && - sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && - sql_check_row(sqlite3_step(q)) && - sqlite3_column_type(q, 0) == SQLITE_BLOB && - sqlite3_column_type(q, 1) == SQLITE_BLOB && - ec_curve_oid_to_name(sqlite3_column_blob( q, 0), - sqlite3_column_bytes(q, 0), - &curve) && - hal_check(hal_ecdsa_key_from_ecpoint(key, keybuf, keybuf_len, - sqlite3_column_blob( q, 1), - sqlite3_column_bytes(q, 1), - curve))); + ok = hal_check(hal_rpc_pkey_find(p11_session_hal_client(session), + p11_session_hal_session(session), + pkey_handle, pkey_type, + sqlite3_column_blob(q, 0), + sqlite3_column_bytes(q, 0))); + fail: sqlite3_finalize(q); return ok; } @@ -1502,9 +1321,9 @@ static void p11_session_free(p11_session_t *session) return; sql_finalize_and_clear(&session->find_query); - hal_hash_cleanup(&session->digest_state); - hal_hash_cleanup(&session->sign_digest_state); - hal_hash_cleanup(&session->verify_digest_state); + (void) hal_rpc_hash_finalize(session->digest_handle, NULL, 0); + (void) hal_rpc_hash_finalize(session->sign_digest_handle, NULL, 0); + (void) hal_rpc_hash_finalize(session->verify_digest_handle, NULL, 0); free(session); } @@ -1917,14 +1736,13 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle) + const CK_OBJECT_HANDLE public_handle, + const uint8_t * const id, const size_t id_len) { const uint8_t *public_exponent = const_0x010001; size_t public_exponent_len = sizeof(const_0x010001); - uint8_t keybuf[hal_rsa_key_t_size]; - hal_rsa_key_t *key = NULL; + hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; CK_ULONG keysize = 0; - size_t modulus_len; CK_RV rv; int i; @@ -1950,26 +1768,31 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, } } - if (keysize == 0) + if (keysize == 0 || id == NULL) return CKR_TEMPLATE_INCOMPLETE; - memset(keybuf, 0, sizeof(keybuf)); +#warning Should do something here with pkey flags - if (!hal_check(hal_rsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), keysize / 8, - public_exponent, public_exponent_len))) + if (!hal_check(hal_rpc_pkey_generate_rsa(p11_session_hal_client(session), + p11_session_hal_session(session), + &pkey, id, id_len, keysize / 8, + public_exponent, public_exponent_len, 0))) lose(CKR_FUNCTION_FAILED); - if (!p11_object_set_rsa_private_key(private_handle, key)) - lose(CKR_FUNCTION_FAILED); + { + uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_rsa_key_t_size]; + size_t der_len, modulus_len; + hal_rsa_key_t *key = NULL; - if (!hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0))) - lose(CKR_FUNCTION_FAILED); + if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der))) || + !hal_check(hal_rsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)) || + !hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0))) + lose(CKR_FUNCTION_FAILED); - { uint8_t modulus[modulus_len]; - if (!hal_check(hal_rsa_key_get_modulus(key, modulus, &modulus_len, sizeof(modulus))) || - !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) || + if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus))) || + !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) || !p11_attribute_set(private_handle, CKA_MODULUS, modulus, modulus_len)) lose(CKR_FUNCTION_FAILED); } @@ -1977,7 +1800,7 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, rv = CKR_OK; fail: - hal_rsa_key_clear(key); + hal_rpc_pkey_close(pkey); return rv; } @@ -1986,15 +1809,15 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, */ static CK_RV generate_keypair_ec(p11_session_t *session, - const CK_ATTRIBUTE_PTR pPublicKeyTemplate, - const CK_ULONG ulPublicKeyAttributeCount, - const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - const CK_ULONG ulPrivateKeyAttributeCount, - const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle) + const CK_ATTRIBUTE_PTR pPublicKeyTemplate, + const CK_ULONG ulPublicKeyAttributeCount, + const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + const CK_ULONG ulPrivateKeyAttributeCount, + const CK_OBJECT_HANDLE private_handle, + const CK_OBJECT_HANDLE public_handle, + const uint8_t * const id, const size_t id_len) { - uint8_t keybuf[hal_ecdsa_key_t_size]; - hal_ecdsa_key_t *key = NULL; + hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; const CK_BYTE *params = NULL; hal_curve_name_t curve; size_t params_len; @@ -2017,18 +1840,25 @@ static CK_RV generate_keypair_ec(p11_session_t *session, } } - if (!ec_curve_oid_to_name(params, params_len, &curve)) + if (!ec_curve_oid_to_name(params, params_len, &curve) || id == NULL) return CKR_TEMPLATE_INCOMPLETE; - memset(keybuf, 0, sizeof(keybuf)); - - if (!hal_check(hal_ecdsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), curve)) || - !p11_object_set_ec_private_key(private_handle, key) || + if (!hal_check(hal_rpc_pkey_generate_ec(p11_session_hal_client(session), + p11_session_hal_session(session), + &pkey, id, id_len, curve, 0)) || !p11_attribute_set(public_handle, CKA_EC_PARAMS, params, params_len) || !p11_attribute_set(private_handle, CKA_EC_PARAMS, params, params_len)) lose(CKR_FUNCTION_FAILED); { + uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_ecdsa_key_t_size]; + hal_ecdsa_key_t *key = NULL; + size_t der_len; + + if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der))) || + !hal_check(hal_ecdsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len))) + lose(CKR_FUNCTION_FAILED); + uint8_t point[hal_ecdsa_key_to_ecpoint_len(key)]; if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point))) || @@ -2039,7 +1869,7 @@ static CK_RV generate_keypair_ec(p11_session_t *session, rv = CKR_OK; fail: - hal_ecdsa_key_clear(key); + hal_rpc_pkey_close(pkey); return rv; } @@ -2062,7 +1892,8 @@ static CK_RV generate_keypair(p11_session_t *session, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle), + const CK_OBJECT_HANDLE public_handle, + const uint8_t * const id, const size_t id_len), const p11_descriptor_t * const public_descriptor, const p11_descriptor_t * const private_descriptor) { @@ -2104,11 +1935,29 @@ static CK_RV generate_keypair(p11_session_t *session, private_descriptor, pMechanism)) == CK_INVALID_HANDLE) lose(CKR_FUNCTION_FAILED); - if ((rv = mechanism_handler(session, - pPublicKeyTemplate, ulPublicKeyAttributeCount, - pPrivateKeyTemplate, ulPrivateKeyAttributeCount, - private_handle, public_handle)) != CKR_OK) - goto fail; + { + size_t public_id_len = 0, private_id_len = 0; + + if (!p11_attribute_get(public_handle, CKA_ID, NULL, &public_id_len, 0) || + !p11_attribute_get(private_handle, CKA_ID, NULL, &public_id_len, 0)) + lose(CKR_TEMPLATE_INCOMPLETE); + + uint8_t public_id[public_id_len], private_id[private_id_len]; + + if (!p11_attribute_get(public_handle, CKA_ID, public_id, NULL, public_id_len) || + !p11_attribute_get(private_handle, CKA_ID, private_id, NULL, public_id_len)) + lose(CKR_TEMPLATE_INCOMPLETE); + + if (public_id_len != private_id_len || memcmp(public_id, private_id, public_id_len) != 0) + lose(CKR_TEMPLATE_INCONSISTENT); + + if ((rv = mechanism_handler(session, + pPublicKeyTemplate, ulPublicKeyAttributeCount, + pPrivateKeyTemplate, ulPrivateKeyAttributeCount, + private_handle, public_handle, + public_id, public_id_len)) != CKR_OK) + goto fail; + } if (!sql_exec("COMMIT")) lose(CKR_FUNCTION_FAILED); @@ -2192,14 +2041,17 @@ static CK_RV p11_check_create_attributes(const p11_session_t *session, * Add data to a digest. */ -static CK_RV digest_update(const hal_hash_descriptor_t * const descriptor, - hal_hash_state_t **state, +static CK_RV digest_update(const p11_session_t * const session, + const hal_digest_algorithm_t algorithm, + hal_hash_handle_t *handle, const uint8_t * const data, const size_t data_len) { - assert(descriptor != NULL && state != NULL && data != NULL); + assert(algorithm != hal_digest_algorithm_none && handle != NULL && data != NULL); - if (*state == NULL) { - switch (hal_hash_initialize(NULL, descriptor, state, NULL, 0)) { + if (handle->handle == HAL_HANDLE_NONE) { + switch (hal_rpc_hash_initialize(p11_session_hal_client(session), + p11_session_hal_session(session), + handle, algorithm, NULL, 0)) { case HAL_OK: break; case HAL_ERROR_ALLOCATION_FAILURE: @@ -2209,130 +2061,88 @@ static CK_RV digest_update(const hal_hash_descriptor_t * const descriptor, } } - if (!hal_check(hal_hash_update(*state, data, data_len))) + if (!hal_check(hal_rpc_hash_update(*handle, data, data_len))) return CKR_FUNCTION_FAILED; return CKR_OK; } /* - * Construct a PKCS #1 DigestInfo object. This requires some (very - * basic) ASN.1 encoding, which we perform inline. + * Finish using a digest context, if we haven't already. */ -static int pkcs1_construct_digestinfo(const hal_hash_descriptor_t * const desc, - hal_hash_state_t *state, - uint8_t *digest_info, const size_t digest_info_len) +static void digest_cleanup(hal_hash_handle_t *handle) { - assert(desc != NULL && state != NULL && digest_info != NULL); - - /* - * Make sure size of output buffer is right. Caller is responsible - * for supplying the right length, the check here is just paranoia. - * - * This encoder will fail if the DigestInfo object is more than - * 129 octets long. Rewrite if and when we need to support - * digests or OIDs long enough for that to be an issue. - */ - - assert(digest_info_len == desc->digest_length + desc->digest_algorithm_id_length + 4); - assert(digest_info_len < 130); - - uint8_t *d = digest_info; - - *d++ = 0x30; /* SEQUENCE */ - *d++ = (uint8_t) (digest_info_len - 2); - - memcpy(d, desc->digest_algorithm_id, desc->digest_algorithm_id_length); - d += desc->digest_algorithm_id_length; - - *d++ = 0x04; /* OCTET STRING */ - *d++ = (uint8_t) desc->digest_length; - - assert(digest_info + digest_info_len == d + desc->digest_length); - - return hal_check(hal_hash_finalize(state, d, desc->digest_length)); + assert(handle != NULL); + if (handle->handle == HAL_HANDLE_NONE) + return; + (void) hal_rpc_hash_finalize(*handle, NULL, 0); + handle->handle = HAL_HANDLE_NONE; } /* - * Pad an octet string with PKCS #1.5 padding for use with RSA. - * - * For the moment, this only handles type 01 encryption blocks, thus - * is only suitable for use with signature and verification. If and - * when we add support for encryption and decryption, this function - * should be extended to take an argument specifying the block type - * and include support for generating type 02 encryption blocks. - * Other than the block type code, the only difference is the padding - * value: for type 01 it's constant (0xFF), for type 02 it should be - * non-zero random bytes from the CSPRNG. + * Compute the length of a signature based on the key. We could get + * this via the RPC API, but its probably faster to look in the local + * attribute database. Rewrite this later if this proves incorrect. */ -static int pkcs1_5_pad(const uint8_t * const data, const size_t data_len, - uint8_t *block, const size_t block_len) +static int get_signature_len(const CK_OBJECT_HANDLE object_handle, + const hal_pkey_handle_t pkey, + size_t *signature_len) { - assert(data != NULL && block != NULL); + assert(signature_len != NULL); - /* - * Congregation will now please turn to RFC 2313 8.1 as we - * construct a PKCS #1.5 type 01 encryption block. - */ + CK_KEY_TYPE cka_key_type; + hal_curve_name_t curve; + CK_BYTE oid[20]; + CK_ULONG len; - if (data_len > block_len - 11) + if (!p11_attribute_get_ulong(object_handle, CKA_KEY_TYPE, &cka_key_type)) return 0; - block[0] = 0x00; - block[1] = 0x01; + switch (cka_key_type) { - /* This is where we'd use non-zero random bytes if constructing a type 02 block. */ - memset(block + 2, 0xFF, block_len - 3 - data_len); - - block[block_len - data_len - 1] = 0x00; - memcpy(block + block_len - data_len, data, data_len); + case CKK_RSA: + if (!p11_attribute_get(object_handle, CKA_MODULUS, NULL, &len, 0)) + return 0; + *signature_len = len; + return 1; -#if DEBUG_PKCS11 > 1 - fprintf(stderr, "[PKCS #1.5 block_len %lu data_len %lu block ", - (unsigned long) block_len, (unsigned long) data_len); - for (int i = 0; i < block_len; i++) - fprintf(stderr, "%s%02x", i == 0 ? "" : ":", block[i]); - fprintf(stderr, "]\n"); -#endif + case CKK_EC: + if (!p11_attribute_get(object_handle, CKA_EC_PARAMS, oid, &len, sizeof(oid)) || + !ec_curve_oid_to_name(oid, len, &curve)) + return 0; + switch (curve) { + case HAL_CURVE_P256: *signature_len = 64; return 1; + case HAL_CURVE_P384: *signature_len = 96; return 1; + case HAL_CURVE_P521: *signature_len = 132; return 1; + default: return 0; + } + } - return 1; + return 0; } /* - * Generate an RSA PKCS #1.5 signature. - * - * As explained in RFC 3447, the RSASP1 (signature generation) - * operation is the same mathematical operation as the RSADP - * (decryption) operation (both use the private key as exponent). + * Generate a signature using the libhal RPC API. */ -static CK_RV sign_rsa_pkcs(p11_session_t *session, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) +static CK_RV sign_hal_rpc(p11_session_t *session, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) { - uint8_t keybuf[hal_rsa_key_t_size]; - hal_rsa_key_t *key = NULL; + hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; size_t signature_len; CK_RV rv; assert(session != NULL && pulSignatureLen != NULL); - const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor; - uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length]; - - if (!p11_object_get_rsa_private_key(session->sign_key_handle, - &key, keybuf, sizeof(keybuf))) + if (!p11_object_get_pkey_handle(session, session->sign_key_handle, &pkey)) lose(CKR_FUNCTION_FAILED); - /* - * Retrieve signature length, which is just the the modulus length. - */ - - if (!hal_check(hal_rsa_key_get_modulus(key, NULL, &signature_len, 0))) + if (!get_signature_len(session->sign_key_handle, pkey, &signature_len)) lose(CKR_FUNCTION_FAILED); rv = signature_len > *pulSignatureLen ? CKR_BUFFER_TOO_SMALL : CKR_OK; @@ -2342,205 +2152,53 @@ static CK_RV sign_rsa_pkcs(p11_session_t *session, if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL) lose(CKR_BUFFER_TOO_SMALL); - if (pSignature != NULL && descriptor != NULL) { - - if (!pkcs1_construct_digestinfo(descriptor, session->sign_digest_state, digest_info, sizeof(digest_info))) - lose(CKR_FUNCTION_FAILED); - - pData = digest_info; - ulDataLen = sizeof(digest_info); - } - - if (pSignature != NULL) { - - if (!pkcs1_5_pad(pData, ulDataLen, pSignature, signature_len)) - lose(CKR_DATA_LEN_RANGE); - - if (!hal_check(hal_rsa_decrypt(NULL, key, pSignature, signature_len, pSignature, signature_len))) - lose(CKR_FUNCTION_FAILED); - } +#warning Should pay more attention to translating error codes here + if (pSignature != NULL && + !hal_check(hal_rpc_pkey_sign(p11_session_hal_session(session), pkey, session->sign_digest_handle, + pData, ulDataLen, pSignature, pulSignatureLen, signature_len))) + lose(CKR_FUNCTION_FAILED); rv = CKR_OK; /* Fall through */ fail: - hal_rsa_key_clear(key); + hal_rpc_pkey_close(pkey); return rv; } /* - * Verify a PKCS #1.5 padded RSA signature. - * - * We don't bother decoding the ASN.1, we just generate the type 01 - * encryption block we expect and compare it with what we got. - * - * Using constant-time comparision code for this is probably - * unnecessary, but it's also harmless. + * Verify a signature using the libhal RPC API. */ -static CK_RV verify_rsa_pkcs(p11_session_t *session, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) +static CK_RV verify_hal_rpc(p11_session_t *session, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) { - uint8_t keybuf[hal_rsa_key_t_size]; - hal_rsa_key_t *key = NULL; + hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; CK_RV rv; assert(session != NULL); - const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor; - uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length]; - uint8_t expected[ulSignatureLen], received[ulSignatureLen]; - unsigned diff = 0; - - if (!p11_object_get_rsa_public_key(session->verify_key_handle, - &key, keybuf, sizeof(keybuf))) + if (!p11_object_get_pkey_handle(session, session->verify_key_handle, &pkey)) lose(CKR_FUNCTION_FAILED); - if (session->verify_digest_descriptor != NULL) { - - if (!pkcs1_construct_digestinfo(session->verify_digest_descriptor, - session->verify_digest_state, - digest_info, sizeof(digest_info))) - lose(CKR_FUNCTION_FAILED); - - pData = digest_info; - ulDataLen = sizeof(digest_info); - - } - - if (!pkcs1_5_pad(pData, ulDataLen, expected, sizeof(expected))) - lose(CKR_DATA_LEN_RANGE); +#warning Should pay more attention to translating error codes here - if (!hal_check(hal_rsa_encrypt(NULL, key, pSignature, ulSignatureLen, received, sizeof(received)))) + if (!hal_check(hal_rpc_pkey_verify(p11_session_hal_session(session), pkey, session->verify_digest_handle, + pData, ulDataLen, pSignature, ulSignatureLen))) lose(CKR_FUNCTION_FAILED); - - for (int i = 0; i < ulSignatureLen; i++) - diff |= expected[i] ^ received[i]; - - if (diff != 0) - lose(CKR_SIGNATURE_INVALID); + /* lose(CKR_SIGNATURE_INVALID); */ rv = CKR_OK; /* Fall through */ fail: - hal_rsa_key_clear(key); + hal_rpc_pkey_close(pkey); return rv; } #warning May need to do something about truncating oversized hashes for ECDSA, see PKCS11 spec -/* - * Generate an ECDSA signature. - */ - -static CK_RV sign_ecdsa(p11_session_t *session, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ - uint8_t keybuf[hal_ecdsa_key_t_size]; - hal_ecdsa_key_t *key = NULL; - hal_curve_name_t curve; - size_t signature_len; - CK_RV rv; - - assert(session != NULL && pulSignatureLen != NULL); - - const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor; - uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length]; - - if (!p11_object_get_ec_private_key(session->sign_key_handle, &key, keybuf, sizeof(keybuf))) - lose(CKR_FUNCTION_FAILED); - - /* - * Signature length is determined by curve parameters. - */ - - if (!hal_check(hal_ecdsa_key_get_curve(key, &curve))) - lose(CKR_FUNCTION_FAILED); - - switch (curve) { - case HAL_CURVE_P256: signature_len = 256; break; - case HAL_CURVE_P384: signature_len = 384; break; - case HAL_CURVE_P521: signature_len = 521; break; - default: lose(CKR_FUNCTION_FAILED); - } - - signature_len = ((signature_len + 7) / 8) * 2; - - rv = signature_len > *pulSignatureLen ? CKR_BUFFER_TOO_SMALL : CKR_OK; - - *pulSignatureLen = signature_len; - - if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL) - lose(CKR_BUFFER_TOO_SMALL); - - if (pSignature != NULL && descriptor != NULL) { - - if (!hal_check(hal_hash_finalize(session->sign_digest_state, digest, sizeof(digest)))) - lose(CKR_FUNCTION_FAILED); - - pData = digest; - ulDataLen = sizeof(digest); - } - - if (pSignature != NULL && !hal_check(hal_ecdsa_sign(NULL, key, pData, ulDataLen, - pSignature, &signature_len, *pulSignatureLen))) - lose(CKR_FUNCTION_FAILED); - - assert(signature_len == *pulSignatureLen); - - rv = CKR_OK; /* Fall through */ - - fail: - hal_ecdsa_key_clear(key); - return rv; -} - -/* - * Verify an ECDSA signature. - */ - -static CK_RV verify_ecdsa(p11_session_t *session, - CK_BYTE_PTR pData, - CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ - uint8_t keybuf[hal_ecdsa_key_t_size]; - hal_ecdsa_key_t *key = NULL; - CK_RV rv; - - assert(session != NULL && pSignature != NULL); - - const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor; - uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length]; - - if (!p11_object_get_ec_public_key(session->verify_key_handle, &key, keybuf, sizeof(keybuf))) - lose(CKR_FUNCTION_FAILED); - - if (session->verify_digest_descriptor != NULL) { - - if (!hal_check(hal_hash_finalize(session->verify_digest_state, digest, sizeof(digest)))) - lose(CKR_FUNCTION_FAILED); - - pData = digest; - ulDataLen = sizeof(digest); - } - - if (!hal_check(hal_ecdsa_verify(NULL, key, pData, ulDataLen, pSignature, ulSignatureLen))) - lose(CKR_SIGNATURE_INVALID); - - rv = CKR_OK; /* Fall through */ - - fail: - hal_ecdsa_key_clear(key); - return rv; -} - /* @@ -2958,13 +2616,11 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, { ENTER_PUBLIC_FUNCTION(C_Login); - static const char pin_query_format[] = - " SELECT pbkdf2_iterations, %s_pin, %s_pin_salt FROM global"; - + const hal_client_handle_t client = {HAL_HANDLE_NONE}; p11_session_t *session; - sqlite3_stmt *q = NULL; - const char *pin_type; + hal_user_t user = HAL_USER_NONE; CK_RV rv = CKR_OK; + hal_error_t err; mutex_lock_or_return_failure(p11_global_mutex); @@ -2998,13 +2654,13 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, switch (userType) { case CKU_USER: - pin_type = "user"; + user = HAL_USER_NORMAL; break; case CKU_SO: for (session = p11_sessions; session != NULL; session = session->link) if (session->state == CKS_RO_PUBLIC_SESSION) lose(CKR_SESSION_READ_ONLY_EXISTS); - pin_type = "so"; + user = HAL_USER_SO; break; case CKU_CONTEXT_SPECIFIC: lose(CKR_OPERATION_NOT_INITIALIZED); @@ -3013,53 +2669,15 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, } /* - * Look up the PIN and make sure it's set. - * - * Not obvious what error we should return if SO PIN isn't set, for - * now consider this state "locked" (because it hasn't been set yet). - */ - - if (!sql_check_ok(sql_prepare(&q, pin_query_format, pin_type, pin_type)) || - !sql_check_row(sqlite3_step(q))) - lose(CKR_FUNCTION_FAILED); - - if (sqlite3_column_type(q, 1) == SQLITE_NULL || - sqlite3_column_type(q, 2) == SQLITE_NULL) { - switch (userType) { - case CKU_USER: - lose(CKR_USER_PIN_NOT_INITIALIZED); - case CKU_SO: - lose(CKR_PIN_LOCKED); - default: - lose(CKR_USER_TYPE_INVALID); - } - } - - /* - * Run PBKDF2 over the supplied PIN and compare results. - * - * Probably not really necessary to use constant-time string - * comparison, but it's harmless and cheap, so we might as well. + * Try to log in the HSM. */ - { - const unsigned iterations = sqlite3_column_int(q, 0); - const uint8_t * const pin = sqlite3_column_blob(q, 1); - const uint8_t * const salt = sqlite3_column_blob(q, 2); - const size_t pin_len = sqlite3_column_bytes(q, 1); - const size_t salt_len = sqlite3_column_bytes(q, 2); - uint8_t pinbuf[pin_len]; - unsigned diff = 0; - - if (!hal_check(hal_pbkdf2(NULL, hal_hash_sha256, pPin, ulPinLen, salt, salt_len, - pinbuf, sizeof(pinbuf), iterations))) - lose(CKR_FUNCTION_FAILED); - - for (int i = 0; i < pin_len; i++) - diff |= pin[i] ^ pinbuf[i]; - - if (diff != 0) +#warning Might need better error code translation here + if (!hal_check((err = hal_rpc_login(client, user, (char *) pPin, ulPinLen)))) { + if (err == HAL_ERROR_PIN_INCORRECT) lose(CKR_PIN_INCORRECT); + else + lose(CKR_FUNCTION_FAILED); } /* @@ -3089,7 +2707,6 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, assert(p11_session_consistent_login()); fail: - sqlite3_finalize(q); mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -3097,6 +2714,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession) { ENTER_PUBLIC_FUNCTION(C_Logout); + const hal_client_handle_t client = {HAL_HANDLE_NONE}; p11_session_t *session; CK_RV rv = CKR_OK; @@ -3121,6 +2739,10 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession) assert(p11_session_consistent_login()); +#warning Might want better error translation here + if (!hal_check(hal_rpc_logout(client))) + lose(CKR_FUNCTION_FAILED); + logged_in_as = not_logged_in; p11_object_delete_all_private(); @@ -3153,6 +2775,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, { ENTER_PUBLIC_FUNCTION(C_CreateObject); + CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE; p11_session_t *session; CK_RV rv; @@ -3205,7 +2828,8 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, const handle_flavor_t flavor = cka_token == NULL ? handle_flavor_session_object : p11_handle_flavor_from_cka_token(cka_token); - CK_OBJECT_HANDLE handle = p11_object_create(session, flavor, pTemplate, ulCount, descriptor, NULL); + if ((handle = p11_object_create(session, flavor, pTemplate, ulCount, descriptor, NULL)) == CK_INVALID_HANDLE) + lose(CKR_FUNCTION_FAILED); if (!p11_attribute_set_bbool(handle, CKA_LOCAL, CK_FALSE)) lose(CKR_FUNCTION_FAILED); @@ -3218,6 +2842,8 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, lose(CKR_FUNCTION_FAILED); } +#warning Somewhere around here we need to create a libhal key object from supplied components + if (!sql_exec("COMMIT")) lose(CKR_FUNCTION_FAILED); @@ -3244,6 +2870,7 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, " WHERE token_object_id = (SELECT token_object_id FROM object WHERE object_handle = ?)"; + hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; p11_session_t *session; sqlite3_stmt *q = NULL; CK_RV rv = CKR_OK; @@ -3255,6 +2882,9 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, if ((rv = p11_object_check_rights(session, hObject, p11_object_access_write)) != CKR_OK) goto fail; + if (p11_object_get_pkey_handle(session, hObject, &pkey) && !hal_check(hal_rpc_pkey_delete(pkey))) + lose(CKR_FUNCTION_FAILED); + if (is_token_handle(hObject) && (!sql_check_ok(sql_prepare(&q, delete_token_object)) || !sql_check_ok(sqlite3_bind_int64(q, 1, hObject)) || @@ -3604,6 +3234,7 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, { ENTER_PUBLIC_FUNCTION(C_DigestInit); + hal_digest_algorithm_t algorithm; p11_session_t *session; CK_RV rv = CKR_OK; @@ -3615,22 +3246,18 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, if (pMechanism == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->digest_descriptor != NULL) + if (session->digest_algorithm != hal_digest_algorithm_none) lose(CKR_OPERATION_ACTIVE); switch (pMechanism->mechanism) { - case CKM_SHA_1: session->digest_descriptor = hal_hash_sha1; break; - case CKM_SHA256: session->digest_descriptor = hal_hash_sha256; break; - case CKM_SHA384: session->digest_descriptor = hal_hash_sha384; break; - case CKM_SHA512: session->digest_descriptor = hal_hash_sha512; break; + case CKM_SHA_1: algorithm = hal_digest_algorithm_sha1; break; + case CKM_SHA256: algorithm = hal_digest_algorithm_sha256; break; + case CKM_SHA384: algorithm = hal_digest_algorithm_sha384; break; + case CKM_SHA512: algorithm = hal_digest_algorithm_sha512; break; default: lose(CKR_MECHANISM_INVALID); } - if (hal_core_find(session->digest_descriptor->core_name, NULL) == NULL) { - session->digest_descriptor = NULL; - lose(CKR_MECHANISM_INVALID); - } - + session->digest_algorithm = algorithm; return mutex_unlock(p11_global_mutex); fail: @@ -3646,6 +3273,7 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, ENTER_PUBLIC_FUNCTION(C_Digest); p11_session_t *session; + size_t digest_len; CK_RV rv = CKR_OK; mutex_lock_or_return_failure(p11_global_mutex); @@ -3656,15 +3284,18 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, if (pData == NULL || pulDigestLen == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->digest_descriptor == NULL) + if (session->digest_algorithm == hal_digest_algorithm_none) lose(CKR_OPERATION_NOT_INITIALIZED); - if (session->digest_state != NULL) + if (session->digest_handle.handle != HAL_HANDLE_NONE) lose(CKR_OPERATION_ACTIVE); - rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK; + if (!hal_check(hal_rpc_hash_get_digest_length(session->digest_algorithm, &digest_len))) + lose(CKR_FUNCTION_FAILED); - *pulDigestLen = session->digest_descriptor->digest_length; + rv = *pulDigestLen < digest_len ? CKR_BUFFER_TOO_SMALL : CKR_OK; + + *pulDigestLen = digest_len; if (pDigest == NULL) return mutex_unlock(p11_global_mutex); @@ -3672,19 +3303,19 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, if (rv == CKR_BUFFER_TOO_SMALL) lose(CKR_BUFFER_TOO_SMALL); - if ((rv = digest_update(session->digest_descriptor, &session->digest_state, - pData, ulDataLen)) != CKR_OK) + if ((rv = digest_update(session, session->digest_algorithm, + &session->digest_handle, pData, ulDataLen)) != CKR_OK) goto fail; - if (!hal_check(hal_hash_finalize(session->digest_state, pDigest, *pulDigestLen))) + if (!hal_check(hal_rpc_hash_finalize(session->digest_handle, pDigest, *pulDigestLen))) lose(CKR_FUNCTION_FAILED); rv = CKR_OK; /* Fall through */ fail: if (session != NULL) { - hal_hash_cleanup(&session->digest_state); - session->digest_descriptor = NULL; + digest_cleanup(&session->digest_handle); + session->digest_algorithm = hal_digest_algorithm_none; } mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -3706,23 +3337,19 @@ CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, if (pPart == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->digest_descriptor == NULL) + if (session->digest_algorithm == hal_digest_algorithm_none) lose(CKR_OPERATION_NOT_INITIALIZED); - if (!session->digest_descriptor->can_restore_state) - lose(CKR_FUNCTION_FAILED); - - if ((rv = digest_update(session->digest_descriptor, - &session->digest_state, - pPart, ulPartLen)) != CKR_OK) + if ((rv = digest_update(session, session->digest_algorithm, + &session->digest_handle, pPart, ulPartLen)) != CKR_OK) goto fail; return mutex_unlock(p11_global_mutex); fail: if (session != NULL) { - hal_hash_cleanup(&session->digest_state); - session->digest_descriptor = NULL; + digest_cleanup(&session->digest_handle); + session->digest_algorithm = hal_digest_algorithm_none; } mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -3734,6 +3361,7 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, ENTER_PUBLIC_FUNCTION(C_DigestFinal); p11_session_t *session; + size_t digest_len; CK_RV rv = CKR_OK; mutex_lock_or_return_failure(p11_global_mutex); @@ -3744,12 +3372,15 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, if (pulDigestLen == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->digest_descriptor == NULL || session->digest_state == NULL) + if (session->digest_algorithm == hal_digest_algorithm_none || session->digest_handle.handle == HAL_HANDLE_NONE) lose(CKR_OPERATION_NOT_INITIALIZED); - rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK; + if (!hal_check(hal_rpc_hash_get_digest_length(session->digest_algorithm, &digest_len))) + lose(CKR_FUNCTION_FAILED); + + rv = *pulDigestLen < digest_len ? CKR_BUFFER_TOO_SMALL : CKR_OK; - *pulDigestLen = session->digest_descriptor->digest_length; + *pulDigestLen = digest_len; if (pDigest == NULL) return mutex_unlock(p11_global_mutex); @@ -3757,15 +3388,15 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, if (rv == CKR_BUFFER_TOO_SMALL) lose(CKR_BUFFER_TOO_SMALL); - if (!hal_check(hal_hash_finalize(session->digest_state, pDigest, *pulDigestLen))) + if (!hal_check(hal_rpc_hash_finalize(session->digest_handle, pDigest, *pulDigestLen))) lose(CKR_FUNCTION_FAILED); rv = CKR_OK; /* Fall through */ fail: if (session != NULL) { - hal_hash_cleanup(&session->digest_state); - session->digest_descriptor = NULL; + digest_cleanup(&session->digest_handle); + session->digest_algorithm = hal_digest_algorithm_none; } mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -3790,7 +3421,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, if (pMechanism == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->sign_key_handle != CK_INVALID_HANDLE || session->sign_digest_descriptor != NULL) + if (session->sign_key_handle != CK_INVALID_HANDLE || session->sign_digest_algorithm != hal_digest_algorithm_none) lose(CKR_OPERATION_ACTIVE); if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK) @@ -3830,22 +3461,22 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, switch (pMechanism->mechanism) { case CKM_RSA_PKCS: case CKM_ECDSA: - session->sign_digest_descriptor = NULL; + session->sign_digest_algorithm = hal_digest_algorithm_none; break; case CKM_SHA1_RSA_PKCS: - session->sign_digest_descriptor = hal_hash_sha1; + session->sign_digest_algorithm = hal_digest_algorithm_sha1; break; case CKM_SHA256_RSA_PKCS: case CKM_ECDSA_SHA256: - session->sign_digest_descriptor = hal_hash_sha256; + session->sign_digest_algorithm = hal_digest_algorithm_sha256; break; case CKM_SHA384_RSA_PKCS: case CKM_ECDSA_SHA384: - session->sign_digest_descriptor = hal_hash_sha384; + session->sign_digest_algorithm = hal_digest_algorithm_sha384; break; case CKM_SHA512_RSA_PKCS: case CKM_ECDSA_SHA512: - session->sign_digest_descriptor = hal_hash_sha512; + session->sign_digest_algorithm = hal_digest_algorithm_sha512; break; default: return CKR_MECHANISM_INVALID; @@ -3856,7 +3487,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, fail: if (session != NULL) { session->sign_key_handle = CK_INVALID_HANDLE; - session->sign_digest_descriptor = NULL; + session->sign_digest_algorithm = hal_digest_algorithm_none; } mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -3884,25 +3515,25 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, if (session->sign_key_handle == CK_INVALID_HANDLE) lose(CKR_OPERATION_NOT_INITIALIZED); - if (session->sign_digest_state != NULL) + if (session->sign_digest_handle.handle != HAL_HANDLE_NONE) lose(CKR_OPERATION_ACTIVE); - if (session->sign_digest_descriptor != NULL && pSignature != NULL && - (rv = digest_update(session->sign_digest_descriptor, - &session->sign_digest_state, pData, ulDataLen)) != CKR_OK) - goto fail; - if (!p11_attribute_get_ulong(session->sign_key_handle, CKA_KEY_TYPE, &key_type)) lose(CKR_FUNCTION_FAILED); + if (session->sign_digest_algorithm != hal_digest_algorithm_none && pSignature != NULL) { + if ((rv = digest_update(session, session->sign_digest_algorithm, + &session->sign_digest_handle, pData, ulDataLen)) != CKR_OK) + goto fail; + pData = NULL; + ulDataLen = 0; + } + switch (key_type) { case CKK_RSA: - rv = sign_rsa_pkcs(session, pData, ulDataLen, pSignature, pulSignatureLen); - break; - case CKK_EC: - rv = sign_ecdsa(session, pData, ulDataLen, pSignature, pulSignatureLen); + rv = sign_hal_rpc(session, pData, ulDataLen, pSignature, pulSignatureLen); break; default: @@ -3912,8 +3543,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, fail: if (session != NULL && pSignature != NULL) { session->sign_key_handle = CK_INVALID_HANDLE; - session->sign_digest_descriptor = NULL; - hal_hash_cleanup(&session->sign_digest_state); + session->sign_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->sign_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -3939,12 +3570,11 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, if (session->sign_key_handle == CK_INVALID_HANDLE) lose(CKR_OPERATION_NOT_INITIALIZED); - if (session->sign_digest_descriptor == NULL || !session->sign_digest_descriptor->can_restore_state) + if (session->sign_digest_algorithm == hal_digest_algorithm_none) lose(CKR_FUNCTION_FAILED); - if ((rv = digest_update(session->sign_digest_descriptor, - &session->sign_digest_state, - pPart, ulPartLen)) != CKR_OK) + if ((rv = digest_update(session, session->sign_digest_algorithm, + &session->sign_digest_handle, pPart, ulPartLen)) != CKR_OK) goto fail; return mutex_unlock(p11_global_mutex); @@ -3952,8 +3582,8 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, fail: if (session != NULL) { session->sign_key_handle = CK_INVALID_HANDLE; - session->sign_digest_descriptor = NULL; - hal_hash_cleanup(&session->sign_digest_state); + session->sign_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->sign_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -3977,7 +3607,7 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, if (pulSignatureLen == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_state == NULL) + if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_handle.handle == HAL_HANDLE_NONE) lose(CKR_OPERATION_NOT_INITIALIZED); if (!p11_attribute_get_ulong(session->sign_key_handle, CKA_KEY_TYPE, &key_type)) @@ -3986,11 +3616,8 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, switch (key_type) { case CKK_RSA: - rv = sign_rsa_pkcs(session, NULL, 0, pSignature, pulSignatureLen); - break; - case CKK_EC: - rv = sign_ecdsa(session, NULL, 0, pSignature, pulSignatureLen); + rv = sign_hal_rpc(session, NULL, 0, pSignature, pulSignatureLen); break; default: @@ -4000,8 +3627,8 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, fail: if (session != NULL && pSignature != NULL) { session->sign_key_handle = CK_INVALID_HANDLE; - session->sign_digest_descriptor = NULL; - hal_hash_cleanup(&session->sign_digest_state); + session->sign_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->sign_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -4027,7 +3654,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, if (pMechanism == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_descriptor != NULL) + if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_algorithm != hal_digest_algorithm_none) lose(CKR_OPERATION_ACTIVE); if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK) @@ -4067,22 +3694,22 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, switch (pMechanism->mechanism) { case CKM_RSA_PKCS: case CKM_ECDSA: - session->verify_digest_descriptor = NULL; + session->verify_digest_algorithm = hal_digest_algorithm_none; break; case CKM_SHA1_RSA_PKCS: - session->verify_digest_descriptor = hal_hash_sha1; + session->verify_digest_algorithm = hal_digest_algorithm_sha1; break; case CKM_SHA256_RSA_PKCS: case CKM_ECDSA_SHA256: - session->verify_digest_descriptor = hal_hash_sha256; + session->verify_digest_algorithm = hal_digest_algorithm_sha256; break; case CKM_SHA384_RSA_PKCS: case CKM_ECDSA_SHA384: - session->verify_digest_descriptor = hal_hash_sha384; + session->verify_digest_algorithm = hal_digest_algorithm_sha384; break; case CKM_SHA512_RSA_PKCS: case CKM_ECDSA_SHA512: - session->verify_digest_descriptor = hal_hash_sha512; + session->verify_digest_algorithm = hal_digest_algorithm_sha512; break; default: return CKR_MECHANISM_INVALID; @@ -4093,7 +3720,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, fail: if (session != NULL) { session->verify_key_handle = CK_INVALID_HANDLE; - session->verify_digest_descriptor = NULL; + session->verify_digest_algorithm = hal_digest_algorithm_none; } mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -4121,10 +3748,13 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, if (session->verify_key_handle == CK_INVALID_HANDLE) lose(CKR_OPERATION_NOT_INITIALIZED); - if (session->verify_digest_descriptor != NULL && - (rv = digest_update(session->verify_digest_descriptor, - &session->verify_digest_state, pData, ulDataLen)) != CKR_OK) - goto fail; + if (session->verify_digest_algorithm != hal_digest_algorithm_none) { + if ((rv = digest_update(session, session->verify_digest_algorithm, + &session->verify_digest_handle, pData, ulDataLen)) != CKR_OK) + goto fail; + pData = NULL; + ulDataLen = 0; + } if (!p11_attribute_get_ulong(session->verify_key_handle, CKA_KEY_TYPE, &key_type)) lose(CKR_FUNCTION_FAILED); @@ -4132,11 +3762,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, switch (key_type) { case CKK_RSA: - rv = verify_rsa_pkcs(session, pData, ulDataLen, pSignature, ulSignatureLen); - break; - case CKK_EC: - rv = verify_ecdsa(session, pData, ulDataLen, pSignature, ulSignatureLen); + rv = verify_hal_rpc(session, pData, ulDataLen, pSignature, ulSignatureLen); break; default: @@ -4147,8 +3774,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, if (session != NULL) { session->verify_key_handle = CK_INVALID_HANDLE; - session->verify_digest_descriptor = NULL; - hal_hash_cleanup(&session->verify_digest_state); + session->verify_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->verify_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -4174,12 +3801,11 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, if (session->verify_key_handle == CK_INVALID_HANDLE) lose(CKR_OPERATION_NOT_INITIALIZED); - if (session->verify_digest_descriptor == NULL || !session->verify_digest_descriptor->can_restore_state) + if (session->verify_digest_algorithm == hal_digest_algorithm_none) lose(CKR_FUNCTION_FAILED); - if ((rv = digest_update(session->verify_digest_descriptor, - &session->verify_digest_state, - pPart, ulPartLen)) != CKR_OK) + if ((rv = digest_update(session, session->verify_digest_algorithm, + &session->verify_digest_handle, pPart, ulPartLen)) != CKR_OK) goto fail; return mutex_unlock(p11_global_mutex); @@ -4187,8 +3813,8 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, fail: if (session != NULL) { session->verify_key_handle = CK_INVALID_HANDLE; - session->verify_digest_descriptor = NULL; - hal_hash_cleanup(&session->verify_digest_state); + session->verify_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->verify_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -4212,7 +3838,7 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, if (pSignature == NULL) lose(CKR_ARGUMENTS_BAD); - if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_state == NULL) + if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_handle.handle == HAL_HANDLE_NONE) lose(CKR_OPERATION_NOT_INITIALIZED); if (!p11_attribute_get_ulong(session->verify_key_handle, CKA_KEY_TYPE, &key_type)) @@ -4221,11 +3847,8 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, switch (key_type) { case CKK_RSA: - rv = verify_rsa_pkcs(session, NULL, 0, pSignature, ulSignatureLen); - break; - case CKK_EC: - rv = verify_ecdsa(session, NULL, 0, pSignature, ulSignatureLen); + rv = verify_hal_rpc(session, NULL, 0, pSignature, ulSignatureLen); break; default: @@ -4236,8 +3859,8 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, if (session != NULL) { session->verify_key_handle = CK_INVALID_HANDLE; - session->verify_digest_descriptor = NULL; - hal_hash_cleanup(&session->verify_digest_state); + session->verify_digest_algorithm = hal_digest_algorithm_none; + digest_cleanup(&session->verify_digest_handle); } mutex_unlock_return_with_rv(rv, p11_global_mutex); @@ -4321,7 +3944,7 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, if (RandomData == NULL) lose(CKR_ARGUMENTS_BAD); - if (!hal_check(hal_get_random(NULL, RandomData, ulRandomLen))) + if (!hal_check(hal_rpc_get_random(RandomData, ulRandomLen))) lose(CKR_FUNCTION_FAILED); fail: @@ -4361,44 +3984,55 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, if (slotID != P11_ONE_AND_ONLY_SLOT) return CKR_SLOT_ID_INVALID; +#if 0 + /* + * Perhaps revisit this after adding an RPC call to let us check + * which cores are available. For now, given that we now have + * software core support for these hash algorithms, this test isn't + * particularly useful. + */ + + hal_digest_algorithm_t algorithm = hal_digest_algorithm_none; + CK_RV rv = CKR_OK; + switch (type) { case CKM_SHA_1: case CKM_SHA1_RSA_PKCS: case CKM_SHA_1_HMAC: case CKM_ECDSA_SHA1: - if (hal_core_find(hal_hash_sha1->core_name, NULL) == NULL) - return CKR_MECHANISM_INVALID; + algorithm = hal_digest_algorithm_sha1; break; case CKM_SHA256: case CKM_SHA256_RSA_PKCS: case CKM_SHA256_HMAC: case CKM_ECDSA_SHA256: - if (hal_core_find(hal_hash_sha256->core_name, NULL) == NULL) - return CKR_MECHANISM_INVALID; + algorithm = hal_digest_algorithm_sha256; break; case CKM_SHA384: case CKM_SHA384_RSA_PKCS: case CKM_SHA384_HMAC: case CKM_ECDSA_SHA384: - if (hal_core_find(hal_hash_sha384->core_name, NULL) == NULL) - return CKR_MECHANISM_INVALID; + algorithm = hal_digest_algorithm_sha384; break; case CKM_SHA512: case CKM_SHA512_RSA_PKCS: case CKM_SHA512_HMAC: case CKM_ECDSA_SHA512: - if (hal_core_find(hal_hash_sha512->core_name, NULL) == NULL) - return CKR_MECHANISM_INVALID; + algorithm = hal_digest_algorithm_sha512; break; default: break; } + if (algorithm != hal_digest_algorithm_none && (rv = digest_available(algorithm)) != CKR_OK) + return rv; +#endif + switch (type) { case CKM_RSA_PKCS_KEY_PAIR_GEN: @@ -1,7 +1,7 @@ -- SQLite3 schema for Cryptech PKCS #11 implementation. -- -- Author: Rob Austein --- Copyright (c) 2015, NORDUnet A/S +-- Copyright (c) 2015-2016, NORDUnet A/S -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without @@ -53,58 +53,6 @@ PRAGMA foreign_keys = ON; --- Values we have to store somewhere and for which we have no better --- place. This is a table with exactly one row (enforced by the CHECK --- clause on the primary index). All columns must either allow NULL --- or provide default values. - -CREATE TABLE IF NOT EXISTS global ( - global_id INTEGER PRIMARY KEY NOT NULL DEFAULT 1 CHECK (global_id = 1), - - -- Key-encryption-key (KEK) - -- - -- The KEK **really** should be somewhere else, like in RAM - -- protected by tamper detection circuitry, but we don't have - -- that yet. Not obvious that a separate file would be more - -- secure, so keep it here until we do have a better place. - - kek BLOB CHECK (kek IS NULL OR (typeof(kek) = "blob" AND length(kek) IN (16, 32))), - - -- PBKDF2-based PIN storage and check values. - -- - -- "so_pin" and "user_pin" are PBKDF2 output, so only - -- moderately sensitive. - -- - -- Not obvious that PKCS #11 ever really allows "so_pin" to be - -- unset, so it may want a NOT NULL constraint, but in that - -- case we'll need to provide a default value, which doesn't - -- seem like much of an improvement. "so_pin" probably - -- requires out-of-band initialization. "user-pin" is allowed - -- to be unset, there's an error code specifically for that - -- situation. - -- - -- Numeric minima for PBKDF2 iterations, length of PIN, and - -- length of PBKDF2 salt are somewhat arbitrary, and will - -- probably change over time (which is why they are minima). - -- Initial testing was with 100000, which takes about 8 seconds - -- on a Novena with the current SHA256 and PBKDF2 - -- implementation, which seems a bit slow, so backed that down - -- a bit. Feel free to suggest better minima. - - pbkdf2_iterations INTEGER NOT NULL DEFAULT 20000, - so_pin BLOB, - user_pin BLOB, - so_pin_salt, BLOB, - user_pin_salt BLOB, - CHECK ((pbkdf2_iterations >= 10000) AND - (so_pin IS NULL OR (typeof(so_pin) = "blob" AND length(so_pin) >= 32)) AND - (user_pin IS NULL OR (typeof(user_pin) = "blob" AND length(user_pin) >= 32)) AND - (so_pin_salt IS NULL OR (typeof(so_pin_salt) = "blob" AND length(so_pin_salt) >= 16)) AND - (user_pin_salt IS NULL OR (typeof(user_pin_salt) = "blob" AND length(user_pin_salt) >= 16))) -); - -INSERT OR IGNORE INTO global DEFAULT VALUES; - CREATE TEMPORARY TABLE IF NOT EXISTS session ( session_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, session_handle INTEGER NOT NULL UNIQUE @@ -115,6 +63,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object ( object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, object_handle INTEGER NOT NULL UNIQUE CHECK (object_handle > 0 AND object_handle <= 0xFFFFFFFF), + hal_pkey_type INTEGER, session_id INTEGER REFERENCES session ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, @@ -129,7 +78,6 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object ( CREATE TEMPORARY TABLE IF NOT EXISTS session_object ( session_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - private_key BLOB UNIQUE, object_id INTEGER NOT NULL UNIQUE REFERENCES object ON DELETE CASCADE ON UPDATE CASCADE @@ -145,8 +93,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS session_attribute ( ); CREATE TABLE IF NOT EXISTS token_object ( - token_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - private_key BLOB UNIQUE + token_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ); CREATE TABLE IF NOT EXISTS token_attribute ( |