Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
    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()
Пример #4
0
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)
Пример #5
0
    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()
Пример #6
0
    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()
Пример #7
0
class DiffieHellman(object):
    """Utility for Diffie-Hellman key exchange."""
    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()

    @classmethod
    def fromDefaults(cls):
        """Create Diffie-Hellman with the default modulus and generator."""
        return cls(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)

    @property
    def modulus(self):
        """Return the prime modulus value.

        @rtype: Union[six.integer_types]
        """
        return self.parameter_numbers.p

    @property
    def generator(self):
        """Return the generator value.

        @rtype: Union[six.integer_types]
        """
        return self.parameter_numbers.g

    @property
    def public(self):
        """Return the public key.

        @rtype: Union[six.integer_types]
        """
        warnings.warn(
            "Attribute 'public' is deprecated. Use 'public_key' instead.",
            DeprecationWarning)
        return self.private_key.public_key().public_numbers().y

    @property
    def public_key(self):
        """Return base64 encoded public key.

        @rtype: six.text_type
        """
        return cryptutil.longToBase64(
            self.private_key.public_key().public_numbers().y)

    def usingDefaultValues(self):
        return (self.modulus == DEFAULT_DH_MODULUS
                and self.generator == DEFAULT_DH_GENERATOR)

    def getSharedSecret(self, composite):
        """Return a shared secret.

        @param composite: Public key of the other party.
        @type composite: Union[six.integer_types]
        @rtype: Union[six.integer_types]
        """
        warnings.warn(
            "Method 'getSharedSecret' is deprecated in favor of 'get_shared_secret'.",
            DeprecationWarning)
        return cryptutil.bytes_to_int(self.get_shared_secret(composite))

    def get_shared_secret(self, public_key):
        """Return a shared secret.

        @param public_key: Public key of the other party.
        @type public_key: Union[six.integer_types]
        @rtype: six.binary_type
        """
        public_numbers = DHPublicNumbers(public_key, self.parameter_numbers)
        return self.private_key.exchange(
            public_numbers.public_key(default_backend()))

    def xorSecret(self, composite, secret, hash_func):
        dh_shared = self.get_shared_secret(composite)
        hashed_dh_shared = hash_func(dh_shared)
        return strxor(secret, hashed_dh_shared)
Пример #8
0
    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
Пример #9
0
class DiffieHellman(object):
    """Utility for Diffie-Hellman key exchange."""

    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()

    @classmethod
    def fromDefaults(cls):
        """Create Diffie-Hellman with the default modulus and generator."""
        return cls(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)

    @property
    def modulus(self):
        """Return the prime modulus value.

        @rtype: Union[six.integer_types]
        """
        warnings.warn("Modulus property will return base64 encoded string.", DeprecationWarning)
        return self.parameter_numbers.p

    @property
    def generator(self):
        """Return the generator value.

        @rtype: Union[six.integer_types]
        """
        warnings.warn("Generator property will return base64 encoded string.", DeprecationWarning)
        return self.parameter_numbers.g

    @property
    def parameters(self):
        """Return base64 encoded modulus and generator.

        @return: Tuple with modulus and generator
        @rtype: Tuple[six.text_type, six.text_type]
        """
        modulus = self.parameter_numbers.p
        generator = self.parameter_numbers.g
        return cryptutil.longToBase64(modulus), cryptutil.longToBase64(generator)

    @property
    def public(self):
        """Return the public key.

        @rtype: Union[six.integer_types]
        """
        warnings.warn("Attribute 'public' is deprecated. Use 'public_key' instead.", DeprecationWarning)
        return self.private_key.public_key().public_numbers().y

    @property
    def public_key(self):
        """Return base64 encoded public key.

        @rtype: six.text_type
        """
        return cryptutil.longToBase64(self.private_key.public_key().public_numbers().y)

    def usingDefaultValues(self):
        return self.parameters == (DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)

    def getSharedSecret(self, composite):
        """Return a shared secret.

        @param composite: Public key of the other party.
        @type composite: Union[six.integer_types]
        @rtype: Union[six.integer_types]
        """
        warnings.warn("Method 'getSharedSecret' is deprecated in favor of '_get_shared_secret'.", DeprecationWarning)
        return cryptutil.bytes_to_int(self._get_shared_secret(composite))

    def _get_shared_secret(self, public_key):
        """Return a shared secret.

        @param public_key: Base64 encoded public key of the other party.
        @type public_key: six.text_type
        @rtype: six.binary_type
        """
        public_numbers = DHPublicNumbers(cryptutil.base64ToLong(public_key), self.parameter_numbers)
        return self.private_key.exchange(public_numbers.public_key(default_backend()))

    def xorSecret(self, composite, secret, hash_func):
        warnings.warn("Method 'xorSecret' is deprecated, use 'xor_secret' instead.", DeprecationWarning)
        dh_shared = self._get_shared_secret(cryptutil.longToBase64(composite))

        # The DH secret must be `btwoc` compatible.
        # See http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3 for details.
        dh_shared = cryptutil.fix_btwoc(dh_shared)

        hashed_dh_shared = hash_func(dh_shared)
        return strxor(secret, hashed_dh_shared)

    def xor_secret(self, public_key, secret, algorithm):
        """Return a base64 encoded XOR of a secret key and hash of a DH exchanged secret.

        @param public_key: Base64 encoded public key of the other party.
        @type public_key: six.text_type
        @param secret: Base64 encoded secret
        @type secret: six.text_type
        @type algorithm: hashes.HashAlgorithm
        @rtype: six.text_type
        """
        dh_shared = self._get_shared_secret(public_key)

        # The DH secret must be `btwoc` compatible.
        # See http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3 for details.
        dh_shared = cryptutil.fix_btwoc(dh_shared)

        digest = hashes.Hash(algorithm, backend=default_backend())
        digest.update(dh_shared)
        hashed_dh_shared = digest.finalize()
        return toBase64(strxor(base64.b64decode(secret), hashed_dh_shared))
Пример #10
0
class DiffieHellman(object):
    """Utility for Diffie-Hellman key exchange."""
    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()

    @classmethod
    def fromDefaults(cls):
        """Create Diffie-Hellman with the default modulus and generator."""
        return cls(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)

    @property
    def modulus(self):
        """Return the prime modulus value.

        @rtype: Union[six.integer_types]
        """
        warnings.warn("Modulus property will return base64 encoded string.",
                      DeprecationWarning)
        return self.parameter_numbers.p

    @property
    def generator(self):
        """Return the generator value.

        @rtype: Union[six.integer_types]
        """
        warnings.warn("Generator property will return base64 encoded string.",
                      DeprecationWarning)
        return self.parameter_numbers.g

    @property
    def parameters(self):
        """Return base64 encoded modulus and generator.

        @return: Tuple with modulus and generator
        @rtype: Tuple[six.text_type, six.text_type]
        """
        modulus = self.parameter_numbers.p
        generator = self.parameter_numbers.g
        return cryptutil.longToBase64(modulus), cryptutil.longToBase64(
            generator)

    @property
    def public(self):
        """Return the public key.

        @rtype: Union[six.integer_types]
        """
        warnings.warn(
            "Attribute 'public' is deprecated. Use 'public_key' instead.",
            DeprecationWarning)
        return self.private_key.public_key().public_numbers().y

    @property
    def public_key(self):
        """Return base64 encoded public key.

        @rtype: six.text_type
        """
        return cryptutil.longToBase64(
            self.private_key.public_key().public_numbers().y)

    def usingDefaultValues(self):
        return self.parameters == (DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)

    def getSharedSecret(self, composite):
        """Return a shared secret.

        @param composite: Public key of the other party.
        @type composite: Union[six.integer_types]
        @rtype: Union[six.integer_types]
        """
        warnings.warn(
            "Method 'getSharedSecret' is deprecated in favor of '_get_shared_secret'.",
            DeprecationWarning)
        return cryptutil.bytes_to_int(self._get_shared_secret(composite))

    def _get_shared_secret(self, public_key):
        """Return a shared secret.

        @param public_key: Base64 encoded public key of the other party.
        @type public_key: six.text_type
        @rtype: six.binary_type
        """
        public_numbers = DHPublicNumbers(cryptutil.base64ToLong(public_key),
                                         self.parameter_numbers)
        return self.private_key.exchange(
            public_numbers.public_key(default_backend()))

    def xorSecret(self, composite, secret, hash_func):
        warnings.warn(
            "Method 'xorSecret' is deprecated, use 'xor_secret' instead.",
            DeprecationWarning)
        dh_shared = self._get_shared_secret(cryptutil.longToBase64(composite))

        # The DH secret must be `btwoc` compatible.
        # See http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3 for details.
        dh_shared = cryptutil.fix_btwoc(dh_shared)

        hashed_dh_shared = hash_func(dh_shared)
        return strxor(secret, hashed_dh_shared)

    def xor_secret(self, public_key, secret, algorithm):
        """Return a base64 encoded XOR of a secret key and hash of a DH exchanged secret.

        @param public_key: Base64 encoded public key of the other party.
        @type public_key: six.text_type
        @param secret: Base64 encoded secret
        @type secret: six.text_type
        @type algorithm: hashes.HashAlgorithm
        @rtype: six.text_type
        """
        dh_shared = self._get_shared_secret(public_key)

        # The DH secret must be `btwoc` compatible.
        # See http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3 for details.
        dh_shared = cryptutil.fix_btwoc(dh_shared)

        digest = hashes.Hash(algorithm, backend=default_backend())
        digest.update(dh_shared)
        hashed_dh_shared = digest.finalize()
        return toBase64(strxor(base64.b64decode(secret), hashed_dh_shared))
Пример #11
0
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')}
Пример #12
0
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')
    }