summaryrefslogtreecommitdiff
path: root/pki/ca.nix
blob: f8e58474a1923c93c7cec784bc55ecc9a7b612b1 (plain)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.local.pki.ca;

  openssl = getExe pkgs.buildPackages.openssl;

  certsType = leafOf:
    with lib.types;
      attrsOf (submodule ({
        config,
        name,
        ...
      }: {
        options =
          {
            cert = mkOption {
              type = path;
              readOnly = true;
            };

            fingerprint = {
              sha1-lower = mkOption {
                type = str;
                readOnly = true;
              };

              sha256-bytes-upper = mkOption {
                type = str;
                readOnly = true;
              };
            };

            fullchain = mkOption {
              type = path;
              readOnly = true;
            };

            issuer = mkOption {
              type = nullOr str;
              readOnly = true;
            };

            path = mkOption {
              type = str;
              readOnly = true;
            };
          }
          // optionalAttrs (leafOf != null) {
            commonName = mkOption {
              type = str;
              readOnly = true;
            };
          }
          // optionalAttrs (leafOf == null) {
            crl = mkOption {
              type = path;
              readOnly = true;
            };

            certWithCrl = mkOption {
              type = path;
              readOnly = true;
            };

            leaves = mkOption {
              type = certsType name;
              readOnly = true;
            };
          };

        config =
          {
            fingerprint = {
              sha1-lower = readFile (pkgs.runCommandNoCCLocal "cert-${config.path}-fprint-sha1-lower" {} ''
                ${openssl} x509 -in ${config.cert} -noout -sha1 -fingerprint \
                  | sed 's/^.*=//' \
                  | tr -d $':\n' \
                  | tr '[A-Z]' '[a-z]' \
                  >>$out
              '');

              sha256-bytes-upper = readFile (pkgs.runCommandNoCCLocal "cert-${config.path}-fprint-sha256-bytes-upper" {} ''
                ${openssl} x509 -in ${config.cert} -noout -sha256 -fingerprint \
                  | sed 's/^.*=//' \
                  | tr -d $'\n' \
                  >>$out
              '');
            };

            fullchain =
              pkgs.writeText "${name}-fullchain-crl.pem"
              (concatStrings (map readFile
                (singleton (
                    if leafOf != null
                    then config.cert
                    else config.certWithCrl
                  )
                  ++ optional (config.issuer != null) cfg.${config.issuer}.fullchain)));

            path = optionalString (config.issuer != null) (cfg.${config.issuer}.path + ".") + name;
          }
          // optionalAttrs (leafOf != null) {
            commonName = readFile (pkgs.runCommandNoCCLocal "cert-${config.path}-common-name" {} ''
              ${openssl} x509 -in ${config.cert} -noout -subject -nameopt multiline \
                | grep commonName \
                | sed 's/^.*=\s*//' \
                | tr -d $'\n' \
                >$out
            '');

            issuer = leafOf;
          }
          // optionalAttrs (leafOf == null) {
            certWithCrl =
              pkgs.writeText "${name}-cert-crl.pem"
              (concatStrings (map readFile [config.cert config.crl]));
          };
      }));
in {
  options.local.pki.ca = mkOption {
    type = certsType null;
    readOnly = true;
  };
}