diff options
author | Christian Blättler <blatc2@bfh.ch> | 2024-04-27 10:10:45 +0200 |
---|---|---|
committer | Christian Blättler <blatc2@bfh.ch> | 2024-04-27 10:10:45 +0200 |
commit | 1739fb4231985841da1754a8e00678e783b09d2f (patch) | |
tree | c60640cfafce1672cc427da2259696791f51bcd9 | |
parent | ceecb31a47c2391bd2edbb2d76632c586e4c839d (diff) |
set valid_after timestamp to rounded value of matching key
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 215 |
1 files changed, 107 insertions, 108 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index ce16fa63..02a19603 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -1436,13 +1436,15 @@ get_rounded_time_interval (struct GNUNET_TIME_Relative precision, * * @param[in,out] oc order context * @param slug slug of the token family - * @param valid_after validity start date of the token, subject to rounding - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * @param[in,out] valid_after validity start date of the token, + subject to rounding. Set to the rounded validity + start date of the matching key. + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static enum GNUNET_GenericReturnValue set_token_family (struct OrderContext *oc, const char *slug, - struct GNUNET_TIME_Timestamp valid_after) + struct GNUNET_TIME_Timestamp *valid_after) { struct TALER_MERCHANTDB_TokenFamilyKeyDetails key_details; struct TALER_MerchantContractTokenFamily *family = NULL; @@ -1455,7 +1457,7 @@ set_token_family (struct OrderContext *oc, struct GNUNET_TIME_Timestamp max_valid_after; if ( GNUNET_OK != get_rounded_time_interval (precision, - valid_after, + *valid_after, &min_valid_after, &max_valid_after)) { @@ -1489,12 +1491,12 @@ set_token_family (struct OrderContext *oc, max_valid_after)) { /* The token family and a matching key is already added. */ + *valid_after = family->keys[i].valid_after; return GNUNET_OK; } } } - qs = TMH_db->lookup_token_family_key (TMH_db->cls, oc->hc->instance->settings.id, slug, @@ -1538,124 +1540,121 @@ set_token_family (struct OrderContext *oc, /* slug is not needed */ GNUNET_free (key_details.token_family.slug); - if (NULL == family) { - struct TALER_MerchantContractTokenFamily new_family = { - .slug = slug, - .name = key_details.token_family.name, - .description = key_details.token_family.description, - .description_i18n = key_details.token_family.description_i18n, - .keys = GNUNET_new (struct TALER_MerchantContractTokenFamilyKey), - .keys_len = 0, - }; - - switch (key_details.token_family.kind) { - case TALER_MERCHANTDB_TFK_Subscription: - new_family.kind = TALER_MCTK_SUBSCRIPTION; - new_family.critical = true; - // TODO: Set trusted domains - break; - case TALER_MERCHANTDB_TFK_Discount: - new_family.kind = TALER_MCTK_DISCOUNT; - new_family.critical = false; - // TODO: Set expected domains - break; - } - - GNUNET_array_append (oc->parse_choices.token_families, - oc->parse_choices.token_families_len, - new_family); - - family = &oc->parse_choices.token_families[oc->parse_choices.token_families_len - 1]; - } - - if (NULL == key_details.pub.public_key) - { - /* There is no matching key for this token family yet. */ - /* We have to generate one. */ - /* If public key is NULL, private key must also be NULL */ - GNUNET_assert (NULL == key_details.priv.private_key); - - enum GNUNET_DB_QueryStatus iqs; - struct GNUNET_CRYPTO_BlindSignPrivateKey *priv; - struct GNUNET_CRYPTO_BlindSignPublicKey *pub; - struct GNUNET_TIME_Timestamp valid_before = - GNUNET_TIME_absolute_to_timestamp( - GNUNET_TIME_absolute_add (min_valid_after.abs_time, - key_details.token_family.duration)); - GNUNET_CRYPTO_blind_sign_keys_create (&priv, - &pub, - // TODO: Make cipher and key length configurable - GNUNET_CRYPTO_BSA_RSA, - 4096); + struct TALER_MerchantContractTokenFamilyKey key; - struct TALER_TokenIssuePublicKeyP token_pub = { - .public_key = pub, - }; - struct TALER_TokenIssuePrivateKeyP token_priv = { - .private_key = priv, - }; - - iqs = TMH_db->insert_token_family_key (TMH_db->cls, - slug, - &token_pub, - &token_priv, - min_valid_after, - valid_before); - - GNUNET_CRYPTO_blind_sign_priv_decref (priv); - - if (iqs <= 0) + if (NULL == family) { - enum TALER_ErrorCode ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - unsigned int http_status = 0; + struct TALER_MerchantContractTokenFamily new_family = { + .slug = slug, + .name = key_details.token_family.name, + .description = key_details.token_family.description, + .description_i18n = key_details.token_family.description_i18n, + .keys = GNUNET_new (struct TALER_MerchantContractTokenFamilyKey), + .keys_len = 0, + }; - switch (iqs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; - ec = TALER_EC_GENERIC_DB_STORE_FAILED; + switch (key_details.token_family.kind) { + case TALER_MERCHANTDB_TFK_Subscription: + new_family.kind = TALER_MCTK_SUBSCRIPTION; + new_family.critical = true; + // TODO: Set trusted domains break; - case GNUNET_DB_STATUS_SOFT_ERROR: - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; - ec = TALER_EC_GENERIC_DB_SOFT_FAILURE; + case TALER_MERCHANTDB_TFK_Discount: + new_family.kind = TALER_MCTK_DISCOUNT; + new_family.critical = false; + // TODO: Set expected domains break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - /* case listed to make compilers happy */ - GNUNET_assert (0); } - GNUNET_break (0); - reply_with_error (oc, - http_status, - ec, - "token_family_slug"); - return GNUNET_SYSERR; + GNUNET_array_append (oc->parse_choices.token_families, + oc->parse_choices.token_families_len, + new_family); + + family = &oc->parse_choices.token_families[oc->parse_choices.token_families_len - 1]; } + if (NULL == key_details.pub.public_key) { - struct TALER_MerchantContractTokenFamilyKey key = { - .pub = token_pub, - .valid_after = min_valid_after, - .valid_before = valid_before, + /* There is no matching key for this token family yet. */ + /* We have to generate one. */ + /* If public key is NULL, private key must also be NULL */ + GNUNET_assert (NULL == key_details.priv.private_key); + + enum GNUNET_DB_QueryStatus iqs; + struct GNUNET_CRYPTO_BlindSignPrivateKey *priv; + struct GNUNET_CRYPTO_BlindSignPublicKey *pub; + struct GNUNET_TIME_Timestamp valid_before = + GNUNET_TIME_absolute_to_timestamp( + GNUNET_TIME_absolute_add (min_valid_after.abs_time, + key_details.token_family.duration)); + + GNUNET_CRYPTO_blind_sign_keys_create (&priv, + &pub, + /* TODO: Make cipher and key length configurable */ + GNUNET_CRYPTO_BSA_RSA, + 4096); + + struct TALER_TokenIssuePublicKeyP token_pub = { + .public_key = pub, }; + struct TALER_TokenIssuePrivateKeyP token_priv = { + .private_key = priv, + }; + + iqs = TMH_db->insert_token_family_key (TMH_db->cls, + slug, + &token_pub, + &token_priv, + min_valid_after, + valid_before); + + GNUNET_CRYPTO_blind_sign_priv_decref (priv); - GNUNET_array_append (family->keys, - family->keys_len, - key); + if (iqs <= 0) + { + enum TALER_ErrorCode ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + unsigned int http_status = 0; + + switch (iqs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; + ec = TALER_EC_GENERIC_DB_STORE_FAILED; + break; + case GNUNET_DB_STATUS_SOFT_ERROR: + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; + ec = TALER_EC_GENERIC_DB_SOFT_FAILURE; + break; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* case listed to make compilers happy */ + GNUNET_assert (0); + } + + GNUNET_break (0); + reply_with_error (oc, + http_status, + ec, + "token_family_slug"); + return GNUNET_SYSERR; + } + + key.pub = token_pub; + key.valid_after = min_valid_after; + key.valid_before = valid_before; + } else { + key.pub = key_details.pub; + key.valid_after = key_details.valid_after; + key.valid_before = key_details.valid_before; } - } else { - struct TALER_MerchantContractTokenFamilyKey key = { - .pub = key_details.pub, - .valid_after = key_details.valid_before, - .valid_before = key_details.valid_before, - }; GNUNET_array_append (family->keys, family->keys_len, key); + + *valid_after = key.valid_after; } return GNUNET_OK; @@ -2595,7 +2594,7 @@ parse_choices (struct OrderContext *oc) if (GNUNET_OK != set_token_family (oc, input.details.token.token_family_slug, - input.details.token.valid_after)) + &input.details.token.valid_after)) { /* error is already scheduled, return. */ return; @@ -2668,15 +2667,15 @@ parse_choices (struct OrderContext *oc) if (0 == output.details.token.count) { - /* Ignore outputs with 'number' field set to 0 */ + /* Ignore outputs with 'number' field set to 0. */ continue; } if (GNUNET_OK != set_token_family (oc, output.details.token.token_family_slug, - output.details.token.valid_after)) + &output.details.token.valid_after)) { - /* error is already scheduled, return. */ + /* Error is already scheduled, return. */ return; } |