Skip to content

Commit

Permalink
Speed-up import of RSA and ECC
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Nov 1, 2019
1 parent 2600a0c commit f9087a6
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
14 changes: 13 additions & 1 deletion lib/Crypto/PublicKey/ECC.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
from Crypto.Util.asn1 import (DerObjectId, DerOctetString, DerSequence,
DerBitString)

from Crypto.IO import PKCS8, PEM
from Crypto.PublicKey import (_expand_subject_public_key_info,
_create_subject_public_key_info,
_extract_subject_public_key_info)
Expand Down Expand Up @@ -589,6 +588,8 @@ def _export_private_der(self, include_ec_params=True):
return DerSequence(seq).encode()

def _export_pkcs8(self, **kwargs):
from Crypto.IO import PKCS8

if kwargs.get('passphrase', None) is not None and 'protection' not in kwargs:
raise ValueError("At least the 'protection' parameter should be present")

Expand All @@ -601,18 +602,26 @@ def _export_pkcs8(self, **kwargs):
return result

def _export_public_pem(self, compress):
from Crypto.IO import PEM

encoded_der = self._export_subjectPublicKeyInfo(compress)
return PEM.encode(encoded_der, "PUBLIC KEY")

def _export_private_pem(self, passphrase, **kwargs):
from Crypto.IO import PEM

encoded_der = self._export_private_der()
return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs)

def _export_private_clear_pkcs8_in_clear_pem(self):
from Crypto.IO import PEM

encoded_der = self._export_pkcs8()
return PEM.encode(encoded_der, "PRIVATE KEY")

def _export_private_encrypted_pkcs8_in_clear_pem(self, passphrase, **kwargs):
from Crypto.IO import PEM

assert passphrase
if 'protection' not in kwargs:
raise ValueError("At least the 'protection' parameter should be present")
Expand Down Expand Up @@ -950,6 +959,7 @@ def _import_private_der(encoded, passphrase, curve_oid=None):


def _import_pkcs8(encoded, passphrase):
from Crypto.IO import PKCS8

# From RFC5915, Section 1:
#
Expand Down Expand Up @@ -1106,6 +1116,8 @@ def import_key(encoded, passphrase=None):
.. _`OpenSSH 6.5+`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf
"""

from Crypto.IO import PEM

encoded = tobytes(encoded)
if passphrase is not None:
passphrase = tobytes(passphrase)
Expand Down
9 changes: 8 additions & 1 deletion lib/Crypto/PublicKey/RSA.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import struct

from Crypto import Random
from Crypto.IO import PKCS8, PEM
from Crypto.Util.py3compat import tobytes, bord, tostr
from Crypto.Util.asn1 import DerSequence

Expand Down Expand Up @@ -333,6 +332,8 @@ def export_key(self, format='PEM', passphrase=None, pkcs=1,
if format == 'DER' and passphrase:
raise ValueError("PKCS#1 private key cannot be encrypted")
else: # PKCS#8
from Crypto.IO import PKCS8

if format == 'PEM' and protection is None:
key_type = 'PRIVATE KEY'
binary_key = PKCS8.wrap(binary_key, oid, None)
Expand All @@ -353,6 +354,8 @@ def export_key(self, format='PEM', passphrase=None, pkcs=1,
if format == 'DER':
return binary_key
if format == 'PEM':
from Crypto.IO import PEM

pem_str = PEM.encode(binary_key, key_type, passphrase, randfunc)
return tobytes(pem_str)

Expand Down Expand Up @@ -652,6 +655,8 @@ def _import_x509_cert(encoded, *kwargs):


def _import_pkcs8(encoded, passphrase):
from Crypto.IO import PKCS8

k = PKCS8.unwrap(encoded, passphrase)
if k[0] != oid:
raise ValueError("No PKCS#8 encoded RSA key")
Expand Down Expand Up @@ -741,6 +746,8 @@ def import_key(extern_key, passphrase=None):
.. _`OpenSSH 6.5`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf
"""

from Crypto.IO import PEM

extern_key = tobytes(extern_key)
if passphrase is not None:
passphrase = tobytes(passphrase)
Expand Down
3 changes: 1 addition & 2 deletions lib/Crypto/Util/_raw_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

import abc
import sys
import platform
from Crypto.Util.py3compat import byte_string
from Crypto.Util._file_system import pycryptodome_filename

Expand Down Expand Up @@ -79,7 +78,7 @@ def address_of(self):
# Note that PyPy ships with an old version of pycparser so we can keep
# using cffi there.
# See https://github.com/Legrandin/pycryptodome/issues/228
if platform.python_implementation() != "PyPy" and sys.flags.optimize == 2:
if '__pypy__' not in sys.builtin_module_names and sys.flags.optimize == 2:
raise ImportError("CFFI with optimize=2 fails due to pycparser bug.")

from cffi import FFI
Expand Down

0 comments on commit f9087a6

Please sign in to comment.