tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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())