diff --git a/include/dune b/include/dune new file mode 100644 index 00000000..b24da6fc --- /dev/null +++ b/include/dune @@ -0,0 +1,39 @@ +(library + (name include) + ; (wrapped false) + (modules taler_signatures) + (libraries)) + +(rule + (targets taler_signatures.ml) + (deps ./gen_taler_signatures.exe) + (action + (with-stdout-to + %{targets} + (run ./gen_taler_signatures.exe)))) + +(executable + (name gen_taler_signatures) + (modules gen_taler_signatures data) + (libraries fmt angstrom)) + +(rule + (targets taler_signatures.h) + (action + (run + wget + -q + -O + %{targets} + "https://git.taler.net/exchange.git/plain/src/include/taler/taler_signatures.h"))) + +(rule + (targets data.ml) + (deps taler_signatures.h) + (action + (with-stdout-to + %{targets} + (progn + (echo "let content = {|") + (cat taler_signatures.h) + (echo "|}"))))) diff --git a/include/gen_taler_signatures.ml b/include/gen_taler_signatures.ml new file mode 100644 index 00000000..5e554002 --- /dev/null +++ b/include/gen_taler_signatures.ml @@ -0,0 +1,50 @@ +(* script to generate signatures.ml module + get signatures definition form `exchange/src/include/taler/taler_signatures.h` + the make a ocaml value for each #define and print them in a + taler_signatures.ml module *) + +open Angstrom + +type define = { + name: string; + value: int; +} + +let define_line : define t = + let is_ident_char = function + | 'A' .. 'Z' | '0' .. '9' | '_' -> true + | _ -> false + in + let p = + string "#define" + *> skip_while (( = ) ' ') + *> string "TALER_SIGNATURE_" + *> take_while1 is_ident_char + >>= fun name -> + skip_while (( = ) ' ') + *> take_while1 (function '0' .. '9' -> true | _ -> false) + >>| fun digits -> + let name = String.lowercase_ascii name in + let value = int_of_string digits in + { name; value } + in + p <* end_of_line + +let all_defines : define list t = + let any_line = take_till (Char.equal '\n') <* end_of_line in + many (choice [ define_line >>| Option.some; any_line *> return None ]) + >>| List.filter_map Fun.id + +let parse input = + match parse_string ~consume:All all_defines input with + | Ok defs -> defs + | Error msg -> failwith msg + +let () = + let l = parse Data.content in + assert (List.length l = 74); + + let pp ppf { name; value } = Fmt.pf ppf "let %s = %d@." name value in + Fmt.pr "%a" (Fmt.list pp) l; + + () diff --git a/src/dune b/src/dune index 7c13b657..d8040682 100644 --- a/src/dune +++ b/src/dune @@ -11,6 +11,8 @@ (libraries base_32 ; + include + ; angstrom zarith ; mirage-crypto diff --git a/src/signatures.ml b/src/signatures.ml new file mode 100644 index 00000000..9db5dbb2 --- /dev/null +++ b/src/signatures.ml @@ -0,0 +1,23 @@ +(* https://docs.taler.net/core/api-common.html#id7 *) + +module Purpose = struct + (* defined in gnunet_crypto_lib.h *) + type t = { + (* This field equals the number of bytes being signed, + namely 'sizeof (struct Data)'. *) + size: Int32.t; (* = uint32_t *) + (* This field is used to express the context in + which the signature is made, ensuring that a + signature cannot be lifted from one part of the protocol + to another. See `src/include/taler/taler_signatures.h` within the + exchange's codebase (git://taler.net/exchange). *) + purpose: Int32.t; (* = uint32_t *) + } +end + +module Data = struct + type t = { + purpose: Purpose.t; + payloads: string list; + } +end