diff --git a/src/api.ml b/src/api.ml index f6dd4427..47d2156e 100644 --- a/src/api.ml +++ b/src/api.ml @@ -90,40 +90,42 @@ module RsaDenominationKey = struct |> Jsont.Object.finish end -(* not acctually implemented *) +(* ! Clause Schnorr cipher is not supported *) module CSDenominationKey = struct - (* Clause Schnorr *) type t = { age_mask: int; - cs_pub: string; + cs_pub: B32.t; } + (* TODO B32.jsont *) + let b32_jsont = Jsont.of_of_string ~kind:"B32" B32.decode ~enc:B32.encode + let jsont = let make age_mask cs_pub = { age_mask; cs_pub } in let age_mask v = v.age_mask in let cs_pub v = v.cs_pub in Jsont.Object.map ~kind:"CSDenominationKey" make |> Jsont.Object.mem "age_mask" Jsont.int ~enc:age_mask - |> Jsont.Object.mem "cs_pub" Jsont.string ~enc:cs_pub + |> Jsont.Object.mem "cs_pub" b32_jsont ~enc:cs_pub |> Jsont.Object.finish end module DenominationKey = struct - type t = - | Rsa of RsaDenominationKey.t - | CS of CSDenominationKey.t + type t = Rsa of RsaDenominationKey.t + (*| CS of CSDenominationKey.t*) - let rsa v = Rsa v - let cs v = CS v + let to_octets = function Rsa denom -> RsaPublicKey.to_octets denom.rsa_pub + + let of_cs _v = + Jsont.Error.msg Jsont.Meta.none "CSDenominationKey are not supported" + + let of_rsa v = Rsa v let jsont = let open Jsont.Object in - let rsa = Case.map "RSA" RsaDenominationKey.jsont ~dec:rsa in - let cs = Case.map "CS" CSDenominationKey.jsont ~dec:cs in - let enc_case = function - | Rsa v -> Case.value rsa v - | CS v -> Case.value cs v - in + let rsa = Case.map "RSA" RsaDenominationKey.jsont ~dec:of_rsa in + let cs = Case.map "CS" CSDenominationKey.jsont ~dec:of_cs in + let enc_case = function Rsa v -> Case.value rsa v in let cases = Case.[ make rsa; make cs ] in map ~kind:"DenominationKey" Fun.id |> case_mem "cipher" Jsont.string ~enc:Fun.id ~enc_case cases @@ -171,7 +173,7 @@ module FutureDenom = struct fee_deposit: Amount.t; fee_refresh: Amount.t; fee_refund: Amount.t; - denom_secmod_sig: EddsaSignature.t; + denom_secmod_sig: Bin_signature.DenominationKeyAnnouncementPS.Sig.t; } let jsont = @@ -218,7 +220,9 @@ module FutureDenom = struct |> mem "fee_deposit" Amount.jsont ~enc:fee_deposit |> mem "fee_refresh" Amount.jsont ~enc:fee_refresh |> mem "fee_refund" Amount.jsont ~enc:fee_refund - |> mem "denom_secmod_sig" EddsaSignature.jsont ~enc:denom_secmod_sig + |> mem "denom_secmod_sig" + Bin_signature.DenominationKeyAnnouncementPS.Sig.jsont + ~enc:denom_secmod_sig |> finish end diff --git a/src/bin_signature.ml b/src/bin_signature.ml index 84fdbac4..f7d30051 100644 --- a/src/bin_signature.ml +++ b/src/bin_signature.ml @@ -88,7 +88,7 @@ module DenominationKeyAnnouncementPS = struct (* TODO taler_signatures purpose we use TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY instead here *) (* purpose.purpose = TALER_SIGNATURE_SM_DENOMINATION_KEY *) - type t = { + type r = { h_denom_pub: DenominationHash.t; h_section_name: Hash_64_cstr.t; anchor_time: TimeAbsoluteNBO.t; @@ -107,6 +107,24 @@ module DenominationKeyAnnouncementPS = struct |+ field TimeAbsoluteNBO.bin (fun t -> t.anchor_time) |+ field TimeRelativeNBO.bin (fun t -> t.duration_withdraw) |> sealr + + module type SIG = sig + type t + + val sign : (string -> string) -> r -> t + val verify : (string -> msg:string -> bool) -> t -> r -> bool + val jsont : t Jsont.t + end + + module Sig : SIG = struct + type t = string + + let sign f r = f @@ Bin.to_string bin r + let verify f s r = f s ~msg:(Bin.to_string bin r) + + (* TODO B32.jsont, for others types too *) + let jsont = Jsont.string + end end module SigningKeyAnnouncementPS = struct diff --git a/src/crypto.ml b/src/crypto.ml index 249d051e..8fda65f3 100644 --- a/src/crypto.ml +++ b/src/crypto.ml @@ -52,6 +52,7 @@ module EddsaSignature : sig type t val sign : key:Mirage_crypto_ec.Ed25519.priv -> string -> t + val sign_as_string : key:Mirage_crypto_ec.Ed25519.priv -> string -> string val of_b32 : string -> (t, string) result val to_b32 : t -> string val to_octets : t -> string @@ -81,6 +82,8 @@ end = struct (* mirage_crypto: "The result is the concatenation of r and s, as specified in RFC 8032." *) Mirage_crypto_ec.Ed25519.sign ~key s + let sign_as_string ~key s = sign ~key s + let check_size t = match String.length t = 64 with | false -> Error "EddsaSignature: invalid string length" diff --git a/src/management.ml b/src/management.ml index e1e21617..1aff93fe 100644 --- a/src/management.ml +++ b/src/management.ml @@ -21,19 +21,18 @@ let mk_future_denom denom_key_signf } : Denomination.t) = let denom_pub = - DenominationKey.Rsa RsaDenominationKey.{ age_mask; rsa_pub= pub } + DenominationKey.of_rsa RsaDenominationKey.{ age_mask; rsa_pub= pub } in let denom_secmod_sig = - let open Bin_type in let open Bin_signature.DenominationKeyAnnouncementPS in let h_denom_pub = h_pub in - let h_section_name = Hash_64_cstr.hash section_name in + let h_section_name = Bin_type.Hash_64_cstr.hash section_name in let anchor_time = stamp_start in let duration_withdraw = Timestamp.diff stamp_start stamp_expire_withdraw |> Timestamp.of_span_exn in - let ps = { h_denom_pub; h_section_name; anchor_time; duration_withdraw } in - ps |> Bin.to_string bin |> denom_key_signf + Sig.sign denom_key_signf + { h_denom_pub; h_section_name; anchor_time; duration_withdraw } in FutureDenom. { @@ -61,8 +60,9 @@ let mk_future_signkey signkey_signf let duration = Timestamp.diff stamp_start stamp_expire |> Timestamp.of_span_exn in - let ps = { exchange_pub; anchor_time; duration } in - ps |> Bin.to_string bin |> signkey_signf + { exchange_pub; anchor_time; duration } + |> Bin.to_string bin + |> signkey_signf in FutureSignKey. { key= pub; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig } @@ -74,7 +74,8 @@ let mk_future_keys_response (secmod_signkey : Secmod_signkey.t) |> List.filter (fun k -> Option.is_none k.Denomination.master_sig) |> List.map (fun denom -> let signf s = - Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s + Crypto.EddsaSignature.sign_as_string + ~key:secmod_denom.sm_key.Signkey.priv s in mk_future_denom signf denom) in diff --git a/test/test.ml b/test/test.ml index 4e9efd4d..4377e198 100644 --- a/test/test.ml +++ b/test/test.ml @@ -15,11 +15,13 @@ let () = in () +let get_ok = function Error e -> failwith e | Ok v -> v + let () = let open Api in let check jsont s = - let encode v = encode jsont v |> Result.get_ok in - let decode v = decode jsont v |> Result.get_ok in + let encode v = encode jsont v |> get_ok in + let decode v = decode jsont v |> get_ok in let ts = decode s in let s' = encode ts in let ts' = decode s' in @@ -35,13 +37,14 @@ let () = check_bad Timestamp.jsont {|{"t_s": "123456780"}|}; check_bad Timestamp.jsont {|{"t_s": "agagou"}|}; - (* TODO use a valid rsa_pub value *) - (* - check DenominationKey.jsont - {|{"cipher": "RSA", "age_mask": 18, "rsa_pub": "agagouh"}|}; - check DenominationKey.jsont + (* CS not implemented *) + check_bad DenominationKey.jsont {|{"cipher": "CS", "age_mask": 18, "cs_pub": "ouhagag"}|}; - *) + + (* TODO test with a valid rsa_pub value *) + (* TODO handle "rsa pub_of_octets failure" correctly *) + (* check_bad DenominationKey.jsont + {|{"cipher": "RSA", "age_mask": 18, "rsa_pub": "agagouh"}|}; *) () let () = diff --git a/tools/offline_bin.ml b/tools/offline_bin.ml index 016667d0..1919706d 100644 --- a/tools/offline_bin.ml +++ b/tools/offline_bin.ml @@ -19,20 +19,12 @@ let denom_signature ~master_key (* TODO check sigs *) denom_secmod_sig= _; } = - let pub_octets = - let denom_pub = - match denom_pub with - | Rsa v -> v - | CS _ -> Fmt.failwith "CS key types are not supported." - in - let pub = denom_pub.RsaDenominationKey.rsa_pub in - RsaPublicKey.to_octets pub - in - let h_denom_pub = HashCode.hash pub_octets in + let octets = DenominationKey.to_octets denom_pub in + let h_denom_pub = HashCode.hash octets in let master_sig = let open Bin_signature.DenominationKeyValidityPS in let master = EddsaPrivateKey.(pub_of_priv master_key) in - let denom_hash = DenominationHash.hash pub_octets in + let denom_hash = DenominationHash.hash octets in { master; start= stamp_start;