[RSA] New methods:

- .make_key()
- .encode_key()
pull/7/head
Daniele Lacamera 2019-09-03 18:40:42 +02:00
parent fda3889766
commit 44b5002dfe
3 changed files with 60 additions and 16 deletions

View File

@ -130,6 +130,10 @@ ffi.cdef(
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
int wc_FreeRsaKey(RsaKey* key);
int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng);
int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen);
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen);
int wc_RsaPrivateKeyDecode(const byte*, word32*, RsaKey*, word32);
int wc_RsaPublicKeyDecode(const byte*, word32*, RsaKey*, word32);
int wc_RsaEncryptSize(RsaKey*);

View File

@ -273,20 +273,21 @@ class _Rsa(object): # pylint: disable=too-few-public-methods
class RsaPublic(_Rsa):
def __init__(self, key):
key = t2b(key)
def __init__(self, key=None):
if key != None:
key = t2b(key)
_Rsa.__init__(self)
idx = _ffi.new("word32*")
idx[0] = 0
ret = _lib.wc_RsaPublicKeyDecode(key, idx,
self.native_object, len(key))
self.native_object, len(key))
if ret < 0:
raise WolfCryptError("Invalid key error (%d)" % ret)
self.output_size = _lib.wc_RsaEncryptSize(self.native_object)
self.size = len(key)
if self.output_size <= 0: # pragma: no cover
raise WolfCryptError("Invalid key error (%d)" % self.output_size)
@ -336,22 +337,61 @@ class RsaPublic(_Rsa):
class RsaPrivate(RsaPublic):
def __init__(self, key): # pylint: disable=super-init-not-called
key = t2b(key)
@classmethod
def make_key(cls, size, rng=Random()):
"""
Generates a new key pair of desired length **size**.
"""
rsa = cls(None)
if rsa == None: # pragma: no cover
raise WolfCryptError("Invalid key error (%d)" % ret)
ret = _lib.wc_MakeRsaKey(rsa.native_object, size, 65537, rng.native_object)
if ret < 0:
raise WolfCryptError("Key generation error (%d)" % ret)
rsa.output_size = _lib.wc_RsaEncryptSize(rsa.native_object)
rsa.size = size
if rsa.output_size <= 0: # pragma: no cover
raise WolfCryptError("Invalid key size error (%d)" % rsa.output_size)
return rsa
def __init__(self, key = None): # pylint: disable=super-init-not-called
_Rsa.__init__(self) # pylint: disable=non-parent-init-called
idx = _ffi.new("word32*")
idx[0] = 0
ret = _lib.wc_RsaPrivateKeyDecode(key, idx,
self.native_object, len(key))
if ret < 0:
raise WolfCryptError("Invalid key error (%d)" % ret)
if key != None:
key = t2b(key)
ret = _lib.wc_RsaPrivateKeyDecode(key, idx,
self.native_object, len(key))
if ret < 0:
raise WolfCryptError("Invalid key error (%d)" % ret)
self.output_size = _lib.wc_RsaEncryptSize(self.native_object)
if self.output_size <= 0: # pragma: no cover
raise WolfCryptError("Invalid key error (%d)" % self.output_size)
self.size = len(key)
self.output_size = _lib.wc_RsaEncryptSize(self.native_object)
if self.output_size <= 0: # pragma: no cover
raise WolfCryptError("Invalid key size error (%d)" % self.output_size)
def encode_key(self):
"""
Encodes the RSA private and public keys in an ASN sequence.
Returns the encoded key.
"""
priv = _ffi.new("byte[%d]" % (self.size * 4))
pub = _ffi.new("byte[%d]" % (self.size * 4))
ret = _lib.wc_RsaKeyToDer(self.native_object, priv, self.size)
if ret <= 0: # pragma: no cover
raise WolfCryptError("Private RSA key error (%d)" % ret)
privlen = ret
ret = _lib.wc_RsaKeyToPublicDer(self.native_object, pub, self.size)
if ret <= 0: # pragma: no cover
raise WolfCryptError("Public RSA key encode error (%d)" % ret)
publen = ret
return _ffi.buffer(priv, privlen)[:], _ffi.buffer(pub, publen)[:]
def decrypt(self, ciphertext):
"""

View File

@ -213,6 +213,9 @@ def test_new_rsa_raises(vectors):
with pytest.raises(WolfCryptError):
RsaPublic(vectors[RsaPublic].key[:-1]) # invalid key length
with pytest.raises(WolfCryptError): # invalid key size
RsaPrivate.make_key(16384)
def test_rsa_encrypt_decrypt(rsa_private, rsa_public):
plaintext = t2b("Everyone gets Friday off.")
@ -247,17 +250,14 @@ def test_rsa_sign_verify(rsa_private, rsa_public):
assert 1024 / 8 == len(signature) == rsa_private.output_size
assert plaintext == rsa_private.verify(signature)
@pytest.fixture
def ecc_private(vectors):
return EccPrivate(vectors[EccPrivate].key)
@pytest.fixture
def ecc_public(vectors):
return EccPublic(vectors[EccPublic].key)
def test_new_ecc_raises(vectors):
with pytest.raises(WolfCryptError):
EccPrivate(vectors[EccPrivate].key[:-1]) # invalid key length