/usr/lib/python2.7/dist-packages/M2Crypto/EC.py is in python-m2crypto 0.27.0-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | from __future__ import absolute_import
"""
M2Crypto wrapper for OpenSSL ECDH/ECDSA API.
@requires: OpenSSL 0.9.8 or newer
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
All rights reserved."""
from M2Crypto import BIO, m2, util
if util.py27plus:
from typing import AnyStr, Callable, Dict, Optional, Tuple, Union # noqa
EC_Key = bytes
class ECError(Exception):
pass
m2.ec_init(ECError)
# Curve identifier constants
NID_secp112r1 = m2.NID_secp112r1 # type: int
NID_secp112r2 = m2.NID_secp112r2 # type: int
NID_secp128r1 = m2.NID_secp128r1 # type: int
NID_secp128r2 = m2.NID_secp128r2 # type: int
NID_secp160k1 = m2.NID_secp160k1 # type: int
NID_secp160r1 = m2.NID_secp160r1 # type: int
NID_secp160r2 = m2.NID_secp160r2 # type: int
NID_secp192k1 = m2.NID_secp192k1 # type: int
NID_secp224k1 = m2.NID_secp224k1 # type: int
NID_secp224r1 = m2.NID_secp224r1 # type: int
NID_secp256k1 = m2.NID_secp256k1 # type: int
NID_secp384r1 = m2.NID_secp384r1 # type: int
NID_secp521r1 = m2.NID_secp521r1 # type: int
NID_sect113r1 = m2.NID_sect113r1 # type: int
NID_sect113r2 = m2.NID_sect113r2 # type: int
NID_sect131r1 = m2.NID_sect131r1 # type: int
NID_sect131r2 = m2.NID_sect131r2 # type: int
NID_sect163k1 = m2.NID_sect163k1 # type: int
NID_sect163r1 = m2.NID_sect163r1 # type: int
NID_sect163r2 = m2.NID_sect163r2 # type: int
NID_sect193r1 = m2.NID_sect193r1 # type: int
NID_sect193r2 = m2.NID_sect193r2 # type: int
# default for secg.org TLS test server
NID_sect233k1 = m2.NID_sect233k1 # type: int
NID_sect233r1 = m2.NID_sect233r1 # type: int
NID_sect239k1 = m2.NID_sect239k1 # type: int
NID_sect283k1 = m2.NID_sect283k1 # type: int
NID_sect283r1 = m2.NID_sect283r1 # type: int
NID_sect409k1 = m2.NID_sect409k1 # type: int
NID_sect409r1 = m2.NID_sect409r1 # type: int
NID_sect571k1 = m2.NID_sect571k1 # type: int
NID_sect571r1 = m2.NID_sect571r1 # type: int
NID_prime192v1 = m2.NID_X9_62_prime192v1 # type: int
NID_prime192v2 = m2.NID_X9_62_prime192v2 # type: int
NID_prime192v3 = m2.NID_X9_62_prime192v3 # type: int
NID_prime239v1 = m2.NID_X9_62_prime239v1 # type: int
NID_prime239v2 = m2.NID_X9_62_prime239v2 # type: int
NID_prime239v3 = m2.NID_X9_62_prime239v3 # type: int
NID_prime256v1 = m2.NID_X9_62_prime256v1 # type: int
NID_c2pnb163v1 = m2.NID_X9_62_c2pnb163v1 # type: int
NID_c2pnb163v2 = m2.NID_X9_62_c2pnb163v2 # type: int
NID_c2pnb163v3 = m2.NID_X9_62_c2pnb163v3 # type: int
NID_c2pnb176v1 = m2.NID_X9_62_c2pnb176v1 # type: int
NID_c2tnb191v1 = m2.NID_X9_62_c2tnb191v1 # type: int
NID_c2tnb191v2 = m2.NID_X9_62_c2tnb191v2 # type: int
NID_c2tnb191v3 = m2.NID_X9_62_c2tnb191v3 # type: int
NID_c2pnb208w1 = m2.NID_X9_62_c2pnb208w1 # type: int
NID_c2tnb239v1 = m2.NID_X9_62_c2tnb239v1 # type: int
NID_c2tnb239v2 = m2.NID_X9_62_c2tnb239v2 # type: int
NID_c2tnb239v3 = m2.NID_X9_62_c2tnb239v3 # type: int
NID_c2pnb272w1 = m2.NID_X9_62_c2pnb272w1 # type: int
NID_c2pnb304w1 = m2.NID_X9_62_c2pnb304w1 # type: int
NID_c2tnb359v1 = m2.NID_X9_62_c2tnb359v1 # type: int
NID_c2pnb368w1 = m2.NID_X9_62_c2pnb368w1 # type: int
NID_c2tnb431r1 = m2.NID_X9_62_c2tnb431r1 # type: int
# To preserve compatibility with older names
NID_X9_62_prime192v1 = NID_prime192v1 # type: int
NID_X9_62_prime192v2 = NID_prime192v2 # type: int
NID_X9_62_prime192v3 = NID_prime192v3 # type: int
NID_X9_62_prime239v1 = NID_prime239v1 # type: int
NID_X9_62_prime239v2 = NID_prime239v2 # type: int
NID_X9_62_prime239v3 = NID_prime239v3 # type: int
NID_X9_62_prime256v1 = NID_prime256v1 # type: int
NID_X9_62_c2pnb163v1 = NID_c2pnb163v1 # type: int
NID_X9_62_c2pnb163v2 = NID_c2pnb163v2 # type: int
NID_X9_62_c2pnb163v3 = NID_c2pnb163v3 # type: int
NID_X9_62_c2pnb176v1 = NID_c2pnb176v1 # type: int
NID_X9_62_c2tnb191v1 = NID_c2tnb191v1 # type: int
NID_X9_62_c2tnb191v2 = NID_c2tnb191v2 # type: int
NID_X9_62_c2tnb191v3 = NID_c2tnb191v3 # type: int
NID_X9_62_c2pnb208w1 = NID_c2pnb208w1 # type: int
NID_X9_62_c2tnb239v1 = NID_c2tnb239v1 # type: int
NID_X9_62_c2tnb239v2 = NID_c2tnb239v2 # type: int
NID_X9_62_c2tnb239v3 = NID_c2tnb239v3 # type: int
NID_X9_62_c2pnb272w1 = NID_c2pnb272w1 # type: int
NID_X9_62_c2pnb304w1 = NID_c2pnb304w1 # type: int
NID_X9_62_c2tnb359v1 = NID_c2tnb359v1 # type: int
NID_X9_62_c2pnb368w1 = NID_c2pnb368w1 # type: int
NID_X9_62_c2tnb431r1 = NID_c2tnb431r1 # type: int
NID_wap_wsg_idm_ecid_wtls1 = m2.NID_wap_wsg_idm_ecid_wtls1 # type: int
NID_wap_wsg_idm_ecid_wtls3 = m2.NID_wap_wsg_idm_ecid_wtls3 # type: int
NID_wap_wsg_idm_ecid_wtls4 = m2.NID_wap_wsg_idm_ecid_wtls4 # type: int
NID_wap_wsg_idm_ecid_wtls5 = m2.NID_wap_wsg_idm_ecid_wtls5 # type: int
NID_wap_wsg_idm_ecid_wtls6 = m2.NID_wap_wsg_idm_ecid_wtls6 # type: int
NID_wap_wsg_idm_ecid_wtls7 = m2.NID_wap_wsg_idm_ecid_wtls7 # type: int
NID_wap_wsg_idm_ecid_wtls8 = m2.NID_wap_wsg_idm_ecid_wtls8 # type: int
NID_wap_wsg_idm_ecid_wtls9 = m2.NID_wap_wsg_idm_ecid_wtls9 # type: int
NID_wap_wsg_idm_ecid_wtls10 = m2.NID_wap_wsg_idm_ecid_wtls10 # type: int
NID_wap_wsg_idm_ecid_wtls11 = m2.NID_wap_wsg_idm_ecid_wtls11 # type: int
NID_wap_wsg_idm_ecid_wtls12 = m2.NID_wap_wsg_idm_ecid_wtls12 # type: int
# The following two curves, according to OpenSSL, have a
# "Questionable extension field!" and are not supported by
# the OpenSSL inverse function. ECError: no inverse.
# As such they cannot be used for signing. They might,
# however, be usable for encryption but that has not
# been tested. Until thir usefulness can be established,
# they are not supported at this time.
# NID_ipsec3 = m2.NID_ipsec3
# NID_ipsec4 = m2.NID_ipsec4
class EC:
"""
Object interface to a EC key pair.
"""
m2_ec_key_free = m2.ec_key_free
def __init__(self, ec, _pyfree=0):
# type: (EC, int) -> None
assert m2.ec_key_type_check(ec), "'ec' type error"
self.ec = ec
self._pyfree = _pyfree
def __del__(self):
# type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_ec_key_free(self.ec)
def __len__(self):
# type: () -> int
assert m2.ec_key_type_check(self.ec), "'ec' type error"
return m2.ec_key_keylen(self.ec)
def gen_key(self):
# type: () -> int
"""
Generates the key pair from its parameters. Use::
keypair = EC.gen_params(curve)
keypair.gen_key()
to create an EC key pair.
"""
assert m2.ec_key_type_check(self.ec), "'ec' type error"
m2.ec_key_gen_key(self.ec)
def pub(self):
# type: () -> EC_pub
# Don't let python free
return EC_pub(self.ec, 0)
def sign_dsa(self, digest):
# type: (bytes) -> Tuple[bytes, bytes]
"""
Sign the given digest using ECDSA. Returns a tuple (r,s), the two
ECDSA signature parameters.
"""
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign(self.ec, digest)
def verify_dsa(self, digest, r, s):
# type: (bytes, bytes, bytes) -> int
"""
Verify the given digest using ECDSA. r and s are the ECDSA
signature parameters.
"""
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_verify(self.ec, digest, r, s)
def sign_dsa_asn1(self, digest):
# type: (bytes) -> bytes
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign_asn1(self.ec, digest)
def verify_dsa_asn1(self, digest, blob):
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_verify_asn1(self.ec, digest, blob)
def compute_dh_key(self, pub_key):
# type: (EC) -> Optional[bytes]
"""
Compute the ECDH shared key of this key pair and the given public
key object. They must both use the same curve. Returns the
shared key in binary as a buffer object. No Key Derivation Function is
applied.
"""
assert self.check_key(), 'key is not initialised'
return m2.ecdh_compute_key(self.ec, pub_key.ec)
def save_key_bio(self, bio, cipher='aes_128_cbc',
callback=util.passphrase_callback):
# type: (BIO.BIO, Optional[str], Callable) -> int
"""
Save the key pair to an M2Crypto.BIO.BIO object in PEM format.
:param bio: M2Crypto.BIO.BIO object to save key to.
:param cipher: Symmetric cipher to protect the key. The default
cipher is 'aes_128_cbc'. If cipher is None, then
the key is saved in the clear.
:param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect
the key. The default is
util.passphrase_callback.
"""
if cipher is None:
return m2.ec_key_write_bio_no_cipher(self.ec, bio._ptr(), callback)
else:
ciph = getattr(m2, cipher, None)
if ciph is None:
raise ValueError('not such cipher %s' % cipher)
return m2.ec_key_write_bio(self.ec, bio._ptr(), ciph(), callback)
def save_key(self, file, cipher='aes_128_cbc',
callback=util.passphrase_callback):
# type: (AnyStr, Optional[str], Callable) -> int
"""
Save the key pair to a file in PEM format.
:param file: Name of filename to save key to.
:param cipher: Symmetric cipher to protect the key. The default
cipher is 'aes_128_cbc'. If cipher is None, then
the key is saved in the clear.
:param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect
the key. The default is
util.passphrase_callback.
"""
with BIO.openfile(file, 'wb') as bio:
return self.save_key_bio(bio, cipher, callback)
def save_pub_key_bio(self, bio):
# type: (BIO.BIO) -> int
"""
Save the public key to an M2Crypto.BIO.BIO object in PEM format.
:param bio: M2Crypto.BIO.BIO object to save key to.
"""
return m2.ec_key_write_pubkey(self.ec, bio._ptr())
def save_pub_key(self, file):
# type: (AnyStr) -> int
"""
Save the public key to a filename in PEM format.
:param file: Name of filename to save key to.
"""
with BIO.openfile(file, 'wb') as bio:
return m2.ec_key_write_pubkey(self.ec, bio._ptr())
def as_pem(self, cipher='aes_128_cbc', callback=util.passphrase_callback):
"""
Returns the key(pair) as a string in PEM format.
If no password is passed and the cipher is set
it exits with error
"""
with BIO.MemoryBuffer() as bio:
self.save_key_bio(bio, cipher, callback)
return bio.read()
def _check_key_type(self):
# type: () -> int
return m2.ec_key_type_check(self.ec)
def check_key(self):
# type: () -> int
assert m2.ec_key_type_check(self.ec), "'ec' type error"
return m2.ec_key_check_key(self.ec)
class EC_pub(EC): # noqa
"""
Object interface to an EC public key.
((don't like this implementation inheritance))
"""
def __init__(self, ec, _pyfree=0):
# type: (EC, int) -> None
EC.__init__(self, ec, _pyfree)
self.der = None # type: Optional[bytes]
def get_der(self):
# type: () -> bytes
"""
Returns the public key in DER format as a buffer object.
"""
assert self.check_key(), 'key is not initialised'
if self.der is None:
self.der = m2.ec_key_get_public_der(self.ec)
return self.der
def get_key(self):
# type: () -> bytes
"""
Returns the public key as a byte string.
"""
assert self.check_key(), 'key is not initialised'
return m2.ec_key_get_public_key(self.ec)
save_key = EC.save_pub_key
save_key_bio = EC.save_pub_key_bio
def gen_params(curve):
# type: (int) -> EC
"""
Factory function that generates EC parameters and
instantiates a EC object from the output.
:param curve: This is the OpenSSL nid of the curve to use.
"""
assert curve in [x['NID'] for x in m2.ec_get_builtin_curves()], \
'Elliptic curve %s is not available on this system.' % \
m2.obj_nid2sn(curve)
return EC(m2.ec_key_new_by_curve_name(curve), 1)
def load_key(file, callback=util.passphrase_callback):
# type: (AnyStr, Callable) -> EC
"""
Factory function that instantiates a EC object.
:param file: Names the filename that contains the PEM representation
of the EC key pair.
:param callback: Python callback object that will be invoked
if the EC key pair is passphrase-protected.
"""
with BIO.openfile(file) as bio:
return load_key_bio(bio, callback)
def load_key_string(string, callback=util.passphrase_callback):
# type: (str, Callable) -> EC
"""
Load an EC key pair from a string.
:param string: String containing EC key pair in PEM format.
:param callback: A Python callable object that is invoked
to acquire a passphrase with which to unlock the
key. The default is util.passphrase_callback.
:return: M2Crypto.EC.EC object.
"""
with BIO.MemoryBuffer(string) as bio:
return load_key_bio(bio, callback)
def load_key_bio(bio, callback=util.passphrase_callback):
# type: (BIO.BIO, Callable) -> EC
"""
Factory function that instantiates a EC object.
:param bio: M2Crypto.BIO object that contains the PEM
representation of the EC key pair.
:param callback: Python callback object that will be invoked
if the EC key pair is passphrase-protected.
"""
return EC(m2.ec_key_read_bio(bio._ptr(), callback), 1)
def load_pub_key(file):
# type: (AnyStr) -> EC_pub
"""
Load an EC public key from filename.
:param file: Name of filename containing EC public key in PEM
format.
:return: M2Crypto.EC.EC_pub object.
"""
with BIO.openfile(file) as bio:
return load_pub_key_bio(bio)
def load_key_string_pubkey(string, callback=util.passphrase_callback):
# type: (str, Callable) -> PKey
"""
Load an M2Crypto.EC.PKey from a public key as a string.
:param string: String containing the key in PEM format.
:param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect the
key.
:return: M2Crypto.EC.PKey object.
"""
with BIO.MemoryBuffer(string) as bio:
return load_key_bio_pubkey(bio, callback)
def load_pub_key_bio(bio):
# type: (BIO.BIO) -> EC_pub
"""
Load an EC public key from an M2Crypto.BIO.BIO object.
:param bio: M2Crypto.BIO.BIO object containing EC public key in PEM
format.
:return: M2Crypto.EC.EC_pub object.
"""
ec = m2.ec_key_read_pubkey(bio._ptr())
if ec is None:
ec_error()
return EC_pub(ec, 1)
def ec_error():
# type: () -> ECError
raise ECError(m2.err_reason_error_string(m2.err_get_error()))
def pub_key_from_der(der):
# type: (bytes) -> EC_pub
"""
Create EC_pub from DER.
"""
return EC_pub(m2.ec_key_from_pubkey_der(der), 1)
def pub_key_from_params(curve, bytes):
# type: (bytes, bytes) -> EC_pub
"""
Create EC_pub from curve name and octet string.
"""
return EC_pub(m2.ec_key_from_pubkey_params(curve, bytes), 1)
def get_builtin_curves():
# type: () -> Tuple[Dict[str, Union[int, str]]]
return m2.ec_get_builtin_curves()
|