~~~ almost ok
This commit is contained in:
parent
fe5751044d
commit
73f64e77be
3 changed files with 141 additions and 137 deletions
|
|
@ -51,21 +51,10 @@ let signkey_data =
|
|||
Signkey.
|
||||
{ pub; stamp_start; stamp_expire; stamp_end; master_sig; revoked_sig }
|
||||
->
|
||||
match master_sig with
|
||||
| None -> Error "signkey_data master_sig is none"
|
||||
| Some master_sig ->
|
||||
Ok (pub, stamp_start, stamp_expire, stamp_end, master_sig, revoked_sig))
|
||||
~decode:(fun
|
||||
(pub, stamp_start, stamp_expire, stamp_end, master_sig, revoked_sig) ->
|
||||
Ok
|
||||
{
|
||||
pub;
|
||||
stamp_start;
|
||||
stamp_expire;
|
||||
stamp_end;
|
||||
master_sig= Some master_sig;
|
||||
revoked_sig;
|
||||
})
|
||||
Ok { pub; stamp_start; stamp_expire; stamp_end; master_sig; revoked_sig })
|
||||
(t6 eddsa_pub time time time master_sig revoked_sig)
|
||||
|
||||
let denom_data =
|
||||
|
|
@ -91,9 +80,6 @@ let denom_data =
|
|||
revoked_sig;
|
||||
}
|
||||
->
|
||||
match master_sig with
|
||||
| None -> Error "denom_data master_sig is none"
|
||||
| Some master_sig ->
|
||||
Ok
|
||||
( pub,
|
||||
value,
|
||||
|
|
@ -135,7 +121,7 @@ let denom_data =
|
|||
fee_refund;
|
||||
age_mask;
|
||||
h_pub;
|
||||
master_sig= Some master_sig;
|
||||
master_sig;
|
||||
revoked_sig;
|
||||
})
|
||||
(t12 rsa_pub amount time time time time amount amount amount amount int
|
||||
|
|
|
|||
195
src/secmod.ml
195
src/secmod.ml
|
|
@ -1,6 +1,7 @@
|
|||
module type S = sig
|
||||
open Crypto
|
||||
|
||||
val sm_pubkey : eddsa_pub
|
||||
val sign_with_sm_key : string -> eddsa_sig
|
||||
val sign_with_signkey : pub:eddsa_pub -> string -> eddsa_sig
|
||||
val verify_with_master_key : eddsa_sig -> msg:string -> (unit, string) result
|
||||
|
|
@ -9,26 +10,20 @@ module type S = sig
|
|||
val verify_with_signkey :
|
||||
pub:eddsa_pub -> eddsa_sig -> msg:string -> (unit, string) result
|
||||
|
||||
(* TODO query database instead? *)
|
||||
val get_sm_key_pub : unit -> eddsa_pub
|
||||
val get_signkeys_data : unit -> Signkey.t list
|
||||
val get_denoms_data : unit -> Denomination.t list
|
||||
val find_signkey_data : eddsa_pub -> Signkey.t option
|
||||
val find_denomination : denomination_hash -> Denomination.t option
|
||||
val find_denom_section_name : denomination_hash -> string option
|
||||
val get_signkeys : unit -> Signkey.t list
|
||||
val get_denominations : unit -> Denomination.t list
|
||||
val get_future_signkeys : unit -> Api.FutureSignKey.t list
|
||||
val get_future_denominations : unit -> Api.FutureDenom.t list
|
||||
val find_signkey : eddsa_pub -> Signkey.t option
|
||||
val find_denomination : rsa_pub -> Denomination.t option
|
||||
|
||||
(* - management operations - *)
|
||||
(* TODO
|
||||
problem of keeping db and secmod state syncronized
|
||||
do db interaction from secmod? *)
|
||||
|
||||
val add_signkey_master_signatures :
|
||||
(eddsa_pub * Signatures.ExchangeSigningKeyValidity.t) list ->
|
||||
val certify_future_signkey :
|
||||
eddsa_pub ->
|
||||
Signatures.ExchangeSigningKeyValidity.t ->
|
||||
(unit, string) result
|
||||
|
||||
val add_denom_master_signatures :
|
||||
(denomination_hash * Signatures.DenominationKeyValidity.t) list ->
|
||||
(unit, string) result
|
||||
val certify_future_denomination :
|
||||
rsa_pub -> Signatures.DenominationKeyValidity.t -> (unit, string) result
|
||||
|
||||
val revoke_signkey :
|
||||
eddsa_pub ->
|
||||
|
|
@ -36,11 +31,11 @@ module type S = sig
|
|||
(unit, string) result
|
||||
|
||||
val revoke_denomination :
|
||||
denomination_hash ->
|
||||
rsa_pub ->
|
||||
Signatures.MasterDenominationKeyRevocation.t ->
|
||||
(unit, string) result
|
||||
|
||||
val store : unit -> (unit, string) result
|
||||
val save : unit -> (unit, string) result
|
||||
end
|
||||
|
||||
module Make (Conn : Pg.CONN) = struct
|
||||
|
|
@ -52,7 +47,7 @@ module Make (Conn : Pg.CONN) = struct
|
|||
type dn = Denomination.t
|
||||
type future_dn = Api.FutureDenom.t
|
||||
|
||||
(* TODO use lock *)
|
||||
(* TODO use lock! *)
|
||||
type t = {
|
||||
sm_key: eddsa_priv;
|
||||
sm_pubkey: eddsa_pub;
|
||||
|
|
@ -64,6 +59,7 @@ module Make (Conn : Pg.CONN) = struct
|
|||
future_dn_ht: (rsa_pub, future_dn) Hashtbl.t;
|
||||
future_sk_key_ht: (eddsa_pub, eddsa_priv) Hashtbl.t;
|
||||
future_dn_key_ht: (rsa_pub, rsa_priv) Hashtbl.t;
|
||||
dn_section_name_ht: (rsa_pub, string) Hashtbl.t;
|
||||
}
|
||||
|
||||
let database_find_sk conn fname pub =
|
||||
|
|
@ -166,6 +162,7 @@ module Make (Conn : Pg.CONN) = struct
|
|||
future_dn_ht= Hashtbl.create 0xff;
|
||||
future_sk_key_ht= Hashtbl.create 0xff;
|
||||
future_dn_key_ht= Hashtbl.create 0xff;
|
||||
dn_section_name_ht= Hashtbl.create 0xff;
|
||||
}
|
||||
in
|
||||
Ok (Some t)
|
||||
|
|
@ -280,6 +277,7 @@ module Make (Conn : Pg.CONN) = struct
|
|||
future_dn_ht= Hashtbl.create 0xff;
|
||||
future_sk_key_ht= Hashtbl.create 0xff;
|
||||
future_dn_key_ht= Hashtbl.create 0xff;
|
||||
dn_section_name_ht= Hashtbl.create 0xff;
|
||||
}
|
||||
in
|
||||
make_future_sk t;
|
||||
|
|
@ -297,6 +295,7 @@ module Make (Conn : Pg.CONN) = struct
|
|||
t
|
||||
| Error e -> Fmt.failwith "secmod init failure: %s." e
|
||||
|
||||
let sm_pubkey = t.sm_pubkey
|
||||
let sign_with_sm_key s = sign_with_sm_key t s
|
||||
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_pubkey s ~msg
|
||||
|
||||
|
|
@ -309,12 +308,11 @@ module Make (Conn : Pg.CONN) = struct
|
|||
EddsaSignature.verify ~key:Config.master_public_key
|
||||
|
||||
let verify_with_signkey ~pub s ~msg =
|
||||
(* check that the key we are verifying with is one of our own *)
|
||||
(* check that [pub] is one of our own keys *)
|
||||
match Hashtbl.find_opt t.sk_ht pub with
|
||||
| None -> Fmt.failwith "secmod failure: signkey not found."
|
||||
| Some _priv -> EddsaSignature.verify ~key:pub s ~msg
|
||||
|
||||
let sm_pubkey = t.sm_pubkey
|
||||
let get_signkeys () = t.sk_ht |> Hashtbl.to_seq_values |> List.of_seq
|
||||
let get_denominations () = t.dn_ht |> Hashtbl.to_seq_values |> List.of_seq
|
||||
|
||||
|
|
@ -367,88 +365,113 @@ module Make (Conn : Pg.CONN) = struct
|
|||
let* () = Pg.insert_signkey (module Conn) sk |> unwrap_err_caqti in
|
||||
Ok ())
|
||||
|
||||
let add_signkey_master_signatures l =
|
||||
Miou.Mutex.protect t.lock @@ fun () ->
|
||||
list_iter
|
||||
(fun (pub, master_sig) ->
|
||||
let certify_future_denomination pub master_sig =
|
||||
match
|
||||
( Hashtbl.find_opt t.future_dn_ht pub,
|
||||
Hashtbl.find_opt t.future_dn_key_ht pub )
|
||||
with
|
||||
| None, _ | _, None -> Error "secmod failure: future signkey not found."
|
||||
| Some future_dn, Some priv -> (
|
||||
match Hashtbl.find_opt t.dn_ht pub with
|
||||
| Some _dn ->
|
||||
Error
|
||||
"secmod failure: this denomination already has a master signature"
|
||||
| None ->
|
||||
let Api.FutureDenom.
|
||||
{
|
||||
section_name;
|
||||
value;
|
||||
stamp_start;
|
||||
stamp_expire_withdraw;
|
||||
stamp_expire_deposit;
|
||||
stamp_expire_legal;
|
||||
denom_pub= _;
|
||||
fee_withdraw;
|
||||
fee_deposit;
|
||||
fee_refresh;
|
||||
fee_refund;
|
||||
denom_secmod_sig= _;
|
||||
} =
|
||||
future_dn
|
||||
in
|
||||
(* TODO dn hash
|
||||
need to compute it from denom_pub *)
|
||||
let h_pub =
|
||||
Hash.DenominationHash.hash (RsaPublicKey.to_octets pub)
|
||||
in
|
||||
let dn =
|
||||
Denomination.
|
||||
{
|
||||
pub;
|
||||
value;
|
||||
stamp_start;
|
||||
stamp_expire_withdraw;
|
||||
stamp_expire_deposit;
|
||||
stamp_expire_legal;
|
||||
fee_withdraw;
|
||||
fee_deposit;
|
||||
fee_refresh;
|
||||
fee_refund;
|
||||
age_mask= 0;
|
||||
h_pub;
|
||||
master_sig;
|
||||
revoked_sig= None;
|
||||
}
|
||||
in
|
||||
Hashtbl.replace t.dn_ht pub dn;
|
||||
Hashtbl.replace t.dn_key_ht pub priv;
|
||||
Hashtbl.replace t.dn_section_name_ht pub section_name;
|
||||
Hashtbl.remove t.future_dn_ht pub;
|
||||
Hashtbl.remove t.future_dn_key_ht pub;
|
||||
|
||||
let* () = Pg.insert_denom (module Conn) dn |> unwrap_err_caqti in
|
||||
Ok ())
|
||||
|
||||
let revoke_signkey pub revoked_sig =
|
||||
match Hashtbl.find_opt t.sk_ht pub with
|
||||
| None -> Error "secmod failure: public key not found."
|
||||
| Some signkey ->
|
||||
let sk_data =
|
||||
{ signkey.sk_data with master_sig= Some master_sig }
|
||||
in
|
||||
let signkey = { signkey with sk_data } in
|
||||
let* () =
|
||||
Pg.insert_signkey (module Conn) sk_data |> unwrap_err_caqti
|
||||
in
|
||||
Hashtbl.replace t.sk_ht pub signkey;
|
||||
Ok ())
|
||||
l
|
||||
| None -> Error "secmod failure: signkey not found."
|
||||
| Some sk ->
|
||||
let sk = { sk with revoked_sig= Some revoked_sig } in
|
||||
Hashtbl.replace t.sk_ht pub sk;
|
||||
|
||||
let add_denom_master_signatures l =
|
||||
Miou.Mutex.protect t.lock @@ fun () ->
|
||||
list_iter
|
||||
(fun (h_denom_pub, master_sig) ->
|
||||
match Hashtbl.find_opt t.dn_ht h_denom_pub with
|
||||
| None -> Error "secmod failure: denomination hash not found."
|
||||
| Some denom ->
|
||||
let dn_data = { denom.dn_data with master_sig= Some master_sig } in
|
||||
let denom = { denom with dn_data } in
|
||||
let* () =
|
||||
Pg.insert_denom (module Conn) dn_data |> unwrap_err_caqti
|
||||
in
|
||||
Hashtbl.replace t.dn_ht h_denom_pub denom;
|
||||
Ok ())
|
||||
l
|
||||
|
||||
let revoke_signkey exchange_pub revoked_sig =
|
||||
Miou.Mutex.protect t.lock @@ fun () ->
|
||||
match Hashtbl.find_opt t.sk_ht exchange_pub with
|
||||
| None -> Error "secmod failure: denomination hash not found."
|
||||
| Some signkey ->
|
||||
let sk_data = { signkey.sk_data with revoked_sig= Some revoked_sig } in
|
||||
let signkey = { signkey with sk_data } in
|
||||
Hashtbl.replace t.sk_ht exchange_pub signkey;
|
||||
(* TODO revoke, apply to database *)
|
||||
Ok ()
|
||||
|
||||
let revoke_denomination h_denom_pub revoked_sig =
|
||||
Miou.Mutex.protect t.lock @@ fun () ->
|
||||
match Hashtbl.find_opt t.dn_ht h_denom_pub with
|
||||
| None -> Error "secmod failure: denomination hash not found."
|
||||
| Some denom ->
|
||||
let dn_data = { denom.dn_data with revoked_sig= Some revoked_sig } in
|
||||
let denom = { denom with dn_data } in
|
||||
Hashtbl.replace t.dn_ht h_denom_pub denom;
|
||||
let revoke_denomination pub revoked_sig =
|
||||
match Hashtbl.find_opt t.dn_ht pub with
|
||||
| None -> Error "secmod failure: denomination not found."
|
||||
| Some dn ->
|
||||
let dn = { dn with revoked_sig= Some revoked_sig } in
|
||||
Hashtbl.replace t.dn_ht pub dn;
|
||||
|
||||
(* TODO revoke, apply to database *)
|
||||
Ok ()
|
||||
|
||||
let store () =
|
||||
Miou.Mutex.protect t.lock @@ fun () ->
|
||||
let save () =
|
||||
let* () =
|
||||
Data_file.write_eddsa Fpath.(Config.secrets_dir / "sk_sm") t.sm_key_priv
|
||||
let fname = Fpath.(Config.secrets_dir / "sk_sm") in
|
||||
Data_file.write_eddsa fname t.sm_key
|
||||
in
|
||||
let* () =
|
||||
Hashtbl.to_seq_values t.sk_ht
|
||||
Hashtbl.to_seq_values t.sk_key_ht
|
||||
|> List.of_seq
|
||||
|> List.mapi (fun i (key : signkey) ->
|
||||
|> List.mapi (fun i priv ->
|
||||
let fname = Fpath.(Config.secrets_dir / Fmt.str "sk_%d" i) in
|
||||
(fname, key.priv))
|
||||
|> list_iter (fun (fname, key) -> Data_file.write_eddsa fname key)
|
||||
Data_file.write_eddsa fname priv)
|
||||
|> list_iter Fun.id
|
||||
in
|
||||
let* () =
|
||||
let* l =
|
||||
Hashtbl.to_seq_values t.dn_ht
|
||||
Hashtbl.to_seq t.dn_key_ht
|
||||
|> List.of_seq
|
||||
|> Syntax.list_map (fun (key : denom) ->
|
||||
let+ section_name =
|
||||
match Hashtbl.find_opt t.dn_section_name_ht key.dn_data.h_pub with
|
||||
|> list_iter (fun (pub, priv) ->
|
||||
let* section_name =
|
||||
match Hashtbl.find_opt t.dn_section_name_ht pub with
|
||||
| None -> Error "invalid state, section_name not found"
|
||||
| Some s -> Ok s
|
||||
in
|
||||
let fname = Fpath.(Config.secrets_dir / section_name) in
|
||||
(fname, key.priv))
|
||||
Data_file.write_rsa fname priv)
|
||||
in
|
||||
list_iter (fun (fname, key) -> Data_file.write_rsa fname key) l
|
||||
in
|
||||
Logs.info (fun m -> m "stored secmod data to file");
|
||||
Logs.info (fun m -> m "saved secmod private keys data");
|
||||
Ok ()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module type S = sig
|
||||
open Crypto
|
||||
|
||||
val sm_pubkey : eddsa_pub
|
||||
val sign_with_sm_key : string -> eddsa_sig
|
||||
val sign_with_signkey : pub:eddsa_pub -> string -> eddsa_sig
|
||||
val verify_with_master_key : eddsa_sig -> msg:string -> (unit, string) result
|
||||
|
|
@ -9,26 +10,20 @@ module type S = sig
|
|||
val verify_with_signkey :
|
||||
pub:eddsa_pub -> eddsa_sig -> msg:string -> (unit, string) result
|
||||
|
||||
(* TODO query database instead? *)
|
||||
val get_sm_key_pub : unit -> eddsa_pub
|
||||
val get_signkeys_data : unit -> Signkey.t list
|
||||
val get_denoms_data : unit -> Denomination.t list
|
||||
val find_signkey_data : eddsa_pub -> Signkey.t option
|
||||
val find_denomination : denomination_hash -> Denomination.t option
|
||||
val find_denom_section_name : denomination_hash -> string option
|
||||
val get_signkeys : unit -> Signkey.t list
|
||||
val get_denominations : unit -> Denomination.t list
|
||||
val get_future_signkeys : unit -> Api.FutureSignKey.t list
|
||||
val get_future_denominations : unit -> Api.FutureDenom.t list
|
||||
val find_signkey : eddsa_pub -> Signkey.t option
|
||||
val find_denomination : rsa_pub -> Denomination.t option
|
||||
|
||||
(* - management operations - *)
|
||||
(* TODO
|
||||
problem of keeping db and secmod state syncronized
|
||||
do db interaction from secmod? *)
|
||||
|
||||
val add_signkey_master_signatures :
|
||||
(eddsa_pub * Signatures.ExchangeSigningKeyValidity.t) list ->
|
||||
val certify_future_signkey :
|
||||
eddsa_pub ->
|
||||
Signatures.ExchangeSigningKeyValidity.t ->
|
||||
(unit, string) result
|
||||
|
||||
val add_denom_master_signatures :
|
||||
(denomination_hash * Signatures.DenominationKeyValidity.t) list ->
|
||||
(unit, string) result
|
||||
val certify_future_denomination :
|
||||
rsa_pub -> Signatures.DenominationKeyValidity.t -> (unit, string) result
|
||||
|
||||
val revoke_signkey :
|
||||
eddsa_pub ->
|
||||
|
|
@ -36,11 +31,11 @@ module type S = sig
|
|||
(unit, string) result
|
||||
|
||||
val revoke_denomination :
|
||||
denomination_hash ->
|
||||
rsa_pub ->
|
||||
Signatures.MasterDenominationKeyRevocation.t ->
|
||||
(unit, string) result
|
||||
|
||||
val store : unit -> (unit, string) result
|
||||
val save : unit -> (unit, string) result
|
||||
end
|
||||
|
||||
module Make (_ : Pg.CONN) : S
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue