From c154e50148794f498259b835d9ac064660e769aa Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 30 Jun 2015 21:25:16 +0200 Subject: [PATCH] fix /test/rsa API to persist private RSA key and use it across requests and allow client to fetch it before requesting the signature --- src/mint/taler-mint-httpd.c | 13 +++- src/mint/taler-mint-httpd_test.c | 102 +++++++++++++++++++++---------- src/mint/taler-mint-httpd_test.h | 44 +++++++++---- 3 files changed, 112 insertions(+), 47 deletions(-) diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index 51cb14c88..66d7e01e2 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -242,10 +242,17 @@ handle_mhd_request (void *cls, "Only POST is allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, - { "/test/rsa", MHD_HTTP_METHOD_POST, "application/json", + { "/test/rsa/get", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, - &TMH_TEST_handler_test_rsa, MHD_HTTP_OK }, - { "/test/rsa", NULL, "text/plain", + &TMH_TEST_handler_test_rsa_get, MHD_HTTP_OK }, + { "/test/rsa/get", NULL, "text/plain", + "Only GET is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, + + { "/test/rsa/sign", MHD_HTTP_METHOD_POST, "application/json", + NULL, 0, + &TMH_TEST_handler_test_rsa_sign, MHD_HTTP_OK }, + { "/test/rsa/sign", NULL, "text/plain", "Only POST is allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, diff --git a/src/mint/taler-mint-httpd_test.c b/src/mint/taler-mint-httpd_test.c index 22c13908e..0c6838ee5 100644 --- a/src/mint/taler-mint-httpd_test.c +++ b/src/mint/taler-mint-httpd_test.c @@ -29,10 +29,16 @@ #include "taler-mint-httpd_responses.h" +/** + * Private key the test module uses for signing. + */ +static struct GNUNET_CRYPTO_rsa_PrivateKey *rsa_pk; + + /** * Handle a "/test/base32" request. Parses the JSON in the post, runs * the Crockford Base32 decoder on the "input" field in the JSON, - * hashes the result and sends the hashed value back as a JSON + * hashes the result and sends the hashed value back as a JSON * string with in Base32 Crockford encoding. Thus, this API * allows testing the hashing and Crockford encoding/decoding * functions. @@ -197,7 +203,7 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh, TMH_PARSE_MEMBER_VARIABLE ("input"), TMH_PARSE_MEMBER_END }; - + res = TMH_PARSE_post_json (connection, connection_cls, upload_data, @@ -296,11 +302,11 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh, /** - * Handle a "/test/eddsa" request. Parses the JSON in the post, + * Handle a "/test/eddsa" request. Parses the JSON in the post, * which must contain a "eddsa_pub" with a public key and an *"eddsa_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 + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is * returned using the same JSON format. * * @param rh context of the handler @@ -384,9 +390,8 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, /** - * Handle a "/test/rsa" request. Parses the JSON in the post, which - * must contain an "blind_ev" blinded value. An RSA public key - * ("rsa_pub") and a blinded signature ("rsa_blind_sig") are returned. + * Handle a "/test/rsa/get" request. Returns the RSA public key + * ("rsa_pub") which is used for signing in "/test/rsa/sign". * * @param rh context of the handler * @param connection the MHD connection to handle @@ -396,21 +401,66 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, * @return MHD result code */ int -TMH_TEST_handler_test_rsa (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) +TMH_TEST_handler_test_rsa_get (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + int res; + struct GNUNET_CRYPTO_rsa_PublicKey *pub; + + if (NULL == rsa_pk) + rsa_pk = GNUNET_CRYPTO_rsa_private_key_create (1024); + if (NULL == rsa_pk) + { + GNUNET_break (0); + return TMH_RESPONSE_reply_internal_error (connection, + "Failed to create RSA key"); + } + pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk); + if (NULL == pub) + { + GNUNET_break (0); + return TMH_RESPONSE_reply_internal_error (connection, + "Failed to get public RSA key"); + } + res = TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o}", + "rsa_pub", + TALER_json_from_rsa_public_key (pub)); + GNUNET_CRYPTO_rsa_public_key_free (pub); + return res; +} + + +/** + * Handle a "/test/rsa/sign" request. Parses the JSON in the post, which + * must contain an "blind_ev" blinded value. A a blinded signature + * ("rsa_blind_sig") is returned. + * + * @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_rsa_sign (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_rsa_PublicKey *pub; struct GNUNET_CRYPTO_rsa_Signature *sig; struct TMH_PARSE_FieldSpecification spec[] = { TMH_PARSE_MEMBER_VARIABLE ("blind_ev"), TMH_PARSE_MEMBER_END }; - struct GNUNET_CRYPTO_rsa_PrivateKey *pk; res = TMH_PARSE_post_json (connection, connection_cls, @@ -427,50 +477,38 @@ TMH_TEST_handler_test_rsa (struct TMH_RequestHandler *rh, json_decref (json); if (GNUNET_YES != res) return (GNUNET_NO == res) ? MHD_YES : MHD_NO; - pk = GNUNET_CRYPTO_rsa_private_key_create (1024); - if (NULL == pk) + if (NULL == rsa_pk) + rsa_pk = GNUNET_CRYPTO_rsa_private_key_create (1024); + if (NULL == rsa_pk) { GNUNET_break (0); TMH_PARSE_release_data (spec); return TMH_RESPONSE_reply_internal_error (connection, "Failed to create RSA key"); } - sig = GNUNET_CRYPTO_rsa_sign (pk, + sig = GNUNET_CRYPTO_rsa_sign (rsa_pk, spec[0].destination, spec[0].destination_size_out); if (NULL == sig) { GNUNET_break (0); - GNUNET_CRYPTO_rsa_private_key_free (pk); TMH_PARSE_release_data (spec); return TMH_RESPONSE_reply_internal_error (connection, "Failed to RSA-sign"); } TMH_PARSE_release_data (spec); - pub = GNUNET_CRYPTO_rsa_private_key_get_public (pk); - GNUNET_CRYPTO_rsa_private_key_free (pk); - if (NULL == pub) - { - GNUNET_break (0); - GNUNET_CRYPTO_rsa_signature_free (sig); - return TMH_RESPONSE_reply_internal_error (connection, - "Failed to get public RSA key"); - } res = TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, - "{s:o, s:o}", - "rsa_pub", - TALER_json_from_rsa_public_key (pub), + "{s:o}", "rsa_blind_sig", TALER_json_from_rsa_signature (sig)); GNUNET_CRYPTO_rsa_signature_free (sig); - GNUNET_CRYPTO_rsa_public_key_free (pub); return res; } /** - * Handle a "/test/transfer" request. Parses the JSON in the post, + * Handle a "/test/transfer" request. Parses the JSON in the post, * which must contain a "secret_enc" with the encrypted link secret, * a "trans_priv" with the transfer private key, a "coin_pub" with * a coin public key. A reply with the decrypted "secret" is diff --git a/src/mint/taler-mint-httpd_test.h b/src/mint/taler-mint-httpd_test.h index 1bc5fb66c..33844aab1 100644 --- a/src/mint/taler-mint-httpd_test.h +++ b/src/mint/taler-mint-httpd_test.h @@ -29,7 +29,7 @@ /** * Handle a "/test/base32" request. Parses the JSON in the post, runs * the Crockford Base32 decoder on the "input" field in the JSON, - * hashes the result and sends the hashed value back as a JSON + * hashes the result and sends the hashed value back as a JSON * string with in Base32 Crockford encoding. Thus, this API * allows testing the hashing and Crockford encoding/decoding * functions. @@ -122,11 +122,11 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh, /** - * Handle a "/test/eddsa" request. Parses the JSON in the post, + * 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 + * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is * returned using the same JSON format. * * @param rh context of the handler @@ -143,10 +143,10 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size); + /** - * Handle a "/test/rsa" request. Parses the JSON in the post, which - * must contain an "blind_ev" blinded value. An RSA public key - * ("rsa_pub") and a blinded signature ("rsa_blind_sig") are returned. + * Handle a "/test/rsa/get" request. Returns the RSA public key + * ("rsa_pub") which is used for signing in "/test/rsa/sign". * * @param rh context of the handler * @param connection the MHD connection to handle @@ -156,15 +156,35 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, * @return MHD result code */ int -TMH_TEST_handler_test_rsa (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); +TMH_TEST_handler_test_rsa_get (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); /** - * Handle a "/test/transfer" request. Parses the JSON in the post, + * Handle a "/test/rsa/sign" request. Parses the JSON in the post, which + * must contain an "blind_ev" blinded value. A a blinded signature + * ("rsa_blind_sig") is returned. + * + * @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_rsa_sign (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + + +/** + * Handle a "/test/transfer" request. Parses the JSON in the post, * which must contain a "secret_enc" with the encrypted link secret, * a "trans_priv" with the transfer private key, a "coin_pub" with * a coin public key. A reply with the decrypted "secret" is