summaryrefslogtreecommitdiff
path: root/p11-kit
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2017-05-23 11:51:33 +0200
committerDaiki Ueno <ueno@gnu.org>2017-05-24 11:27:28 +0200
commitdfe606d40c33a6213b89b310df0964392fd6d64d (patch)
treef933da2ae2bea4ab894c9376ab2f1e99da434442 /p11-kit
parent3b484b87e13e52873ea48f920132ecd96cb79cbc (diff)
rpc: Convert mechanism parameters for portability
This is similar to commit ba49b85e, but for mechanism parameters.
Diffstat (limited to 'p11-kit')
-rw-r--r--p11-kit/rpc-client.c153
-rw-r--r--p11-kit/rpc-message.c342
-rw-r--r--p11-kit/rpc-message.h31
-rw-r--r--p11-kit/rpc-server.c33
-rw-r--r--p11-kit/test-rpc.c66
5 files changed, 467 insertions, 158 deletions
diff --git a/p11-kit/rpc-client.c b/p11-kit/rpc-client.c
index 3521ddd..0dd4525 100644
--- a/p11-kit/rpc-client.c
+++ b/p11-kit/rpc-client.c
@@ -379,143 +379,6 @@ proto_read_ulong_array (p11_rpc_message *msg, CK_ULONG_PTR arr,
return p11_buffer_failed (msg->input) ? PARSE_ERROR : CKR_OK;
}
-/* Used to override the supported mechanisms in tests */
-CK_MECHANISM_TYPE *p11_rpc_mechanisms_override_supported = NULL;
-
-static bool
-mechanism_has_sane_parameters (CK_MECHANISM_TYPE type)
-{
- int i;
-
- /* This can be set from tests, to override default set of supported */
- if (p11_rpc_mechanisms_override_supported) {
- for (i = 0; p11_rpc_mechanisms_override_supported[i] != 0; i++) {
- if (p11_rpc_mechanisms_override_supported[i] == type)
- return true;
- }
-
- return false;
- }
-
- /* This list is incomplete */
- switch (type) {
- case CKM_RSA_PKCS_OAEP:
- case CKM_RSA_PKCS_PSS:
- return true;
- default:
- return false;
- }
-}
-
-static bool
-mechanism_has_no_parameters (CK_MECHANISM_TYPE mech)
-{
- /* This list is incomplete */
-
- switch (mech) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- case CKM_RSA_X9_31_KEY_PAIR_GEN:
- case CKM_RSA_PKCS:
- case CKM_RSA_9796:
- case CKM_RSA_X_509:
- case CKM_RSA_X9_31:
- case CKM_MD2_RSA_PKCS:
- case CKM_MD5_RSA_PKCS:
- case CKM_SHA1_RSA_PKCS:
- case CKM_SHA256_RSA_PKCS:
- case CKM_SHA384_RSA_PKCS:
- case CKM_SHA512_RSA_PKCS:
- case CKM_RIPEMD128_RSA_PKCS:
- case CKM_RIPEMD160_RSA_PKCS:
- case CKM_SHA1_RSA_X9_31:
- case CKM_DSA_KEY_PAIR_GEN:
- case CKM_DSA_PARAMETER_GEN:
- case CKM_DSA:
- case CKM_DSA_SHA1:
- case CKM_FORTEZZA_TIMESTAMP:
- case CKM_EC_KEY_PAIR_GEN:
- case CKM_ECDSA:
- case CKM_ECDSA_SHA1:
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- case CKM_DH_PKCS_PARAMETER_GEN:
- case CKM_X9_42_DH_KEY_PAIR_GEN:
- case CKM_X9_42_DH_PARAMETER_GEN:
- case CKM_KEA_KEY_PAIR_GEN:
- case CKM_GENERIC_SECRET_KEY_GEN:
- case CKM_RC2_KEY_GEN:
- case CKM_RC4_KEY_GEN:
- case CKM_RC4:
- case CKM_RC5_KEY_GEN:
- case CKM_AES_KEY_GEN:
- case CKM_AES_ECB:
- case CKM_AES_MAC:
- case CKM_DES_KEY_GEN:
- case CKM_DES2_KEY_GEN:
- case CKM_DES3_KEY_GEN:
- case CKM_CDMF_KEY_GEN:
- case CKM_CAST_KEY_GEN:
- case CKM_CAST3_KEY_GEN:
- case CKM_CAST128_KEY_GEN:
- case CKM_IDEA_KEY_GEN:
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- case CKM_TLS_PRE_MASTER_KEY_GEN:
- case CKM_SKIPJACK_KEY_GEN:
- case CKM_BATON_KEY_GEN:
- case CKM_JUNIPER_KEY_GEN:
- case CKM_RC2_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST128_ECB:
- case CKM_RC5_ECB:
- case CKM_IDEA_ECB:
- case CKM_RC2_MAC:
- case CKM_DES_MAC:
- case CKM_DES3_MAC:
- case CKM_CDMF_MAC:
- case CKM_CAST_MAC:
- case CKM_CAST3_MAC:
- case CKM_RC5_MAC:
- case CKM_IDEA_MAC:
- case CKM_SSL3_MD5_MAC:
- case CKM_SSL3_SHA1_MAC:
- case CKM_SKIPJACK_WRAP:
- case CKM_BATON_WRAP:
- case CKM_JUNIPER_WRAP:
- case CKM_MD2:
- case CKM_MD2_HMAC:
- case CKM_MD5:
- case CKM_MD5_HMAC:
- case CKM_SHA_1:
- case CKM_SHA_1_HMAC:
- case CKM_SHA256:
- case CKM_SHA256_HMAC:
- case CKM_SHA384:
- case CKM_SHA384_HMAC:
- case CKM_SHA512:
- case CKM_SHA512_HMAC:
- case CKM_FASTHASH:
- case CKM_RIPEMD128:
- case CKM_RIPEMD128_HMAC:
- case CKM_RIPEMD160:
- case CKM_RIPEMD160_HMAC:
- case CKM_KEY_WRAP_LYNKS:
- return true;
- default:
- return false;
- };
-}
-
-static bool
-mechanism_is_supported (CK_MECHANISM_TYPE mech)
-{
- if (mechanism_has_no_parameters (mech) ||
- mechanism_has_sane_parameters (mech))
- return true;
- return false;
-}
static void
mechanism_list_purge (CK_MECHANISM_TYPE_PTR mechs,
CK_ULONG *n_mechs)
@@ -526,7 +389,7 @@ mechanism_list_purge (CK_MECHANISM_TYPE_PTR mechs,
assert (n_mechs != NULL);
for (i = 0; i < (int)(*n_mechs); ++i) {
- if (!mechanism_is_supported (mechs[i])) {
+ if (!p11_rpc_mechanism_is_supported (mechs[i])) {
/* Remove the mechanism from the list */
memmove (&mechs[i], &mechs[i + 1],
@@ -549,8 +412,8 @@ proto_write_mechanism (p11_rpc_message *msg,
/* Make sure this is in the right order */
assert (!msg->signature || p11_rpc_message_verify_part (msg, "M"));
- /* The mechanism type */
- p11_rpc_buffer_add_uint32 (msg->output, mech->mechanism);
+ if (!p11_rpc_mechanism_is_supported (mech->mechanism))
+ return CKR_MECHANISM_INVALID;
/*
* PKCS#11 mechanism parameters are not easy to serialize. They're
@@ -564,13 +427,7 @@ proto_write_mechanism (p11_rpc_message *msg,
* pointing to garbage if they don't think it's going to be used.
*/
- if (mechanism_has_no_parameters (mech->mechanism))
- p11_rpc_buffer_add_byte_array (msg->output, NULL, 0);
- else if (mechanism_has_sane_parameters (mech->mechanism))
- p11_rpc_buffer_add_byte_array (msg->output, mech->pParameter,
- mech->ulParameterLen);
- else
- return CKR_MECHANISM_INVALID;
+ p11_rpc_buffer_add_mechanism (msg->output, mech);
return p11_buffer_failed (msg->output) ? CKR_HOST_MEMORY : CKR_OK;
}
@@ -746,7 +603,7 @@ proto_read_sesssion_info (p11_rpc_message *msg,
{ _ret = CKR_HOST_MEMORY; goto _cleanup; }
#define IN_MECHANISM_TYPE(val) \
- if(!mechanism_is_supported (val)) \
+ if(!p11_rpc_mechanism_is_supported (val)) \
{ _ret = CKR_MECHANISM_INVALID; goto _cleanup; } \
if (!p11_rpc_message_write_ulong (&_msg, val)) \
{ _ret = CKR_HOST_MEMORY; goto _cleanup; }
diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c
index ae6af2f..32f5a45 100644
--- a/p11-kit/rpc-message.c
+++ b/p11-kit/rpc-message.c
@@ -1240,3 +1240,345 @@ p11_rpc_buffer_get_attribute (p11_buffer *buffer,
attr->type = type;
return true;
}
+
+/* Used to override the supported mechanisms in tests */
+CK_MECHANISM_TYPE *p11_rpc_mechanisms_override_supported = NULL;
+
+typedef struct {
+ CK_MECHANISM_TYPE type;
+ p11_rpc_value_encoder encode;
+ p11_rpc_value_decoder decode;
+} p11_rpc_mechanism_serializer;
+
+void
+p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value (p11_buffer *buffer,
+ const void *value,
+ CK_ULONG value_length)
+{
+ CK_RSA_PKCS_PSS_PARAMS params;
+
+ /* Check if value can be converted to CK_RSA_PKCS_PSS_PARAMS. */
+ if (value_length != sizeof (CK_RSA_PKCS_PSS_PARAMS)) {
+ p11_buffer_fail (buffer);
+ return;
+ }
+
+ memcpy (&params, value, value_length);
+
+ /* Check if params.hashAlg, params.mgf, and params.sLen can be
+ * converted to uint64_t. */
+ if (params.hashAlg > UINT64_MAX || params.mgf > UINT64_MAX ||
+ params.sLen > UINT64_MAX) {
+ p11_buffer_fail (buffer);
+ return;
+ }
+
+ p11_rpc_buffer_add_uint64 (buffer, params.hashAlg);
+ p11_rpc_buffer_add_uint64 (buffer, params.mgf);
+ p11_rpc_buffer_add_uint64 (buffer, params.sLen);
+}
+
+bool
+p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value (p11_buffer *buffer,
+ size_t *offset,
+ void *value,
+ CK_ULONG *value_length)
+{
+ uint64_t val[3];
+
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[0]))
+ return false;
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[1]))
+ return false;
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[2]))
+ return false;
+
+ if (value) {
+ CK_RSA_PKCS_PSS_PARAMS params;
+
+ params.hashAlg = val[0];
+ params.mgf = val[1];
+ params.sLen = val[2];
+
+ memcpy (value, &params, sizeof (CK_RSA_PKCS_PSS_PARAMS));
+ }
+
+ if (value_length)
+ *value_length = sizeof (CK_RSA_PKCS_PSS_PARAMS);
+
+ return true;
+}
+
+void
+p11_rpc_buffer_add_rsa_pkcs_oaep_mechanism_value (p11_buffer *buffer,
+ const void *value,
+ CK_ULONG value_length)
+{
+ CK_RSA_PKCS_OAEP_PARAMS params;
+
+ /* Check if value can be converted to CK_RSA_PKCS_OAEP_PARAMS. */
+ if (value_length != sizeof (CK_RSA_PKCS_OAEP_PARAMS)) {
+ p11_buffer_fail (buffer);
+ return;
+ }
+
+ memcpy (&params, value, value_length);
+
+ /* Check if params.hashAlg, params.mgf, and params.source can be
+ * converted to uint64_t. */
+ if (params.hashAlg > UINT64_MAX || params.mgf > UINT64_MAX ||
+ params.source > UINT64_MAX) {
+ p11_buffer_fail (buffer);
+ return;
+ }
+
+ p11_rpc_buffer_add_uint64 (buffer, params.hashAlg);
+ p11_rpc_buffer_add_uint64 (buffer, params.mgf);
+ p11_rpc_buffer_add_uint64 (buffer, params.source);
+
+ /* parmas.pSourceData can only be an array of CK_BYTE or
+ * NULL */
+ p11_rpc_buffer_add_byte_array (buffer,
+ (unsigned char *)params.pSourceData,
+ params.ulSourceDataLen);
+}
+
+bool
+p11_rpc_buffer_get_rsa_pkcs_oaep_mechanism_value (p11_buffer *buffer,
+ size_t *offset,
+ void *value,
+ CK_ULONG *value_length)
+{
+ uint64_t val[3];
+ const unsigned char *data;
+ size_t len;
+
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[0]))
+ return false;
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[1]))
+ return false;
+ if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[2]))
+ return false;
+ if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
+ return false;
+
+ if (value) {
+ CK_RSA_PKCS_OAEP_PARAMS params;
+
+ params.hashAlg = val[0];
+ params.mgf = val[1];
+ params.source = val[2];
+ params.pSourceData = (void *) data;
+ params.ulSourceDataLen = len;
+
+ memcpy (value, &params, sizeof (CK_RSA_PKCS_OAEP_PARAMS));
+ }
+
+ if (value_length)
+ *value_length = sizeof (CK_RSA_PKCS_OAEP_PARAMS);
+
+ return true;
+}
+
+static p11_rpc_mechanism_serializer p11_rpc_mechanism_serializers[] = {
+ { CKM_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
+ { CKM_RSA_PKCS_OAEP, p11_rpc_buffer_add_rsa_pkcs_oaep_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_oaep_mechanism_value }
+};
+
+static p11_rpc_mechanism_serializer p11_rpc_byte_array_mechanism_serializer = {
+ 0, p11_rpc_buffer_add_byte_array_value, p11_rpc_buffer_get_byte_array_value
+};
+
+static bool
+mechanism_has_sane_parameters (CK_MECHANISM_TYPE type)
+{
+ int i;
+
+ /* This can be set from tests, to override default set of supported */
+ if (p11_rpc_mechanisms_override_supported) {
+ for (i = 0; p11_rpc_mechanisms_override_supported[i] != 0; i++) {
+ if (p11_rpc_mechanisms_override_supported[i] == type)
+ return true;
+ }
+
+ return false;
+ }
+
+ for (i = 0; i < ELEMS(p11_rpc_mechanism_serializers); i++) {
+ if (p11_rpc_mechanism_serializers[i].type == type)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+mechanism_has_no_parameters (CK_MECHANISM_TYPE mech)
+{
+ /* This list is incomplete */
+
+ switch (mech) {
+ case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
+ case CKM_RSA_PKCS:
+ case CKM_RSA_9796:
+ case CKM_RSA_X_509:
+ case CKM_RSA_X9_31:
+ case CKM_MD2_RSA_PKCS:
+ case CKM_MD5_RSA_PKCS:
+ case CKM_SHA1_RSA_PKCS:
+ case CKM_SHA256_RSA_PKCS:
+ case CKM_SHA384_RSA_PKCS:
+ case CKM_SHA512_RSA_PKCS:
+ case CKM_RIPEMD128_RSA_PKCS:
+ case CKM_RIPEMD160_RSA_PKCS:
+ case CKM_SHA1_RSA_X9_31:
+ case CKM_DSA_KEY_PAIR_GEN:
+ case CKM_DSA_PARAMETER_GEN:
+ case CKM_DSA:
+ case CKM_DSA_SHA1:
+ case CKM_FORTEZZA_TIMESTAMP:
+ case CKM_EC_KEY_PAIR_GEN:
+ case CKM_ECDSA:
+ case CKM_ECDSA_SHA1:
+ case CKM_DH_PKCS_KEY_PAIR_GEN:
+ case CKM_DH_PKCS_PARAMETER_GEN:
+ case CKM_X9_42_DH_KEY_PAIR_GEN:
+ case CKM_X9_42_DH_PARAMETER_GEN:
+ case CKM_KEA_KEY_PAIR_GEN:
+ case CKM_GENERIC_SECRET_KEY_GEN:
+ case CKM_RC2_KEY_GEN:
+ case CKM_RC4_KEY_GEN:
+ case CKM_RC4:
+ case CKM_RC5_KEY_GEN:
+ case CKM_AES_KEY_GEN:
+ case CKM_AES_ECB:
+ case CKM_AES_MAC:
+ case CKM_DES_KEY_GEN:
+ case CKM_DES2_KEY_GEN:
+ case CKM_DES3_KEY_GEN:
+ case CKM_CDMF_KEY_GEN:
+ case CKM_CAST_KEY_GEN:
+ case CKM_CAST3_KEY_GEN:
+ case CKM_CAST128_KEY_GEN:
+ case CKM_IDEA_KEY_GEN:
+ case CKM_SSL3_PRE_MASTER_KEY_GEN:
+ case CKM_TLS_PRE_MASTER_KEY_GEN:
+ case CKM_SKIPJACK_KEY_GEN:
+ case CKM_BATON_KEY_GEN:
+ case CKM_JUNIPER_KEY_GEN:
+ case CKM_RC2_ECB:
+ case CKM_DES_ECB:
+ case CKM_DES3_ECB:
+ case CKM_CDMF_ECB:
+ case CKM_CAST_ECB:
+ case CKM_CAST3_ECB:
+ case CKM_CAST128_ECB:
+ case CKM_RC5_ECB:
+ case CKM_IDEA_ECB:
+ case CKM_RC2_MAC:
+ case CKM_DES_MAC:
+ case CKM_DES3_MAC:
+ case CKM_CDMF_MAC:
+ case CKM_CAST_MAC:
+ case CKM_CAST3_MAC:
+ case CKM_RC5_MAC:
+ case CKM_IDEA_MAC:
+ case CKM_SSL3_MD5_MAC:
+ case CKM_SSL3_SHA1_MAC:
+ case CKM_SKIPJACK_WRAP:
+ case CKM_BATON_WRAP:
+ case CKM_JUNIPER_WRAP:
+ case CKM_MD2:
+ case CKM_MD2_HMAC:
+ case CKM_MD5:
+ case CKM_MD5_HMAC:
+ case CKM_SHA_1:
+ case CKM_SHA_1_HMAC:
+ case CKM_SHA256:
+ case CKM_SHA256_HMAC:
+ case CKM_SHA384:
+ case CKM_SHA384_HMAC:
+ case CKM_SHA512:
+ case CKM_SHA512_HMAC:
+ case CKM_FASTHASH:
+ case CKM_RIPEMD128:
+ case CKM_RIPEMD128_HMAC:
+ case CKM_RIPEMD160:
+ case CKM_RIPEMD160_HMAC:
+ case CKM_KEY_WRAP_LYNKS:
+ return true;
+ default:
+ return false;
+ };
+}
+
+bool
+p11_rpc_mechanism_is_supported (CK_MECHANISM_TYPE mech)
+{
+ if (mechanism_has_no_parameters (mech) ||
+ mechanism_has_sane_parameters (mech))
+ return true;
+ return false;
+}
+
+void
+p11_rpc_buffer_add_mechanism (p11_buffer *buffer, const CK_MECHANISM *mech)
+{
+ p11_rpc_mechanism_serializer *serializer = NULL;
+ size_t i;
+
+ /* The mechanism type */
+ p11_rpc_buffer_add_uint32 (buffer, mech->mechanism);
+
+ if (mechanism_has_no_parameters (mech->mechanism)) {
+ p11_rpc_buffer_add_byte_array (buffer, NULL, 0);
+ return;
+ }
+
+ assert (mechanism_has_sane_parameters (mech->mechanism));
+
+ for (i = 0; i < ELEMS (p11_rpc_mechanism_serializers); i++) {
+ if (p11_rpc_mechanism_serializers[i].type == mech->mechanism) {
+ serializer = &p11_rpc_mechanism_serializers[i];
+ break;
+ }
+ }
+
+ if (serializer == NULL)
+ serializer = &p11_rpc_byte_array_mechanism_serializer;
+
+ serializer->encode (buffer, mech->pParameter, mech->ulParameterLen);
+}
+
+bool
+p11_rpc_buffer_get_mechanism (p11_buffer *buffer,
+ size_t *offset,
+ CK_MECHANISM *mech)
+{
+ uint32_t mechanism;
+ p11_rpc_mechanism_serializer *serializer = NULL;
+ size_t i;
+
+ /* The mechanism type */
+ if (!p11_rpc_buffer_get_uint32 (buffer, offset, &mechanism))
+ return false;
+
+ mech->mechanism = mechanism;
+
+ for (i = 0; i < ELEMS (p11_rpc_mechanism_serializers); i++) {
+ if (p11_rpc_mechanism_serializers[i].type == mech->mechanism) {
+ serializer = &p11_rpc_mechanism_serializers[i];
+ break;
+ }
+ }
+
+ if (serializer == NULL)
+ serializer = &p11_rpc_byte_array_mechanism_serializer;
+
+ if (!serializer->decode (buffer, offset,
+ mech->pParameter, &mech->ulParameterLen))
+ return false;
+
+ return true;
+}
diff --git a/p11-kit/rpc-message.h b/p11-kit/rpc-message.h
index 5c81c1c..989bbc0 100644
--- a/p11-kit/rpc-message.h
+++ b/p11-kit/rpc-message.h
@@ -444,4 +444,35 @@ bool p11_rpc_buffer_get_byte_array_value (p11_buffer *buffer,
void *value,
CK_ULONG *value_length);
+bool p11_rpc_mechanism_is_supported (CK_MECHANISM_TYPE mech);
+
+void p11_rpc_buffer_add_mechanism (p11_buffer *buffer,
+ const CK_MECHANISM *mech);
+
+bool p11_rpc_buffer_get_mechanism (p11_buffer *buffer,
+ size_t *offset,
+ CK_MECHANISM *mech);
+
+void p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value
+ (p11_buffer *buffer,
+ const void *value,
+ CK_ULONG value_length);
+
+bool p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value
+ (p11_buffer *buffer,
+ size_t *offset,
+ void *value,
+ CK_ULONG *value_length);
+
+void p11_rpc_buffer_add_rsa_pkcs_oaep_mechanism_value
+ (p11_buffer *buffer,
+ const void *value,
+ CK_ULONG value_length);
+
+bool p11_rpc_buffer_get_rsa_pkcs_oaep_mechanism_value
+ (p11_buffer *buffer,
+ size_t *offset,
+ void *value,
+ CK_ULONG *value_length);
+
#endif /* _RPC_MESSAGE_H */
diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c
index 1eebf1b..47beed0 100644
--- a/p11-kit/rpc-server.c
+++ b/p11-kit/rpc-server.c
@@ -400,9 +400,8 @@ static CK_RV
proto_read_mechanism (p11_rpc_message *msg,
CK_MECHANISM_PTR mech)
{
- const unsigned char *data;
- uint32_t value;
- size_t n_data;
+ size_t offset;
+ CK_MECHANISM temp;
assert (msg != NULL);
assert (mech != NULL);
@@ -411,17 +410,31 @@ proto_read_mechanism (p11_rpc_message *msg,
/* Make sure this is in the right order */
assert (!msg->signature || p11_rpc_message_verify_part (msg, "M"));
- /* The mechanism type */
- if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &value))
+ /* Check the length needed to store the parameter */
+ memset (&temp, 0, sizeof (temp));
+ offset = msg->parsed;
+ if (!p11_rpc_buffer_get_mechanism (msg->input, &offset, &temp)) {
+ msg->parsed = offset;
return PARSE_ERROR;
+ }
- /* The mechanism data */
- if (!p11_rpc_buffer_get_byte_array (msg->input, &msg->parsed, &data, &n_data))
+ mech->mechanism = temp.mechanism;
+
+ /* The mechanism doesn't require parameter */
+ if (temp.ulParameterLen == 0) {
+ mech->pParameter = NULL;
+ mech->ulParameterLen = 0;
+ msg->parsed = offset;
+ return CKR_OK;
+ }
+
+ /* Actually retrieve the parameter */
+ mech->pParameter = p11_rpc_message_alloc_extra (msg, temp.ulParameterLen);
+ if (!p11_rpc_buffer_get_mechanism (msg->input, &msg->parsed, mech))
return PARSE_ERROR;
- mech->mechanism = value;
- mech->pParameter = (CK_VOID_PTR)data;
- mech->ulParameterLen = n_data;
+ assert (msg->parsed == offset);
+
return CKR_OK;
}
diff --git a/p11-kit/test-rpc.c b/p11-kit/test-rpc.c
index c6490bf..a20e939 100644
--- a/p11-kit/test-rpc.c
+++ b/p11-kit/test-rpc.c
@@ -55,6 +55,8 @@
#include <stdio.h>
#include <stdlib.h>
+#define ELEMS(x) (sizeof (x) / sizeof (x[0]))
+
static void
test_new_free (void)
{
@@ -567,6 +569,69 @@ test_byte_array_value (void)
p11_buffer_uninit (&buffer);
}
+static void
+test_mechanism_value (void)
+{
+ p11_buffer buffer;
+ CK_MECHANISM_TYPE *mechanisms;
+ CK_RSA_PKCS_PSS_PARAMS pss_params = {
+ CKM_SHA256,
+ CKG_MGF1_SHA256,
+ 32
+ };
+ CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
+ CKM_SHA384,
+ CKG_MGF1_SHA384,
+ 0,
+ NULL,
+ 0
+ };
+ CK_MECHANISM mechs[] = {
+ { CKM_RSA_PKCS_PSS, &pss_params, sizeof (pss_params) },
+ { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof (oaep_params) }
+ };
+
+ CK_MECHANISM val;
+ size_t offset = 0;
+ bool ret;
+ size_t i;
+
+ mechanisms = p11_rpc_mechanisms_override_supported;
+ p11_rpc_mechanisms_override_supported = NULL;
+
+ p11_buffer_init (&buffer, 0);
+
+ for (i = 0; i < ELEMS (mechs); i++) {
+ size_t offset2 = offset;
+
+ p11_rpc_buffer_add_mechanism (&buffer, &mechs[i]);
+ assert (!p11_buffer_failed (&buffer));
+
+ memset (&val, 0, sizeof (val));
+ ret = p11_rpc_buffer_get_mechanism (&buffer, &offset, &val);
+ assert_num_eq (true, ret);
+ assert_num_eq (mechs[i].mechanism, val.mechanism);
+ assert_ptr_eq (NULL, val.pParameter);
+ assert_num_eq (mechs[i].ulParameterLen, val.ulParameterLen);
+
+ val.pParameter = malloc (val.ulParameterLen);
+ assert_ptr_not_null (val.pParameter);
+
+ offset = offset2;
+ ret = p11_rpc_buffer_get_mechanism (&buffer, &offset, &val);
+ assert_num_eq (true, ret);
+ assert_num_eq (mechs[i].mechanism, val.mechanism);
+ assert_num_eq (mechs[i].ulParameterLen, val.ulParameterLen);
+ assert (memcmp (val.pParameter, mechs[i].pParameter, val.ulParameterLen) == 0);
+
+ free (val.pParameter);
+ }
+
+ p11_buffer_uninit (&buffer);
+
+ p11_rpc_mechanisms_override_supported = mechanisms;
+}
+
static p11_virtual base;
static unsigned int rpc_initialized = 0;
@@ -1257,6 +1322,7 @@ main (int argc,
p11_test (test_mechanism_type_array_value, "/rpc/mechanism-type-array-value");
p11_test (test_date_value, "/rpc/date-value");
p11_test (test_byte_array_value, "/rpc/byte-array-value");
+ p11_test (test_mechanism_value, "/rpc/mechanism-value");
p11_test (test_initialize_fails_on_client, "/rpc/initialize-fails-on-client");
p11_test (test_initialize_fails_on_server, "/rpc/initialize-fails-on-server");