pykey.py (40324B)
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 import base64 34 import binascii 35 import hashlib 36 import math 37 import sys 38 39 import ecdsa 40 import rsa 41 from pyasn1.codec.der import encoder 42 from pyasn1.type import namedtype, tag, univ 43 from pyasn1_modules import rfc2459 44 45 # "constants" to make it easier for consumers to specify hash algorithms 46 HASH_MD5 = "hash:md5" 47 HASH_SHA1 = "hash:sha1" 48 HASH_SHA256 = "hash:sha256" 49 HASH_SHA384 = "hash:sha384" 50 HASH_SHA512 = "hash:sha512" 51 52 53 # NOTE: With bug 1621441 we migrated from one library for ecdsa to another. 54 # These libraries differ somewhat in terms of functionality and interface. In 55 # order to ensure there are no diffs and that the generated signatures are 56 # exactly the same between the two libraries, we need to patch some stuff in. 57 58 59 def _gen_k(curve): 60 # This calculation is arbitrary, but it matches what we were doing pre- 61 # bug 1621441 (see the above NOTE). Crucially, this generation of k is 62 # non-random; the ecdsa library exposes an option to deterministically 63 # generate a value of k for us, but it doesn't match up to what we were 64 # doing before so we have to inject a custom value. 65 num_bytes = int(math.log(curve.order - 1, 2) + 1) // 8 + 8 66 entropy = int.from_bytes(b"\04" * num_bytes, byteorder="big") 67 p = curve.curve.p() 68 return (entropy % (p - 1)) + 1 69 70 71 # As above, the library has built-in logic for truncating digests that are too 72 # large, but they use a slightly different technique than our previous library. 73 # Re-implement that logic here. 74 def _truncate_digest(digest, curve): 75 i = int.from_bytes(digest, byteorder="big") 76 p = curve.curve.p() 77 while i > p: 78 i >>= 1 79 return i.to_bytes(math.ceil(i.bit_length() / 8), byteorder="big") 80 81 82 def byteStringToHexifiedBitString(bytes): 83 """Takes a string of bytes and returns a hex string representing 84 those bytes for use with pyasn1.type.univ.BitString. It must be of 85 the form "'<hex bytes>'H", where the trailing 'H' indicates to 86 pyasn1 that the input is a hex string.""" 87 return "'%s'H" % bytes.hex() 88 89 90 class UnknownBaseError(Exception): 91 """Base class for handling unexpected input in this module.""" 92 93 def __init__(self, value): 94 super().__init__() 95 self.value = value 96 self.category = "input" 97 98 def __str__(self): 99 return 'Unknown %s type "%s"' % (self.category, repr(self.value)) 100 101 102 class UnknownKeySpecificationError(UnknownBaseError): 103 """Helper exception type to handle unknown key specifications.""" 104 105 def __init__(self, value): 106 UnknownBaseError.__init__(self, value) 107 self.category = "key specification" 108 109 110 class UnknownHashAlgorithmError(UnknownBaseError): 111 """Helper exception type to handle unknown key specifications.""" 112 113 def __init__(self, value): 114 UnknownBaseError.__init__(self, value) 115 self.category = "hash algorithm" 116 117 118 class UnsupportedHashAlgorithmError(Exception): 119 """Helper exception type for unsupported hash algorithms.""" 120 121 def __init__(self, value): 122 super().__init__() 123 self.value = value 124 125 def __str__(self): 126 return 'Unsupported hash algorithm "%s"' % repr(self.value) 127 128 129 class RSAPublicKey(univ.Sequence): 130 """Helper type for encoding an RSA public key""" 131 132 componentType = namedtype.NamedTypes( 133 namedtype.NamedType("N", univ.Integer()), 134 namedtype.NamedType("E", univ.Integer()), 135 ) 136 137 138 class RSAPrivateKey(univ.Sequence): 139 """Helper type for encoding an RSA private key""" 140 141 componentType = namedtype.NamedTypes( 142 namedtype.NamedType("version", univ.Integer()), 143 namedtype.NamedType("modulus", univ.Integer()), 144 namedtype.NamedType("publicExponent", univ.Integer()), 145 namedtype.NamedType("privateExponent", univ.Integer()), 146 namedtype.NamedType("prime1", univ.Integer()), 147 namedtype.NamedType("prime2", univ.Integer()), 148 namedtype.NamedType("exponent1", univ.Integer()), 149 namedtype.NamedType("exponent2", univ.Integer()), 150 namedtype.NamedType("coefficient", univ.Integer()), 151 ) 152 153 154 class ECPrivateKey(univ.Sequence): 155 """Helper type for encoding an EC private key 156 ECPrivateKey ::= SEQUENCE { 157 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 158 privateKey OCTET STRING, 159 parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 160 (NOTE: parameters field is not supported) 161 publicKey [1] BIT STRING OPTIONAL 162 }""" 163 164 componentType = namedtype.NamedTypes( 165 namedtype.NamedType("version", univ.Integer()), 166 namedtype.NamedType("privateKey", univ.OctetString()), 167 namedtype.OptionalNamedType( 168 "publicKey", 169 univ.BitString().subtype( 170 explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1) 171 ), 172 ), 173 ) 174 175 176 class ECPoint(univ.Sequence): 177 """Helper type for encoding a EC point""" 178 179 componentType = namedtype.NamedTypes( 180 namedtype.NamedType("x", univ.Integer()), 181 namedtype.NamedType("y", univ.Integer()), 182 ) 183 184 185 class PrivateKeyInfo(univ.Sequence): 186 """Helper type for encoding a PKCS #8 private key info""" 187 188 componentType = namedtype.NamedTypes( 189 namedtype.NamedType("version", univ.Integer()), 190 namedtype.NamedType("privateKeyAlgorithm", rfc2459.AlgorithmIdentifier()), 191 namedtype.NamedType("privateKey", univ.OctetString()), 192 ) 193 194 195 class RSAKey: 196 # For reference, when encoded as a subject public key info, the 197 # base64-encoded sha-256 hash of this key is 198 # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= 199 sharedRSA_N = int( 200 "00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857" 201 "6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a" 202 "a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c" 203 "c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b" 204 "2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716" 205 "d855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075" 206 "31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a" 207 "95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3" 208 "fe4923fa7251c431d503acda180a35ed8d", 209 16, 210 ) 211 sharedRSA_E = 65537 212 sharedRSA_D = int( 213 "009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da" 214 "a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46" 215 "3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2" 216 "39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c" 217 "7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa" 218 "79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3" 219 "6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c" 220 "f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931" 221 "5b62b30e6011f224725946eec57c6d9441", 222 16, 223 ) 224 sharedRSA_P = int( 225 "00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb" 226 "a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f" 227 "8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d" 228 "d5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177" 229 "3ca5d19301f48c742b", 230 16, 231 ) 232 sharedRSA_Q = int( 233 "00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47" 234 "8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d" 235 "1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833" 236 "28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16" 237 "5810a77b9845bc3127", 238 16, 239 ) 240 sharedRSA_exp1 = int( 241 "0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35" 242 "81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc" 243 "f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66" 244 "21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765" 245 "5315be9c24d191992d", 246 16, 247 ) 248 sharedRSA_exp2 = int( 249 "28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26" 250 "ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1" 251 "b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0" 252 "aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a" 253 "5a4a6287c151de2d", 254 16, 255 ) 256 sharedRSA_coef = int( 257 "28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b" 258 "e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab" 259 "cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf" 260 "8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf" 261 "7402af6c43247f43", 262 16, 263 ) 264 265 # For reference, when encoded as a subject public key info, the 266 # base64-encoded sha-256 hash of this key is 267 # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= 268 alternateRSA_N = int( 269 "00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f" 270 "a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244" 271 "c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313" 272 "b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7" 273 "295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773" 274 "7699958666254797ed426908880811422069988a43fee48ce68781dd22b6" 275 "a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b" 276 "35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457" 277 "324ad7de86e6552f1d1e191d712168d3bb", 278 16, 279 ) 280 alternateRSA_E = 65537 281 alternateRSA_D = int( 282 "7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079" 283 "0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732" 284 "7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1" 285 "12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e" 286 "b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0" 287 "58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962" 288 "857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0" 289 "8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750" 290 "78c4021a9a2c93c9a70390e9d0a54401", 291 16, 292 ) 293 alternateRSA_P = int( 294 "00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81" 295 "258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d" 296 "3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979" 297 "9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f" 298 "27b06fe09ddda7c0a1", 299 16, 300 ) 301 alternateRSA_Q = int( 302 "00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708" 303 "4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac" 304 "6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb" 305 "a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd" 306 "fe764c1967b3e8cadb", 307 16, 308 ) 309 alternateRSA_exp1 = int( 310 "01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d" 311 "3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3" 312 "c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27" 313 "9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60" 314 "9b5790a63c595181", 315 16, 316 ) 317 alternateRSA_exp2 = int( 318 "0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a" 319 "f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b" 320 "1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733" 321 "cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798" 322 "1cd6234d571e90b7df", 323 16, 324 ) 325 alternateRSA_coef = int( 326 "6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8" 327 "594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6" 328 "8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828" 329 "27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a" 330 "7b0df271e19a65c0", 331 16, 332 ) 333 334 evRSA_N = int( 335 "00b549895c9d00108d11a1f99f87a9e3d1a5db5dfaecf188da57bf641368" 336 "8f2ce4722cff109038c17402c93a2a473dbd286aed3fdcd363cf5a291477" 337 "01bdd818d7615bf9356bd5d3c8336aaa8c0971368a06c3cd4461b93e5142" 338 "4e1744bb2eaad46aab38ce196821961f87714a1663693f09761cdf4d6ba1" 339 "25eacec7be270d388f789f6cdf78ae3144ed28c45e79293863a7a22a4898" 340 "0a36a40e72d579c9b925dff8c793362ffd6897a7c1754c5e97c967c3eadd" 341 "1aae8aa2ccce348a0169b80e28a2d70c1a960c6f335f2da09b9b643f5abf" 342 "ba49e8aaa981e960e27d87480bdd55dd9417fa18509fbb554ccf81a4397e" 343 "8ba8128a34bdf27865c189e5734fb22905", 344 16, 345 ) 346 evRSA_E = 65537 347 evRSA_D = int( 348 "00983d54f94d6f4c76eb23d6f93d78523530cf73b0d16254c6e781768d45" 349 "f55681d1d02fb2bd2aac6abc1c389860935c52a0d8f41482010394778314" 350 "1d864bff30803638a5c0152570ae9d18f3d8ca163efb475b0dddf32e7e16" 351 "ec7565e6bb5e025c41c5c66e57a03cede554221f83045347a2c4c451c3dc" 352 "e476b787ce0c057244be9e04ef13118dbbb3d5e0a6cc87029eafd4a69ed9" 353 "b14759b15e39d8a9884e56f54d2f9ab013f0d15f318a9ab6b2f73d1ec3c9" 354 "fe274ae89431a10640be7899b0011c5e5093a1834708689de100634dabde" 355 "60fbd6aaefa3a33df34a1f36f60c043036b748d1c9ee98c4031a0afec60e" 356 "fda0a990be524f5614eac4fdb34a52f951", 357 16, 358 ) 359 evRSA_P = int( 360 "00eadc2cb33e5ff1ca376bbd95bd6a1777d2cf4fac47545e92d11a6209b9" 361 "d5e4ded47834581c169b3c884742a09ea187505c1ca55414d8d25b497632" 362 "d5ec2aaa05233430fad49892777a7d68e038f561a3b8969e60b0a263defb" 363 "fda48a9b0ff39d95bc88b15267c8ade97b5107948e41e433249d87f7db10" 364 "9d5d74584d86bcc1d7", 365 16, 366 ) 367 evRSA_Q = int( 368 "00c59ae576a216470248d944a55b9e9bf93299da341ec56e558eba821abc" 369 "e1bf57b79cf411d2904c774f9dba1f15185f607b0574a08205d6ec28b66a" 370 "36d634232eaaf2fea37561abaf9d644b68db38c9964cb8c96ec0ac61eba6" 371 "4d05b446542f423976f5acde4ecc95536d2df578954f93f0cfd9c58fb78b" 372 "a2a76dd5ac284dc883", 373 16, 374 ) 375 evRSA_exp1 = int( 376 "00c1d2ef3906331c52aca64811f9fe425beb2898322fb3db51032ce8d7e9" 377 "fc32240be92019cf2480fcd5e329837127118b2a59a1bfe06c883e3a4447" 378 "f3f031cd9aebd0b8d368fc79740d2cce8eadb324df7f091eafe1564361d5" 379 "4920b01b0471230e5e47d93f8ed33963c517bc4fc78f6d8b1f9eba85bcce" 380 "db7033026508db6285", 381 16, 382 ) 383 evRSA_exp2 = int( 384 "008521b8db5694dfbe804a315f9efc9b65275c5490acf2a3456d65e6e610" 385 "bf9f647fc67501d4f5772f232ac70ccdef9fc2a6dfa415c7c41b6afc7af9" 386 "d07c3ca03f7ed93c09f0b99f2c304434322f1071709bbc1baa4c91575fa6" 387 "a959e07d4996956d95e22b57938b6e47c8d51ffedfc9bf888ce0d1a3e42b" 388 "65a89bed4b91d3e5f5", 389 16, 390 ) 391 evRSA_coef = int( 392 "00dc497b06b920c8be0b0077b798e977eef744a90ec2c5d7e6cbb22448fa" 393 "c72da81a33180e0d8a02e831460c7fc7fd3a612f7b9930b61b799f8e908e" 394 "632e9ba0409b6aa70b03a3ba787426263b5bd5843df8476edb5d14f6a861" 395 "3ebaf5b9cd5ca42f5fbd2802e08e4e49e5709f5151510caa5ab2c1c6eb3e" 396 "fe9295d16e8c25c916", 397 16, 398 ) 399 400 evRSA2040_N = int( 401 "00ca7020dc215f57914d343fae4a015111697af997a5ece91866499fc23f" 402 "1b88a118cbd30b10d91c7b9a0d4ee8972fcae56caf57f25fc1275a2a4dbc" 403 "b982428c32ef587bf2387410330a0ffb16b8029bd783969ef675f6de38c1" 404 "8f67193cb6c072f8b23d0b3374112627a57b90055771d9e62603f53788d7" 405 "f63afa724f5d108096df31f89f26b1eb5f7c4357980e008fcd55d827dd26" 406 "2395ca2f526a07897cc40c593b38716ebc0caa596719c6f29ac9b73a7a94" 407 "4748a3aa3e09e9eb4d461ea0027e540926614728b9d243975cf9a0541bef" 408 "d25e76b51f951110b0e7644fc7e38441791b6d2227384cb8004e23342372" 409 "b1cf5cc3e73e31b7bbefa160e6862ebb", 410 16, 411 ) 412 evRSA2040_E = 65537 413 evRSA2040_D = int( 414 "00b2db74bce92362abf72955a638ae8720ba3033bb7f971caf39188d7542" 415 "eaa1c1abb5d205b1e2111f4791c08911a2e141e8cfd7054702d23100b564" 416 "2c06e1a31b118afd1f9a2f396cced425c501d91435ca8656766ced2b93bb" 417 "b8669fce9bacd727d1dacb3dafabc3293e35389eef8ea0b58e1aeb1a20e6" 418 "a61f9fcd453f7567fe31d123b616a26fef4df1d6c9f7490111d028eefd1d" 419 "972045b1a242273dd7a67ebf111db2741a5a93c7b2289cc4a236f5a99a6e" 420 "c7a8206fdae1c1d04bdbb1980d4a298c5a17dae4186474a5f7835d882bce" 421 "f24aef4ed6f149f94d96c9f7d78e647fc778a9017ff208d3b4a1768b1821" 422 "62102cdab032fabbab38d5200a324649", 423 16, 424 ) 425 evRSA2040_P = int( 426 "0f3844d0d4d4d6a21acd76a6fc370b8550e1d7ec5a6234172e790f0029ae" 427 "651f6d5c59330ab19802b9d7a207de7a1fb778e3774fdbdc411750633d8d" 428 "1b3fe075006ffcfd1d10e763c7a9227d2d5f0c2dade1c9e659c350a159d3" 429 "6bb986f12636d4f9942b288bc0fe21da8799477173144249ca2e389e6c5c" 430 "25aa78c8cad7d4df", 431 16, 432 ) 433 evRSA2040_Q = int( 434 "0d4d0bedd1962f07a1ead6b23a4ed67aeaf1270f052a6d29ba074945c636" 435 "1a5c4f8f07bf859e067aed3f4e6e323ef2aa8a6acd340b0bdc7cfe4fd329" 436 "e3c97f870c7f7735792c6aa9d0f7e7542a28ed6f01b0e55a2b8d9c24a65c" 437 "6da314c95484f5c7c3954a81bb016b07ed17ee9b06039695bca059a79f8d" 438 "c2423d328d5265a5", 439 16, 440 ) 441 evRSA2040_exp1 = int( 442 "09f29a2ff05be8a96d614ba31b08935420a86c6bc42b99a6692ea0da5763" 443 "f01e596959b7ddce73ef9c2e4f6e5b40710887500d44ba0c3cd3132cba27" 444 "475f39c2df7552e2d123a2497a4f97064028769a48a3624657f72bf539f3" 445 "d0de234feccd3be8a0aa90c6bf6e9b0bed43070a24d061ff3ed1751a3ef2" 446 "ff7f6b90b9dbd5fb", 447 16, 448 ) 449 evRSA2040_exp2 = int( 450 "01a659e170cac120a03be1cf8f9df1caa353b03593bd7476e5853bd874c2" 451 "87388601c6c341ce9d1d284a5eef1a3a669d32b816a5eaecd8b7844fe070" 452 "64b9bca0c2b318d540277b3f7f1510d386bb36e03b04771e5d229e88893e" 453 "13b753bfb94518bb638e2404bd6e6a993c1668d93fc0b82ff08aaf34347d" 454 "3fe8397108c87ca5", 455 16, 456 ) 457 evRSA2040_coef = int( 458 "040257c0d4a21c0b9843297c65652db66304fb263773d728b6abfa06d37a" 459 "c0ca62c628023e09e37dc0a901e4ce1224180e2582a3aa4b6a1a7b98e2bd" 460 "70077aec14ac8ab66a755c71e0fc102471f9bbc1b46a95aa0b645f2c38e7" 461 "6450289619ea3f5e8ae61037bffcf8249f22aa4e76e2a01909f3feb290ce" 462 "93edf57b10ebe796", 463 16, 464 ) 465 466 rsa2040_N = int( 467 "00bac0652fdfbc0055882ffbaeaceec88fa2d083c297dd5d40664dd3d90f" 468 "52f9aa02bd8a50fba16e0fd991878ef475f9b350d9f8e3eb2abd717ce327" 469 "b09788531f13df8e3e4e3b9d616bb8a41e5306eed2472163161051180127" 470 "6a4eb66f07331b5cbc8bcae7016a8f9b3d4f2ac4553c624cf5263bcb348e" 471 "8840de6612870960a792191b138fb217f765cec7bff8e94f16b39419bf75" 472 "04c59a7e4f79bd6d173e9c7bf3d9d2a4e73cc180b0590a73d584fb7fc9b5" 473 "4fa544607e53fc685c7a55fd44a81d4142b6af51ea6fa6cea52965a2e8c5" 474 "d84f3ca024d6fbb9b005b9651ce5d9f2ecf40ed404981a9ffc02636e311b" 475 "095c6332a0c87dc39271b5551481774b", 476 16, 477 ) 478 rsa2040_E = 65537 479 rsa2040_D = int( 480 "603db267df97555cbed86b8df355034af28f1eb7f3e7829d239bcc273a7c" 481 "7a69a10be8f21f1b6c4b02c6bae3731c3158b5bbff4605f57ab7b7b2a0cb" 482 "a2ec005a2db5b1ea6e0aceea5bc745dcd2d0e9d6b80d7eb0ea2bc08127bc" 483 "e35fa50c42cc411871ba591e23ba6a38484a33eff1347f907ee9a5a92a23" 484 "11bb0b435510020f78e3bb00099db4d1182928096505fcba84f3ca1238fd" 485 "1eba5eea1f391bbbcc5424b168063fc17e1ca6e1912ccba44f9d0292308a" 486 "1fedb80612529b39f59d0a3f8180b5ba201132197f93a5815ded938df8e7" 487 "d93c9b15766588f339bb59100afda494a7e452d7dd4c9a19ce2ec3a33a18" 488 "b20f0b4dade172bee19f26f0dcbe41", 489 16, 490 ) 491 rsa2040_P = int( 492 "0ec3869cb92d406caddf7a319ab29448bc505a05913707873361fc5b986a" 493 "499fb65eeb815a7e37687d19f128087289d9bb8818e7bcca502c4900ad9a" 494 "ece1179be12ff3e467d606fc820ea8f07ac9ebffe2236e38168412028822" 495 "3e42dbe68dfd972a85a6447e51695f234da7911c67c9ab9531f33df3b994" 496 "32d4ee88c9a4efbb", 497 16, 498 ) 499 rsa2040_Q = int( 500 "0ca63934549e85feac8e0f5604303fd1849fe88af4b7f7e1213283bbc7a2" 501 "c2a509f9273c428c68de3db93e6145f1b400bd6d4a262614e9043ad362d4" 502 "eba4a6b995399c8934a399912199e841d8e8dbff0489f69e663796730b29" 503 "80530b31cb70695a21625ea2adccc09d930516fa872211a91e22dd89fd9e" 504 "b7da8574b72235b1", 505 16, 506 ) 507 rsa2040_exp1 = int( 508 "0d7d3a75e17f65f8a658a485c4095c10a4f66979e2b73bca9cf8ef21253e" 509 "1facac6d4791f58392ce8656f88f1240cc90c29653e3100c6d7a38ed44b1" 510 "63b339e5f3b6e38912126c69b3ceff2e5192426d9649b6ffca1abb75d2ba" 511 "2ed6d9a26aa383c5973d56216ff2edb90ccf887742a0f183ac92c94cf187" 512 "657645c7772d9ad7", 513 16, 514 ) 515 rsa2040_exp2 = int( 516 "03f550194c117f24bea285b209058032f42985ff55acebe88b16df9a3752" 517 "7b4e61dc91a68dbc9a645134528ce5f248bda2893c96cb7be79ee73996c7" 518 "c22577f6c2f790406f3472adb3b211b7e94494f32c5c6fcc0978839fe472" 519 "4c31b06318a2489567b4fca0337acb1b841227aaa5f6c74800a2306929f0" 520 "2ce038bad943df41", 521 16, 522 ) 523 rsa2040_coef = int( 524 "080a7dbfa8c2584814c71664c56eb62ce4caf16afe88d4499159d674774a" 525 "3a3ecddf1256c02fc91525c527692422d0aba94e5c41ee12dc71bb66f867" 526 "9fa17e096f28080851ba046eb31885c1414e8985ade599d907af17453d1c" 527 "caea2c0d06443f8367a6be154b125e390ee0d90f746f08801dd3f5367f59" 528 "fba2e5a67c05f375", 529 16, 530 ) 531 532 rsa1024_N = int( 533 "00d3a97440101eba8c5df9503e6f935eb52ffeb3ebe9d0dc5cace26f973c" 534 "a94cbc0d9c31d66c0c013bce9c82d0d480328df05fb6bcd7990a5312ddae" 535 "6152ad6ee61c8c1bdd8663c68bd36224a9882ae78e89f556dfdbe6f51da6" 536 "112cbfc27c8a49336b41afdb75321b52b24a7344d1348e646351a551c757" 537 "1ccda0b8fe35f61a75", 538 16, 539 ) 540 rsa1024_E = 65537 541 rsa1024_D = int( 542 "5b6708e185548fc07ff062dba3792363e106ff9177d60ee3227162391024" 543 "1813f958a318f26db8b6a801646863ebbc69190d6c2f5e7723433e99666d" 544 "76b3987892cd568f1f18451e8dc05477c0607ee348380ebb7f4c98d0c036" 545 "a0260bc67b2dab46cbaa4ce87636d839d8fddcbae2da3e02e8009a21225d" 546 "d7e47aff2f82699d", 547 16, 548 ) 549 rsa1024_P = int( 550 "00fcdee570323e8fc399dbfc63d8c1569546fb3cd6886c628668ab1e1d0f" 551 "ca71058febdf76d702970ad6579d80ac2f9521075e40ef8f3f39983bd819" 552 "07e898bad3", 553 16, 554 ) 555 rsa1024_Q = int( 556 "00d64801c955b4eb75fbae230faa8b28c9cc5e258be63747ff5ac8d2af25" 557 "3e9f6d6ce03ea2eb13ae0eb32572feb848c32ca00743635374338fedacd8" 558 "c5885f7897", 559 16, 560 ) 561 rsa1024_exp1 = int( 562 "76c0526d5b1b28368a75d5d42a01b9a086e20b9310241e2cd2d0b166a278" 563 "c694ff1e9d25d9193d47789b52bb0fa194de1af0b77c09007f12afdfeef9" 564 "58d108c3", 565 16, 566 ) 567 rsa1024_exp2 = int( 568 "008a41898d8b14217c4d782cbd15ef95d0a660f45ed09a4884f4e170367b" 569 "946d2f20398b907896890e88fe17b54bd7febe133ebc7720c86fe0649cca" 570 "7ca121e05f", 571 16, 572 ) 573 rsa1024_coef = int( 574 "22db133445f7442ea2a0f582031ee214ff5f661972986f172651d8d6b4ec" 575 "3163e99bff1c82fe58ec3d075c6d8f26f277020edb77c3ba821b9ba3ae18" 576 "ff8cb2cb", 577 16, 578 ) 579 580 rsa1016_N = int( 581 "00d29bb12fb84fddcd29b3a519cb66c43b8d8f8be545ba79384ce663ed03" 582 "df75991600eb920790d2530cece544db99a71f05896a3ed207165534aa99" 583 "057e47c47e3bc81ada6fa1e12e37268b5046a55268f9dad7ccb485d81a2e" 584 "19d50d4f0b6854acaf6d7be69d9a083136e15afa8f53c1c8c84fc6077279" 585 "dd0e55d7369a5bdd", 586 16, 587 ) 588 rsa1016_E = 65537 589 rsa1016_D = int( 590 "3c4965070bf390c251d5a2c5277c5b5fd0bdee85cad7fe2b27982bb28511" 591 "4a507004036ae1cf8ae54b25e4db39215abd7e903f618c2d8b2f08cc6cd1" 592 "2dbccd72205e4945b6b3df389e5e43de0a148bb2c84e2431fdbe5920b044" 593 "bb272f45ecff0721b7dfb60397fc613a9ea35c22300530cae8f9159c534d" 594 "f3bf0910951901", 595 16, 596 ) 597 rsa1016_P = int( 598 "0f9f17597c85b8051b9c69afb55ef576c996dbd09047d0ccde5b9d60ea5c" 599 "67fe4fac67be803f4b6ac5a3f050f76b966fb14f5cf105761e5ade6dd960" 600 "b183ba55", 601 16, 602 ) 603 rsa1016_Q = int( 604 "0d7b637112ce61a55168c0f9c9386fb279ab40cba0d549336bba65277263" 605 "aac782611a2c81d9b635cf78c40018859e018c5e9006d12e3d2ee6f346e7" 606 "9fa43369", 607 16, 608 ) 609 rsa1016_exp1 = int( 610 "09fd6c9a3ea6e91ae32070f9fc1c210ff9352f97be5d1eeb951bb39681e9" 611 "dc5b672a532221b3d8900c9a9d99b9d0a4e102dc450ca1b87b0b1389de65" 612 "16c0ae0d", 613 16, 614 ) 615 rsa1016_exp2 = int( 616 "0141b832491b7dd4a83308920024c79cae64bd447df883bb4c5672a96bab" 617 "48b7123b34f26324452cdceb17f21e570e347cbe2fd4c2d8f9910eac2cb6" 618 "d895b8c9", 619 16, 620 ) 621 rsa1016_coef = int( 622 "0458dd6aee18c88b2f9b81f1bc3075ae20dc1f9973d20724f20b06043d61" 623 "47c8789d4a07ae88bc82c8438c893e017b13947f62e0b18958a31eb664b1" 624 "9e64d3e0", 625 16, 626 ) 627 628 def __init__(self, specification): 629 if specification == "default": 630 self.RSA_N = self.sharedRSA_N 631 self.RSA_E = self.sharedRSA_E 632 self.RSA_D = self.sharedRSA_D 633 self.RSA_P = self.sharedRSA_P 634 self.RSA_Q = self.sharedRSA_Q 635 self.RSA_exp1 = self.sharedRSA_exp1 636 self.RSA_exp2 = self.sharedRSA_exp2 637 self.RSA_coef = self.sharedRSA_coef 638 elif specification == "alternate": 639 self.RSA_N = self.alternateRSA_N 640 self.RSA_E = self.alternateRSA_E 641 self.RSA_D = self.alternateRSA_D 642 self.RSA_P = self.alternateRSA_P 643 self.RSA_Q = self.alternateRSA_Q 644 self.RSA_exp1 = self.alternateRSA_exp1 645 self.RSA_exp2 = self.alternateRSA_exp2 646 self.RSA_coef = self.alternateRSA_coef 647 elif specification == "ev": 648 self.RSA_N = self.evRSA_N 649 self.RSA_E = self.evRSA_E 650 self.RSA_D = self.evRSA_D 651 self.RSA_P = self.evRSA_P 652 self.RSA_Q = self.evRSA_Q 653 self.RSA_exp1 = self.evRSA_exp1 654 self.RSA_exp2 = self.evRSA_exp2 655 self.RSA_coef = self.evRSA_coef 656 elif specification == "evRSA2040": 657 self.RSA_N = self.evRSA2040_N 658 self.RSA_E = self.evRSA2040_E 659 self.RSA_D = self.evRSA2040_D 660 self.RSA_P = self.evRSA2040_P 661 self.RSA_Q = self.evRSA2040_Q 662 self.RSA_exp1 = self.evRSA2040_exp1 663 self.RSA_exp2 = self.evRSA2040_exp2 664 self.RSA_coef = self.evRSA2040_coef 665 elif specification == "rsa2040": 666 self.RSA_N = self.rsa2040_N 667 self.RSA_E = self.rsa2040_E 668 self.RSA_D = self.rsa2040_D 669 self.RSA_P = self.rsa2040_P 670 self.RSA_Q = self.rsa2040_Q 671 self.RSA_exp1 = self.rsa2040_exp1 672 self.RSA_exp2 = self.rsa2040_exp2 673 self.RSA_coef = self.rsa2040_coef 674 elif specification == "rsa1024": 675 self.RSA_N = self.rsa1024_N 676 self.RSA_E = self.rsa1024_E 677 self.RSA_D = self.rsa1024_D 678 self.RSA_P = self.rsa1024_P 679 self.RSA_Q = self.rsa1024_Q 680 self.RSA_exp1 = self.rsa1024_exp1 681 self.RSA_exp2 = self.rsa1024_exp2 682 self.RSA_coef = self.rsa1024_coef 683 elif specification == "rsa1016": 684 self.RSA_N = self.rsa1016_N 685 self.RSA_E = self.rsa1016_E 686 self.RSA_D = self.rsa1016_D 687 self.RSA_P = self.rsa1016_P 688 self.RSA_Q = self.rsa1016_Q 689 self.RSA_exp1 = self.rsa1016_exp1 690 self.RSA_exp2 = self.rsa1016_exp2 691 self.RSA_coef = self.rsa1016_coef 692 else: 693 raise UnknownKeySpecificationError(specification) 694 695 def toDER(self): 696 privateKeyInfo = PrivateKeyInfo() 697 privateKeyInfo["version"] = 0 698 algorithmIdentifier = rfc2459.AlgorithmIdentifier() 699 algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption 700 # Directly setting parameters to univ.Null doesn't currently work. 701 nullEncapsulated = encoder.encode(univ.Null()) 702 algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) 703 privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier 704 rsaPrivateKey = RSAPrivateKey() 705 rsaPrivateKey["version"] = 0 706 rsaPrivateKey["modulus"] = self.RSA_N 707 rsaPrivateKey["publicExponent"] = self.RSA_E 708 rsaPrivateKey["privateExponent"] = self.RSA_D 709 rsaPrivateKey["prime1"] = self.RSA_P 710 rsaPrivateKey["prime2"] = self.RSA_Q 711 rsaPrivateKey["exponent1"] = self.RSA_exp1 712 rsaPrivateKey["exponent2"] = self.RSA_exp2 713 rsaPrivateKey["coefficient"] = self.RSA_coef 714 rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) 715 privateKeyInfo["privateKey"] = univ.OctetString(rsaPrivateKeyEncoded) 716 return encoder.encode(privateKeyInfo) 717 718 def toPEM(self): 719 output = "-----BEGIN PRIVATE KEY-----" 720 der = self.toDER() 721 b64 = base64.b64encode(der).decode() 722 while b64: 723 output += "\n" + b64[:64] 724 b64 = b64[64:] 725 output += "\n-----END PRIVATE KEY-----" 726 return output 727 728 def asSubjectPublicKeyInfo(self): 729 """Returns a subject public key info representing 730 this key for use by pyasn1.""" 731 algorithmIdentifier = rfc2459.AlgorithmIdentifier() 732 algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption 733 # Directly setting parameters to univ.Null doesn't currently work. 734 nullEncapsulated = encoder.encode(univ.Null()) 735 algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) 736 spki = rfc2459.SubjectPublicKeyInfo() 737 spki["algorithm"] = algorithmIdentifier 738 rsaKey = RSAPublicKey() 739 rsaKey["N"] = univ.Integer(self.RSA_N) 740 rsaKey["E"] = univ.Integer(self.RSA_E) 741 subjectPublicKey = univ.BitString( 742 byteStringToHexifiedBitString(encoder.encode(rsaKey)) 743 ) 744 spki["subjectPublicKey"] = subjectPublicKey 745 return spki 746 747 def sign(self, data, hashAlgorithm): 748 """Returns a hexified bit string representing a 749 signature by this key over the specified data. 750 Intended for use with pyasn1.type.univ.BitString""" 751 hashAlgorithmName = None 752 if hashAlgorithm == HASH_MD5: 753 hashAlgorithmName = "MD5" 754 elif hashAlgorithm == HASH_SHA1: 755 hashAlgorithmName = "SHA-1" 756 elif hashAlgorithm == HASH_SHA256: 757 hashAlgorithmName = "SHA-256" 758 elif hashAlgorithm == HASH_SHA384: 759 hashAlgorithmName = "SHA-384" 760 elif hashAlgorithm == HASH_SHA512: 761 hashAlgorithmName = "SHA-512" 762 else: 763 raise UnknownHashAlgorithmError(hashAlgorithm) 764 rsaPrivateKey = rsa.PrivateKey( 765 self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q 766 ) 767 signature = rsa.sign(data, rsaPrivateKey, hashAlgorithmName) 768 return byteStringToHexifiedBitString(signature) 769 770 771 ecPublicKey = univ.ObjectIdentifier("1.2.840.10045.2.1") 772 secp256k1 = univ.ObjectIdentifier("1.3.132.0.10") 773 secp224r1 = univ.ObjectIdentifier("1.3.132.0.33") 774 secp256r1 = univ.ObjectIdentifier("1.2.840.10045.3.1.7") 775 secp384r1 = univ.ObjectIdentifier("1.3.132.0.34") 776 secp521r1 = univ.ObjectIdentifier("1.3.132.0.35") 777 778 779 def longToEvenLengthHexString(val): 780 h = format(val, "x") 781 if not len(h) % 2 == 0: 782 h = "0" + h 783 return h 784 785 786 class ECCKey: 787 secp256k1KeyPair = ( 788 "35ee7c7289d8fef7a86afe5da66d8bc2ebb6a8543fd2fead089f45ce7acd0fa6" 789 + "4382a9500c41dad770ffd4b511bf4b492eb1238800c32c4f76c73a3f3294e7c5", 790 "67cebc208a5fa3df16ec2bb34acc59a42ab4abb0538575ca99b92b6a2149a04f", 791 ) 792 793 secp224r1KeyPair = ( 794 "668d72cca6fd6a1b3557b5366104d84408ecb637f08e8c86bbff82cc" 795 + "00e88f0066d7af63c3298ba377348a1202b03b37fd6b1ff415aa311e", 796 "04389459926c3296c242b83e10a6cd2011c8fe2dae1b772ea5b21067", 797 ) 798 799 secp256r1KeyPair = ( 800 "4fbfbbbb61e0f8f9b1a60a59ac8704e2ec050b423e3cf72e923f2c4f794b455c" 801 + "2a69d233456c36c4119d0706e00eedc8d19390d7991b7b2d07a304eaa04aa6c0", 802 "2191403d5710bf15a265818cd42ed6fedf09add92d78b18e7a1e9feb95524702", 803 ) 804 805 secp384r1KeyPair = ( 806 "a1687243362b5c7b1889f379154615a1c73fb48dee863e022915db608e252de4b71" 807 + "32da8ce98e831534e6a9c0c0b09c8d639ade83206e5ba813473a11fa330e05da8c9" 808 + "6e4383fe27873da97103be2888cff002f05af71a1fddcc8374aa6ea9ce", 809 "035c7a1b10d9fafe837b64ad92f22f5ced0789186538669b5c6d872cec3d926122b" 810 + "393772b57602ff31365efe1393246", 811 ) 812 813 secp521r1KeyPair = ( 814 "014cdc9cacc47941096bc9cc66752ec27f597734fa66c62b792f88c519d6d37f0d1" 815 + "6ea1c483a1827a010b9128e3a08070ca33ef5f57835b7c1ba251f6cc3521dc42b01" 816 + "0653451981b445d343eed3782a35d6cff0ff484f5a883d209f1b9042b726703568b" 817 + "2f326e18b833bdd8aa0734392bcd19501e10d698a79f53e11e0a22bdd2aad90", 818 "014f3284fa698dd9fe1118dd331851cdfaac5a3829278eb8994839de9471c940b85" 819 + "8c69d2d05e8c01788a7d0b6e235aa5e783fc1bee807dcc3865f920e12cf8f2d29", 820 ) 821 822 def __init__(self, specification): 823 if specification == "secp256k1": 824 key_pair = self.secp256k1KeyPair 825 self.keyOID = secp256k1 826 self.curve = ecdsa.SECP256k1 827 elif specification == "secp224r1": 828 key_pair = self.secp224r1KeyPair 829 self.keyOID = secp224r1 830 self.curve = ecdsa.NIST224p 831 elif specification == "secp256r1": 832 key_pair = self.secp256r1KeyPair 833 self.keyOID = secp256r1 834 self.curve = ecdsa.NIST256p 835 elif specification == "secp384r1": 836 key_pair = self.secp384r1KeyPair 837 self.keyOID = secp384r1 838 self.curve = ecdsa.NIST384p 839 elif specification == "secp521r1": 840 key_pair = self.secp521r1KeyPair 841 self.keyOID = secp521r1 842 self.curve = ecdsa.NIST521p 843 else: 844 raise UnknownKeySpecificationError(specification) 845 846 self.public_key, self.private_key = ( 847 binascii.unhexlify(key_pair[0]), 848 binascii.unhexlify(key_pair[1]), 849 ) 850 self.key = ecdsa.SigningKey.from_string(self.private_key, curve=self.curve) 851 852 def getPublicKeyHexifiedString(self): 853 """Returns the EC public key as a hex string using the uncompressed 854 point representation. This is intended to be used in the encoder 855 functions, as it surrounds the value with ''H to indicate its type.""" 856 p1, p2 = ( 857 self.public_key[: len(self.public_key) // 2], 858 self.public_key[len(self.public_key) // 2 :], 859 ) 860 # We don't want leading zeroes. 861 p1, p2 = (p1.lstrip(b"\0"), p2.lstrip(b"\0")) 862 # '04' indicates that the points are in uncompressed form. 863 return byteStringToHexifiedBitString(b"\04" + p1 + p2) 864 865 def toPEM(self): 866 """Return the EC private key in PEM-encoded form.""" 867 output = "-----BEGIN EC PRIVATE KEY-----" 868 der = self.toDER() 869 b64 = base64.b64encode(der).decode() 870 while b64: 871 output += "\n" + b64[:64] 872 b64 = b64[64:] 873 output += "\n-----END EC PRIVATE KEY-----" 874 return output 875 876 def toDER(self): 877 """Return the EC private key in DER-encoded form, encoded per SEC 1 878 section C.4 format.""" 879 privateKeyInfo = PrivateKeyInfo() 880 privateKeyInfo["version"] = 0 881 algorithmIdentifier = rfc2459.AlgorithmIdentifier() 882 algorithmIdentifier["algorithm"] = ecPublicKey 883 algorithmIdentifier["parameters"] = self.keyOID 884 privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier 885 ecPrivateKey = ECPrivateKey() 886 ecPrivateKey["version"] = 1 887 ecPrivateKey["privateKey"] = self.private_key 888 ecPrivateKey["publicKey"] = univ.BitString( 889 self.getPublicKeyHexifiedString() 890 ).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 891 ecPrivateKeyEncoded = encoder.encode(ecPrivateKey) 892 privateKeyInfo["privateKey"] = univ.OctetString(ecPrivateKeyEncoded) 893 return encoder.encode(privateKeyInfo) 894 895 def asSubjectPublicKeyInfo(self): 896 """Returns a subject public key info representing 897 this key for use by pyasn1.""" 898 algorithmIdentifier = rfc2459.AlgorithmIdentifier() 899 algorithmIdentifier["algorithm"] = ecPublicKey 900 algorithmIdentifier["parameters"] = self.keyOID 901 spki = rfc2459.SubjectPublicKeyInfo() 902 spki["algorithm"] = algorithmIdentifier 903 spki["subjectPublicKey"] = univ.BitString(self.getPublicKeyHexifiedString()) 904 return spki 905 906 def signRaw(self, data, hashAlgorithm): 907 """Performs the ECDSA signature algorithm over the given data. 908 The returned value is a string representing the bytes of the 909 resulting point when encoded by left-padding each of (r, s) to 910 the key size and concatenating them. 911 """ 912 assert hashAlgorithm.startswith("hash:") 913 hashAlgorithm = hashAlgorithm[len("hash:") :] 914 k = _gen_k(self.curve) 915 digest = hashlib.new(hashAlgorithm, data).digest() 916 digest = _truncate_digest(digest, self.curve) 917 # NOTE: Under normal circumstances it's advisable to use 918 # sign_digest_deterministic. In this case we don't want the library's 919 # default generation of k, so we call the normal "sign" method and 920 # inject it here. 921 return self.key.sign_digest(digest, sigencode=ecdsa.util.sigencode_string, k=k) 922 923 def sign(self, data, hashAlgorithm): 924 """Returns a hexified bit string representing a 925 signature by this key over the specified data. 926 Intended for use with pyasn1.type.univ.BitString""" 927 # signRaw returns an encoded point, which is useful in some situations. 928 # However, for signatures on X509 certificates, we need to decode it so 929 # we can encode it as a BITSTRING consisting of a SEQUENCE of two 930 # INTEGERs. 931 raw = self.signRaw(data, hashAlgorithm) 932 point = ECPoint() 933 point["x"] = int.from_bytes(raw[: len(raw) // 2], byteorder="big") 934 point["y"] = int.from_bytes(raw[len(raw) // 2 :], byteorder="big") 935 return byteStringToHexifiedBitString(encoder.encode(point)) 936 937 938 def keyFromSpecification(specification): 939 """Pass in a specification, get the appropriate key back.""" 940 if specification.startswith("secp"): 941 return ECCKey(specification) 942 return RSAKey(specification) 943 944 945 # The build harness will call this function with an output file-like 946 # object and a path to a file containing a specification. This will 947 # read the specification and output the key as ASCII-encoded PKCS #8. 948 def main(output, inputPath): 949 with open(inputPath) as configStream: 950 output.write(keyFromSpecification(configStream.read().strip()).toPEM() + "\n") 951 952 953 # When run as a standalone program, this will read a specification from 954 # stdin and output the certificate as PEM to stdout. 955 if __name__ == "__main__": 956 print(keyFromSpecification(sys.stdin.read().strip()).toPEM())