Project

General

Profile

Download (14.9 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/bin/env python
2
#
3
# generate-ffdhe.py
4
#
5
# Generate PEM strings for the FFDHE parameters in RFC 7919
6
# For reference, see https://tools.ietf.org/rfc/rfc7919.txt
7
#
8
# This is derived from a similar script from the Mumble project.
9
# https://github.com/mumble-voip/mumble/blob/master/scripts/generate-ffdhe.py
10

    
11
from __future__ import (unicode_literals, print_function, division)
12

    
13
# Python 3 doesn't have a long type.
14
# Map the long type to int here, so
15
# we can easily be compatible with both
16
# interpreters.
17
try:
18
    type(long)
19
except NameError:
20
    long = int
21

    
22
import os
23
import base64
24
import codecs
25

    
26
# The following P values are directly sourced from RFC 7919 at
27
# https://tools.ietf.org/rfc/rfc7919.txt
28

    
29
ffdhe_str = {
30
    '2048': '''
31
    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
32
    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
33
    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
34
    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
35
    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
36
    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
37
    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
38
    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
39
    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
40
    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
41
    886B4238 61285C97 FFFFFFFF FFFFFFFF
42
    ''',
43
    '3072': '''
44
    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
45
    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
46
    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
47
    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
48
    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
49
    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
50
    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
51
    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
52
    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
53
    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
54
    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
55
    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
56
    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
57
    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
58
    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
59
    3C1B20EE 3FD59D7C 25E41D2B 66C62E37 FFFFFFFF FFFFFFFF
60
    ''',
61
    '4096': '''
62
    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
63
    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
64
    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
65
    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
66
    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
67
    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
68
    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
69
    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
70
    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
71
    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
72
    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
73
    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
74
    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
75
    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
76
    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
77
    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
78
    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
79
    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
80
    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
81
    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
82
    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E655F6A
83
    FFFFFFFF FFFFFFFF
84
    ''',
85
    '6144': '''
86
    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
87
    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
88
    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
89
    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
90
    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
91
    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
92
    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
93
    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
94
    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
95
    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
96
    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
97
    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
98
    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
99
    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
100
    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
101
    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
102
    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
103
    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
104
    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
105
    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
106
    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
107
    0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
108
    3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
109
    CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
110
    A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
111
    0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
112
    763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
113
    B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
114
    D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
115
    E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
116
    5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
117
    A41D570D 7938DAD4 A40E329C D0E40E65 FFFFFFFF FFFFFFFF
118
    ''',
119
    '8192': '''
120
    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
121
    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
122
    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
123
    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
124
    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
125
    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
126
    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
127
    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
128
    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
129
    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
130
    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
131
    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
132
    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
133
    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
134
    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
135
    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
136
    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
137
    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
138
    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
139
    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
140
    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
141
    0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
142
    3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
143
    CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
144
    A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
145
    0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
146
    763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
147
    B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
148
    D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
149
    E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
150
    5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
151
    A41D570D 7938DAD4 A40E329C CFF46AAA 36AD004C F600C838
152
    1E425A31 D951AE64 FDB23FCE C9509D43 687FEB69 EDD1CC5E
153
    0B8CC3BD F64B10EF 86B63142 A3AB8829 555B2F74 7C932665
154
    CB2C0F1C C01BD702 29388839 D2AF05E4 54504AC7 8B758282
155
    2846C0BA 35C35F5C 59160CC0 46FD8251 541FC68C 9C86B022
156
    BB709987 6A460E74 51A8A931 09703FEE 1C217E6C 3826E52C
157
    51AA691E 0E423CFC 99E9E316 50C1217B 624816CD AD9A95F9
158
    D5B80194 88D9C0A0 A1FE3075 A577E231 83F81D4A 3F2FA457
159
    1EFC8CE0 BA8A4FE8 B6855DFE 72B0A66E DED2FBAB FBE58A30
160
    FAFABE1C 5D71A87E 2F741EF8 C1FE86FE A6BBFDE5 30677F0D
161
    97D11D49 F7A8443D 0822E506 A9F4614E 011E2A94 838FF88C
162
    D68C8BB7 C5C6424C FFFFFFFF FFFFFFFF
163
    '''
164
    }
165

    
166
# All groups from RFC 7919 use generator 2.
167

    
168
g = '''02'''
169

    
170
def dehexify(hexString):
171
    '''
172
        Convert the "bignum" hexString
173
        representation to a bytearray
174
        containing the number.
175
    '''
176
    return bytearray.fromhex(' '.join(line.strip() for line in hexString.splitlines()))
177

    
178
def derLength(size):
179
    '''
180
        Returns the ASN.1 DER length bytes
181
        for the given size.
182

    
183
        Short form: For lengths <= 127,
184
        the length is just a byte containing
185
        the literal number. (Note that for
186
        numbers <= 127, the MSB is not
187
        set.)
188

    
189
        In doctest form, that is:
190

    
191
        >>> derLength(1)
192
        bytearray(b'\\x01')
193

    
194
        >>> derLength(127)
195
        bytearray(b'\\x7f')
196

    
197
        Long form: For lengths > 127,
198
        the encoding is different: The
199
        first byte has the MSB set (that
200
        is, by itself, 0x80). The rest of
201
        the bits in the first byte specify
202
        the number of bytes that follow.
203

    
204
        So, to encode the length 128, you
205
        would emit
206

    
207
            0x81 0x80
208

    
209
        The high bit of the first byte is set.
210
        This means the remaining 7 bits contain
211
        how many bytes follow it. If we mask the
212
        MSB away, we end up with 0x01. So, only
213
        a single byte follows.
214
        The value of the following byte is 0x80,
215
        which is 128 decimal.
216

    
217
        In doctest form, that is:
218

    
219
        >>> derLength(128)
220
        bytearray(b'\\x81\\x80')
221

    
222
        Error cases:
223

    
224
        The size passed to this function must be an integer:
225

    
226
        >>> derLength(0.1)
227
        Traceback (most recent call last):
228
        ...
229
        Exception: bad type
230

    
231
        >>> derLength('5')
232
        Traceback (most recent call last):
233
        ...
234
        Exception: bad type
235

    
236
        Negative numbers are not supported, and throw an exception:
237

    
238
        >>> derLength(-1)
239
        Traceback (most recent call last):
240
        ...
241
        Exception: bad size
242

    
243
        The long form does not support very large numbers. This is
244
        because the 'additional bytes' counter can only count up to
245
        127 (2**7-1) bytes.
246

    
247
        So, if we try to encode a length that will use exactly 127
248
        bytes, it will succeed:
249

    
250
        >>> derLength(int('ff'*127, 16)) # doctest:+ELLIPSIS
251
        bytearray(b'\\xff...\\xff')
252

    
253
        But if we try to go over that limit, we get an exception:
254

    
255
        >>> derLength(int('ff'*128, 16))
256
        Traceback (most recent call last):
257
        ...
258
        Exception: unencodable
259
    '''
260

    
261
    # Ensure that the passed-in size is an integer.
262
    if not isinstance(size, (int, long)):
263
        raise Exception('bad type')
264

    
265
    if size > 127:
266
        # Convert 'size' to a hexString-style
267
        # bignum that we can pass to dehexify.
268
        #
269
        # Strip '0x' prefix from the hex string.
270
        hexString = hex(size)[2:]
271
        # In Python 2.7, the output of hex()
272
        # can have an L suffix. Make sure we
273
        # strip that.
274
        if hexString.endswith('L'):
275
            hexString = hexString[:-1]
276
        # Ensure the final hex string only
277
        # contains full bytes. If not, prepend
278
        # a zero byte.
279
        if len(hexString) % 2 != 0:
280
            hexString = '0' + hexString
281

    
282
        # If the computed hexString bignum
283
        # contains more than 127 bytes, we
284
        # can't encode it using ASN.1 DER
285
        # encoding. Throw an exception.
286
        nbytes = len(hexString) // 2
287
        if nbytes > 127:
288
            raise Exception('unencodable')
289

    
290
        buf = dehexify(hexString)
291
        out = bytearray((0x80 | nbytes,))
292
        out += buf
293
        return out
294
    elif size > 0:
295
        # Short form is simply the number itself,
296
        # as a byte.
297
        return bytearray((size,))
298
    else:
299
        # We don't support negative sizes.
300
        raise Exception('bad size')
301

    
302
def derSequence(sequence):
303
    '''
304
        Encode an ASN.1 DER sequence
305

    
306
        Takes a sequence of DER data as its input.
307

    
308
        Returns a bytearray of the resulting data.
309

    
310
        The encoding of a DER sequence is simply
311
        an identifier (0x30), a length (the length
312
        of the content bytes -- see the derLength
313
        function), and the content itself (just a
314
        byte stream of other ASN.1 DER objects)
315
    '''
316
    out = bytearray((0x30,)) # SEQUENCE tag
317
    content = bytearray()
318
    for entry in sequence:
319
        content += entry
320
    out += derLength(len(content))
321
    out += content
322
    return out
323

    
324
def derUnsignedInteger(hexString):
325
    '''
326
        Encode a hex string to a ASN.1 DER INTEGER.
327
        This function only handles unsigned integers.
328

    
329
        Returns a bytearray of the resulting data.
330

    
331
        The encoding of an ASN.1 DER INTEGER is an
332
        identifier (0x02), a length (the length of the
333
        content bytes -- see the derLength function),
334
        and the content, which in this case is the
335
        bytes that make up the integer.
336

    
337
        An INTEGER can be signed, or unsigned. Our
338
        function here only deals with unsigned integers.
339

    
340
        Signed integers have the MSB/sign bit set.
341

    
342
        Our input data is guaranteed to be unsigned,
343
        so if we detect that the MSB is set in the
344
        data, we prepend a zero byte to it. This
345
        is the way to signal that the value is unsigned
346
        rather than signed.
347
    '''
348
    out = bytearray((0x02,)) # INTEGER tag
349
    buf = dehexify(hexString)
350

    
351
    # If the sign bit is set, prepend a zero byte.
352
    # Otherwise, the number will be treated as signed,
353
    # which we don't want.
354
    if (buf[0] & 0x80) != 0:
355
        buf = bytearray((0,)) + buf
356
    out += derLength(len(buf))
357
    out += buf
358
    return out
359

    
360
def pem(der, kind='DH PARAMETERS'):
361
    '''
362
        Convert the ASN.1 DER data to PEM form.
363

    
364
        Returns the resulting string (type 'unicode' for Python 2).
365

    
366
        The PEM format consists of a header, the content itself (base64,
367
        using the standard alphabet) and a trailer.
368

    
369
        The header is of the form:
370
            -----BEGIN $KIND-----
371

    
372
        and the trailer is of the form:
373
            -----END $KIND-----
374

    
375
        where $KIND defines the type of data
376
        contained in the PEM data.
377

    
378
        Between the header and the trailer is
379
        the content itself. The content is the
380
        DER form encoded using base64.
381

    
382
        Our implementation splits the base64
383
        data such that each line of base64 data
384
        can be no longer than 64 characters long.
385
    '''
386
    out = u'-----BEGIN {0}-----\n'.format(kind)
387
    enc = base64.b64encode(der)
388
    n = 0
389
    for ch in enc:
390
        if type(ch) == int: # Python 3
391
            out += chr(ch)
392
        else:
393
            out += ch
394
        n += 1
395
        if n == 64:
396
            out += '\n'
397
            n = 0
398
    if out[-1] != '\n':
399
        out += '\n'
400
    out += u'-----END {0}-----\n'.format(kind)
401
    return out
402

    
403
def writePEM(f, identifier, str):
404
    f.write(str)
405
            
406
def main():
407
    for len, str in ffdhe_str.items():
408
        f = codecs.open(os.path.join('output', 'dh-parameters.' + len), 'w', 'utf-8')
409

    
410
        writePEM(f, 'ffdhe' + len + '_pem', pem(
411
            derSequence((
412
                derUnsignedInteger(str),
413
                derUnsignedInteger(g),
414
            ))
415
        ))
416

    
417
if __name__ == '__main__':
418
    main()
(2-2/2)