54 lines
1.6 KiB
OCaml
54 lines
1.6 KiB
OCaml
|
open Rresult
|
||
|
|
||
|
module Commands = Wire_commands
|
||
|
module Wire_lwt = Wire_lwt
|
||
|
|
||
|
let wire_of_cstruct = Wire_asn.wire_of_cstruct
|
||
|
let wire_to_cstruct = Wire_asn.wire_to_cstruct
|
||
|
|
||
|
type t = {
|
||
|
host : string;
|
||
|
cacert : X509.Certificate.t;
|
||
|
cakey : X509.Private_key.t;
|
||
|
}
|
||
|
|
||
|
let check_csr_dn csr user =
|
||
|
let subject =
|
||
|
[X509.Distinguished_name.(Relative_distinguished_name.singleton (CN user))] in
|
||
|
if X509.Distinguished_name.equal
|
||
|
subject
|
||
|
(X509.Signing_request.info csr).subject
|
||
|
then Ok ()
|
||
|
else R.error_msgf "Bad subject in csr: %a"
|
||
|
X509.Distinguished_name.pp (X509.Signing_request.info csr).subject
|
||
|
|
||
|
let sign t csr user =
|
||
|
check_csr_dn csr user >>= fun () ->
|
||
|
let issuer = X509.Certificate.subject t.cacert in
|
||
|
let email = Printf.sprintf "%s@%s" user t.host in
|
||
|
let valid_from = Ptime_clock.now () in
|
||
|
let valid_until =
|
||
|
Ptime.add_span valid_from
|
||
|
(Ptime.Span.of_int_s (Duration.of_day 90 |> Duration.to_sec))
|
||
|
|> Option.get
|
||
|
in
|
||
|
let extensions =
|
||
|
let open X509.Extension in
|
||
|
let auth = Some (X509.Public_key.id (X509.Certificate.public_key t.cacert)),
|
||
|
X509.General_name.empty, None in
|
||
|
X509.Extension.empty
|
||
|
|> add Authority_key_id (false, auth)
|
||
|
|> add Subject_key_id (false, X509.(Public_key.id (Signing_request.info csr).public_key))
|
||
|
|> add Subject_alt_name (false, X509.General_name.singleton Rfc_822 [email])
|
||
|
|> add Ext_key_usage (true, [`Client_auth])
|
||
|
in
|
||
|
X509.Signing_request.sign
|
||
|
csr
|
||
|
~valid_from
|
||
|
~valid_until
|
||
|
~extensions
|
||
|
t.cakey
|
||
|
issuer
|
||
|
|> R.reword_error (fun ve ->
|
||
|
R.msgf "Signing failed: %a" X509.Validation.pp_validation_error ve)
|