From 759837da70a819ce1c32efd5e2db6537367e098b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 17 Apr 2015 19:45:30 +0200 Subject: adding /test/ecdsa and /test/eddsa to test client signing and verification over Curve25519 --- src/mint/taler-mint-httpd.c | 14 +++ src/mint/taler-mint-httpd_test.c | 179 +++++++++++++++++++++++++++++++++++++++ src/mint/taler-mint-httpd_test.h | 46 ++++++++++ 3 files changed, 239 insertions(+) (limited to 'src/mint') diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index b72db4768..32bad4048 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -210,6 +210,20 @@ handle_mhd_request (void *cls, { "/test/base32", NULL, "text/plain", "Only POST is allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, + + { "/test/ecdsa", MHD_HTTP_METHOD_POST, "application/json", + NULL, 0, + &TMH_TEST_handler_test_ecdsa, MHD_HTTP_OK }, + { "/test/ecdsa", NULL, "text/plain", + "Only POST is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, + + { "/test/eddsa", MHD_HTTP_METHOD_POST, "application/json", + NULL, 0, + &TMH_TEST_handler_test_eddsa, MHD_HTTP_OK }, + { "/test/eddsa", NULL, "text/plain", + "Only POST is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, #endif { NULL, NULL, NULL, NULL, 0, 0 } diff --git a/src/mint/taler-mint-httpd_test.c b/src/mint/taler-mint-httpd_test.c index 7d1c1dd57..c7e0af05d 100644 --- a/src/mint/taler-mint-httpd_test.c +++ b/src/mint/taler-mint-httpd_test.c @@ -88,6 +88,185 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh, } +/** + * Handle a "/test/ecdsa" request. Parses the JSON in the post, + * which must contain a "ecdsa_pub" with a public key and an + *"ecdsa_sig" with the corresponding signature for a purpose + * of #TALER_SIGNATURE_CLIENT_TEST_ECDSA. If the signature is + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_ECDSA is + * returned using the same JSON format. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +TMH_TEST_handler_test_ecdsa (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + json_t *json; + int res; + struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_CRYPTO_EcdsaSignature sig; + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct TMH_PARSE_FieldSpecification spec[] = { + TMH_PARSE_MEMBER_FIXED ("ecdsa_pub", &pub), + TMH_PARSE_MEMBER_FIXED ("ecdsa_sig", &sig), + TMH_PARSE_MEMBER_END + }; + struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; + + res = TMH_PARSE_post_json (connection, + connection_cls, + upload_data, + upload_data_size, + &json); + if (GNUNET_SYSERR == res) + return MHD_NO; + if ( (GNUNET_NO == res) || (NULL == json) ) + return MHD_YES; + res = TMH_PARSE_json_data (connection, + json, + spec); + if (GNUNET_YES != res) + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); + purpose.purpose = htonl (TALER_SIGNATURE_CLIENT_TEST_ECDSA); + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_CLIENT_TEST_ECDSA, + &purpose, + &sig, + &pub)) + { + TMH_PARSE_release_data (spec); + json_decref (json); + return TMH_RESPONSE_reply_signature_invalid (connection, + "ecdsa_sig"); + } + TMH_PARSE_release_data (spec); + json_decref (json); + pk = GNUNET_CRYPTO_ecdsa_key_create (); + purpose.purpose = htonl (TALER_SIGNATURE_MINT_TEST_ECDSA); + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_sign (pk, + &purpose, + &sig)) + { + GNUNET_free (pk); + return TMH_RESPONSE_reply_internal_error (connection, + "Failed to ECDSA-sign"); + } + GNUNET_CRYPTO_ecdsa_key_get_public (pk, + &pub); + GNUNET_free (pk); + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o}", + "ecdsa_pub", + TALER_json_from_data (&pub, + sizeof (pub)), + "ecdsa_sig", + TALER_json_from_data (&sig, + sizeof (sig))); +} + + +/** + * Handle a "/test/eddsa" request. Parses the JSON in the post, + * which must contain a "eddsa_pub" with a public key and an + *"ecdsa_sig" with the corresponding signature for a purpose + * of #TALER_SIGNATURE_CLIENT_TEST_EDDSA. If the signature is + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is + * returned using the same JSON format. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + json_t *json; + int res; + struct GNUNET_CRYPTO_EddsaPublicKey pub; + struct GNUNET_CRYPTO_EddsaSignature sig; + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct TMH_PARSE_FieldSpecification spec[] = { + TMH_PARSE_MEMBER_FIXED ("eddsa_pub", &pub), + TMH_PARSE_MEMBER_FIXED ("eddsa_sig", &sig), + TMH_PARSE_MEMBER_END + }; + struct GNUNET_CRYPTO_EddsaPrivateKey *pk; + + res = TMH_PARSE_post_json (connection, + connection_cls, + upload_data, + upload_data_size, + &json); + if (GNUNET_SYSERR == res) + return MHD_NO; + if ( (GNUNET_NO == res) || (NULL == json) ) + return MHD_YES; + res = TMH_PARSE_json_data (connection, + json, + spec); + if (GNUNET_YES != res) + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); + purpose.purpose = htonl (TALER_SIGNATURE_CLIENT_TEST_EDDSA); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_CLIENT_TEST_EDDSA, + &purpose, + &sig, + &pub)) + { + TMH_PARSE_release_data (spec); + json_decref (json); + return TMH_RESPONSE_reply_signature_invalid (connection, + "eddsa_sig"); + } + TMH_PARSE_release_data (spec); + json_decref (json); + pk = GNUNET_CRYPTO_eddsa_key_create (); + purpose.purpose = htonl (TALER_SIGNATURE_MINT_TEST_EDDSA); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_sign (pk, + &purpose, + &sig)) + { + GNUNET_free (pk); + return TMH_RESPONSE_reply_internal_error (connection, + "Failed to EdDSA-sign"); + } + GNUNET_CRYPTO_eddsa_key_get_public (pk, + &pub); + GNUNET_free (pk); + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o}", + "eddsa_pub", + TALER_json_from_data (&pub, + sizeof (pub)), + "eddsa_sig", + TALER_json_from_data (&sig, + sizeof (sig))); +} + + + /** * Handle a "/test" request. Parses the JSON in the post. * diff --git a/src/mint/taler-mint-httpd_test.h b/src/mint/taler-mint-httpd_test.h index 6584af581..609473ec1 100644 --- a/src/mint/taler-mint-httpd_test.h +++ b/src/mint/taler-mint-httpd_test.h @@ -49,6 +49,52 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh, size_t *upload_data_size); +/** + * Handle a "/test/ecdsa" request. Parses the JSON in the post, + * which must contain a "ecdsa_pub" with a public key and an + *"ecdsa_sig" with the corresponding signature for a purpose + * of #TALER_SIGNATURE_CLIENT_TEST_ECDSA. If the signature is + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_ECDSA is + * returned using the same JSON format. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +TMH_TEST_handler_test_ecdsa (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + + +/** + * Handle a "/test/eddsa" request. Parses the JSON in the post, + * which must contain a "eddsa_pub" with a public key and an + *"ecdsa_sig" with the corresponding signature for a purpose + * of #TALER_SIGNATURE_CLIENT_TEST_EDDSA. If the signature is + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is + * returned using the same JSON format. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + + /** * Handle a "/test" request. Parses the JSON in the post. * -- cgit v1.2.3