This commit is contained in:
parent
a937595d6f
commit
8580a107ab
3 changed files with 80 additions and 67 deletions
|
|
@ -13,6 +13,6 @@ type t = {
|
||||||
fee_refund: Amount.t;
|
fee_refund: Amount.t;
|
||||||
age_mask: int;
|
age_mask: int;
|
||||||
h_pub: denomination_hash;
|
h_pub: denomination_hash;
|
||||||
master_sig: Signatures.DenominationKeyValidity.t option;
|
master_sig: Signatures.DenominationKeyValidity.t;
|
||||||
revoked_sig: Signatures.MasterDenominationKeyRevocation.t option;
|
revoked_sig: Signatures.MasterDenominationKeyRevocation.t option;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
143
src/secmod.ml
143
src/secmod.ml
|
|
@ -171,8 +171,7 @@ module Make (Conn : Pg.CONN) = struct
|
||||||
Ok (Some t)
|
Ok (Some t)
|
||||||
| _, _, _ -> error_invalid_state
|
| _, _, _ -> error_invalid_state
|
||||||
|
|
||||||
(* TODO *)
|
let sign_with_sm_key t s = EddsaSignature.sign ~key:t.sm_key s
|
||||||
let sign_with_sm_key _ = assert false
|
|
||||||
|
|
||||||
let make_future_sk t =
|
let make_future_sk t =
|
||||||
let start = Time.Absolute.of_ptime (Ptime_clock.now ()) in
|
let start = Time.Absolute.of_ptime (Ptime_clock.now ()) in
|
||||||
|
|
@ -188,7 +187,7 @@ module Make (Conn : Pg.CONN) = struct
|
||||||
let exchange_pub = pub in
|
let exchange_pub = pub in
|
||||||
let anchor_time = stamp_start in
|
let anchor_time = stamp_start in
|
||||||
let duration = Timestamp.diff stamp_start stamp_expire in
|
let duration = Timestamp.diff stamp_start stamp_expire in
|
||||||
sign_f ~f:sign_with_sm_key { exchange_pub; anchor_time; duration }
|
sign_f ~f:(sign_with_sm_key t) { exchange_pub; anchor_time; duration }
|
||||||
in
|
in
|
||||||
let future_sk =
|
let future_sk =
|
||||||
Api.FutureSignKey.
|
Api.FutureSignKey.
|
||||||
|
|
@ -243,7 +242,7 @@ module Make (Conn : Pg.CONN) = struct
|
||||||
let duration_withdraw =
|
let duration_withdraw =
|
||||||
Timestamp.diff stamp_start stamp_expire_withdraw
|
Timestamp.diff stamp_start stamp_expire_withdraw
|
||||||
in
|
in
|
||||||
sign_f ~f:sign_with_sm_key
|
sign_f ~f:(sign_with_sm_key t)
|
||||||
{ h_denom_pub; h_section_name; anchor_time; duration_withdraw }
|
{ h_denom_pub; h_section_name; anchor_time; duration_withdraw }
|
||||||
in
|
in
|
||||||
let future_dn =
|
let future_dn =
|
||||||
|
|
@ -268,26 +267,24 @@ module Make (Conn : Pg.CONN) = struct
|
||||||
()
|
()
|
||||||
|
|
||||||
let make_new () =
|
let make_new () =
|
||||||
let lock = Miou.Mutex.create () in
|
let sm_key, sm_pubkey = Mirage_crypto_ec.Ed25519.generate () in
|
||||||
let sm_key_priv, sm_key_pub = Mirage_crypto_ec.Ed25519.generate () in
|
let t =
|
||||||
let sk_ht =
|
{
|
||||||
[ make_new_signkey () ]
|
sm_key;
|
||||||
|> List.map (fun v -> (v.sk_data.pub, v))
|
sm_pubkey;
|
||||||
|> List.to_seq
|
sk_ht= Hashtbl.create 0xff;
|
||||||
|> Hashtbl.of_seq
|
dn_ht= Hashtbl.create 0xff;
|
||||||
|
sk_key_ht= Hashtbl.create 0xff;
|
||||||
|
dn_key_ht= Hashtbl.create 0xff;
|
||||||
|
future_sk_ht= Hashtbl.create 0xff;
|
||||||
|
future_dn_ht= Hashtbl.create 0xff;
|
||||||
|
future_sk_key_ht= Hashtbl.create 0xff;
|
||||||
|
future_dn_key_ht= Hashtbl.create 0xff;
|
||||||
|
}
|
||||||
in
|
in
|
||||||
let dn_section_name_ht = Hashtbl.create 0xff in
|
make_future_sk t;
|
||||||
let dn_ht =
|
List.iter (make_future_dn t) Config.Coin.all_coins;
|
||||||
Config.Coin.all_coins
|
t
|
||||||
|> List.map (fun coin ->
|
|
||||||
let denom = make_new_denom coin in
|
|
||||||
Hashtbl.replace dn_section_name_ht denom.dn_data.h_pub
|
|
||||||
coin.section_name;
|
|
||||||
(denom.dn_data.h_pub, denom))
|
|
||||||
|> List.to_seq
|
|
||||||
|> Hashtbl.of_seq
|
|
||||||
in
|
|
||||||
{ lock; sm_key_priv; sm_key_pub; sk_ht; dn_ht; dn_section_name_ht }
|
|
||||||
|
|
||||||
let t =
|
let t =
|
||||||
match load (module Conn) with
|
match load (module Conn) with
|
||||||
|
|
@ -300,59 +297,75 @@ module Make (Conn : Pg.CONN) = struct
|
||||||
t
|
t
|
||||||
| Error e -> Fmt.failwith "secmod init failure: %s." e
|
| Error e -> Fmt.failwith "secmod init failure: %s." e
|
||||||
|
|
||||||
(* note: don't expose a signing function if we want a real "security module" one day *)
|
let sign_with_sm_key s = sign_with_sm_key t s
|
||||||
let sign_with_sm_key s = EddsaSignature.sign ~key:t.sm_key_priv s
|
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_pubkey s ~msg
|
||||||
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_key_pub s ~msg
|
|
||||||
|
|
||||||
let verify_with_master_key s ~msg =
|
|
||||||
EddsaSignature.verify ~key:Config.master_public_key s ~msg
|
|
||||||
|
|
||||||
(* TODO
|
|
||||||
- do something to force `pub` to be one of the valid signkey
|
|
||||||
how to handle revocation?
|
|
||||||
raise exn for now *)
|
|
||||||
let sign_with_signkey ~pub s =
|
let sign_with_signkey ~pub s =
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
match Hashtbl.find_opt t.sk_key_ht pub with
|
||||||
match Hashtbl.find_opt t.sk_ht pub with
|
| None -> Fmt.failwith "secmod failure: signkey not found."
|
||||||
| None -> Fmt.failwith "secmod failure: public key not found."
|
| Some priv -> EddsaSignature.sign ~key:priv s
|
||||||
| Some signkey ->
|
|
||||||
let v = EddsaSignature.sign ~key:signkey.priv s in
|
let verify_with_master_key =
|
||||||
v
|
EddsaSignature.verify ~key:Config.master_public_key
|
||||||
|
|
||||||
let verify_with_signkey ~pub s ~msg =
|
let verify_with_signkey ~pub s ~msg =
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
(* check that the key we are verifying with is one of our own *)
|
||||||
match Hashtbl.find_opt t.sk_ht pub with
|
match Hashtbl.find_opt t.sk_ht pub with
|
||||||
| None -> Error "secmod failure: public key not found."
|
| None -> Fmt.failwith "secmod failure: signkey not found."
|
||||||
| Some signkey -> EddsaSignature.verify ~key:signkey.sk_data.pub s ~msg
|
| Some _priv -> EddsaSignature.verify ~key:pub s ~msg
|
||||||
|
|
||||||
let get_sm_key_pub () = t.sm_key_pub
|
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
|
||||||
|
|
||||||
let get_signkeys () =
|
let get_future_signkeys () =
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
t.future_sk_ht |> Hashtbl.to_seq_values |> List.of_seq
|
||||||
Hashtbl.to_seq_values t.sk_ht |> List.of_seq
|
|
||||||
|
|
||||||
let get_denoms () =
|
let get_future_denominations () =
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
t.future_dn_ht |> Hashtbl.to_seq_values |> List.of_seq
|
||||||
Hashtbl.to_seq_values t.dn_ht |> List.of_seq
|
|
||||||
|
|
||||||
let find_signkey pub =
|
let find_signkey pub = Hashtbl.find_opt t.sk_ht pub
|
||||||
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.sk_ht pub
|
let find_denomination pub = Hashtbl.find_opt t.dn_ht pub
|
||||||
|
|
||||||
let find_denom h_denom =
|
let certify_future_signkey pub master_sig =
|
||||||
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.dn_ht h_denom
|
match
|
||||||
|
( Hashtbl.find_opt t.future_sk_ht pub,
|
||||||
|
Hashtbl.find_opt t.future_sk_key_ht pub )
|
||||||
|
with
|
||||||
|
| None, _ | _, None -> Error "secmod failure: future signkey not found."
|
||||||
|
| Some future_sk, Some priv -> (
|
||||||
|
match Hashtbl.find_opt t.sk_ht pub with
|
||||||
|
| Some _sk ->
|
||||||
|
Error "secmod failure: this signkey already has a master signature"
|
||||||
|
| None ->
|
||||||
|
let Api.FutureSignKey.
|
||||||
|
{
|
||||||
|
key;
|
||||||
|
stamp_start;
|
||||||
|
stamp_expire;
|
||||||
|
stamp_end;
|
||||||
|
signkey_secmod_sig= _;
|
||||||
|
} =
|
||||||
|
future_sk
|
||||||
|
in
|
||||||
|
let sk =
|
||||||
|
Signkey.
|
||||||
|
{
|
||||||
|
pub= key;
|
||||||
|
stamp_start;
|
||||||
|
stamp_expire;
|
||||||
|
stamp_end;
|
||||||
|
master_sig;
|
||||||
|
revoked_sig= None;
|
||||||
|
}
|
||||||
|
in
|
||||||
|
Hashtbl.replace t.sk_ht pub sk;
|
||||||
|
Hashtbl.replace t.sk_key_ht pub priv;
|
||||||
|
Hashtbl.remove t.future_sk_ht pub;
|
||||||
|
Hashtbl.remove t.future_sk_key_ht pub;
|
||||||
|
|
||||||
let get_signkeys_data () = get_signkeys () |> List.map (fun v -> v.sk_data)
|
let* () = Pg.insert_signkey (module Conn) sk |> unwrap_err_caqti in
|
||||||
let get_denoms_data () = get_denoms () |> List.map (fun v -> v.dn_data)
|
Ok ())
|
||||||
|
|
||||||
let find_signkey_data pub =
|
|
||||||
find_signkey pub |> Option.map (fun v -> v.sk_data)
|
|
||||||
|
|
||||||
let find_denomination h_denom =
|
|
||||||
find_denom h_denom |> Option.map (fun v -> v.dn_data)
|
|
||||||
|
|
||||||
let find_denom_section_name h_denom =
|
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
|
||||||
Hashtbl.find_opt t.dn_section_name_ht h_denom
|
|
||||||
|
|
||||||
let add_signkey_master_signatures l =
|
let add_signkey_master_signatures l =
|
||||||
Miou.Mutex.protect t.lock @@ fun () ->
|
Miou.Mutex.protect t.lock @@ fun () ->
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,6 @@ type t = {
|
||||||
stamp_start: Timestamp.t;
|
stamp_start: Timestamp.t;
|
||||||
stamp_expire: Timestamp.t;
|
stamp_expire: Timestamp.t;
|
||||||
stamp_end: Timestamp.t;
|
stamp_end: Timestamp.t;
|
||||||
master_sig: Signatures.ExchangeSigningKeyValidity.t option;
|
master_sig: Signatures.ExchangeSigningKeyValidity.t;
|
||||||
revoked_sig: Signatures.MasterSigningKeyRevocation.t option;
|
revoked_sig: Signatures.MasterSigningKeyRevocation.t option;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue