package key-parsers

  1. Overview
  2. Docs

Source file ltpa.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
59
60
61
(** Read a big-endian arbitrary length number *)
let get_z_be cs off len =
  let r = ref Z.zero in
  let base = Z.of_int 0x100 in
  for i = off to off + len - 1 do
    r := Z.add (Z.mul base !r) @@ Z.of_int @@ Cstruct.get_uint8 cs i
  done;
  !r

module Rsa = struct
  (** If public exponent is not 0x10001, it is unclear how to parse the key *)
  let check_public_exponent e =
    if not (Z.equal e (Z.of_int 0x10001)) then
      invalid_arg ("RSA_LTPA: invalid public exponent: " ^ Z.to_string e)

  module Private = struct
    type t =
      { e : Derivable.Z.t
      ; d : Derivable.Z.t
      ; p : Derivable.Z.t
      ; q : Derivable.Z.t }
    [@@deriving ord, eq, show]

    let decode cs =
      try
        let d_len = Int32.to_int @@ Cstruct.BE.get_uint32 cs 0 in
        let d = get_z_be cs 4 d_len in
        let e_off = 4 + d_len in
        let e_len = 3 in
        let e = get_z_be cs e_off e_len in
        check_public_exponent e;
        let p_len = (d_len / 2) + 1 in
        let p_off = e_off + 3 in
        let p = get_z_be cs p_off p_len in
        let q = get_z_be cs (p_off + p_len) p_len in
        Result.Ok {e; d; p; q}
      with
      | Invalid_argument s -> Result.Error s
  end

  module Public = struct
    type t =
      { e : Derivable.Z.t
      ; n : Derivable.Z.t }
    [@@deriving ord, eq, show]

    let decode cs =
      try
        let e_off = Cstruct.length cs - 3 in
        let e_len = 3 in
        let e = get_z_be cs e_off e_len in
        check_public_exponent e;
        let n_len = e_off in
        let n = get_z_be cs 0 n_len in
        Result.Ok {e; n}
      with
      | Invalid_argument s -> Result.Error s
  end
end

module RSA = Rsa