From 3e37c63fbd0abff5d0d05eea60a05f6b28598ee6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 23 Nov 2020 16:36:07 +0100 Subject: implement sm signing of key announcements --- src/include/taler_crypto_lib.h | 45 +++++++++++++++++++- src/include/taler_signatures.h | 80 ++++++++++++++++++++++++++++++++++++ src/util/crypto_helper_denom.c | 28 +++++++++++-- src/util/taler-helper-crypto-eddsa.c | 50 ++++++++++++++++++++++ src/util/taler-helper-crypto-eddsa.h | 11 +++++ src/util/taler-helper-crypto-rsa.c | 55 ++++++++++++++++++++++++- src/util/taler-helper-crypto-rsa.h | 11 +++++ src/util/test_helper_rsa.conf | 2 + 8 files changed, 276 insertions(+), 6 deletions(-) diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index e09051049..ff742d557 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -32,6 +32,44 @@ GNUNET_NETWORK_STRUCT_BEGIN +/** + * @brief Type of public keys for Taler security modules (software or hardware). + * Note that there are usually at least two security modules (RSA and EdDSA), + * each with its own private key. + */ +struct TALER_SecurityModulePublicKeyP +{ + /** + * Taler uses EdDSA for security modules. + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; +}; + + +/** + * @brief Type of private keys for Taler security modules (software or hardware). + */ +struct TALER_SecurityModulePrivateKeyP +{ + /** + * Taler uses EdDSA for security modules. + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; +}; + + +/** + * @brief Type of signatures used for Taler security modules (software or hardware). + */ +struct TALER_SecurityModuleSignatureP +{ + /** + * Taler uses EdDSA for security modules. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; +}; + + /** * @brief Type of public keys for Taler reserves. */ @@ -758,6 +796,9 @@ struct TALER_CRYPTO_DenominationHelper; * zero if the key has been revoked or purged * @param h_denom_pub hash of the @a denom_pub that is available (or was purged) * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param sm_pub public key of the security module, NULL if the key was revoked or purged + * @param sm_sig signature from the security module, NULL if the key was revoked or purged + * The signature was already verified against @a sm_pub. */ typedef void (*TALER_CRYPTO_DenominationKeyStatusCallback)( @@ -766,7 +807,9 @@ typedef void struct GNUNET_TIME_Absolute start_time, struct GNUNET_TIME_Relative validity_duration, const struct GNUNET_HashCode *h_denom_pub, - const struct TALER_DenominationPublicKey *denom_pub); + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_SecurityModulePublicKeyP *sm_pub, + const struct TALER_SecurityModuleSignatureP *sm_sig); /** diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 3da11b303..1b197b2c7 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -210,6 +210,20 @@ #define TALER_SIGNATURE_WALLET_COIN_LINK 1204 +/******************************/ +/* Security module signatures */ +/******************************/ + +/** + * Signature on a denomination key announcement. + */ +#define TALER_SIGNATURE_SM_DENOMINATION_KEY 1250 + +/** + * Signature on an exchange message signing key announcement. + */ +#define TALER_SIGNATURE_SM_SIGNING_KEY 1251 + /*******************/ /* Test signatures */ /*******************/ @@ -253,6 +267,72 @@ GNUNET_NETWORK_STRUCT_BEGIN +/** + * @brief format used by the denomination crypto helper when affirming + * that it created a denomination key. + */ +struct TALER_DenominationKeyAnnouncementPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_SM_DENOMINATION_KEY. + * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the denomination public key. + */ + struct GNUNET_HashCode h_denom_pub; + + /** + * Hash of the section name in the configuration of this denomination. + */ + struct GNUNET_HashCode h_section_name; + + /** + * When does the key become available? + */ + struct GNUNET_TIME_AbsoluteNBO anchor_time; + + /** + * How long is the key available after @e anchor_time? + */ + struct GNUNET_TIME_RelativeNBO duration_withdraw; + +}; + + +/** + * @brief format used by the signing crypto helper when affirming + * that it created an exchange signing key. + */ +struct TALER_SigningKeyAnnouncementPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY. + * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Public signing key of the exchange this is about. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * When does the key become available? + */ + struct GNUNET_TIME_AbsoluteNBO anchor_time; + + /** + * How long is the key available after @e anchor_time? + */ + struct GNUNET_TIME_RelativeNBO duration_withdraw; + +}; + /** * @brief Format used for to allow the wallet to authenticate * link data provided by the exchange. diff --git a/src/util/crypto_helper_denom.c b/src/util/crypto_helper_denom.c index b999be02a..a216d305b 100644 --- a/src/util/crypto_helper_denom.c +++ b/src/util/crypto_helper_denom.c @@ -20,6 +20,7 @@ */ #include "platform.h" #include "taler_util.h" +#include "taler_signatures.h" #include "taler-helper-crypto-rsa.h" @@ -276,7 +277,12 @@ handle_mt_avail (struct TALER_CRYPTO_DenominationHelper *dh, { struct TALER_DenominationPublicKey denom_pub; - struct GNUNET_HashCode h_denom_pub; + struct TALER_DenominationKeyAnnouncementPS dka = { + .purpose.purpose = htonl (TALER_SIGNATURE_SM_DENOMINATION_KEY), + .purpose.size = htonl (sizeof (dka)), + .anchor_time = kan->anchor_time, + .duration_withdraw = kan->duration_withdraw + }; denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf, @@ -287,13 +293,25 @@ handle_mt_avail (struct TALER_CRYPTO_DenominationHelper *dh, return GNUNET_SYSERR; } GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, - &h_denom_pub); + &dka.h_denom_pub); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_SM_DENOMINATION_KEY, + &dka, + &kan->secm_sig.eddsa_signature, + &kan->secm_pub.eddsa_pub)) + { + GNUNET_break_op (0); + GNUNET_CRYPTO_rsa_public_key_free (denom_pub.rsa_public_key); + return GNUNET_SYSERR; + } dh->dkc (dh->dkc_cls, section_name, GNUNET_TIME_absolute_ntoh (kan->anchor_time), GNUNET_TIME_relative_ntoh (kan->duration_withdraw), - &h_denom_pub, - &denom_pub); + &dka.h_denom_pub, + &denom_pub, + &kan->secm_pub, + &kan->secm_sig); GNUNET_CRYPTO_rsa_public_key_free (denom_pub.rsa_public_key); } return GNUNET_OK; @@ -324,6 +342,8 @@ handle_mt_purge (struct TALER_CRYPTO_DenominationHelper *dh, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO, &pn->h_denom_pub, + NULL, + NULL, NULL); return GNUNET_OK; } diff --git a/src/util/taler-helper-crypto-eddsa.c b/src/util/taler-helper-crypto-eddsa.c index 2f6a6cc9e..a20ffd794 100644 --- a/src/util/taler-helper-crypto-eddsa.c +++ b/src/util/taler-helper-crypto-eddsa.c @@ -44,6 +44,8 @@ #include #include #include "taler_error_codes.h" +#include "taler_signatures.h" + /** * One particular key. @@ -171,6 +173,12 @@ struct WorkItem }; +/** + * Private key of this security module. Used to sign denomination key + * announcements. + */ +static struct TALER_SecurityModulePrivateKeyP smpriv; + /** * Head of DLL of actual keys, sorted by anchor. */ @@ -593,6 +601,13 @@ static int notify_client_key_add (struct Client *client, const struct Key *key) { + struct TALER_SigningKeyAnnouncementPS ska = { + .purpose.purpose = htonl (TALER_SIGNATURE_SM_SIGNING_KEY), + .purpose.size = htonl (sizeof (ska)), + .exchange_pub = key->exchange_pub, + .anchor_time = GNUNET_TIME_absolute_hton (key->anchor), + .duration_withdraw = GNUNET_TIME_relative_hton (duration) + }; struct TALER_CRYPTO_EddsaKeyAvailableNotification an = { .header.size = htons (sizeof (an)), .header.type = htons (TALER_HELPER_EDDSA_MT_AVAIL), @@ -601,6 +616,9 @@ notify_client_key_add (struct Client *client, .exchange_pub = key->exchange_pub }; + GNUNET_CRYPTO_eddsa_sign (&smpriv.eddsa_priv, + &ska, + &an.secm_sig.eddsa_signature); if (GNUNET_OK != transmit (&client->addr, client->addr_size, @@ -1363,6 +1381,38 @@ run (void *cls, now = GNUNET_TIME_absolute_get (); } GNUNET_TIME_round_abs (&now); + + { + char *pfn; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "taler-helper-crypto-eddsa", + "SM_PRIV_KEY", + &pfn)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "taler-helper-crypto-eddsa", + "SM_PRIV_KEY"); + global_ret = 1; + return; + } + if (GNUNET_SYSERR == + GNUNET_CRYPTO_eddsa_key_from_file (pfn, + GNUNET_YES, + &smpriv.eddsa_priv)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "taler-helper-crypto-rsa", + "SM_PRIV_KEY", + "Could not use file to persist private key"); + GNUNET_free (pfn); + global_ret = 1; + return; + } + GNUNET_free (pfn); + } + if (GNUNET_OK != load_durations ()) { diff --git a/src/util/taler-helper-crypto-eddsa.h b/src/util/taler-helper-crypto-eddsa.h index 215af566c..fe6ca4055 100644 --- a/src/util/taler-helper-crypto-eddsa.h +++ b/src/util/taler-helper-crypto-eddsa.h @@ -58,6 +58,17 @@ struct TALER_CRYPTO_EddsaKeyAvailableNotification */ struct GNUNET_TIME_RelativeNBO duration; + /** + * Public key used to generate the @e sicm_sig. + */ + struct TALER_SecurityModulePublicKeyP secm_pub; + + /** + * Signature affirming the announcement, of + * purpose #TALER_SIGNATURE_SM_SIGNING_KEY. + */ + struct TALER_SecurityModuleSignatureP secm_sig; + /** * The public key. */ diff --git a/src/util/taler-helper-crypto-rsa.c b/src/util/taler-helper-crypto-rsa.c index e72a7824b..af9c76ef2 100644 --- a/src/util/taler-helper-crypto-rsa.c +++ b/src/util/taler-helper-crypto-rsa.c @@ -44,6 +44,8 @@ #include #include #include "taler_error_codes.h" +#include "taler_signatures.h" + /** * Information we keep per denomination. @@ -243,6 +245,12 @@ struct WorkItem */ static int global_ret; +/** + * Private key of this security module. Used to sign denomination key + * announcements. + */ +static struct TALER_SecurityModulePrivateKeyP smpriv; + /** * Number of worker threads to use. Default (0) is to use one per CPU core * available. @@ -693,14 +701,24 @@ static int notify_client_dk_add (struct Client *client, const struct DenominationKey *dk) { - struct TALER_CRYPTO_RsaKeyAvailableNotification *an; struct Denomination *denom = dk->denom; size_t nlen = strlen (denom->section) + 1; + struct TALER_DenominationKeyAnnouncementPS dka = { + .purpose.purpose = htonl (TALER_SIGNATURE_SM_DENOMINATION_KEY), + .purpose.size = htonl (sizeof (dka)), + .h_denom_pub = dk->h_denom_pub, + .anchor_time = GNUNET_TIME_absolute_hton (dk->anchor), + .duration_withdraw = GNUNET_TIME_relative_hton (denom->duration_withdraw) + }; + struct TALER_CRYPTO_RsaKeyAvailableNotification *an; size_t buf_len; void *buf; void *p; size_t tlen; + GNUNET_CRYPTO_hash (denom->section, + nlen, + &dka.h_section_name); buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub.rsa_public_key, &buf); GNUNET_assert (buf_len < UINT16_MAX); @@ -714,6 +732,9 @@ notify_client_dk_add (struct Client *client, an->section_name_len = htons ((uint16_t) nlen); an->anchor_time = GNUNET_TIME_absolute_hton (dk->anchor); an->duration_withdraw = GNUNET_TIME_relative_hton (denom->duration_withdraw); + GNUNET_CRYPTO_eddsa_sign (&smpriv.eddsa_priv, + &dka, + &an->secm_sig.eddsa_signature); p = (void *) &an[1]; memcpy (p, buf, @@ -1742,6 +1763,38 @@ run (void *cls, now = GNUNET_TIME_absolute_get (); } GNUNET_TIME_round_abs (&now); + + { + char *pfn; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "taler-helper-crypto-rsa", + "SM_PRIV_KEY", + &pfn)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "taler-helper-crypto-rsa", + "SM_PRIV_KEY"); + global_ret = 1; + return; + } + if (GNUNET_SYSERR == + GNUNET_CRYPTO_eddsa_key_from_file (pfn, + GNUNET_YES, + &smpriv.eddsa_priv)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "taler-helper-crypto-rsa", + "SM_PRIV_KEY", + "Could not use file to persist private key"); + GNUNET_free (pfn); + global_ret = 1; + return; + } + GNUNET_free (pfn); + } + if (GNUNET_OK != load_durations ()) { diff --git a/src/util/taler-helper-crypto-rsa.h b/src/util/taler-helper-crypto-rsa.h index d2bc07f7a..d7617e551 100644 --- a/src/util/taler-helper-crypto-rsa.h +++ b/src/util/taler-helper-crypto-rsa.h @@ -63,6 +63,17 @@ struct TALER_CRYPTO_RsaKeyAvailableNotification */ struct GNUNET_TIME_RelativeNBO duration_withdraw; + /** + * Public key used to generate the @e sicm_sig. + */ + struct TALER_SecurityModulePublicKeyP secm_pub; + + /** + * Signature affirming the announcement, of + * purpose #TALER_SIGNATURE_SM_DENOMINATION_KEY. + */ + struct TALER_SecurityModuleSignatureP secm_sig; + /* followed by @e pub_size bytes of the public key */ /* followed by @e section_name bytes of the configuration section name diff --git a/src/util/test_helper_rsa.conf b/src/util/test_helper_rsa.conf index 9880ae153..2bce81122 100644 --- a/src/util/test_helper_rsa.conf +++ b/src/util/test_helper_rsa.conf @@ -7,3 +7,5 @@ lookahead_sign = 5 minutes overlap_duration = 1 s KEY_DIR = ${TALER_RUNTIME_DIR}/test_helper_rsa/ UNIXPATH = ${TALER_RUNTIME_DIR}test_helper_rsa.unix + +SM_PRIV_KEY = ${TALER_DATA_HOME}/taler-helper-crypto-rsa/.private-key -- cgit v1.2.3