def __new__(cls, ffdh_name, bases, dct): the_class = super(_FFDHParamsMetaclass, cls).__new__(cls, ffdh_name, bases, dct) if conf.crypto_valid and ffdh_name != "_FFDHParams": pn = DHParameterNumbers(the_class.m, the_class.g) params = pn.parameters(default_backend()) _ffdh_groups[ffdh_name] = [params, the_class.mLen] return the_class
def __init__(self, modulus, generator): """Create a new instance. @type modulus: Union[six.integer_types] @type generator: Union[six.integer_types] """ self.parameter_numbers = DHParameterNumbers(modulus, generator) parameters = self.parameter_numbers.parameters(default_backend()) self.private_key = parameters.generate_private_key()
def create_dh_parameter(): DH_MODULUS = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" \ "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" \ "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" \ "49286651ECE65381FFFFFFFFFFFFFFFF" DH_GENERATOR = 2 return DHParameterNumbers(p=hex_to_long(DH_MODULUS), g=DH_GENERATOR)
def __init__(self, modulus, generator): """Create a new instance. @type modulus: six.text_type, Union[six.integer_types] are deprecated @type generator: six.text_type, Union[six.integer_types] are deprecated """ if isinstance(modulus, six.integer_types): warnings.warn("Modulus should be passed as base64 encoded string.") else: modulus = cryptutil.base64ToLong(modulus) if isinstance(generator, six.integer_types): warnings.warn( "Generator should be passed as base64 encoded string.") else: generator = cryptutil.base64ToLong(generator) self.parameter_numbers = DHParameterNumbers(modulus, generator) parameters = self.parameter_numbers.parameters(default_backend()) self.private_key = parameters.generate_private_key()
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import dh, ec from cryptography.hazmat.primitives import serialization if conf.crypto_valid_advanced: from cryptography.hazmat.primitives.asymmetric import x25519 from cryptography.hazmat.primitives.asymmetric import x448 # We have to start by a dirty hack in order to allow long generators, # which some versions of openssl love to use... if conf.crypto_valid: from cryptography.hazmat.primitives.asymmetric.dh import DHParameterNumbers try: # We test with dummy values whether the size limitation has been removed. # noqa: E501 pn_test = DHParameterNumbers(2, 7) except ValueError: # We get rid of the limitation through the cryptography v1.9 __init__. def DHParameterNumbers__init__hack(self, p, g, q=None): if (not isinstance(p, six.integer_types) or not isinstance(g, six.integer_types)): raise TypeError("p and g must be integers") if q is not None and not isinstance(q, six.integer_types): raise TypeError("q must be integer or None") self._p = p self._g = g self._q = q DHParameterNumbers.__init__ = DHParameterNumbers__init__hack
def establish_association(endpoint, assoc_type, session_type, generator, generate_modulus): """Actually establish the association.""" generator = int(generator) if generate_modulus: parameters = generate_parameters(generator=generator, key_size=2048, backend=default_backend()) parameter_numbers = parameters.parameter_numbers() else: parameter_numbers = DHParameterNumbers(DEFAULT_DH_MODULUS, generator) parameters = parameter_numbers.parameters(default_backend()) private_key = parameters.generate_private_key() public_key = int_to_base64(private_key.public_key().public_numbers().y) logging.debug("Private key: %s", private_key.private_numbers().x) logging.debug("Public key: %s", private_key.public_key().public_numbers().y) data = { 'openid.ns': OPENID2_NS, 'openid.mode': 'associate', 'openid.assoc_type': assoc_type, 'openid.session_type': session_type, 'openid.dh_consumer_public': public_key } if parameter_numbers != DHParameterNumbers(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR): data['openid.dh_modulus'] = int_to_base64(parameter_numbers.p) data['openid.dh_gen'] = int_to_base64(parameter_numbers.g) logging.info("Query arguments: %s", data) response = requests.post(endpoint, data=data) if response.status_code != 200: if response.status_code == 400: # Is it an error response? error_data = parse_kv_response(response) if error_data.get('mode') == 'error': # It's an error response raise ValueError("Server responded with error: {}".format( error_data.get('error'))) raise ValueError("Response returned incorrect status code: {}".format( response.status_code)) association_data = parse_association_response(response) logging.debug("Association data: %s", association_data) if association_data['assoc_type'] != assoc_type: raise ValueError( "Unexpected assoc_type returned {}, expected {}".format( association_data['assoc_type'], assoc_type)) if association_data['session_type'] != session_type: raise ValueError( "Unexpected session_type returned {}, expected {}".format( association_data['session_type'], session_type)) server_public_key = base64_to_int(association_data['dh_server_public']) shared_secret = private_key.exchange( DHPublicNumbers(server_public_key, parameter_numbers).public_key(default_backend())) # Not an ordinary DH secret is used here. # According to http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3, the first bit of # the DH secret must be zero. If it isn't, the bytes must be prepended by zero byte before they're hashed. shared_secret = bytearray(shared_secret) if shared_secret[0] > 127: shared_secret = bytearray([0]) + shared_secret shared_secret = bytes(shared_secret) logging.debug("DH shared secret: %s", base64.b64encode(shared_secret)) algorithm = getattr(hashes, assoc_type[5:]) digest = hashes.Hash(algorithm(), backend=default_backend()) digest.update(shared_secret) hashed_dh_shared = digest.finalize() mac_key = strxor(base64.b64decode(association_data['enc_mac_key']), hashed_dh_shared) return { 'assoc_type': association_data['assoc_type'], 'session_type': association_data['session_type'], 'assoc_handle': association_data['assoc_handle'], 'expires_in': association_data['expires_in'], 'mac_key': base64.b64encode(mac_key).decode('utf-8') }