Source code

Revision control

Other Tools

1
#!/usr/bin/env python
2
#
3
# This Source Code Form is subject to the terms of the Mozilla Public
4
# License, v. 2.0. If a copy of the MPL was not distributed with this
5
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7
"""
8
Reads a key specification from stdin or a file and outputs a
9
PKCS #8 file representing the (private) key. Also provides
10
methods for signing data and representing the key as a subject
11
public key info for use with pyasn1.
12
13
The key specification format is as follows:
14
15
default: a 2048-bit RSA key
16
alternate: a different 2048-bit RSA key
17
ev: a 2048-bit RSA key that, when combined with the right pycert
18
specification, results in a certificate that is enabled for
19
extended validation in debug Firefox (see ExtendedValidation.cpp).
20
evRSA2040: a 2040-bit RSA key that, when combined with the right pycert
21
specification, results in a certificate that is enabled for
22
extended validation in debug Firefox.
23
rsa2040: a 2040-bit RSA key
24
rsa1024: a 1024-bit RSA key
25
rsa1016: a 1016-bit RSA key
26
secp256k1: an ECC key on the curve secp256k1
27
secp244r1: an ECC key on the curve secp244r1
28
secp256r1: an ECC key on the curve secp256r1
29
secp384r1: an ECC key on the curve secp384r1
30
secp521r1: an ECC key on the curve secp521r1
31
"""
32
33
from pyasn1.codec.der import encoder
34
from pyasn1.type import univ, namedtype, tag
35
from pyasn1_modules import rfc2459
36
from ecc import encoding
37
from ecc import Key
38
import base64
39
import binascii
40
import mock
41
import rsa
42
import sys
43
44
# "constants" to make it easier for consumers to specify hash algorithms
45
HASH_MD5 = 'hash:md5'
46
HASH_SHA1 = 'hash:sha1'
47
HASH_SHA256 = 'hash:sha256'
48
HASH_SHA384 = 'hash:sha384'
49
HASH_SHA512 = 'hash:sha512'
50
51
52
def byteStringToHexifiedBitString(string):
53
"""Takes a string of bytes and returns a hex string representing
54
those bytes for use with pyasn1.type.univ.BitString. It must be of
55
the form "'<hex bytes>'H", where the trailing 'H' indicates to
56
pyasn1 that the input is a hex string."""
57
return "'%s'H" % binascii.hexlify(string)
58
59
60
class UnknownBaseError(Exception):
61
"""Base class for handling unexpected input in this module."""
62
63
def __init__(self, value):
64
super(UnknownBaseError, self).__init__()
65
self.value = value
66
self.category = 'input'
67
68
def __str__(self):
69
return 'Unknown %s type "%s"' % (self.category, repr(self.value))
70
71
72
class UnknownKeySpecificationError(UnknownBaseError):
73
"""Helper exception type to handle unknown key specifications."""
74
75
def __init__(self, value):
76
UnknownBaseError.__init__(self, value)
77
self.category = 'key specification'
78
79
80
class UnknownHashAlgorithmError(UnknownBaseError):
81
"""Helper exception type to handle unknown key specifications."""
82
83
def __init__(self, value):
84
UnknownBaseError.__init__(self, value)
85
self.category = 'hash algorithm'
86
87
88
class UnsupportedHashAlgorithmError(Exception):
89
"""Helper exception type for unsupported hash algorithms."""
90
91
def __init__(self, value):
92
super(UnsupportedHashAlgorithmError, self).__init__()
93
self.value = value
94
95
def __str__(self):
96
return 'Unsupported hash algorithm "%s"' % repr(self.value)
97
98
99
class RSAPublicKey(univ.Sequence):
100
"""Helper type for encoding an RSA public key"""
101
componentType = namedtype.NamedTypes(
102
namedtype.NamedType('N', univ.Integer()),
103
namedtype.NamedType('E', univ.Integer()))
104
105
106
class RSAPrivateKey(univ.Sequence):
107
"""Helper type for encoding an RSA private key"""
108
componentType = namedtype.NamedTypes(
109
namedtype.NamedType('version', univ.Integer()),
110
namedtype.NamedType('modulus', univ.Integer()),
111
namedtype.NamedType('publicExponent', univ.Integer()),
112
namedtype.NamedType('privateExponent', univ.Integer()),
113
namedtype.NamedType('prime1', univ.Integer()),
114
namedtype.NamedType('prime2', univ.Integer()),
115
namedtype.NamedType('exponent1', univ.Integer()),
116
namedtype.NamedType('exponent2', univ.Integer()),
117
namedtype.NamedType('coefficient', univ.Integer()),
118
)
119
120
121
class ECPrivateKey(univ.Sequence):
122
"""Helper type for encoding an EC private key
123
ECPrivateKey ::= SEQUENCE {
124
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
125
privateKey OCTET STRING,
126
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
127
(NOTE: parameters field is not supported)
128
publicKey [1] BIT STRING OPTIONAL
129
}"""
130
componentType = namedtype.NamedTypes(
131
namedtype.NamedType('version', univ.Integer()),
132
namedtype.NamedType('privateKey', univ.OctetString()),
133
namedtype.OptionalNamedType('publicKey', univ.BitString().subtype(
134
explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)))
135
)
136
137
138
class ECPoint(univ.Sequence):
139
"""Helper type for encoding a EC point"""
140
componentType = namedtype.NamedTypes(
141
namedtype.NamedType('x', univ.Integer()),
142
namedtype.NamedType('y', univ.Integer())
143
)
144
145
146
class PrivateKeyInfo(univ.Sequence):
147
"""Helper type for encoding a PKCS #8 private key info"""
148
componentType = namedtype.NamedTypes(
149
namedtype.NamedType('version', univ.Integer()),
150
namedtype.NamedType('privateKeyAlgorithm', rfc2459.AlgorithmIdentifier()),
151
namedtype.NamedType('privateKey', univ.OctetString())
152
)
153
154
155
class RSAKey(object):
156
# For reference, when encoded as a subject public key info, the
157
# base64-encoded sha-256 hash of this key is
158
# VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=
159
sharedRSA_N = long(
160
'00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857'
161
'6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a'
162
'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c'
163
'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b'
164
'2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716'
165
'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075'
166
'31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a'
167
'95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3'
168
'fe4923fa7251c431d503acda180a35ed8d', 16)
169
sharedRSA_E = 65537L
170
sharedRSA_D = long(
171
'009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da'
172
'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46'
173
'3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2'
174
'39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c'
175
'7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa'
176
'79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3'
177
'6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c'
178
'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931'
179
'5b62b30e6011f224725946eec57c6d9441', 16)
180
sharedRSA_P = long(
181
'00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb'
182
'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f'
183
'8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d'
184
'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177'
185
'3ca5d19301f48c742b', 16)
186
sharedRSA_Q = long(
187
'00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47'
188
'8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d'
189
'1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833'
190
'28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16'
191
'5810a77b9845bc3127', 16)
192
sharedRSA_exp1 = long(
193
'0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35'
194
'81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc'
195
'f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66'
196
'21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765'
197
'5315be9c24d191992d', 16)
198
sharedRSA_exp2 = long(
199
'28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26'
200
'ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1'
201
'b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0'
202
'aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a'
203
'5a4a6287c151de2d', 16)
204
sharedRSA_coef = long(
205
'28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b'
206
'e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab'
207
'cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf'
208
'8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf'
209
'7402af6c43247f43', 16)
210
211
# For reference, when encoded as a subject public key info, the
212
# base64-encoded sha-256 hash of this key is
213
# MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI=
214
alternateRSA_N = long(
215
'00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f'
216
'a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244'
217
'c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313'
218
'b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7'
219
'295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773'
220
'7699958666254797ed426908880811422069988a43fee48ce68781dd22b6'
221
'a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b'
222
'35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457'
223
'324ad7de86e6552f1d1e191d712168d3bb', 16)
224
alternateRSA_E = 65537L
225
alternateRSA_D = long(
226
'7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079'
227
'0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732'
228
'7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1'
229
'12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e'
230
'b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0'
231
'58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962'
232
'857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0'
233
'8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750'
234
'78c4021a9a2c93c9a70390e9d0a54401', 16)
235
alternateRSA_P = long(
236
'00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81'
237
'258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d'
238
'3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979'
239
'9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f'
240
'27b06fe09ddda7c0a1', 16)
241
alternateRSA_Q = long(
242
'00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708'
243
'4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac'
244
'6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb'
245
'a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd'
246
'fe764c1967b3e8cadb', 16)
247
alternateRSA_exp1 = long(
248
'01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d'
249
'3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3'
250
'c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27'
251
'9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60'
252
'9b5790a63c595181', 16)
253
alternateRSA_exp2 = long(
254
'0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a'
255
'f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b'
256
'1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733'
257
'cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798'
258
'1cd6234d571e90b7df', 16)
259
alternateRSA_coef = long(
260
'6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8'
261
'594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6'
262
'8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828'
263
'27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a'
264
'7b0df271e19a65c0', 16)
265
266
evRSA_N = long(
267
'00b549895c9d00108d11a1f99f87a9e3d1a5db5dfaecf188da57bf641368'
268
'8f2ce4722cff109038c17402c93a2a473dbd286aed3fdcd363cf5a291477'
269
'01bdd818d7615bf9356bd5d3c8336aaa8c0971368a06c3cd4461b93e5142'
270
'4e1744bb2eaad46aab38ce196821961f87714a1663693f09761cdf4d6ba1'
271
'25eacec7be270d388f789f6cdf78ae3144ed28c45e79293863a7a22a4898'
272
'0a36a40e72d579c9b925dff8c793362ffd6897a7c1754c5e97c967c3eadd'
273
'1aae8aa2ccce348a0169b80e28a2d70c1a960c6f335f2da09b9b643f5abf'
274
'ba49e8aaa981e960e27d87480bdd55dd9417fa18509fbb554ccf81a4397e'
275
'8ba8128a34bdf27865c189e5734fb22905', 16)
276
evRSA_E = 65537L
277
evRSA_D = long(
278
'00983d54f94d6f4c76eb23d6f93d78523530cf73b0d16254c6e781768d45'
279
'f55681d1d02fb2bd2aac6abc1c389860935c52a0d8f41482010394778314'
280
'1d864bff30803638a5c0152570ae9d18f3d8ca163efb475b0dddf32e7e16'
281
'ec7565e6bb5e025c41c5c66e57a03cede554221f83045347a2c4c451c3dc'
282
'e476b787ce0c057244be9e04ef13118dbbb3d5e0a6cc87029eafd4a69ed9'
283
'b14759b15e39d8a9884e56f54d2f9ab013f0d15f318a9ab6b2f73d1ec3c9'
284
'fe274ae89431a10640be7899b0011c5e5093a1834708689de100634dabde'
285
'60fbd6aaefa3a33df34a1f36f60c043036b748d1c9ee98c4031a0afec60e'
286
'fda0a990be524f5614eac4fdb34a52f951', 16)
287
evRSA_P = long(
288
'00eadc2cb33e5ff1ca376bbd95bd6a1777d2cf4fac47545e92d11a6209b9'
289
'd5e4ded47834581c169b3c884742a09ea187505c1ca55414d8d25b497632'
290
'd5ec2aaa05233430fad49892777a7d68e038f561a3b8969e60b0a263defb'
291
'fda48a9b0ff39d95bc88b15267c8ade97b5107948e41e433249d87f7db10'
292
'9d5d74584d86bcc1d7', 16)
293
evRSA_Q = long(
294
'00c59ae576a216470248d944a55b9e9bf93299da341ec56e558eba821abc'
295
'e1bf57b79cf411d2904c774f9dba1f15185f607b0574a08205d6ec28b66a'
296
'36d634232eaaf2fea37561abaf9d644b68db38c9964cb8c96ec0ac61eba6'
297
'4d05b446542f423976f5acde4ecc95536d2df578954f93f0cfd9c58fb78b'
298
'a2a76dd5ac284dc883', 16)
299
evRSA_exp1 = long(
300
'00c1d2ef3906331c52aca64811f9fe425beb2898322fb3db51032ce8d7e9'
301
'fc32240be92019cf2480fcd5e329837127118b2a59a1bfe06c883e3a4447'
302
'f3f031cd9aebd0b8d368fc79740d2cce8eadb324df7f091eafe1564361d5'
303
'4920b01b0471230e5e47d93f8ed33963c517bc4fc78f6d8b1f9eba85bcce'
304
'db7033026508db6285', 16)
305
evRSA_exp2 = long(
306
'008521b8db5694dfbe804a315f9efc9b65275c5490acf2a3456d65e6e610'
307
'bf9f647fc67501d4f5772f232ac70ccdef9fc2a6dfa415c7c41b6afc7af9'
308
'd07c3ca03f7ed93c09f0b99f2c304434322f1071709bbc1baa4c91575fa6'
309
'a959e07d4996956d95e22b57938b6e47c8d51ffedfc9bf888ce0d1a3e42b'
310
'65a89bed4b91d3e5f5', 16)
311
evRSA_coef = long(
312
'00dc497b06b920c8be0b0077b798e977eef744a90ec2c5d7e6cbb22448fa'
313
'c72da81a33180e0d8a02e831460c7fc7fd3a612f7b9930b61b799f8e908e'
314
'632e9ba0409b6aa70b03a3ba787426263b5bd5843df8476edb5d14f6a861'
315
'3ebaf5b9cd5ca42f5fbd2802e08e4e49e5709f5151510caa5ab2c1c6eb3e'
316
'fe9295d16e8c25c916', 16)
317
318
evRSA2040_N = long(
319
'00ca7020dc215f57914d343fae4a015111697af997a5ece91866499fc23f'
320
'1b88a118cbd30b10d91c7b9a0d4ee8972fcae56caf57f25fc1275a2a4dbc'
321
'b982428c32ef587bf2387410330a0ffb16b8029bd783969ef675f6de38c1'
322
'8f67193cb6c072f8b23d0b3374112627a57b90055771d9e62603f53788d7'
323
'f63afa724f5d108096df31f89f26b1eb5f7c4357980e008fcd55d827dd26'
324
'2395ca2f526a07897cc40c593b38716ebc0caa596719c6f29ac9b73a7a94'
325
'4748a3aa3e09e9eb4d461ea0027e540926614728b9d243975cf9a0541bef'
326
'd25e76b51f951110b0e7644fc7e38441791b6d2227384cb8004e23342372'
327
'b1cf5cc3e73e31b7bbefa160e6862ebb', 16)
328
evRSA2040_E = 65537L
329
evRSA2040_D = long(
330
'00b2db74bce92362abf72955a638ae8720ba3033bb7f971caf39188d7542'
331
'eaa1c1abb5d205b1e2111f4791c08911a2e141e8cfd7054702d23100b564'
332
'2c06e1a31b118afd1f9a2f396cced425c501d91435ca8656766ced2b93bb'
333
'b8669fce9bacd727d1dacb3dafabc3293e35389eef8ea0b58e1aeb1a20e6'
334
'a61f9fcd453f7567fe31d123b616a26fef4df1d6c9f7490111d028eefd1d'
335
'972045b1a242273dd7a67ebf111db2741a5a93c7b2289cc4a236f5a99a6e'
336
'c7a8206fdae1c1d04bdbb1980d4a298c5a17dae4186474a5f7835d882bce'
337
'f24aef4ed6f149f94d96c9f7d78e647fc778a9017ff208d3b4a1768b1821'
338
'62102cdab032fabbab38d5200a324649', 16)
339
evRSA2040_P = long(
340
'0f3844d0d4d4d6a21acd76a6fc370b8550e1d7ec5a6234172e790f0029ae'
341
'651f6d5c59330ab19802b9d7a207de7a1fb778e3774fdbdc411750633d8d'
342
'1b3fe075006ffcfd1d10e763c7a9227d2d5f0c2dade1c9e659c350a159d3'
343
'6bb986f12636d4f9942b288bc0fe21da8799477173144249ca2e389e6c5c'
344
'25aa78c8cad7d4df', 16)
345
evRSA2040_Q = long(
346
'0d4d0bedd1962f07a1ead6b23a4ed67aeaf1270f052a6d29ba074945c636'
347
'1a5c4f8f07bf859e067aed3f4e6e323ef2aa8a6acd340b0bdc7cfe4fd329'
348
'e3c97f870c7f7735792c6aa9d0f7e7542a28ed6f01b0e55a2b8d9c24a65c'
349
'6da314c95484f5c7c3954a81bb016b07ed17ee9b06039695bca059a79f8d'
350
'c2423d328d5265a5', 16)
351
evRSA2040_exp1 = long(
352
'09f29a2ff05be8a96d614ba31b08935420a86c6bc42b99a6692ea0da5763'
353
'f01e596959b7ddce73ef9c2e4f6e5b40710887500d44ba0c3cd3132cba27'
354
'475f39c2df7552e2d123a2497a4f97064028769a48a3624657f72bf539f3'
355
'd0de234feccd3be8a0aa90c6bf6e9b0bed43070a24d061ff3ed1751a3ef2'
356
'ff7f6b90b9dbd5fb', 16)
357
evRSA2040_exp2 = long(
358
'01a659e170cac120a03be1cf8f9df1caa353b03593bd7476e5853bd874c2'
359
'87388601c6c341ce9d1d284a5eef1a3a669d32b816a5eaecd8b7844fe070'
360
'64b9bca0c2b318d540277b3f7f1510d386bb36e03b04771e5d229e88893e'
361
'13b753bfb94518bb638e2404bd6e6a993c1668d93fc0b82ff08aaf34347d'
362
'3fe8397108c87ca5', 16)
363
evRSA2040_coef = long(
364
'040257c0d4a21c0b9843297c65652db66304fb263773d728b6abfa06d37a'
365
'c0ca62c628023e09e37dc0a901e4ce1224180e2582a3aa4b6a1a7b98e2bd'
366
'70077aec14ac8ab66a755c71e0fc102471f9bbc1b46a95aa0b645f2c38e7'
367
'6450289619ea3f5e8ae61037bffcf8249f22aa4e76e2a01909f3feb290ce'
368
'93edf57b10ebe796', 16)
369
370
rsa2040_N = long(
371
'00bac0652fdfbc0055882ffbaeaceec88fa2d083c297dd5d40664dd3d90f'
372
'52f9aa02bd8a50fba16e0fd991878ef475f9b350d9f8e3eb2abd717ce327'
373
'b09788531f13df8e3e4e3b9d616bb8a41e5306eed2472163161051180127'
374
'6a4eb66f07331b5cbc8bcae7016a8f9b3d4f2ac4553c624cf5263bcb348e'
375
'8840de6612870960a792191b138fb217f765cec7bff8e94f16b39419bf75'
376
'04c59a7e4f79bd6d173e9c7bf3d9d2a4e73cc180b0590a73d584fb7fc9b5'
377
'4fa544607e53fc685c7a55fd44a81d4142b6af51ea6fa6cea52965a2e8c5'
378
'd84f3ca024d6fbb9b005b9651ce5d9f2ecf40ed404981a9ffc02636e311b'
379
'095c6332a0c87dc39271b5551481774b', 16)
380
rsa2040_E = 65537L
381
rsa2040_D = long(
382
'603db267df97555cbed86b8df355034af28f1eb7f3e7829d239bcc273a7c'
383
'7a69a10be8f21f1b6c4b02c6bae3731c3158b5bbff4605f57ab7b7b2a0cb'
384
'a2ec005a2db5b1ea6e0aceea5bc745dcd2d0e9d6b80d7eb0ea2bc08127bc'
385
'e35fa50c42cc411871ba591e23ba6a38484a33eff1347f907ee9a5a92a23'
386
'11bb0b435510020f78e3bb00099db4d1182928096505fcba84f3ca1238fd'
387
'1eba5eea1f391bbbcc5424b168063fc17e1ca6e1912ccba44f9d0292308a'
388
'1fedb80612529b39f59d0a3f8180b5ba201132197f93a5815ded938df8e7'
389
'd93c9b15766588f339bb59100afda494a7e452d7dd4c9a19ce2ec3a33a18'
390
'b20f0b4dade172bee19f26f0dcbe41', 16)
391
rsa2040_P = long(
392
'0ec3869cb92d406caddf7a319ab29448bc505a05913707873361fc5b986a'
393
'499fb65eeb815a7e37687d19f128087289d9bb8818e7bcca502c4900ad9a'
394
'ece1179be12ff3e467d606fc820ea8f07ac9ebffe2236e38168412028822'
395
'3e42dbe68dfd972a85a6447e51695f234da7911c67c9ab9531f33df3b994'
396
'32d4ee88c9a4efbb', 16)
397
rsa2040_Q = long(
398
'0ca63934549e85feac8e0f5604303fd1849fe88af4b7f7e1213283bbc7a2'
399
'c2a509f9273c428c68de3db93e6145f1b400bd6d4a262614e9043ad362d4'
400
'eba4a6b995399c8934a399912199e841d8e8dbff0489f69e663796730b29'
401
'80530b31cb70695a21625ea2adccc09d930516fa872211a91e22dd89fd9e'
402
'b7da8574b72235b1', 16)
403
rsa2040_exp1 = long(
404
'0d7d3a75e17f65f8a658a485c4095c10a4f66979e2b73bca9cf8ef21253e'
405
'1facac6d4791f58392ce8656f88f1240cc90c29653e3100c6d7a38ed44b1'
406
'63b339e5f3b6e38912126c69b3ceff2e5192426d9649b6ffca1abb75d2ba'
407
'2ed6d9a26aa383c5973d56216ff2edb90ccf887742a0f183ac92c94cf187'
408
'657645c7772d9ad7', 16)
409
rsa2040_exp2 = long(
410
'03f550194c117f24bea285b209058032f42985ff55acebe88b16df9a3752'
411
'7b4e61dc91a68dbc9a645134528ce5f248bda2893c96cb7be79ee73996c7'
412
'c22577f6c2f790406f3472adb3b211b7e94494f32c5c6fcc0978839fe472'
413
'4c31b06318a2489567b4fca0337acb1b841227aaa5f6c74800a2306929f0'
414
'2ce038bad943df41', 16)
415
rsa2040_coef = long(
416
'080a7dbfa8c2584814c71664c56eb62ce4caf16afe88d4499159d674774a'
417
'3a3ecddf1256c02fc91525c527692422d0aba94e5c41ee12dc71bb66f867'
418
'9fa17e096f28080851ba046eb31885c1414e8985ade599d907af17453d1c'
419
'caea2c0d06443f8367a6be154b125e390ee0d90f746f08801dd3f5367f59'
420
'fba2e5a67c05f375', 16)
421
422
rsa1024_N = long(
423
'00d3a97440101eba8c5df9503e6f935eb52ffeb3ebe9d0dc5cace26f973c'
424
'a94cbc0d9c31d66c0c013bce9c82d0d480328df05fb6bcd7990a5312ddae'
425
'6152ad6ee61c8c1bdd8663c68bd36224a9882ae78e89f556dfdbe6f51da6'
426
'112cbfc27c8a49336b41afdb75321b52b24a7344d1348e646351a551c757'
427
'1ccda0b8fe35f61a75', 16)
428
rsa1024_E = 65537L
429
rsa1024_D = long(
430
'5b6708e185548fc07ff062dba3792363e106ff9177d60ee3227162391024'
431
'1813f958a318f26db8b6a801646863ebbc69190d6c2f5e7723433e99666d'
432
'76b3987892cd568f1f18451e8dc05477c0607ee348380ebb7f4c98d0c036'
433
'a0260bc67b2dab46cbaa4ce87636d839d8fddcbae2da3e02e8009a21225d'
434
'd7e47aff2f82699d', 16)
435
rsa1024_P = long(
436
'00fcdee570323e8fc399dbfc63d8c1569546fb3cd6886c628668ab1e1d0f'
437
'ca71058febdf76d702970ad6579d80ac2f9521075e40ef8f3f39983bd819'
438
'07e898bad3', 16)
439
rsa1024_Q = long(
440
'00d64801c955b4eb75fbae230faa8b28c9cc5e258be63747ff5ac8d2af25'
441
'3e9f6d6ce03ea2eb13ae0eb32572feb848c32ca00743635374338fedacd8'
442
'c5885f7897', 16)
443
rsa1024_exp1 = long(
444
'76c0526d5b1b28368a75d5d42a01b9a086e20b9310241e2cd2d0b166a278'
445
'c694ff1e9d25d9193d47789b52bb0fa194de1af0b77c09007f12afdfeef9'
446
'58d108c3', 16)
447
rsa1024_exp2 = long(
448
'008a41898d8b14217c4d782cbd15ef95d0a660f45ed09a4884f4e170367b'
449
'946d2f20398b907896890e88fe17b54bd7febe133ebc7720c86fe0649cca'
450
'7ca121e05f', 16)
451
rsa1024_coef = long(
452
'22db133445f7442ea2a0f582031ee214ff5f661972986f172651d8d6b4ec'
453
'3163e99bff1c82fe58ec3d075c6d8f26f277020edb77c3ba821b9ba3ae18'
454
'ff8cb2cb', 16)
455
456
rsa1016_N = long(
457
'00d29bb12fb84fddcd29b3a519cb66c43b8d8f8be545ba79384ce663ed03'
458
'df75991600eb920790d2530cece544db99a71f05896a3ed207165534aa99'
459
'057e47c47e3bc81ada6fa1e12e37268b5046a55268f9dad7ccb485d81a2e'
460
'19d50d4f0b6854acaf6d7be69d9a083136e15afa8f53c1c8c84fc6077279'
461
'dd0e55d7369a5bdd', 16)
462
rsa1016_E = 65537L
463
rsa1016_D = long(
464
'3c4965070bf390c251d5a2c5277c5b5fd0bdee85cad7fe2b27982bb28511'
465
'4a507004036ae1cf8ae54b25e4db39215abd7e903f618c2d8b2f08cc6cd1'
466
'2dbccd72205e4945b6b3df389e5e43de0a148bb2c84e2431fdbe5920b044'
467
'bb272f45ecff0721b7dfb60397fc613a9ea35c22300530cae8f9159c534d'
468
'f3bf0910951901', 16)
469
rsa1016_P = long(
470
'0f9f17597c85b8051b9c69afb55ef576c996dbd09047d0ccde5b9d60ea5c'
471
'67fe4fac67be803f4b6ac5a3f050f76b966fb14f5cf105761e5ade6dd960'
472
'b183ba55', 16)
473
rsa1016_Q = long(
474
'0d7b637112ce61a55168c0f9c9386fb279ab40cba0d549336bba65277263'
475
'aac782611a2c81d9b635cf78c40018859e018c5e9006d12e3d2ee6f346e7'
476
'9fa43369', 16)
477
rsa1016_exp1 = long(
478
'09fd6c9a3ea6e91ae32070f9fc1c210ff9352f97be5d1eeb951bb39681e9'
479
'dc5b672a532221b3d8900c9a9d99b9d0a4e102dc450ca1b87b0b1389de65'
480
'16c0ae0d', 16)
481
rsa1016_exp2 = long(
482
'0141b832491b7dd4a83308920024c79cae64bd447df883bb4c5672a96bab'
483
'48b7123b34f26324452cdceb17f21e570e347cbe2fd4c2d8f9910eac2cb6'
484
'd895b8c9', 16)
485
rsa1016_coef = long(
486
'0458dd6aee18c88b2f9b81f1bc3075ae20dc1f9973d20724f20b06043d61'
487
'47c8789d4a07ae88bc82c8438c893e017b13947f62e0b18958a31eb664b1'
488
'9e64d3e0', 16)
489
490
def __init__(self, specification):
491
if specification == 'default':
492
self.RSA_N = self.sharedRSA_N
493
self.RSA_E = self.sharedRSA_E
494
self.RSA_D = self.sharedRSA_D
495
self.RSA_P = self.sharedRSA_P
496
self.RSA_Q = self.sharedRSA_Q
497
self.RSA_exp1 = self.sharedRSA_exp1
498
self.RSA_exp2 = self.sharedRSA_exp2
499
self.RSA_coef = self.sharedRSA_coef
500
elif specification == 'alternate':
501
self.RSA_N = self.alternateRSA_N
502
self.RSA_E = self.alternateRSA_E
503
self.RSA_D = self.alternateRSA_D
504
self.RSA_P = self.alternateRSA_P
505
self.RSA_Q = self.alternateRSA_Q
506
self.RSA_exp1 = self.alternateRSA_exp1
507
self.RSA_exp2 = self.alternateRSA_exp2
508
self.RSA_coef = self.alternateRSA_coef
509
elif specification == 'ev':
510
self.RSA_N = self.evRSA_N
511
self.RSA_E = self.evRSA_E
512
self.RSA_D = self.evRSA_D
513
self.RSA_P = self.evRSA_P
514
self.RSA_Q = self.evRSA_Q
515
self.RSA_exp1 = self.evRSA_exp1
516
self.RSA_exp2 = self.evRSA_exp2
517
self.RSA_coef = self.evRSA_coef
518
elif specification == 'evRSA2040':
519
self.RSA_N = self.evRSA2040_N
520
self.RSA_E = self.evRSA2040_E
521
self.RSA_D = self.evRSA2040_D
522
self.RSA_P = self.evRSA2040_P
523
self.RSA_Q = self.evRSA2040_Q
524
self.RSA_exp1 = self.evRSA2040_exp1
525
self.RSA_exp2 = self.evRSA2040_exp2
526
self.RSA_coef = self.evRSA2040_coef
527
elif specification == 'rsa2040':
528
self.RSA_N = self.rsa2040_N
529
self.RSA_E = self.rsa2040_E
530
self.RSA_D = self.rsa2040_D
531
self.RSA_P = self.rsa2040_P
532
self.RSA_Q = self.rsa2040_Q
533
self.RSA_exp1 = self.rsa2040_exp1
534
self.RSA_exp2 = self.rsa2040_exp2
535
self.RSA_coef = self.rsa2040_coef
536
elif specification == 'rsa1024':
537
self.RSA_N = self.rsa1024_N
538
self.RSA_E = self.rsa1024_E
539
self.RSA_D = self.rsa1024_D
540
self.RSA_P = self.rsa1024_P
541
self.RSA_Q = self.rsa1024_Q
542
self.RSA_exp1 = self.rsa1024_exp1
543
self.RSA_exp2 = self.rsa1024_exp2
544
self.RSA_coef = self.rsa1024_coef
545
elif specification == 'rsa1016':
546
self.RSA_N = self.rsa1016_N
547
self.RSA_E = self.rsa1016_E
548
self.RSA_D = self.rsa1016_D
549
self.RSA_P = self.rsa1016_P
550
self.RSA_Q = self.rsa1016_Q
551
self.RSA_exp1 = self.rsa1016_exp1
552
self.RSA_exp2 = self.rsa1016_exp2
553
self.RSA_coef = self.rsa1016_coef
554
else:
555
raise UnknownKeySpecificationError(specification)
556
557
def toDER(self):
558
privateKeyInfo = PrivateKeyInfo()
559
privateKeyInfo['version'] = 0
560
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
561
algorithmIdentifier['algorithm'] = rfc2459.rsaEncryption
562
# Directly setting parameters to univ.Null doesn't currently work.
563
nullEncapsulated = encoder.encode(univ.Null())
564
algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
565
privateKeyInfo['privateKeyAlgorithm'] = algorithmIdentifier
566
rsaPrivateKey = RSAPrivateKey()
567
rsaPrivateKey['version'] = 0
568
rsaPrivateKey['modulus'] = self.RSA_N
569
rsaPrivateKey['publicExponent'] = self.RSA_E
570
rsaPrivateKey['privateExponent'] = self.RSA_D
571
rsaPrivateKey['prime1'] = self.RSA_P
572
rsaPrivateKey['prime2'] = self.RSA_Q
573
rsaPrivateKey['exponent1'] = self.RSA_exp1
574
rsaPrivateKey['exponent2'] = self.RSA_exp2
575
rsaPrivateKey['coefficient'] = self.RSA_coef
576
rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey)
577
privateKeyInfo['privateKey'] = univ.OctetString(rsaPrivateKeyEncoded)
578
return encoder.encode(privateKeyInfo)
579
580
def toPEM(self):
581
output = '-----BEGIN PRIVATE KEY-----'
582
der = self.toDER()
583
b64 = base64.b64encode(der)
584
while b64:
585
output += '\n' + b64[:64]
586
b64 = b64[64:]
587
output += '\n-----END PRIVATE KEY-----'
588
return output
589
590
def asSubjectPublicKeyInfo(self):
591
"""Returns a subject public key info representing
592
this key for use by pyasn1."""
593
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
594
algorithmIdentifier['algorithm'] = rfc2459.rsaEncryption
595
# Directly setting parameters to univ.Null doesn't currently work.
596
nullEncapsulated = encoder.encode(univ.Null())
597
algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
598
spki = rfc2459.SubjectPublicKeyInfo()
599
spki['algorithm'] = algorithmIdentifier
600
rsaKey = RSAPublicKey()
601
rsaKey['N'] = univ.Integer(self.RSA_N)
602
rsaKey['E'] = univ.Integer(self.RSA_E)
603
subjectPublicKey = univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey)))
604
spki['subjectPublicKey'] = subjectPublicKey
605
return spki
606
607
def sign(self, data, hashAlgorithm):
608
"""Returns a hexified bit string representing a
609
signature by this key over the specified data.
610
Intended for use with pyasn1.type.univ.BitString"""
611
hashAlgorithmName = None
612
if hashAlgorithm == HASH_MD5:
613
hashAlgorithmName = "MD5"
614
elif hashAlgorithm == HASH_SHA1:
615
hashAlgorithmName = "SHA-1"
616
elif hashAlgorithm == HASH_SHA256:
617
hashAlgorithmName = "SHA-256"
618
elif hashAlgorithm == HASH_SHA384:
619
hashAlgorithmName = "SHA-384"
620
elif hashAlgorithm == HASH_SHA512:
621
hashAlgorithmName = "SHA-512"
622
else:
623
raise UnknownHashAlgorithmError(hashAlgorithm)
624
rsaPrivateKey = rsa.PrivateKey(self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q)
625
signature = rsa.sign(data, rsaPrivateKey, hashAlgorithmName)
626
return byteStringToHexifiedBitString(signature)
627
628
629
ecPublicKey = univ.ObjectIdentifier('1.2.840.10045.2.1')
630
secp256k1 = univ.ObjectIdentifier('1.3.132.0.10')
631
secp224r1 = univ.ObjectIdentifier('1.3.132.0.33')
632
secp256r1 = univ.ObjectIdentifier('1.2.840.10045.3.1.7')
633
secp384r1 = univ.ObjectIdentifier('1.3.132.0.34')
634
secp521r1 = univ.ObjectIdentifier('1.3.132.0.35')
635
636
# ecc.curves.DOMAINS uses a 5-tuple to define curves.
637
# The first number is p where F_p is the finite field of the curve.
638
# The second number is the order n of the base point G.
639
# The third number is the parameter b of the definition of the curve
640
# E: y^2 = x^3 + ax + b (a in this case is 0)
641
# The fourth and fifth numbers constitute the base point G.
642
secp256k1Params = (long('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16),
643
long('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16),
644
7,
645
long('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16),
646
long('483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', 16))
647
648
649
def longToEvenLengthHexString(val):
650
h = format(val, 'x')
651
if not len(h) % 2 == 0:
652
h = '0' + h
653
return h
654
655
656
def notRandom(n):
657
return n * '\x04'
658
659
660
class ECCKey(object):
661
secp256k1Encoded = str('08fd87b04fba98090100004035ee7c7289d8fef7a8'
662
'6afe5da66d8bc2ebb6a8543fd2fead089f45ce7acd0fa64382a9500c41dad'
663
'770ffd4b511bf4b492eb1238800c32c4f76c73a3f3294e7c5002067cebc20'
664
'8a5fa3df16ec2bb34acc59a42ab4abb0538575ca99b92b6a2149a04f')
665
666
secp224r1Encoded = str('0ee5587c4d18526f00e00038668d72cca6fd6a1b35'
667
'57b5366104d84408ecb637f08e8c86bbff82cc00e88f0066d7af63c3298ba'
668
'377348a1202b03b37fd6b1ff415aa311e001c04389459926c3296c242b83e'
669
'10a6cd2011c8fe2dae1b772ea5b21067')
670
671
secp256r1Encoded = str('cb872ac99cd31827010000404fbfbbbb61e0f8f9b1'
672
'a60a59ac8704e2ec050b423e3cf72e923f2c4f794b455c2a69d233456c36c'
673
'4119d0706e00eedc8d19390d7991b7b2d07a304eaa04aa6c000202191403d'
674
'5710bf15a265818cd42ed6fedf09add92d78b18e7a1e9feb95524702')
675
676
secp384r1Encoded = str('d3103f5ac81741e801800060a1687243362b5c7b18'
677
'89f379154615a1c73fb48dee863e022915db608e252de4b7132da8ce98e83'
678
'1534e6a9c0c0b09c8d639ade83206e5ba813473a11fa330e05da8c96e4383'
679
'fe27873da97103be2888cff002f05af71a1fddcc8374aa6ea9ce0030035c7'
680
'a1b10d9fafe837b64ad92f22f5ced0789186538669b5c6d872cec3d926122'
681
'b393772b57602ff31365efe1393246')
682
683
secp521r1Encoded = str('77f4b0ac81948ddc02090084014cdc9cacc4794109'
684
'6bc9cc66752ec27f597734fa66c62b792f88c519d6d37f0d16ea1c483a182'
685
'7a010b9128e3a08070ca33ef5f57835b7c1ba251f6cc3521dc42b01065345'
686
'1981b445d343eed3782a35d6cff0ff484f5a883d209f1b9042b726703568b'
687
'2f326e18b833bdd8aa0734392bcd19501e10d698a79f53e11e0a22bdd2aad'
688
'900042014f3284fa698dd9fe1118dd331851cdfaac5a3829278eb8994839d'
689
'e9471c940b858c69d2d05e8c01788a7d0b6e235aa5e783fc1bee807dcc386'
690
'5f920e12cf8f2d29')
691
692
def __init__(self, specification=None):
693
if specification == 'secp256k1':
694
self.key = Key.Key.decode(binascii.unhexlify(self.secp256k1Encoded))
695
self.keyOID = secp256k1
696
elif specification == 'secp224r1':
697
self.key = Key.Key.decode(binascii.unhexlify(self.secp224r1Encoded))
698
self.keyOID = secp224r1
699
elif specification == 'secp256r1':
700
self.key = Key.Key.decode(binascii.unhexlify(self.secp256r1Encoded))
701
self.keyOID = secp256r1
702
elif specification == 'secp384r1':
703
self.key = Key.Key.decode(binascii.unhexlify(self.secp384r1Encoded))
704
self.keyOID = secp384r1
705
elif specification == 'secp521r1':
706
self.key = Key.Key.decode(binascii.unhexlify(self.secp521r1Encoded))
707
self.keyOID = secp521r1
708
else:
709
raise UnknownKeySpecificationError(specification)
710
711
def getPublicKeyHexifiedString(self):
712
"""Returns the EC public key as a hex string using the uncompressed
713
point representation. This is intended to be used in the encoder
714
functions, as it surrounds the value with ''H to indicate its type."""
715
# We need to extract the point that represents this key.
716
# The library encoding of the key is an 8-byte id, followed by 2
717
# bytes for the key length in bits, followed by the point on the
718
# curve (represented by two python longs). There appear to also
719
# be 2 bytes indicating the length of the point as encoded, but
720
# Decoder takes care of that.
721
encoded = self.key.encode()
722
_, _, points = encoding.Decoder(encoded).int(8).int(2).point(2).out()
723
# '04' indicates that the points are in uncompressed form.
724
return "'%s%s%s'H" % ('04', longToEvenLengthHexString(points[0]),
725
longToEvenLengthHexString(points[1]))
726
727
def toPEM(self):
728
"""Return the EC private key in PEM-encoded form."""
729
output = '-----BEGIN EC PRIVATE KEY-----'
730
der = self.toDER()
731
b64 = base64.b64encode(der)
732
while b64:
733
output += '\n' + b64[:64]
734
b64 = b64[64:]
735
output += '\n-----END EC PRIVATE KEY-----'
736
return output
737
738
def toDER(self):
739
"""Return the EC private key in DER-encoded form, encoded per SEC 1
740
section C.4 format."""
741
privateKeyInfo = PrivateKeyInfo()
742
privateKeyInfo['version'] = 0
743
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
744
algorithmIdentifier['algorithm'] = ecPublicKey
745
algorithmIdentifier['parameters'] = self.keyOID
746
privateKeyInfo['privateKeyAlgorithm'] = algorithmIdentifier
747
ecPrivateKey = ECPrivateKey()
748
ecPrivateKey['version'] = 1
749
ecPrivateKey['privateKey'] = binascii.unhexlify(longToEvenLengthHexString(
750
self.key._priv[1]))
751
ecPrivateKey['publicKey'] = univ.BitString(
752
self.getPublicKeyHexifiedString()
753
).subtype(
754
explicitTag=tag.Tag(tag.tagClassContext,
755
tag.tagFormatSimple, 1)
756
)
757
ecPrivateKeyEncoded = encoder.encode(ecPrivateKey)
758
privateKeyInfo['privateKey'] = univ.OctetString(ecPrivateKeyEncoded)
759
return encoder.encode(privateKeyInfo)
760
761
def asSubjectPublicKeyInfo(self):
762
"""Returns a subject public key info representing
763
this key for use by pyasn1."""
764
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
765
algorithmIdentifier['algorithm'] = ecPublicKey
766
algorithmIdentifier['parameters'] = self.keyOID
767
spki = rfc2459.SubjectPublicKeyInfo()
768
spki['algorithm'] = algorithmIdentifier
769
spki['subjectPublicKey'] = univ.BitString(self.getPublicKeyHexifiedString())
770
return spki
771
772
def signRaw(self, data, hashAlgorithm):
773
"""Performs the ECDSA signature algorithm over the given data.
774
The returned value is a string representing the bytes of the
775
resulting point when encoded by left-padding each of (r, s) to
776
the key size and concatenating them.
777
"""
778
# There is some non-determinism in ECDSA signatures. Work around
779
# this by patching ecc.ecdsa.urandom to not be random.
780
with mock.patch('ecc.ecdsa.urandom', side_effect=notRandom):
781
# Patch in secp256k1 if applicable.
782
if self.keyOID == secp256k1:
783
with mock.patch('ecc.curves.DOMAINS', {256: secp256k1Params}):
784
return self.key.sign(data, hashAlgorithm.split(':')[-1])
785
else:
786
return self.key.sign(data, hashAlgorithm.split(':')[-1])
787
788
def sign(self, data, hashAlgorithm):
789
"""Returns a hexified bit string representing a
790
signature by this key over the specified data.
791
Intended for use with pyasn1.type.univ.BitString"""
792
# ecc.Key.sign returns an encoded point, which is useful in some
793
# situations. However, for signatures on X509 certificates, we
794
# need to decode it so we can encode it as a BITSTRING
795
# consisting of a SEQUENCE of two INTEGERs.
796
x, y = encoding.dec_point(self.signRaw(data, hashAlgorithm))
797
point = ECPoint()
798
point['x'] = x
799
point['y'] = y
800
return byteStringToHexifiedBitString(encoder.encode(point))
801
802
803
def keyFromSpecification(specification):
804
"""Pass in a specification, get the appropriate key back."""
805
if specification.startswith('secp'):
806
return ECCKey(specification)
807
else:
808
return RSAKey(specification)
809
810
# The build harness will call this function with an output file-like
811
# object and a path to a file containing a specification. This will
812
# read the specification and output the key as ASCII-encoded PKCS #8.
813
814
815
def main(output, inputPath):
816
with open(inputPath) as configStream:
817
output.write(keyFromSpecification(configStream.read().strip()).toPEM() + '\n')
818
819
820
# When run as a standalone program, this will read a specification from
821
# stdin and output the certificate as PEM to stdout.
822
if __name__ == '__main__':
823
print keyFromSpecification(sys.stdin.read().strip()).toPEM()