aml_signatures.c (8367B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file aml_signatures.c 18 * @brief Utility functions for AML officers 19 * @author Christian Grothoff 20 */ 21 #include "taler/taler_util.h" 22 #include "taler/taler_signatures.h" 23 24 25 GNUNET_NETWORK_STRUCT_BEGIN 26 27 /** 28 * @brief Format used to generate the signature on an AML decision. 29 */ 30 struct TALER_AmlDecisionPS 31 { 32 /** 33 * Purpose must be #TALER_SIGNATURE_AML_DECISION. 34 * Used for an EdDSA signature with the `struct TALER_AmlOfficerPublicKeyP`. 35 */ 36 struct GNUNET_CRYPTO_SignaturePurpose purpose; 37 38 /** 39 * Time when this decision was made. 40 */ 41 struct GNUNET_TIME_TimestampNBO decision_time; 42 43 /** 44 * Time when attributes expire, if any. 45 */ 46 struct GNUNET_TIME_TimestampNBO attributes_expiration_time; 47 48 /** 49 * Hash of the account identifier to which the decision applies. 50 */ 51 struct TALER_NormalizedPaytoHashP h_payto GNUNET_PACKED; 52 53 /** 54 * Hash over the justification text. 55 */ 56 struct GNUNET_HashCode h_justification GNUNET_PACKED; 57 58 /** 59 * Hash over the justification text. 60 */ 61 struct GNUNET_HashCode h_properties GNUNET_PACKED; 62 63 /** 64 * Hash over JSON object with new KYC rules. 65 */ 66 struct GNUNET_HashCode h_new_rules; 67 68 /** 69 * Hash over string with new check. 70 */ 71 struct GNUNET_HashCode h_new_measure; 72 73 /** 74 * Hash over new attributes, all zeroes 75 * if no attributes are being set. 76 */ 77 struct GNUNET_HashCode h_attributes; 78 79 /** 80 * 0: no investigation, 1: yes investigation. 81 */ 82 uint64_t flags; 83 }; 84 85 GNUNET_NETWORK_STRUCT_END 86 87 void 88 TALER_officer_aml_decision_sign_hashed ( 89 const char *justification, 90 struct GNUNET_TIME_Timestamp decision_time, 91 const struct TALER_NormalizedPaytoHashP *h_payto, 92 const json_t *new_rules, 93 const json_t *properties, 94 const char *new_measure, 95 bool to_investigate, 96 struct GNUNET_TIME_Timestamp attributes_expiration, 97 const struct GNUNET_HashCode *h_attributes, 98 const struct TALER_AmlOfficerPrivateKeyP *officer_priv, 99 struct TALER_AmlOfficerSignatureP *officer_sig) 100 { 101 struct TALER_AmlDecisionPS ad = { 102 .purpose.purpose = htonl (TALER_SIGNATURE_AML_DECISION), 103 .purpose.size = htonl (sizeof (ad)), 104 .decision_time = GNUNET_TIME_timestamp_hton (decision_time), 105 .attributes_expiration_time = GNUNET_TIME_timestamp_hton ( 106 attributes_expiration), 107 .h_payto = *h_payto, 108 .flags = GNUNET_htonll (to_investigate ? 1 : 0) 109 }; 110 111 GNUNET_CRYPTO_hash (justification, 112 strlen (justification), 113 &ad.h_justification); 114 if (NULL != properties) 115 TALER_json_hash (properties, 116 &ad.h_properties); 117 TALER_json_hash (new_rules, 118 &ad.h_new_rules); 119 if (NULL != new_measure) 120 GNUNET_CRYPTO_hash (new_measure, 121 strlen (new_measure), 122 &ad.h_new_measure); 123 if (NULL != h_attributes) 124 ad.h_attributes = *h_attributes; 125 GNUNET_CRYPTO_eddsa_sign (&officer_priv->eddsa_priv, 126 &ad, 127 &officer_sig->eddsa_signature); 128 } 129 130 131 void 132 TALER_officer_aml_decision_sign ( 133 const char *justification, 134 struct GNUNET_TIME_Timestamp decision_time, 135 const struct TALER_NormalizedPaytoHashP *h_payto, 136 const json_t *new_rules, 137 const json_t *properties, 138 const char *new_measure, 139 bool to_investigate, 140 struct GNUNET_TIME_Timestamp attributes_expiration, 141 const json_t *attributes, 142 const struct TALER_AmlOfficerPrivateKeyP *officer_priv, 143 struct TALER_AmlOfficerSignatureP *officer_sig) 144 { 145 struct GNUNET_HashCode h_attributes; 146 147 if (NULL != attributes) 148 TALER_json_hash (attributes, 149 &h_attributes); 150 return TALER_officer_aml_decision_sign_hashed ( 151 justification, 152 decision_time, 153 h_payto, 154 new_rules, 155 properties, 156 new_measure, 157 to_investigate, 158 attributes_expiration, 159 (NULL != attributes) ? &h_attributes : NULL, 160 officer_priv, 161 officer_sig); 162 } 163 164 165 enum GNUNET_GenericReturnValue 166 TALER_officer_aml_decision_verify_hashed ( 167 const char *justification, 168 struct GNUNET_TIME_Timestamp decision_time, 169 const struct TALER_NormalizedPaytoHashP *h_payto, 170 const json_t *new_rules, 171 const json_t *properties, 172 const char *new_measures, 173 bool to_investigate, 174 struct GNUNET_TIME_Timestamp attributes_expiration, 175 const struct GNUNET_HashCode *h_attributes, 176 const struct TALER_AmlOfficerPublicKeyP *officer_pub, 177 const struct TALER_AmlOfficerSignatureP *officer_sig) 178 { 179 struct TALER_AmlDecisionPS ad = { 180 .purpose.purpose = htonl (TALER_SIGNATURE_AML_DECISION), 181 .purpose.size = htonl (sizeof (ad)), 182 .decision_time = GNUNET_TIME_timestamp_hton (decision_time), 183 .attributes_expiration_time = GNUNET_TIME_timestamp_hton ( 184 attributes_expiration), 185 .h_payto = *h_payto, 186 .flags = GNUNET_htonll (to_investigate ? 1 : 0) 187 }; 188 189 GNUNET_CRYPTO_hash (justification, 190 strlen (justification), 191 &ad.h_justification); 192 if (NULL != properties) 193 TALER_json_hash (properties, 194 &ad.h_properties); 195 TALER_json_hash (new_rules, 196 &ad.h_new_rules); 197 if (NULL != new_measures) 198 GNUNET_CRYPTO_hash (new_measures, 199 strlen (new_measures), 200 &ad.h_new_measure); 201 if (NULL != h_attributes) 202 ad.h_attributes = *h_attributes; 203 return GNUNET_CRYPTO_eddsa_verify ( 204 TALER_SIGNATURE_AML_DECISION, 205 &ad, 206 &officer_sig->eddsa_signature, 207 &officer_pub->eddsa_pub); 208 } 209 210 211 enum GNUNET_GenericReturnValue 212 TALER_officer_aml_decision_verify ( 213 const char *justification, 214 struct GNUNET_TIME_Timestamp decision_time, 215 const struct TALER_NormalizedPaytoHashP *h_payto, 216 const json_t *new_rules, 217 const json_t *properties, 218 const char *new_measures, 219 bool to_investigate, 220 struct GNUNET_TIME_Timestamp attributes_expiration, 221 const json_t *attributes, 222 const struct TALER_AmlOfficerPublicKeyP *officer_pub, 223 const struct TALER_AmlOfficerSignatureP *officer_sig) 224 { 225 struct GNUNET_HashCode h_attributes; 226 227 if (NULL != attributes) 228 TALER_json_hash (attributes, 229 &h_attributes); 230 return TALER_officer_aml_decision_verify_hashed ( 231 justification, 232 decision_time, 233 h_payto, 234 new_rules, 235 properties, 236 new_measures, 237 to_investigate, 238 attributes_expiration, 239 (NULL != attributes) ? &h_attributes : NULL, 240 officer_pub, 241 officer_sig); 242 } 243 244 245 GNUNET_NETWORK_STRUCT_BEGIN 246 247 /** 248 * @brief Format used to generate the signature on any AML query. 249 */ 250 struct TALER_AmlQueryPS 251 { 252 /** 253 * Purpose must be #TALER_SIGNATURE_AML_QUERY. 254 * Used for an EdDSA signature with the `struct TALER_AmlOfficerPublicKeyP`. 255 */ 256 struct GNUNET_CRYPTO_SignaturePurpose purpose; 257 258 }; 259 260 GNUNET_NETWORK_STRUCT_END 261 262 263 void 264 TALER_officer_aml_query_sign ( 265 const struct TALER_AmlOfficerPrivateKeyP *officer_priv, 266 struct TALER_AmlOfficerSignatureP *officer_sig) 267 { 268 struct TALER_AmlQueryPS aq = { 269 .purpose.purpose = htonl (TALER_SIGNATURE_AML_QUERY), 270 .purpose.size = htonl (sizeof (aq)) 271 }; 272 273 GNUNET_CRYPTO_eddsa_sign (&officer_priv->eddsa_priv, 274 &aq, 275 &officer_sig->eddsa_signature); 276 } 277 278 279 enum GNUNET_GenericReturnValue 280 TALER_officer_aml_query_verify ( 281 const struct TALER_AmlOfficerPublicKeyP *officer_pub, 282 const struct TALER_AmlOfficerSignatureP *officer_sig) 283 { 284 struct TALER_AmlQueryPS aq = { 285 .purpose.purpose = htonl (TALER_SIGNATURE_AML_QUERY), 286 .purpose.size = htonl (sizeof (aq)) 287 }; 288 289 return GNUNET_CRYPTO_eddsa_verify ( 290 TALER_SIGNATURE_AML_QUERY, 291 &aq, 292 &officer_sig->eddsa_signature, 293 &officer_pub->eddsa_pub); 294 } 295 296 297 /* end of aml_signatures.c */