diff options
author | Mohammed Attia <skeuomorf@gmail.com> | 2014-03-06 02:08:07 +0200 |
---|---|---|
committer | Mohammed Attia <skeuomorf@gmail.com> | 2014-04-02 04:49:54 +0200 |
commit | 3677eaf1fcb12f2746e2444020716eb8dc223857 (patch) | |
tree | 5861ceb08c011698af84e220249c2c7c6f7db76c | |
parent | 550f1739d88e8a40a905797544af21dd83bec477 (diff) | |
download | cryptography-3677eaf1fcb12f2746e2444020716eb8dc223857.tar.gz cryptography-3677eaf1fcb12f2746e2444020716eb8dc223857.tar.bz2 cryptography-3677eaf1fcb12f2746e2444020716eb8dc223857.zip |
Add basic DSA backend methods
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 3293741c..370a6515 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -29,7 +29,7 @@ from cryptography.hazmat.backends.interfaces import ( ) from cryptography.hazmat.bindings.openssl.binding import Binding from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.asymmetric import rsa, dsa from cryptography.hazmat.primitives.asymmetric.padding import ( MGF1, PKCS1v15, PSS ) @@ -409,13 +409,79 @@ class Backend(object): return _RSAVerificationContext(self, public_key, signature, padding, algorithm) + def generate_dsa_parameters(self, key_size, ctx=None): + if key_size not in [1024, 2048, 3072]: + raise ValueError("Key size must be 1024 or 2048 or" + "3072 bits") + + if ctx is None: + ctx = self._lib.DSA_new() + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.DSA_free) + + res = self._lib.DSA_generate_parameters_ex( + ctx, key_size, self._ffi.NULL, self._ffi.NULL, + self._ffi.NULL, self._ffi.NULL + ) + + assert res == 1 + + return dsa.DSAParams( + modulus=self._bn_to_int(ctx.p), + subroup_order=self._bn_to_int(ctx.q), + generator=self._bn_to_int(ctx.g) + ) + + def generate_dsa_private_key(self, parameters, key_size): + ctx = self._lib.DSA_new() + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.DSA_free) + if all([parameters.p, parameters.q, parameters.g]): + if ctx.p not in [1024, 2048, 3072]: + raise ValueError("Prime Modulus length must be 1024 or 2048 or" + "3072 bits") + + if ctx.q not in [160, 256]: + raise ValueError("Subgroup order length must be 160 or" + "256 bits") + + if (ctx.p, ctx.q) not in [ + (1024, 160), + (2048, 256), + (3072, 256)]: + raise ValueError("Prime Modulus and Subgroup order lengths" + "must be one of these pairs (1024, 160)" + "or (2048, 256) or (3072, 256)") + + if ctx.g <= 1 or ctx.g >= ctx.p: + raise ValueError("Generator must be > 1 and < Prime Modulus") + + ctx.p = self._int_to_bn(parameters.p) + ctx.q = self._int_to_bn(parameters.q) + ctx.g = self._int_to_bn(parameters.g) + + else: + if key_size not in [1024, 2048, 3072]: + raise ValueError("Key size must be 1024 or 2048 or" + "3072 bits") + self.generate_dsa_parameters(key_size, ctx) + + self._lib.DSA_generate_key(ctx) + + return dsa.DSAPrivateKey( + modulus=self._bn_to_int(ctx.p), + subgroup_order=self._bn_to_int(ctx.q), + generator=self._bn_to_int(ctx.g), + x=self._bn_to_int(ctx.priv_key), + y=self._bn_to_int(ctx.pub_key) + ) + def mgf1_hash_supported(self, algorithm): if self._lib.Cryptography_HAS_MGF1_MD: return self.hash_supported(algorithm) else: return isinstance(algorithm, hashes.SHA1) - class GetCipherByName(object): def __init__(self, fmt): self._fmt = fmt |