diff --git a/contrib/gana b/contrib/gana index 20f8eb7a7..3a0709c68 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 20f8eb7a72e2160409f0f78264ec5198e9caa193 +Subproject commit 3a0709c68490ba3c5612cdb1da36ee298097ebce diff --git a/src/exchangedb/0003-aml_staff.sql b/src/exchangedb/0003-aml_staff.sql index 3c538df1d..9015c7803 100644 --- a/src/exchangedb/0003-aml_staff.sql +++ b/src/exchangedb/0003-aml_staff.sql @@ -28,7 +28,7 @@ COMMENT ON TABLE aml_staff COMMENT ON COLUMN aml_staff.decider_pub IS 'Public key of the AML staff member.'; COMMENT ON COLUMN aml_staff.master_sig - IS 'The master public key signature on the AML staff member status.'; + IS 'The master public key signature on the AML staff member status, of type TALER_SIGNATURE_MASTER_AML_KEY.'; COMMENT ON COLUMN aml_staff.decider_name IS 'Name of the staff member.'; COMMENT ON COLUMN aml_staff.is_active diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 97e82b4c3..d63fd7ccd 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -499,6 +499,43 @@ struct TALER_PurseMergeSignatureP }; +/** + * @brief Type of online public keys used by AML officers. + */ +struct TALER_AmlOfficerPublicKeyP +{ + /** + * Taler uses EdDSA for AML decision signing. + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; +}; + + +/** + * @brief Type of online private keys used to identify + * AML officers. + */ +struct TALER_AmlOfficerPrivateKeyP +{ + /** + * Taler uses EdDSA for AML decision signing. + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; +}; + + +/** + * @brief Type of signatures used by AML officers. + */ +struct TALER_AmlOfficerSignatureP +{ + /** + * Taler uses EdDSA for AML decision signing. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; +}; + + /** * @brief Type of blinding keys for Taler. * must be 32 bytes (DB) @@ -2819,6 +2856,31 @@ TALER_wallet_purse_create_verify ( const struct TALER_PurseContractSignatureP *purse_sig); +/** + * Sign a request to delete a purse. + * + * @param purse_priv key identifying the purse + * @param[out] purse_sig resulting signature + */ +void +TALER_wallet_purse_delete_sign ( + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig); + + +/** + * Verify a purse deletion request. + * + * @param purse_pub purse’s public key + * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_DELETE + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_purse_delete_verify ( + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig); + + /** * Sign a request to upload an encrypted contract. * @@ -4528,6 +4590,47 @@ TALER_exchange_online_purse_status_verify ( /* ********************* offline signing ************************** */ +/** + * Create AML officer status change signature. + * + * @param officer_pub public key of the AML officer + * @param officer_name name of the officer + * @param change_date when to affect the status change + * @param is_active true to enable the officer + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_aml_officer_status_sign ( + const struct TALER_AmlOfficerPublicKeyP *officer_pub, + const char *officer_name, + struct GNUNET_TIME_Timestamp change_date, + bool is_active, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify AML officer status change signature. + * + * @param officer_pub public key of the AML officer + * @param officer_name name of the officer + * @param change_date when to affect the status change + * @param is_active true to enable the officer + * @param master_pub public key to verify against + * @param master_sig the signature the signature + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_exchange_offline_aml_officer_status_verify ( + const struct TALER_AmlOfficerPublicKeyP *officer_pub, + const char *officer_name, + struct GNUNET_TIME_Timestamp change_date, + bool is_active, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + /** * Create auditor addition signature. * diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c index d0b644e7f..d6638998b 100644 --- a/src/util/offline_signatures.c +++ b/src/util/offline_signatures.c @@ -23,6 +23,97 @@ #include "taler_signatures.h" +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * @brief Signature made by the exchange offline key over the information of + * an AML officer status change. + */ +struct TALER_MasterAmlOfficerStatusPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_AML_KEY. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the change. + */ + struct GNUNET_TIME_TimestampNBO change_date; + + /** + * Public key of the AML officer. + */ + struct TALER_AmlOfficerPublicKeyP officer_pub; + + /** + * Hash over the AML officer's name. + */ + struct GNUNET_HashCode h_officer_name GNUNET_PACKED; + + /** + * 1 if enabled, 0 if disabled, in NBO. + */ + uint32_t is_active GNUNET_PACKED; +}; +GNUNET_NETWORK_STRUCT_END + + +void +TALER_exchange_offline_aml_officer_status_sign ( + const struct TALER_AmlOfficerPublicKeyP *officer_pub, + const char *officer_name, + struct GNUNET_TIME_Timestamp change_date, + bool is_active, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterAmlOfficerStatusPS as = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY), + .purpose.size = htonl (sizeof (as)), + .change_date = GNUNET_TIME_timestamp_hton (change_date), + .officer_pub = *officer_pub, + .is_active = htonl (is_active ? 1 : 0) + }; + + GNUNET_CRYPTO_hash (officer_name, + strlen (officer_name) + 1, + &as.h_officer_name); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &as, + &master_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_offline_aml_officer_status_verify ( + const struct TALER_AmlOfficerPublicKeyP *officer_pub, + const char *officer_name, + struct GNUNET_TIME_Timestamp change_date, + bool is_active, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterAmlOfficerStatusPS as = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY), + .purpose.size = htonl (sizeof (as)), + .change_date = GNUNET_TIME_timestamp_hton (change_date), + .officer_pub = *officer_pub, + .is_active = htonl (is_active ? 1 : 0) + }; + + GNUNET_CRYPTO_hash (officer_name, + strlen (officer_name) + 1, + &as.h_officer_name); + return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_AML_KEY, + &as, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + GNUNET_NETWORK_STRUCT_BEGIN /** diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 6866ca19b..b74a9fead 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -907,6 +907,59 @@ TALER_wallet_purse_create_verify ( } +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Message signed to delete a purse. + */ +struct TALER_PurseDeletePS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DELETE + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + +}; + + +GNUNET_NETWORK_STRUCT_END + + +void +TALER_wallet_purse_delete_sign ( + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig) +{ + struct TALER_PurseDeletePS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE) + }; + + GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv, + &pm, + &purse_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_purse_delete_verify ( + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig) +{ + struct TALER_PurseDeletePS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE) + }; + + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_WALLET_PURSE_DELETE, + &pm, + &purse_sig->eddsa_signature, + &purse_pub->eddsa_pub); +} + + void TALER_wallet_purse_status_sign ( const struct TALER_PurseContractPrivateKeyP *purse_priv,