From dfe606d40c33a6213b89b310df0964392fd6d64d Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 23 May 2017 11:51:33 +0200 Subject: rpc: Convert mechanism parameters for portability This is similar to commit ba49b85e, but for mechanism parameters. --- p11-kit/rpc-client.c | 153 +--------------------- p11-kit/rpc-message.c | 342 ++++++++++++++++++++++++++++++++++++++++++++++++++ p11-kit/rpc-message.h | 31 +++++ p11-kit/rpc-server.c | 33 +++-- p11-kit/test-rpc.c | 66 ++++++++++ 5 files changed, 467 insertions(+), 158 deletions(-) (limited to 'p11-kit') 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 (¶ms, 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, ¶ms, 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 (¶ms, 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, ¶ms, 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 #include +#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"); -- cgit v1.1