summaryrefslogtreecommitdiffstats
path: root/tools/scripts
diff options
context:
space:
mode:
authorJustin Coffman <coffmanjk@gmail.com>2018-06-22 11:13:09 -0400
committerJustin Coffman <coffmanjk@gmail.com>2018-06-22 11:13:09 -0400
commit3efa35305eb8c1852fbf15ecd5cbc6fff08b272f (patch)
treef52e40e5d30977d2bb76a923a6b2bcb756601032 /tools/scripts
parent3937cbaa88eaee9459acc4a959e73b7d8863bbf9 (diff)
downloadpfsense-3efa35305eb8c1852fbf15ecd5cbc6fff08b272f.zip
pfsense-3efa35305eb8c1852fbf15ecd5cbc6fff08b272f.tar.gz
Provide DH groups from RFC 7919.
Replaced 2048-bit and 4096-bit groups with RFC 7919 parameters. Added 3072, 6144, and 8192-bit groups from same. Relocated PEM generator script to tools directory.
Diffstat (limited to 'tools/scripts')
-rwxr-xr-xtools/scripts/generate_ffdhe.py418
1 files changed, 418 insertions, 0 deletions
diff --git a/tools/scripts/generate_ffdhe.py b/tools/scripts/generate_ffdhe.py
new file mode 100755
index 0000000..107bcec
--- /dev/null
+++ b/tools/scripts/generate_ffdhe.py
@@ -0,0 +1,418 @@
+#!/usr/bin/env python
+#
+# generate-ffdhe.py
+#
+# Generate PEM strings for the FFDHE parameters in RFC 7919
+# For reference, see https://tools.ietf.org/rfc/rfc7919.txt
+#
+# This is derived from a similar script from the Mumble project.
+# https://github.com/mumble-voip/mumble/blob/master/scripts/generate-ffdhe.py
+
+from __future__ import (unicode_literals, print_function, division)
+
+# Python 3 doesn't have a long type.
+# Map the long type to int here, so
+# we can easily be compatible with both
+# interpreters.
+try:
+ type(long)
+except NameError:
+ long = int
+
+import os
+import base64
+import codecs
+
+# The following P values are directly sourced from RFC 7919 at
+# https://tools.ietf.org/rfc/rfc7919.txt
+
+ffdhe_str = {
+ '2048': '''
+ FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
+ D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
+ 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
+ 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
+ 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
+ 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
+ B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
+ 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
+ 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
+ 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
+ 886B4238 61285C97 FFFFFFFF FFFFFFFF
+ ''',
+ '3072': '''
+ FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
+ D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
+ 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
+ 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
+ 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
+ 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
+ B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
+ 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
+ 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
+ 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
+ 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
+ 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
+ AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
+ 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
+ ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
+ 3C1B20EE 3FD59D7C 25E41D2B 66C62E37 FFFFFFFF FFFFFFFF
+ ''',
+ '4096': '''
+ FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
+ D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
+ 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
+ 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
+ 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
+ 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
+ B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
+ 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
+ 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
+ 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
+ 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
+ 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
+ AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
+ 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
+ ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
+ 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
+ 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
+ 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
+ A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
+ 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
+ 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E655F6A
+ FFFFFFFF FFFFFFFF
+ ''',
+ '6144': '''
+ FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
+ D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
+ 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
+ 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
+ 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
+ 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
+ B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
+ 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
+ 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
+ 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
+ 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
+ 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
+ AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
+ 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
+ ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
+ 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
+ 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
+ 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
+ A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
+ 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
+ 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
+ 0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
+ 3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
+ CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
+ A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
+ 0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
+ 763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
+ B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
+ D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
+ E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
+ 5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
+ A41D570D 7938DAD4 A40E329C D0E40E65 FFFFFFFF FFFFFFFF
+ ''',
+ '8192': '''
+ FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
+ D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
+ 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
+ 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
+ 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
+ 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
+ B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
+ 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
+ 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
+ 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
+ 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
+ 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
+ AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
+ 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
+ ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
+ 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
+ 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
+ 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
+ A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
+ 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
+ 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
+ 0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
+ 3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
+ CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
+ A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
+ 0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
+ 763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
+ B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
+ D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
+ E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
+ 5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
+ A41D570D 7938DAD4 A40E329C CFF46AAA 36AD004C F600C838
+ 1E425A31 D951AE64 FDB23FCE C9509D43 687FEB69 EDD1CC5E
+ 0B8CC3BD F64B10EF 86B63142 A3AB8829 555B2F74 7C932665
+ CB2C0F1C C01BD702 29388839 D2AF05E4 54504AC7 8B758282
+ 2846C0BA 35C35F5C 59160CC0 46FD8251 541FC68C 9C86B022
+ BB709987 6A460E74 51A8A931 09703FEE 1C217E6C 3826E52C
+ 51AA691E 0E423CFC 99E9E316 50C1217B 624816CD AD9A95F9
+ D5B80194 88D9C0A0 A1FE3075 A577E231 83F81D4A 3F2FA457
+ 1EFC8CE0 BA8A4FE8 B6855DFE 72B0A66E DED2FBAB FBE58A30
+ FAFABE1C 5D71A87E 2F741EF8 C1FE86FE A6BBFDE5 30677F0D
+ 97D11D49 F7A8443D 0822E506 A9F4614E 011E2A94 838FF88C
+ D68C8BB7 C5C6424C FFFFFFFF FFFFFFFF
+ '''
+ }
+
+# All groups from RFC 7919 use generator 2.
+
+g = '''02'''
+
+def dehexify(hexString):
+ '''
+ Convert the "bignum" hexString
+ representation to a bytearray
+ containing the number.
+ '''
+ return bytearray.fromhex(' '.join(line.strip() for line in hexString.splitlines()))
+
+def derLength(size):
+ '''
+ Returns the ASN.1 DER length bytes
+ for the given size.
+
+ Short form: For lengths <= 127,
+ the length is just a byte containing
+ the literal number. (Note that for
+ numbers <= 127, the MSB is not
+ set.)
+
+ In doctest form, that is:
+
+ >>> derLength(1)
+ bytearray(b'\\x01')
+
+ >>> derLength(127)
+ bytearray(b'\\x7f')
+
+ Long form: For lengths > 127,
+ the encoding is different: The
+ first byte has the MSB set (that
+ is, by itself, 0x80). The rest of
+ the bits in the first byte specify
+ the number of bytes that follow.
+
+ So, to encode the length 128, you
+ would emit
+
+ 0x81 0x80
+
+ The high bit of the first byte is set.
+ This means the remaining 7 bits contain
+ how many bytes follow it. If we mask the
+ MSB away, we end up with 0x01. So, only
+ a single byte follows.
+ The value of the following byte is 0x80,
+ which is 128 decimal.
+
+ In doctest form, that is:
+
+ >>> derLength(128)
+ bytearray(b'\\x81\\x80')
+
+ Error cases:
+
+ The size passed to this function must be an integer:
+
+ >>> derLength(0.1)
+ Traceback (most recent call last):
+ ...
+ Exception: bad type
+
+ >>> derLength('5')
+ Traceback (most recent call last):
+ ...
+ Exception: bad type
+
+ Negative numbers are not supported, and throw an exception:
+
+ >>> derLength(-1)
+ Traceback (most recent call last):
+ ...
+ Exception: bad size
+
+ The long form does not support very large numbers. This is
+ because the 'additional bytes' counter can only count up to
+ 127 (2**7-1) bytes.
+
+ So, if we try to encode a length that will use exactly 127
+ bytes, it will succeed:
+
+ >>> derLength(int('ff'*127, 16)) # doctest:+ELLIPSIS
+ bytearray(b'\\xff...\\xff')
+
+ But if we try to go over that limit, we get an exception:
+
+ >>> derLength(int('ff'*128, 16))
+ Traceback (most recent call last):
+ ...
+ Exception: unencodable
+ '''
+
+ # Ensure that the passed-in size is an integer.
+ if not isinstance(size, (int, long)):
+ raise Exception('bad type')
+
+ if size > 127:
+ # Convert 'size' to a hexString-style
+ # bignum that we can pass to dehexify.
+ #
+ # Strip '0x' prefix from the hex string.
+ hexString = hex(size)[2:]
+ # In Python 2.7, the output of hex()
+ # can have an L suffix. Make sure we
+ # strip that.
+ if hexString.endswith('L'):
+ hexString = hexString[:-1]
+ # Ensure the final hex string only
+ # contains full bytes. If not, prepend
+ # a zero byte.
+ if len(hexString) % 2 != 0:
+ hexString = '0' + hexString
+
+ # If the computed hexString bignum
+ # contains more than 127 bytes, we
+ # can't encode it using ASN.1 DER
+ # encoding. Throw an exception.
+ nbytes = len(hexString) // 2
+ if nbytes > 127:
+ raise Exception('unencodable')
+
+ buf = dehexify(hexString)
+ out = bytearray((0x80 | nbytes,))
+ out += buf
+ return out
+ elif size > 0:
+ # Short form is simply the number itself,
+ # as a byte.
+ return bytearray((size,))
+ else:
+ # We don't support negative sizes.
+ raise Exception('bad size')
+
+def derSequence(sequence):
+ '''
+ Encode an ASN.1 DER sequence
+
+ Takes a sequence of DER data as its input.
+
+ Returns a bytearray of the resulting data.
+
+ The encoding of a DER sequence is simply
+ an identifier (0x30), a length (the length
+ of the content bytes -- see the derLength
+ function), and the content itself (just a
+ byte stream of other ASN.1 DER objects)
+ '''
+ out = bytearray((0x30,)) # SEQUENCE tag
+ content = bytearray()
+ for entry in sequence:
+ content += entry
+ out += derLength(len(content))
+ out += content
+ return out
+
+def derUnsignedInteger(hexString):
+ '''
+ Encode a hex string to a ASN.1 DER INTEGER.
+ This function only handles unsigned integers.
+
+ Returns a bytearray of the resulting data.
+
+ The encoding of an ASN.1 DER INTEGER is an
+ identifier (0x02), a length (the length of the
+ content bytes -- see the derLength function),
+ and the content, which in this case is the
+ bytes that make up the integer.
+
+ An INTEGER can be signed, or unsigned. Our
+ function here only deals with unsigned integers.
+
+ Signed integers have the MSB/sign bit set.
+
+ Our input data is guaranteed to be unsigned,
+ so if we detect that the MSB is set in the
+ data, we prepend a zero byte to it. This
+ is the way to signal that the value is unsigned
+ rather than signed.
+ '''
+ out = bytearray((0x02,)) # INTEGER tag
+ buf = dehexify(hexString)
+
+ # If the sign bit is set, prepend a zero byte.
+ # Otherwise, the number will be treated as signed,
+ # which we don't want.
+ if (buf[0] & 0x80) != 0:
+ buf = bytearray((0,)) + buf
+ out += derLength(len(buf))
+ out += buf
+ return out
+
+def pem(der, kind='DH PARAMETERS'):
+ '''
+ Convert the ASN.1 DER data to PEM form.
+
+ Returns the resulting string (type 'unicode' for Python 2).
+
+ The PEM format consists of a header, the content itself (base64,
+ using the standard alphabet) and a trailer.
+
+ The header is of the form:
+ -----BEGIN $KIND-----
+
+ and the trailer is of the form:
+ -----END $KIND-----
+
+ where $KIND defines the type of data
+ contained in the PEM data.
+
+ Between the header and the trailer is
+ the content itself. The content is the
+ DER form encoded using base64.
+
+ Our implementation splits the base64
+ data such that each line of base64 data
+ can be no longer than 64 characters long.
+ '''
+ out = u'-----BEGIN {0}-----\n'.format(kind)
+ enc = base64.b64encode(der)
+ n = 0
+ for ch in enc:
+ if type(ch) == int: # Python 3
+ out += chr(ch)
+ else:
+ out += ch
+ n += 1
+ if n == 64:
+ out += '\n'
+ n = 0
+ if out[-1] != '\n':
+ out += '\n'
+ out += u'-----END {0}-----\n'.format(kind)
+ return out
+
+def writePEM(f, identifier, str):
+ f.write(str)
+
+def main():
+ for len, str in ffdhe_str.items():
+ f = codecs.open(os.path.join('output', 'dh-parameters.' + len), 'w', 'utf-8')
+
+ writePEM(f, 'ffdhe' + len + '_pem', pem(
+ derSequence((
+ derUnsignedInteger(str),
+ derUnsignedInteger(g),
+ ))
+ ))
+
+if __name__ == '__main__':
+ main()
OpenPOWER on IntegriCloud