ntplogtemp: Record nvme temperatures on Asahi
[ntpsec.git] / ntpclients / ntpkeygen.py
blob4d629feb247dc111336d2393f6f55c4971fb6b6f
1 #! @PYSHEBANG@
2 # -*- coding: utf-8 -*-
4 # Copyright the NTPsec project contributors
6 # SPDX-License-Identifier: BSD-2-Clause
8 '''
9 ntpkeygen - generate cryptographic keys for NTP clients and servers
11 All file names are like "ntpkey_<type>_<hostname>.<filestamp>", where
12 <type> is the file type, <hostname> the generating host name and
13 <filestamp> the generation time in NTP seconds. The NTP programs
14 expect generic names such as "ntpkey_<type>_whimsy.udel.edu" with the
15 association maintained by soft links. Following is a list of file
16 types.
18 ntpkey_AES_<hostname>.<filestamp>
19 AES (128-bit) keys used to compute CMAC mode authentcation
20 using shared key cryptography
22 The file can be edited by hand to support MD5 and SHA-1 for
23 old digest mode authentication.
24 '''
26 from __future__ import print_function
28 import os
29 import sys
30 import socket
31 import time
32 import getopt
33 import stat
35 try:
36 import secrets
37 def gen_key(bytes, asciified=True):
38 if asciified:
39 result = ''
40 for index in range(bytes):
41 # Start ASCII characters with 0x24 so as not to include comment-beginning #
42 result += chr(0x24 + secrets.randbelow(0x5a))
43 return result
44 else:
45 return secrets.token_hex(bytes)
46 except ImportError:
47 import random
48 def gen_key(bytes, asciified=True):
49 result = ''
50 if asciified:
51 for index in range(bytes):
52 # Start ASCII characters with 0x24 so as not to include comment-beginning #
53 result += chr(random.randint(0x24, 0x7e))
54 else:
55 for index in range(bytes):
56 result += "%02x" % random.randint(0x0, 0xff)
57 return result
60 # Cryptodefines
62 NUMKEYS = 10 # number of keys generated of each type
63 KEYSIZE = 16 # maximum key size
66 def gen_keys(ident, groupname):
67 "Generate semi-random AES keys for versions of ntpd with CMAC support."
68 with fheader("AES", ident, groupname) as wp:
69 for i in range(1, NUMKEYS+1):
70 key = gen_key(KEYSIZE, True)
71 wp.write("%2d AES %s\n" % (i, key))
72 for i in range(1, NUMKEYS+1):
73 key = gen_key(KEYSIZE, False)
74 wp.write("%2d AES %s\n" % (i + NUMKEYS, key))
78 # Generate file header and link
80 def fheader(fileid, # file name id
81 ulink, # linkname
82 owner # owner name
84 "Generate file header and link"
85 try:
86 filename = "ntpkey_%s_%s.%u" % (fileid, owner, int(time.time()))
87 orig_umask = os.umask(stat.S_IWGRP | stat.S_IRWXO)
88 wp = open(filename, "w")
89 os.umask(orig_umask)
91 linkname = "ntp.keys"
92 if os.path.exists(linkname):
93 os.remove(linkname) # The symlink() line below matters
94 os.symlink(filename, linkname)
96 sys.stderr.write("Generating new %s file and link\n" % ulink)
97 sys.stderr.write("%s->%s\n" % (linkname, filename))
98 wp.write("# %s\n# %s\n" % (filename, time.ctime()))
99 return wp
100 except IOError:
101 sys.stderr.write("Key file creation or link failed.\n")
102 raise SystemExit(1)
105 if __name__ == '__main__':
106 try:
107 (options, arguments) = getopt.getopt(sys.argv[1:], "hV",
108 ["help", "version"])
109 except getopt.GetoptError as e:
110 print(e)
111 raise SystemExit(1)
113 for (switch, val) in options:
114 if switch in ("-h", "--help"):
115 print("usage: ntpkeygen")
116 raise SystemExit(0)
117 elif switch in ("-V", "--version"):
118 print("ntpkeygen ntpsec-@NTPSEC_VERSION_EXTENDED@")
119 raise SystemExit(0)
121 # The seed is ignored by random.SystemRandom,
122 # even though the docs do not say so.
123 gen_keys("AES", socket.gethostname())
124 raise SystemExit(0)
126 # end