~ test/
This commit is contained in:
parent
6bf2771f1c
commit
4ae149e97a
11 changed files with 40 additions and 165 deletions
|
|
@ -5,7 +5,8 @@
|
||||||
option: correct use opt_mem or Jsont.option
|
option: correct use opt_mem or Jsont.option
|
||||||
better types:
|
better types:
|
||||||
- payto_uri
|
- payto_uri
|
||||||
- uri *)
|
- uri
|
||||||
|
use of monotonic time for some validity_start/_end fields *)
|
||||||
|
|
||||||
let protocol_version = "31:0:0"
|
let protocol_version = "31:0:0"
|
||||||
|
|
||||||
|
|
@ -497,8 +498,6 @@ module AuditorSetupMessage = struct
|
||||||
auditor_name: string;
|
auditor_name: string;
|
||||||
auditor_pub: EddsaPublicKey.t;
|
auditor_pub: EddsaPublicKey.t;
|
||||||
master_sig: MasterAddAuditor.t;
|
master_sig: MasterAddAuditor.t;
|
||||||
(* TODO monotonic time
|
|
||||||
something about using monotonic system time here! *)
|
|
||||||
validity_start: Timestamp.t;
|
validity_start: Timestamp.t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,7 +522,6 @@ end
|
||||||
module AuditorTeardownMessage = struct
|
module AuditorTeardownMessage = struct
|
||||||
type t = {
|
type t = {
|
||||||
master_sig: MasterDelAuditor.t;
|
master_sig: MasterDelAuditor.t;
|
||||||
(* TODO monotonic time *)
|
|
||||||
validity_end: Timestamp.t;
|
validity_end: Timestamp.t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -630,7 +628,6 @@ module WireSetupMessage = struct
|
||||||
payto_uri: string;
|
payto_uri: string;
|
||||||
master_sig_wire: MasterWireDetails.t;
|
master_sig_wire: MasterWireDetails.t;
|
||||||
master_sig_add: MasterAddWire.t;
|
master_sig_add: MasterAddWire.t;
|
||||||
(* TODO monotonic time *)
|
|
||||||
validity_start: Timestamp.t;
|
validity_start: Timestamp.t;
|
||||||
bank_label: string option;
|
bank_label: string option;
|
||||||
priority: int option;
|
priority: int option;
|
||||||
|
|
@ -668,7 +665,6 @@ module WireTeardownMessage = struct
|
||||||
type t = {
|
type t = {
|
||||||
payto_uri: string;
|
payto_uri: string;
|
||||||
master_sig_del: MasterDelWire.t;
|
master_sig_del: MasterDelWire.t;
|
||||||
(* TODO monotonic time *)
|
|
||||||
validity_end: Timestamp.t;
|
validity_end: Timestamp.t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,7 @@ module Binary_format_rsa = struct
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
end
|
end
|
||||||
|
|
||||||
(* TODO key format
|
|
||||||
- check what is the exact format in GNUNET
|
|
||||||
- endianess issue? *)
|
|
||||||
module EddsaPublicKey = struct
|
module EddsaPublicKey = struct
|
||||||
(* EdDSA and ECDHE public keys always point on Curve25519
|
|
||||||
and represented using the standard 256 bits Ed25519 compact format,
|
|
||||||
converted to Crockford Base32. *)
|
|
||||||
open Mirage_crypto_ec.Ed25519
|
open Mirage_crypto_ec.Ed25519
|
||||||
|
|
||||||
type t = pub
|
type t = pub
|
||||||
|
|
@ -161,8 +155,6 @@ module EddsaSignature : sig
|
||||||
val bin : t Bin.t
|
val bin : t Bin.t
|
||||||
val caqti : t Caqti_type.t
|
val caqti : t Caqti_type.t
|
||||||
end = struct
|
end = struct
|
||||||
(* TODO key format
|
|
||||||
endianess issue? *)
|
|
||||||
(* transmitted as 64-bytes base32
|
(* transmitted as 64-bytes base32
|
||||||
binary-encoded objects with just the R and S values *)
|
binary-encoded objects with just the R and S values *)
|
||||||
type t = string
|
type t = string
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
(* TODO use SHA512.of_raw_string_opt *)
|
|
||||||
open Digestif
|
open Digestif
|
||||||
|
|
||||||
module type S = sig
|
module type S = sig
|
||||||
|
|
@ -20,7 +19,7 @@ module H32 = struct
|
||||||
|
|
||||||
let of_octets s =
|
let of_octets s =
|
||||||
match SHA256.of_raw_string_opt s with
|
match SHA256.of_raw_string_opt s with
|
||||||
| None -> Fmt.failwith "H32.of_octets failure: data is not 32 bytes"
|
| None -> Fmt.failwith "H32.of_octets failure"
|
||||||
| Some t -> t
|
| Some t -> t
|
||||||
|
|
||||||
let to_octets = SHA256.to_raw_string
|
let to_octets = SHA256.to_raw_string
|
||||||
|
|
@ -50,7 +49,7 @@ module H64 = struct
|
||||||
|
|
||||||
let of_octets s =
|
let of_octets s =
|
||||||
match SHA512.of_raw_string_opt s with
|
match SHA512.of_raw_string_opt s with
|
||||||
| None -> Fmt.failwith "H64.of_octets failure: data is not 64 bytes"
|
| None -> Fmt.failwith "H64.of_octets failure"
|
||||||
| Some t -> t
|
| Some t -> t
|
||||||
|
|
||||||
let to_octets = SHA512.to_raw_string
|
let to_octets = SHA512.to_raw_string
|
||||||
|
|
|
||||||
|
|
@ -167,25 +167,7 @@ module Keys_post = struct
|
||||||
let* () = list_iter (verify_signkey_signature sm) signkey_sigs in
|
let* () = list_iter (verify_signkey_signature sm) signkey_sigs in
|
||||||
Ok ()
|
Ok ()
|
||||||
|
|
||||||
(* TODO move to test *)
|
let do_ ~db_conn:_ (module Sm : Secmod.S)
|
||||||
let check_master_signatures_update ~db_conn (module Sm : Secmod.S) =
|
|
||||||
Sm.get_denoms_data ()
|
|
||||||
|> list_iter (fun denom ->
|
|
||||||
let error = Error "update_master_signatures sanity check failure" in
|
|
||||||
let* opt =
|
|
||||||
Pg.find_denom db_conn denom.Denom_data.h_pub |> unwrap_err_caqti
|
|
||||||
in
|
|
||||||
let* v = match opt with None -> error | Some v -> Ok v in
|
|
||||||
let check = function false -> error | true -> Ok () in
|
|
||||||
let* () =
|
|
||||||
check (Timestamp.compare v.stamp_start denom.stamp_start = 0)
|
|
||||||
in
|
|
||||||
let* () = check (v.value = denom.value) in
|
|
||||||
let* () = check (v.fee_refund = denom.fee_refund) in
|
|
||||||
let* () = check (v.age_mask = denom.age_mask) in
|
|
||||||
Ok ())
|
|
||||||
|
|
||||||
let do_ ~db_conn (module Sm : Secmod.S)
|
|
||||||
MasterSignatures.{ denom_sigs; signkey_sigs } =
|
MasterSignatures.{ denom_sigs; signkey_sigs } =
|
||||||
let* () =
|
let* () =
|
||||||
signkey_sigs
|
signkey_sigs
|
||||||
|
|
@ -200,7 +182,6 @@ module Keys_post = struct
|
||||||
|> Sm.add_denom_master_signatures
|
|> Sm.add_denom_master_signatures
|
||||||
in
|
in
|
||||||
let* () = Sm.store () in
|
let* () = Sm.store () in
|
||||||
let* () = check_master_signatures_update ~db_conn (module Sm) in
|
|
||||||
Ok ()
|
Ok ()
|
||||||
|
|
||||||
let jsont = MasterSignatures.jsont
|
let jsont = MasterSignatures.jsont
|
||||||
|
|
@ -298,9 +279,7 @@ module Auditors = struct
|
||||||
h_auditor_url= Hash.Cstring.H64.hash auditor_url;
|
h_auditor_url= Hash.Cstring.H64.hash auditor_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
(* TODO timestamps last_change +/- checks *)
|
(* TODO monotonic time *)
|
||||||
(* todo: there is something about use of monotonic time
|
|
||||||
+ protection against replay attack that I don't understand *)
|
|
||||||
let do_ ~db_conn v =
|
let do_ ~db_conn v =
|
||||||
let auditor_pub = v.AuditorSetupMessage.auditor_pub in
|
let auditor_pub = v.AuditorSetupMessage.auditor_pub in
|
||||||
let validity_start = v.AuditorSetupMessage.validity_start in
|
let validity_start = v.AuditorSetupMessage.validity_start in
|
||||||
|
|
@ -490,7 +469,7 @@ module Global_fees = struct
|
||||||
|
|
||||||
let jsont = GlobalFees.jsont
|
let jsont = GlobalFees.jsont
|
||||||
|
|
||||||
(* TODO global_fees
|
(* TODO better global_fees
|
||||||
ensure it is defined for the current time.
|
ensure it is defined for the current time.
|
||||||
there should be only one global_fees for each moment in time
|
there should be only one global_fees for each moment in time
|
||||||
and once set for a timeframe, it should not change. *)
|
and once set for a timeframe, it should not change. *)
|
||||||
|
|
@ -518,7 +497,7 @@ module Wire = struct
|
||||||
bank_label= _;
|
bank_label= _;
|
||||||
priority= _;
|
priority= _;
|
||||||
} =
|
} =
|
||||||
(* TODO wire *)
|
(* TODO are those read from payto_uri? *)
|
||||||
let conversion_url = "" in
|
let conversion_url = "" in
|
||||||
let credit_restrictions = "" in
|
let credit_restrictions = "" in
|
||||||
let debit_restrictions = "" in
|
let debit_restrictions = "" in
|
||||||
|
|
@ -553,9 +532,7 @@ module Wire = struct
|
||||||
match last_change_opt with
|
match last_change_opt with
|
||||||
| Some _ -> Error "wire already setup"
|
| Some _ -> Error "wire already setup"
|
||||||
| None ->
|
| None ->
|
||||||
(* TODO wire *)
|
let r =
|
||||||
let last_change = Timestamp.of_ptime (Ptime_clock.now ()) in
|
|
||||||
let v =
|
|
||||||
ExchangeWireAccount.
|
ExchangeWireAccount.
|
||||||
{
|
{
|
||||||
payto_uri= v.payto_uri;
|
payto_uri= v.payto_uri;
|
||||||
|
|
@ -567,7 +544,10 @@ module Wire = struct
|
||||||
priority= v.priority;
|
priority= v.priority;
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
let+ () = Pg.insert_wire db_conn ~last_change v |> unwrap_err_caqti in
|
let+ () =
|
||||||
|
Pg.insert_wire db_conn ~last_change:v.validity_start r
|
||||||
|
|> unwrap_err_caqti
|
||||||
|
in
|
||||||
()
|
()
|
||||||
|
|
||||||
let jsont = WireSetupMessage.jsont
|
let jsont = WireSetupMessage.jsont
|
||||||
|
|
|
||||||
21
src/pg.ml
21
src/pg.ml
|
|
@ -1,21 +1,13 @@
|
||||||
(* TODO
|
(* TODO
|
||||||
|
check signed/unsigned ints
|
||||||
check there is no issues with signed/unsigned integers
|
check endianness
|
||||||
|
can we avoid amount tuple boilerplate?
|
||||||
how to fix postgres/caqti tuple type?
|
clean up caqti error type
|
||||||
try something with OID?
|
|
||||||
need to add boilerplate in each query for amounts
|
|
||||||
|
|
||||||
GNU Taler db-events?
|
|
||||||
it seems caqti/pgx does not support it
|
|
||||||
|
|
||||||
transaction
|
transaction
|
||||||
|
|
||||||
should check validity of signatures got from db, for /management at least
|
GNU Taler use of db-events?
|
||||||
|
it seems caqti/pgx does not support it *)
|
||||||
clean up caqti error type *)
|
|
||||||
(* TODO time
|
|
||||||
fix comparison with timestamp footgun *)
|
|
||||||
|
|
||||||
module type CONN = Caqti_miou.CONNECTION
|
module type CONN = Caqti_miou.CONNECTION
|
||||||
|
|
||||||
|
|
@ -330,7 +322,6 @@ let update_wire =
|
||||||
|
|
||||||
let disable_wire =
|
let disable_wire =
|
||||||
let disable_wire =
|
let disable_wire =
|
||||||
(* TODO check syntax on this *)
|
|
||||||
Caqti_type.(t2 payto_uri time ->. unit)
|
Caqti_type.(t2 payto_uri time ->. unit)
|
||||||
"UPDATE wire_accounts SET conversion_url=NULL, debit_restrictions=NULL, \
|
"UPDATE wire_accounts SET conversion_url=NULL, debit_restrictions=NULL, \
|
||||||
credit_restrictions=NULL, master_sig=NULL, bank_label=NULL, \
|
credit_restrictions=NULL, master_sig=NULL, bank_label=NULL, \
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,6 @@ open Caqti_type
|
||||||
open Crypto
|
open Crypto
|
||||||
open Api
|
open Api
|
||||||
|
|
||||||
(* TODO
|
|
||||||
check that we use Caqti_type.octets for binary data *)
|
|
||||||
|
|
||||||
let amount : Amount.t t =
|
let amount : Amount.t t =
|
||||||
let open Amount in
|
let open Amount in
|
||||||
custom
|
custom
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
(* TODO debug sig
|
(* TODO signatures
|
||||||
check with taler-wallet-core/src/crypto/cryptoImplementation.js
|
check with taler-wallet-core/src/crypto/cryptoImplementation.js
|
||||||
unsigned-ints
|
check signed/unsigned ints
|
||||||
|
check endianness
|
||||||
|
|
||||||
can we skip defining a specific record for signatures and directly use Api records? *)
|
better handling of decoding failure *)
|
||||||
open Hash
|
open Hash
|
||||||
|
|
||||||
module Aliases = struct
|
module Aliases = struct
|
||||||
|
|
@ -185,7 +186,7 @@ end
|
||||||
|
|
||||||
module DenominationKeyAnnouncement = struct
|
module DenominationKeyAnnouncement = struct
|
||||||
module R = struct
|
module R = struct
|
||||||
(* TODO CS: use purpose TALER_SIGNATURE_SM_CS_DENOMINATION_KEY *)
|
(* CS: use purpose TALER_SIGNATURE_SM_CS_DENOMINATION_KEY *)
|
||||||
(* purpose.purpose = TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY *)
|
(* purpose.purpose = TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY *)
|
||||||
type r = {
|
type r = {
|
||||||
h_denom_pub: DenominationHash.t;
|
h_denom_pub: DenominationHash.t;
|
||||||
|
|
@ -252,8 +253,7 @@ module DenominationKeyValidity = struct
|
||||||
fee_withdraw: AmountNBO.t;
|
fee_withdraw: AmountNBO.t;
|
||||||
fee_deposit: AmountNBO.t;
|
fee_deposit: AmountNBO.t;
|
||||||
fee_refresh: AmountNBO.t;
|
fee_refresh: AmountNBO.t;
|
||||||
(* TODO debug sig
|
(* TODO signatures taler doc *)
|
||||||
missing field from taler doc *)
|
|
||||||
fee_refund: AmountNBO.t;
|
fee_refund: AmountNBO.t;
|
||||||
denom_hash: DenominationHash.t;
|
denom_hash: DenominationHash.t;
|
||||||
}
|
}
|
||||||
|
|
@ -424,8 +424,7 @@ end
|
||||||
|
|
||||||
module GlobalFees = struct
|
module GlobalFees = struct
|
||||||
module R = struct
|
module R = struct
|
||||||
(* TODO debug sig
|
(* TODO signatures taler doc *)
|
||||||
taler doc *)
|
|
||||||
(* purpose.purpose = TALER_SIGNATURE_MASTER_GLOBAL_FEES *)
|
(* purpose.purpose = TALER_SIGNATURE_MASTER_GLOBAL_FEES *)
|
||||||
type r = {
|
type r = {
|
||||||
start_date: TimestampNBO.t;
|
start_date: TimestampNBO.t;
|
||||||
|
|
|
||||||
11
test/dune
11
test/dune
|
|
@ -4,13 +4,6 @@
|
||||||
(libraries mte fmt))
|
(libraries mte fmt))
|
||||||
|
|
||||||
(test
|
(test
|
||||||
(name crypto)
|
(name test_crypto)
|
||||||
(modules crypto)
|
(modules test_crypto)
|
||||||
(libraries mte fmt))
|
(libraries mte fmt))
|
||||||
|
|
||||||
; TODO
|
|
||||||
; cram test?
|
|
||||||
; gcc -o a.out ./test/signatures.c && ./a.out > a.output
|
|
||||||
; rm ./a.out
|
|
||||||
; dune exec ./test/test.exe > b.output
|
|
||||||
; cmp -l a.output b.output
|
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct H64 {
|
|
||||||
uint8_t hash[64];
|
|
||||||
};
|
|
||||||
struct Hhh {
|
|
||||||
struct H64 hash;
|
|
||||||
};
|
|
||||||
struct Purpose {
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t purpose;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS {
|
|
||||||
struct Purpose purpose;
|
|
||||||
struct Hhh h;
|
|
||||||
uint32_t noreveal_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct Purpose purpose;
|
|
||||||
struct PS ps;
|
|
||||||
|
|
||||||
purpose.size = 3 * 4 + 64;
|
|
||||||
purpose.purpose = 1050;
|
|
||||||
|
|
||||||
struct Hhh h = {
|
|
||||||
.hash = {
|
|
||||||
.hash = {
|
|
||||||
1 , 2 , 3 , 4 , 5, 6, 7, 8,
|
|
||||||
9 , 10, 11, 12, 13, 14, 15, 16,
|
|
||||||
17, 18, 19, 20, 21, 22, 23, 24,
|
|
||||||
25, 26, 27, 28, 29, 30, 31, 32,
|
|
||||||
33, 34, 35, 36, 37, 38, 39, 40,
|
|
||||||
41, 42, 43, 44, 45, 46, 47, 48,
|
|
||||||
49, 50, 51, 52, 53, 54, 55, 56,
|
|
||||||
57, 58, 59, 60, 61, 62, 63, 64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t noreveal_index = 0;
|
|
||||||
|
|
||||||
ps.purpose = purpose;
|
|
||||||
ps.h = h;
|
|
||||||
ps.noreveal_index = noreveal_index;
|
|
||||||
|
|
||||||
|
|
||||||
fwrite(&ps, sizeof(ps), 1, stdout);
|
|
||||||
|
|
||||||
// printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
21
test/test.ml
21
test/test.ml
|
|
@ -97,19 +97,14 @@ let () =
|
||||||
|
|
||||||
()
|
()
|
||||||
|
|
||||||
(*
|
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let open Binary_formats.WithdrawConfirmationPS in
|
let round_trip s =
|
||||||
let str64 = String.init 64 (fun i -> Char.unsafe_chr (i + 1)) in
|
let s' = s |> B32.encode |> B32.decode |> Result.get_ok in
|
||||||
let dummy_t = { h_planchets= { hash= str64 }; noreveal_index= 0_l } in
|
assert (s = s')
|
||||||
let size = Bin.size_of_value bin dummy_t |> Option.get in
|
in
|
||||||
assert (size = 76);
|
let s = String.init 0xff Char.chr in
|
||||||
|
round_trip s;
|
||||||
|
let s_l = List.init 0x0f (fun i -> String.init i Char.chr) in
|
||||||
|
List.iter round_trip s_l;
|
||||||
|
|
||||||
(* for cmp test with signatures.c output *)
|
|
||||||
(*
|
|
||||||
let raw_str = Bin.to_string bin dummy_t in
|
|
||||||
Printf.printf "%s" raw_str;
|
|
||||||
*)
|
|
||||||
()
|
()
|
||||||
*)
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,9 @@
|
||||||
|
(* Test vectors taken from GNUnet:
|
||||||
|
https://git.gnunet.org/gnunet/gnunet/file/src/cli/util/crypto-test-vectors.json.html *)
|
||||||
|
|
||||||
let encode = B32.encode
|
let encode = B32.encode
|
||||||
let decode s = B32.decode s |> Result.get_ok
|
let decode s = B32.decode s |> Result.get_ok
|
||||||
|
|
||||||
let round_trip s =
|
|
||||||
let s' = s |> encode |> decode in
|
|
||||||
match s' = s with
|
|
||||||
| false -> Fmt.failwith "b32 round trip failure: @\nin :`%S`@\nout:`%S`" s' s
|
|
||||||
| true -> ()
|
|
||||||
|
|
||||||
let () =
|
|
||||||
let s = String.init 0xff Char.chr in
|
|
||||||
round_trip s;
|
|
||||||
let s_l = List.init 0x0f (fun i -> String.init i Char.chr) in
|
|
||||||
List.iter round_trip s_l; ()
|
|
||||||
|
|
||||||
(* test vectors from:
|
|
||||||
https://git.gnunet.org/gnunet/gnunet/file/src/cli/util/crypto-test-vectors.json.html *)
|
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
(* hash *)
|
(* hash *)
|
||||||
let input = "91JPRV3F5GG4EKJNDSJQ8" in
|
let input = "91JPRV3F5GG4EKJNDSJQ8" in
|
||||||
|
|
@ -96,7 +84,7 @@ let () =
|
||||||
()
|
()
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
(* rsa blinding *)
|
(* rsa_blind_signing *)
|
||||||
(* rsa_private_key data is given in gcrypt sexpr format.. *)
|
(* rsa_private_key data is given in gcrypt sexpr format.. *)
|
||||||
let message_hash =
|
let message_hash =
|
||||||
"XKQMJ4CNTXBFE1V2WR6JS063J7PZQE4XMB5JH3RS5X0THQ1JQSQ69Y7KDBC9TYRJEZH48MEPY2SF4QHQ4VHXC0YQX5935MQEGP0AX6R"
|
"XKQMJ4CNTXBFE1V2WR6JS063J7PZQE4XMB5JH3RS5X0THQ1JQSQ69Y7KDBC9TYRJEZH48MEPY2SF4QHQ4VHXC0YQX5935MQEGP0AX6R"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue