gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: totp algorithm


From: gnunet
Subject: [taler-exchange] branch master updated: totp algorithm
Date: Thu, 02 Mar 2023 15:55:31 +0100

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

priscilla-huang pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new b46c03b2 totp algorithm
b46c03b2 is described below

commit b46c03b2c9e7d8e5136a84b2fb3d6af8277947df
Author: priscilla <priscilla.huang@efrei.net>
AuthorDate: Thu Mar 2 09:54:54 2023 -0500

    totp algorithm
---
 src/include/taler_crypto_lib.h |  20 +++-
 src/util/crypto_confirmation.c | 262 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 279 insertions(+), 3 deletions(-)

diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index b6ec2ed8..db50efa1 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -591,7 +591,17 @@ enum TALER_MerchantConfirmationAlgorithm
   /**
    * No purchase confirmation.
    */
-  TALER_MCA_NONE = 0
+  TALER_MCA_NONE = 0,
+
+  /**
+   * Purchase confirmation without payment
+   */
+  TALER_MCA_WITHOUT_PRICE = 1,
+
+  /**
+   * Purchase confirmation with payment
+   */
+  TALER_MCA_WITH_PRICE = 2
 
 };
 
@@ -939,7 +949,13 @@ GNUNET_NETWORK_STRUCT_END
 
 
 /**
- * FIXME.
+ * It is build pos confirmation to verify paiement.
+ *
+ * @param pos_key encoded key for verification payment
+ * @param pos_alg algorithm to compute the payment verification
+ * @param total of the order paid
+ * @parmam ts is the time given
+ *
  */
 char *
 TALER_build_pos_confirmation (const char *pos_key,
diff --git a/src/util/crypto_confirmation.c b/src/util/crypto_confirmation.c
index 61a73f4c..e47a61a6 100644
--- a/src/util/crypto_confirmation.c
+++ b/src/util/crypto_confirmation.c
@@ -17,23 +17,283 @@
  * @file util/crypto_confirmation.c
  * @brief confirmation computation
  * @author Christian Grothoff
+ * @author Priscilla Huang
  */
 #include "platform.h"
 #include "taler_util.h"
+#include <taler/taler_mhd_lib.h>
+#include <gnunet/gnunet_db_lib.h>
 #include <gcrypt.h>
 
+/**
+ * How long is a TOTP code valid?
+ */
+#define TOTP_VALIDITY_PERIOD GNUNET_TIME_relative_multiply ( \
+   GNUNET_TIME_UNIT_SECONDS, 30)
+
+/**
+ * Range of time we allow (plus-minus).
+ */
+#define TIME_INTERVAL_RANGE 2
+
+
+
+/**
+ * Compute TOTP code at current time with offset
+ * @a time_off for the @a key.
+ *
+ * @param ts current time
+ * @param time_off offset to apply when computing the code
+ * @param key pos_key in binary
+ * @param key_size number of bytes in @a key
+ */
+static uint64_t
+compute_totp (struct GNUNET_TIME_Timestamp ts,
+              int time_off,
+              const void *key,
+              size_t key_size)
+{
+  struct GNUNET_TIME_Absolute now;
+  time_t t;
+  uint64_t ctr;
+  uint8_t hmac[20]; /* SHA1: 20 bytes */
+
+  now = ts.abs_time;
+  while (time_off < 0)
+  {
+    now = GNUNET_TIME_absolute_subtract (now,
+                                         TOTP_VALIDITY_PERIOD);
+    time_off++;
+  }
+  while (time_off > 0)
+  {
+    now = GNUNET_TIME_absolute_add (now,
+                                    TOTP_VALIDITY_PERIOD);
+    time_off--;
+  }
+  t = now.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
+  ctr = GNUNET_htonll (t / 30LLU);
+
+  {
+    gcry_md_hd_t md;
+    const unsigned char *mc;
+
+    GNUNET_assert (GPG_ERR_NO_ERROR ==
+                   gcry_md_open (&md,
+                                 GCRY_MD_SHA1,
+                                 GCRY_MD_FLAG_HMAC));
+    gcry_md_setkey (md,
+                    key,
+                    key_size);
+    gcry_md_write (md,
+                   &ctr,
+                   sizeof (ctr));
+    mc = gcry_md_read (md,
+                       GCRY_MD_SHA1);
+    GNUNET_assert (NULL != mc);
+    memcpy (hmac,
+            mc,
+            sizeof (hmac));
+    gcry_md_close (md);
+  }
+
+  {
+    uint32_t code = 0;
+    int offset;
+
+    offset = hmac[sizeof (hmac) - 1] & 0x0f;
+    for (int count = 0; count < 4; count++)
+      code |= hmac[offset + 3 - count] << (8 * count);
+    code &= 0x7fffffff;
+    /* always use 8 digits (maximum) */
+    code = code % 100000000;
+    return code;
+  }
+}
+
+
+/**
+ * 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)
+{
+  /**
+   * 32 characters for decoding, using RFC 3548.
+   */
+  static const char *decTable__ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+  unsigned int wpos;
+  unsigned int rpos;
+  unsigned int bits;
+  unsigned int vbit;
+  unsigned char *udata;
+
+  udata = val;
+  vbit = 0;
+  wpos = 0;
+  rpos = 0;
+  bits = 0;
+  while ((rpos < val_size) || (vbit >= 8))
+  {
+    if ((rpos < val_size) && (vbit < 8))
+    {
+      char c = val[rpos++];
+      if (c == '=') { // padding character
+        break;
+      }
+      const char *p = strchr(decTable__, toupper(c));
+      if (! p)
+      { // invalid character
+        return -1;
+      }
+      bits = (bits << 5) | (p - decTable__);
+      vbit += 5;
+    }
+    if (vbit >= 8)
+    {
+      udata[wpos++] = (bits >> (vbit - 8)) & 0xFF;
+      vbit -= 8;
+    }
+  }
+  return wpos;
+}
+
 
+/**
+ * It is build pos confirmation to verify payment.
+ *
+ * @param pos_key base32 (RFC 3548, not Crockford!) encoded key for 
verification payment
+ * @param pos_alg algorithm to compute the payment verification
+ * @param total of the order paid
+ * @param ts is the current time given
+ */
 char *
 TALER_build_pos_confirmation (const char *pos_key,
                               enum TALER_MerchantConfirmationAlgorithm pos_alg,
                               const struct TALER_Amount *total,
                               struct GNUNET_TIME_Timestamp ts)
 {
+  size_t pos_key_length = strlen (pos_key);
+  void *key; /* pos_key in binary */
+  size_t key_len; /* lengh of the key */
+  uint64_t code; /* totp code */
+  char *ret;
+  int dret;
+
+  if (TALER_MCA_NONE == pos_alg)
+    return NULL;
+  key_len = pos_key_length * 5 / 8;
+  key = GNUNET_malloc (key_len);
+  dret = base32decode (pos_key,
+                       pos_key_length,
+                       key,
+                       key_len);
+  if (-1 == dret)
+  {
+    GNUNET_free (key);
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  GNUNET_assert (dret <= key_len);
+  key_len = (size_t) dret;
   switch (pos_alg)
   {
   case TALER_MCA_NONE:
+    GNUNET_break (0);
+    GNUNET_free (key);
     return NULL;
+  case TALER_MCA_WITHOUT_PRICE: /* and 30s */
+    ret = NULL;
+    /* Return all T-OTP codes in range separated by new lines, e.g.
+       "12345678
+        24522552
+        25262425
+        42543525
+        25253552"
+    */
+    for (int i = -TIME_INTERVAL_RANGE; i<= TIME_INTERVAL_RANGE; i++)
+    {
+      code = compute_totp (ts,
+                           i,
+                           key,
+                           key_len);
+      if (NULL == ret)
+      {
+        GNUNET_asprintf (&ret,
+                         "%llu",
+                         (unsigned long long) code);
+      }
+      else
+      {
+        char *tmp;
+
+        GNUNET_asprintf (&tmp,
+                         "%s\n%llu",
+                         ret,
+                         (unsigned long long) code);
+        GNUNET_free (ret);
+        ret = tmp;
+      }
+    }
+    GNUNET_free (key);
+    return ret;
+  case TALER_MCA_WITH_PRICE:
+    {
+      struct GNUNET_HashCode hkey;
+      struct TALER_AmountNBO ntotal;
+      ret = NULL;
+
+      TALER_amount_hton (&ntotal,
+                         total);
+      GNUNET_assert (GNUNET_YES ==
+                     GNUNET_CRYPTO_kdf (&hkey,
+                                        sizeof (hkey),
+                                        &ntotal,
+                                        sizeof (ntotal),
+                                        key,
+                                        key_len,
+                                        NULL,
+                                        0));
+      GNUNET_free (key);
+
+      for (int i = -TIME_INTERVAL_RANGE; i<= TIME_INTERVAL_RANGE; i++)
+    {
+      code = compute_totp (ts,
+                           i,
+                           &hkey,
+                           sizeof (hkey));
+      if (NULL == ret)
+      {
+        GNUNET_asprintf (&ret,
+                         "%llu",
+                         (unsigned long long) code);
+      }
+      else
+      {
+        char *tmp;
+
+        GNUNET_asprintf (&tmp,
+                         "%s\n%llu",
+                         ret,
+                         (unsigned long long) code);
+        GNUNET_free (ret);
+        ret = tmp;
+      }
+    }
+      GNUNET_free (key);
+      return ret;
+    }
   }
-  GNUNET_break (0); // FIXME: not implemented
+  GNUNET_free (key);
+  GNUNET_break (0);
   return NULL;
 }

-- 
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]