package conex

  1. Overview
  2. Docs

Source file conex_unix_private_key.ml

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
open Conex_utils
open Conex_unix_persistency

let private_dir = Filename.concat (Sys.getenv "HOME") ".conex"

let private_s = "private"

let ids () =
  match collect_dir private_dir with
  | Ok files ->
    List.fold_left (fun acc s ->
        match List.rev (String.cuts '.' s) with
        | p::tl when p = private_s -> (String.concat "." (List.rev tl))::acc
        | _ -> acc (* TODO warn *) ) [] files
  | Error _ -> []

let private_key_path id = Filename.concat private_dir (id ^ "." ^ private_s)

let backup id filename =
  if exists filename then begin
    let backfn =
      let open Unix in
      let t = gmtime (stat filename).st_mtime in
      Printf.sprintf "%s.%4d%2d%2d%2d%2d%2d" id
        (t.tm_year + 1900) (succ t.tm_mon) t.tm_mday t.tm_hour t.tm_min t.tm_sec
    in
    let backup = private_key_path backfn in
    let rec inc n =
      if n = 10 then Error "too many backup keys, only 10 supported"
      else
        let nam = backup ^ "." ^ string_of_int n in
        if exists nam then inc (succ n) else Ok nam
    in
    (if exists backup then inc 0 else Ok backup) >>= fun backup ->
    rename filename backup
  end else
    Ok ()

let write id key =
  let filename = private_key_path id in
  backup id filename >>= fun () ->
  (if not (exists private_dir) then
     mkdir ~mode:0o700 private_dir
   else Ok ()) >>= fun () ->
  match file_type private_dir with
  | Ok Directory -> write_file ~mode:0o400 filename key
  | _ -> Error (private_dir ^ " is not a directory!")

let read to_ts id =
  let fn = private_key_path id in
  if exists fn then
    read_file fn >>= fun key ->
    let stat = Unix.stat fn in
    match to_ts stat.Unix.st_mtime with
    | None -> Error ("couldn't convert modification time to Uint.t")
    | Some ts -> Ok (key, ts)
  else
    Error ("couldn't find private key for " ^ id)
OCaml

Innovation. Community. Security.