gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: add new TOTP-specfic JSON parser


From: gnunet
Subject: [taler-exchange] branch master updated: add new TOTP-specfic JSON parsers
Date: Thu, 01 Feb 2024 23:19:54 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new f0a05b86 add new TOTP-specfic JSON parsers
f0a05b86 is described below

commit f0a05b8694fc6c65a6643e62ae309e48399d7066
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 1 23:19:49 2024 +0100

    add new TOTP-specfic JSON parsers
---
 src/include/taler_crypto_lib.h |  16 +++++
 src/include/taler_json_lib.h   |  31 ++++++++-
 src/json/Makefile.am           |   2 +-
 src/json/json_helper.c         | 150 +++++++++++++++++++++++++++++++++++++++++
 src/util/Makefile.am           |   2 +-
 src/util/crypto_confirmation.c |  41 ++++++-----
 6 files changed, 217 insertions(+), 25 deletions(-)

diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index b872af08..e3ae829f 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -937,6 +937,22 @@ struct TALER_GlobalFeeSetNBOP
 GNUNET_NETWORK_STRUCT_END
 
 
+/**
+ * Compute RFC 3548 base32 decoding of @a val and write
+ * result to @a udata.
+ *
+ * @param val value to decode
+ * @param val_size number of bytes in @a val
+ * @param key is the val in bits
+ * @param key_len is the size of @a key
+ */
+int
+TALER_rfc3548_base32decode (const char *val,
+                            size_t val_size,
+                            void *key,
+                            size_t key_len);
+
+
 /**
  * @brief Builds POS confirmation token to verify payment.
  *
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 859ec887..98e565f0 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015, 2016, 2021, 2022 Taler Systems SA
+  Copyright (C) 2014-2024 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -59,7 +59,6 @@ struct TALER_EncryptedContract
    */
   size_t econtract_size;
 
-
 };
 
 
@@ -286,6 +285,34 @@ TALER_JSON_spec_age_commitment (const char *name,
                                 struct TALER_AgeCommitment *age_commitment);
 
 
+/**
+ * Provide specification to parse an OTP key.
+ * An OTP key must be an RFC 3548 base32-encoded
+ * value (so NOT our usual Crockford-base32 encoding!).
+ *
+ * @param name name of the OTP key field in the JSON
+ * @param[out] otp_key where to store the OTP key
+ * @return spec for parsing an age commitment
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_otp_key (const char *name,
+                         const char **otp_key);
+
+
+/**
+ * Provide specification to parse an OTP method type.
+ * The value could be provided as an integer or
+ * as a descriptive string.
+ *
+ * @param name name of the OTP method type in the JSON
+ * @param[out] mca where to store the method type
+ * @return spec for parsing an age commitment
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_otp_type (const char *name,
+                          enum TALER_MerchantConfirmationAlgorithm *mca);
+
+
 /**
  * Generate specification to parse all fees for
  * a denomination under a prefix @a pfx.
diff --git a/src/json/Makefile.am b/src/json/Makefile.am
index 6886b285..ce863cb7 100644
--- a/src/json/Makefile.am
+++ b/src/json/Makefile.am
@@ -16,7 +16,7 @@ libtalerjson_la_SOURCES = \
   json_pack.c \
   json_wire.c
 libtalerjson_la_LDFLAGS = \
-  -version-info 2:0:0 \
+  -version-info 3:0:1 \
   -no-undefined
 libtalerjson_la_LIBADD = \
   $(top_builddir)/src/util/libtalerutil.la \
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 01ca45f2..0a533610 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -1666,4 +1666,154 @@ TALER_JSON_spec_version (const char *field,
 }
 
 
+/**
+ * Parse given JSON object to an OTP key.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_otp_key (void *cls,
+               json_t *root,
+               struct GNUNET_JSON_Specification *spec)
+{
+  const char *pos_key;
+
+  (void) cls;
+  pos_key = json_string_value (root);
+  if (NULL == pos_key)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  {
+    size_t pos_key_length = strlen (pos_key);
+    void *key; /* pos_key in binary */
+    size_t key_len; /* length of the key */
+    int dret;
+
+    key_len = pos_key_length * 5 / 8;
+    key = GNUNET_malloc (key_len);
+    dret = TALER_rfc3548_base32decode (pos_key,
+                                       pos_key_length,
+                                       key,
+                                       key_len);
+    if (-1 == dret)
+    {
+      GNUNET_free (key);
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_free (key);
+  }
+  *(const char **) spec->ptr = pos_key;
+  return GNUNET_OK;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_otp_key (const char *name,
+                         const char **otp_key)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_otp_key,
+    .field = name,
+    .ptr = otp_key
+  };
+
+  *otp_key = NULL;
+  return ret;
+}
+
+
+/**
+ * Parse given JSON object to `enum TALER_MerchantConfirmationAlgorithm`
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_otp_type (void *cls,
+                json_t *root,
+                struct GNUNET_JSON_Specification *spec)
+{
+  static const struct Entry
+  {
+    const char *name;
+    enum TALER_MerchantConfirmationAlgorithm val;
+  } lt [] = {
+    { .name = "NONE",
+      .val = TALER_MCA_NONE },
+    { .name = "TOTP_WITHOUT_PRICE",
+      .val = TALER_MCA_WITHOUT_PRICE },
+    { .name = "TOTP_WITH_PRICE",
+      .val = TALER_MCA_WITH_PRICE },
+    { .name = NULL,
+      .val = TALER_MCA_NONE },
+  };
+  enum TALER_MerchantConfirmationAlgorithm *res
+    = (enum TALER_MerchantConfirmationAlgorithm *) spec->ptr;
+
+  (void) cls;
+  if (json_is_string (root))
+  {
+    const char *str;
+
+    str = json_string_value (root);
+    if (NULL == str)
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+    for (unsigned int i = 0; NULL != lt[i].name; i++)
+    {
+      if (0 == strcasecmp (str,
+                           lt[i].name))
+      {
+        *res = lt[i].val;
+        return GNUNET_OK;
+      }
+    }
+    GNUNET_break_op (0);
+  }
+  if (json_is_integer (root))
+  {
+    json_int_t val;
+
+    val = json_integer_value (root);
+    for (unsigned int i = 0; NULL != lt[i].name; i++)
+    {
+      if (val == lt[i].val)
+      {
+        *res = lt[i].val;
+        return GNUNET_OK;
+      }
+    }
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_break_op (0);
+  return GNUNET_SYSERR;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_otp_type (const char *name,
+                          enum TALER_MerchantConfirmationAlgorithm *mca)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_otp_type,
+    .field = name,
+    .ptr = mca
+  };
+
+  *mca = TALER_MCA_NONE;
+  return ret;
+}
+
+
 /* end of json/json_helper.c */
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 478f75cf..914ddfdf 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -120,7 +120,7 @@ libtalerutil_la_LIBADD = \
   -lm
 
 libtalerutil_la_LDFLAGS = \
-  -version-info 1:0:0 \
+  -version-info 2:0:1 \
   -no-undefined
 
 
diff --git a/src/util/crypto_confirmation.c b/src/util/crypto_confirmation.c
index f19fc4a3..204c373d 100644
--- a/src/util/crypto_confirmation.c
+++ b/src/util/crypto_confirmation.c
@@ -112,20 +112,11 @@ compute_totp (struct GNUNET_TIME_Timestamp ts,
 }
 
 
-/**
- * Compute RFC 3548 base32 decoding of @a val and write
- * result to @a udata.
- *
- * @param val value to decode
- * @param val_size number of bytes in @a val
- * @param key is the val in bits
- * @param key_len is the size of @a key
- */
-static int
-base32decode (const char *val,
-              size_t val_size,
-              void *key,
-              size_t key_len)
+int
+TALER_rfc3548_base32decode (const char *val,
+                            size_t val_size,
+                            void *key,
+                            size_t key_len)
 {
   /**
    * 32 characters for decoding, using RFC 3548.
@@ -142,13 +133,21 @@ base32decode (const char *val,
     if ((rpos < val_size) && (vbit < 8))
     {
       char c = val[rpos++];
-      if (c == '=')   // padding character
+
+      if (c == '=')
       {
-        break;
+        /* padding character */
+        if (rpos == val_size)
+          break; /* Ok, 1x '=' padding is allowed */
+        if ( ('=' == val[rpos]) &&
+             (rpos + 1 == val_size) )
+          break; /* Ok, 2x '=' padding is allowed */
+        return -1; /* invalid padding */
       }
       const char *p = strchr (decTable__, toupper (c));
       if (! p)
-      { // invalid character
+      {
+        /* invalid character */
         return -1;
       }
       bits = (bits << 5) | (p - decTable__);
@@ -226,10 +225,10 @@ TALER_build_pos_confirmation (const char *pos_key,
     return NULL;
   key_len = pos_key_length * 5 / 8;
   key = GNUNET_malloc (key_len);
-  dret = base32decode (pos_key,
-                       pos_key_length,
-                       key,
-                       key_len);
+  dret = TALER_rfc3548_base32decode (pos_key,
+                                     pos_key_length,
+                                     key,
+                                     key_len);
   if (-1 == dret)
   {
     GNUNET_free (key);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]