示例#1
0
def test_base64():
    allowed_s = string.ascii_letters + string.digits + '+/='
    allowed_d = {}
    for c in allowed_s:
        allowed_d[ord(c)] = None
    isAllowed = allowed_d.__contains__

    def checkEncoded(s):
        for c in s:
            assert isAllowed(c), s

    cases = [
        '',
        'x',
        '\x00',
        '\x01',
        '\x00' * 100,
        ''.join(map(chr, list(range(256)))),
    ]

    for s in cases:
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert str(s_prime, encoding="utf-8") == s, (s, b64, s_prime)

    # Randomized test
    for _ in range(50):
        n = random.randrange(2048)
        s = ''.join(map(chr, [random.randrange(256) for _ in range(n)]))
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert str(s_prime, encoding="utf-8") == s, (s, b64, s_prime)
def test_base64():
    allowed_s = string.ascii_letters + string.digits + '+/='
    allowed_d = {}
    for c in allowed_s:
        allowed_d[c] = None
    isAllowed = allowed_d.has_key

    def checkEncoded(s):
        for c in s:
            assert isAllowed(c), s

    cases = [
        '',
        'x',
        '\x00',
        '\x01',
        '\x00' * 100,
        ''.join(map(chr, range(256))),
        ]

    for s in cases:
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert s_prime == s, (s, b64, s_prime)

    # Randomized test
    for _ in xrange(50):
        n = random.randrange(2048)
        s = ''.join(map(chr, map(lambda _: random.randrange(256), range(n))))
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert s_prime == s, (s, b64, s_prime)
示例#3
0
def test_base64():
    allowed_s = string.ascii_letters + string.digits + '+/='
    allowed_d = {}
    for c in allowed_s:
        allowed_d[ord(c)] = None
    isAllowed = allowed_d.__contains__

    def checkEncoded(s):
        for c in s:
            assert isAllowed(c), s

    cases = [
        '',
        'x',
        '\x00',
        '\x01',
        '\x00' * 100,
        ''.join(map(chr, list(range(256)))),
    ]

    for s in cases:
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert str(s_prime, encoding="utf-8") == s, (s, b64, s_prime)

    # Randomized test
    for _ in range(50):
        n = random.randrange(2048)
        s = ''.join(map(chr, [random.randrange(256) for _ in range(n)]))
        b64 = oidutil.toBase64(s)
        checkEncoded(b64)
        s_prime = oidutil.fromBase64(b64)
        assert str(s_prime, encoding="utf-8") == s, (s, b64, s_prime)
示例#4
0
    def serialize(self):
        """
        Convert an association to KV form.

        @return: String in KV form suitable for deserialization by
            deserialize.

        @rtype: str
        """
        data = {
            'version': '2',
            'handle': self.handle,
            'secret': oidutil.toBase64(self.secret),
            'issued': str(int(self.issued)),
            'lifetime': str(int(self.lifetime)),
            'assoc_type': self.assoc_type
        }

        assert len(data) == len(self.assoc_keys)

        pairs = []
        for field_name in self.assoc_keys:
            pairs.append((field_name, data[field_name]))

        return kvform.seqToKV(pairs, strict=True)
示例#5
0
    def serialize(self):
        """
        Convert an association to KV form.

        @return: String in KV form suitable for deserialization by
            deserialize.

        @rtype: str
        """
        data = {
            "version": "2",
            "handle": self.handle,
            "secret": oidutil.toBase64(self.secret),
            "issued": str(int(self.issued)),
            "lifetime": str(int(self.lifetime)),
            "assoc_type": self.assoc_type,
        }

        assert len(data) == len(self.assoc_keys)

        pairs = []
        for field_name in self.assoc_keys:
            pairs.append((field_name, data[field_name]))

        return kvform.seqToKV(pairs, strict=True)
    def verify(self, assoc_handle, sig, signed_pairs):
        """Verify that the signature for some data is valid.

        @param assoc_handle: The handle of the association used to sign the
            data.
        @type assoc_handle: str

        @param sig: The base-64 encoded signature to check.
        @type sig: str

        @param signed_pairs: The data to check, an ordered list of key-value
            pairs.  The keys should be as they are in the request's C{signed}
            list, without any C{"openid."} prefix.
        @type signed_pairs: list of pairs

        @returns: C{True} if the signature is valid, C{False} if not.
        @returntype: bool
        """
        assoc = self.getAssociation(assoc_handle, dumb=True)
        if not assoc:
            oidutil.log("failed to get assoc with handle %r to verify sig %r"
                        % (assoc_handle, sig))
            return False

        # Not using Association.checkSignature here is intentional;
        # Association should not know things like "the list of signed pairs is
        # in the request's 'signed' parameter and it is comma-separated."
        expected_sig = oidutil.toBase64(assoc.sign(signed_pairs))

        return sig == expected_sig
示例#7
0
def associate(services, url):
    '''Create an association (OpenID section 8) between RP and OP.
    Return response as a dictionary.'''
    req_data = {
        'openid.ns':"http://specs.openid.net/auth/2.0",
        'openid.mode':"associate",
        'openid.assoc_type':"HMAC-SHA1",
        'openid.session_type':"no-encryption",
        }
    if url.startswith('http:'):
        # Use DH exchange
        req_data['openid.session_type'] = "DH-SHA1"
        # Private key: random number between 1 and dh_prime-1
        priv = random.SystemRandom().randrange(1, dh_prime - 1)
        # Public key: 2^priv mod prime
        pubkey = pow(2L, priv, dh_prime)
        dh_public_base64 = base64.b64encode(btwoc(pubkey))
        # No need to send key and generator
        req_data['openid.dh_consumer_public'] = dh_public_base64
    if is_compat_1x(services):
        # 14.2.1: clear session_type in 1.1 compatibility mode
        if req_data['openid.session_type'] == "no-encryption":
            req_data['openid.session_type'] = ''
        del req_data['openid.ns']
    res = urllib.urlopen(url, b(urllib.urlencode(req_data)))
    try:
        if res.getcode() != 200:
            raise ValueError("OpenID provider refuses connection with status %s" % res.getcode())
        data = parse_response(res.read())
    except ValueError:
        endpoint = OpenIDServiceEndpoint.fromOPEndpointURL(url)
        store = MemoryStore()
        consumer = GenericConsumer(store)
        try:
            assoc = consumer._requestAssociation(endpoint, req_data['openid.assoc_type'], req_data['openid.session_type'])
            data = {
                'assoc_handle': assoc.handle,
                'expires_in': assoc.lifetime,
                'mac_key': oidutil.toBase64(assoc.secret),
            }
        except ServerError:
            data = {
                'error': 'Server %s refused its suggested association type: session_type=%s, assoc_type=%s' % (url, req_data['openid.assoc_type'], req_data['openid.session_type']),
            }
    if 'error' in data:
        raise ValueError, "associate failed: "+data['error']
    if url.startswith('http:'):
        enc_mac_key = b(data.get('enc_mac_key'))
        if not enc_mac_key:
            raise ValueError, "Provider protocol error: not using DH-SHA1"
        enc_mac_key = base64.b64decode(enc_mac_key)
        dh_server_public = unbtwoc(base64.b64decode(b(data['dh_server_public'])))
        # shared secret: sha1(2^(server_priv*priv) mod prime) xor enc_mac_key
        shared_secret = btwoc(pow(dh_server_public, priv, dh_prime))
        shared_secret = hashlib.sha1(shared_secret).digest()
        if len(shared_secret) != len(enc_mac_key):
            raise ValueError, "incorrect DH key size"
        # Fake mac_key result
        data['mac_key'] = b(base64.b64encode(string_xor(enc_mac_key, shared_secret)))
    return data
    def verify(self, assoc_handle, sig, signed_pairs):
        """Verify that the signature for some data is valid.

        @param assoc_handle: The handle of the association used to sign the
            data.
        @type assoc_handle: str

        @param sig: The base-64 encoded signature to check.
        @type sig: str

        @param signed_pairs: The data to check, an ordered list of key-value
            pairs.  The keys should be as they are in the request's C{signed}
            list, without any C{"openid."} prefix.
        @type signed_pairs: list of pairs

        @returns: C{True} if the signature is valid, C{False} if not.
        @returntype: bool
        """
        assoc = self.getAssociation(assoc_handle, dumb=True)
        if not assoc:
            oidutil.log("failed to get assoc with handle %r to verify sig %r" %
                        (assoc_handle, sig))
            return False

        # Not using Association.checkSignature here is intentional;
        # Association should not know things like "the list of signed pairs is
        # in the request's 'signed' parameter and it is comma-separated."
        expected_sig = oidutil.toBase64(assoc.sign(signed_pairs))

        return sig == expected_sig
    def createAssociation(self, dumb=True, assoc_type='HMAC-SHA1'):
        """Make a new association.

        @param dumb: Is this association for a dumb-mode transaction?
        @type dumb: bool

        @param assoc_type: The type of association to create.  Currently
            there is only one type defined, C{HMAC-SHA1}.
        @type assoc_type: str

        @returns: the new association.
        @returntype: L{openid.association.Association}
        """
        secret = cryptutil.getBytes(20)
        uniq = oidutil.toBase64(cryptutil.getBytes(4))
        handle = '{%s}{%x}{%s}' % (assoc_type, int(time.time()), uniq)

        assoc = Association.fromExpiresIn(self.SECRET_LIFETIME, handle, secret,
                                          assoc_type)

        if dumb:
            key = self._dumb_key
        else:
            key = self._normal_key
        self.store.storeAssociation(key, assoc)
        return assoc
示例#10
0
    def serialize(self):
        """
        Convert an association to KV form.

        @return: String in KV form suitable for deserialization by
            deserialize.

        @rtype: str
        """
        data = {
            'version': '2',
            'handle': self.handle,
            'secret': oidutil.toBase64(self.secret),
            'issued': str(int(self.issued)),
            'lifetime': str(int(self.lifetime)),
            'assoc_type': self.assoc_type
        }

        assert len(data) == len(self.assoc_keys)

        pairs = []
        for field_name in self.assoc_keys:
            pairs.append((field_name, data[field_name]))

        return kvform.seqToKV(pairs, strict=True)
    def createAssociation(self, dumb=True, assoc_type='HMAC-SHA1'):
        """Make a new association.

        @param dumb: Is this association for a dumb-mode transaction?
        @type dumb: bool

        @param assoc_type: The type of association to create.  Currently
            there is only one type defined, C{HMAC-SHA1}.
        @type assoc_type: str

        @returns: the new association.
        @returntype: L{openid.association.Association}
        """
        secret = cryptutil.getBytes(20)
        uniq = oidutil.toBase64(cryptutil.getBytes(4))
        handle = '{%s}{%x}{%s}' % (assoc_type, int(time.time()), uniq)

        assoc = Association.fromExpiresIn(
            self.SECRET_LIFETIME, handle, secret, assoc_type)

        if dumb:
            key = self._dumb_key
        else:
            key = self._normal_key
        self.store.storeAssociation(key, assoc)
        return assoc
示例#12
0
def _safe64(s):
    h64 = oidutil.toBase64(cryptutil.sha1(s))
    # to be able to manipulate it, make it a bytearray
    h64 = bytearray(h64)
    h64 = h64.replace(b'+', b'_')
    h64 = h64.replace(b'/', b'.')
    h64 = h64.replace(b'=', b'')
    return bytes(h64)
示例#13
0
def _safe64(s):
    h64 = oidutil.toBase64(cryptutil.sha1(s))
    # to be able to manipulate it, make it a bytearray
    h64 = bytearray(h64)
    h64 = h64.replace(b'+', b'_')
    h64 = h64.replace(b'/', b'.')
    h64 = h64.replace(b'=', b'')
    return bytes(h64)
示例#14
0
def _safe64(s):
    h64 = oidutil.toBase64(cryptutil.sha1(s))
    # to be able to manipulate it, make it a bytearray
    h64 = bytearray(h64)
    h64 = h64.replace(b"+", b"_")
    h64 = h64.replace(b"/", b".")
    h64 = h64.replace(b"=", b"")
    return bytes(h64)
示例#15
0
    def storeAssociation(self, server_url, assoc):
        iden = '%s-%s' % (server_url, assoc.handle)
        datum = {'secret': oidutil.toBase64(assoc.secret),
                 'issued': str(assoc.issued),
                 'lifetime': str(assoc.lifetime),
                 'assoc_type': assoc.assoc_type}

        data = {iden: datum}
        self.save_unique_data('association', data)
示例#16
0
    def storeAssociation(self, server_url, assoc):
        iden = '%s-%s' % (server_url, assoc.handle)
        datum = {
            'secret': oidutil.toBase64(assoc.secret),
            'issued': str(assoc.issued),
            'lifetime': str(assoc.lifetime),
            'assoc_type': assoc.assoc_type
        }

        data = {iden: datum}
        self.save_unique_data('association', data, ttl=assoc.lifetime)
示例#17
0
    def test_base64(self):
        allowed_s = string.ascii_letters + string.digits + '+/='
        allowed_d = {}
        for c in allowed_s:
            allowed_d[c] = None

        def checkEncoded(s):
            for c in s:
                self.assertIn(c, allowed_d, msg=s)

        cases = [
            b'',
            b'x',
            b'\x00',
            b'\x01',
            b'\x00' * 100,
        ]
        if six.PY2:
            cases.append(b''.join(chr(i) for i in range(256)))
        else:
            assert six.PY3
            cases.append(bytes(i for i in range(256)))

        for s in cases:
            b64 = oidutil.toBase64(s)
            checkEncoded(b64)
            s_prime = oidutil.fromBase64(b64)
            assert s_prime == s, (s, b64, s_prime)

        # Randomized test
        for _ in range(50):
            n = random.randrange(2048)
            if six.PY2:
                s = b''.join(chr(random.randrange(256)) for i in range(n))
            else:
                assert six.PY3
                s = bytes(random.randrange(256) for i in range(n))
            b64 = oidutil.toBase64(s)
            checkEncoded(b64)
            s_prime = oidutil.fromBase64(b64)
            assert s_prime == s, (s, b64, s_prime)
示例#18
0
    def test_base64(self):
        allowed_s = string.ascii_letters + string.digits + '+/='
        allowed_d = {}
        for c in allowed_s:
            allowed_d[c] = None

        def checkEncoded(s):
            for c in s:
                self.assertIn(c, allowed_d, msg=s)

        cases = [
            b'',
            b'x',
            b'\x00',
            b'\x01',
            b'\x00' * 100,
        ]
        if six.PY2:
            cases.append(b''.join(chr(i) for i in range(256)))
        else:
            assert six.PY3
            cases.append(bytes(i for i in range(256)))

        for s in cases:
            b64 = oidutil.toBase64(s)
            checkEncoded(b64)
            s_prime = oidutil.fromBase64(b64)
            assert s_prime == s, (s, b64, s_prime)

        # Randomized test
        for _ in range(50):
            n = random.randrange(2048)
            if six.PY2:
                s = b''.join(chr(random.randrange(256)) for i in range(n))
            else:
                assert six.PY3
                s = bytes(random.randrange(256) for i in range(n))
            b64 = oidutil.toBase64(s)
            checkEncoded(b64)
            s_prime = oidutil.fromBase64(b64)
            assert s_prime == s, (s, b64, s_prime)
示例#19
0
 def test_exchange_dynamic(self):
     # Test complete key exchange with random values
     # Consumer part
     consumer_dh = DiffieHellman.fromDefaults()
     consumer_public_key = consumer_dh.public_key
     # Server part
     secret = toBase64(os.urandom(32))
     server_dh = DiffieHellman.fromDefaults()
     mac_key = server_dh.xor_secret(consumer_public_key, secret, hashes.SHA256())
     server_public_key = server_dh.public_key
     # Consumer part
     shared_secret = consumer_dh.xor_secret(server_public_key, mac_key, hashes.SHA256())
     # Check secret was negotiated correctly
     self.assertEqual(secret, shared_secret)
示例#20
0
    def getMessageSignature(self, message):
        """Return the signature of a message.

        If I am not a sign-all association, the message must have a
        signed list.

        @return: the signature, base64 encoded
        @rtype: six.text_type

        @raises ValueError: If there is no signed list and I am not a sign-all
            type of association.
        """
        pairs = self._makePairs(message)
        return oidutil.toBase64(self.sign(pairs))
示例#21
0
文件: server.py 项目: abtain/Heraldry
    def test_plaintext(self):
        response = self.request.answer(self.assoc)
        rfg = response.fields.get

        self.failUnlessEqual(rfg("assoc_type"), "HMAC-SHA1")
        self.failUnlessEqual(rfg("assoc_handle"), self.assoc.handle)

        self.failUnlessEqual(
            rfg("expires_in"), "%d" % (self.signatory.SECRET_LIFETIME,))
        self.failUnlessEqual(
            rfg("mac_key"), oidutil.toBase64(self.assoc.secret))
        self.failIf(rfg("session_type"))
        self.failIf(rfg("enc_mac_key"))
        self.failIf(rfg("dh_server_public"))
示例#22
0
 def test_plainFallback(self):
     sess = DiffieHellmanConsumerSession()
     server_resp = {
         'assoc_type': 'HMAC-SHA1',
         'assoc_handle': 'handle',
         'expires_in': '1000',
         'mac_key': oidutil.toBase64(self.secret),
         }
     ret = self.consumer._parseAssociation(server_resp, sess, 'server_url')
     self.failIf(ret is None)
     self.failUnlessEqual(ret.assoc_type, 'HMAC-SHA1')
     self.failUnlessEqual(ret.secret, self.secret)
     self.failUnlessEqual(ret.handle, 'handle')
     self.failUnlessEqual(ret.lifetime, 1000)
示例#23
0
    def getMessageSignature(self, message):
        """Return the signature of a message.

        If I am not a sign-all association, the message must have a
        signed list.

        @return: the signature, base64 encoded
        @rtype: six.text_type

        @raises ValueError: If there is no signed list and I am not a sign-all
            type of association.
        """
        pairs = self._makePairs(message)
        return oidutil.toBase64(self.sign(pairs))
示例#24
0
 def test_exchange_dynamic(self):
     # Test complete key exchange with random values
     # Consumer part
     consumer_dh = DiffieHellman.fromDefaults()
     consumer_public_key = consumer_dh.public_key
     # Server part
     secret = toBase64(os.urandom(32))
     server_dh = DiffieHellman.fromDefaults()
     mac_key = server_dh.xor_secret(consumer_public_key, secret,
                                    hashes.SHA256())
     server_public_key = server_dh.public_key
     # Consumer part
     shared_secret = consumer_dh.xor_secret(server_public_key, mac_key,
                                            hashes.SHA256())
     # Check secret was negotiated correctly
     self.assertEqual(secret, shared_secret)
示例#25
0
 def storeAssociation(self, server_url, association):
     Association().save({
         'url':
         server_url,
         'handle':
         association.handle,
         'secret':
         oidutil.toBase64(association.secret),
         'issued':
         association.issued,
         'lifetime':
         association.lifetime,
         'type':
         association.assoc_type,
         'expires':
         datetime.datetime.utcnow() +
         datetime.timedelta(seconds=association.lifetime)
     })
示例#26
0
文件: dh.py 项目: ziima/python-openid
    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))
示例#27
0
    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))
示例#28
0
    def serialize(self):
        """
        Convert an association to KV form.

        @return: String in KV form suitable for deserialization by
            deserialize.

        @rtype: str
        """
        data = {
            "version": "2",
            "handle": self.handle,
            "secret": oidutil.toBase64(self.secret),
            "issued": str(int(self.issued)),
            "lifetime": str(int(self.lifetime)),
            "assoc_type": self.assoc_type,
        }

        assert len(data) == len(self.assoc_keys)
        pairs = []
        for field_name in self.assoc_keys:
            pairs.append((field_name, data[field_name]))

        return kvform.seqToKV(pairs, strict=True)
    def signDict(self, fields, data, prefix='openid.'):
        """
        Generate a signature for some fields in a dictionary


        @param fields: The fields to sign, in order

        @type fields: sequence of str


        @param data: Dictionary of values to sign

        @type data: {str:str}


        @return: the signature, base64 encoded

        @rtype: str
        """
        pairs = []
        for field in fields:
            pairs.append((field, data.get(prefix + field, '')))

        return oidutil.toBase64(self.sign(pairs))
示例#30
0
    def signDict(self, fields, data, prefix='openid.'):
        """
        Generate a signature for some fields in a dictionary


        @param fields: The fields to sign, in order

        @type fields: sequence of str


        @param data: Dictionary of values to sign

        @type data: {str:str}


        @return: the signature, base64 encoded

        @rtype: str
        """
        pairs = []
        for field in fields:
            pairs.append((field, data.get(prefix + field, '')))

        return oidutil.toBase64(self.sign(pairs))
示例#31
0
def longToBase64(l):
    return toBase64(longToBinary(l))
示例#32
0
def longToBase64(l):
    return toBase64(longToBinary(l))
示例#33
0
def _safe64(s):
    h64 = oidutil.toBase64(sha1(s.encode('utf-8')).digest())
    h64 = h64.replace('+', '_')
    h64 = h64.replace('/', '.')
    h64 = h64.replace('=', '')
    return h64
示例#34
0
def longToBase64(l):
    return toBase64(int_to_bytes(l))
示例#35
0
 def _safe64(s):
     h64 = oidutil.toBase64(cryptutil.sha1(s))
     h64 = h64.replace("+", "_")
     h64 = h64.replace("/", ".")
     h64 = h64.replace("=", "")
     return h64
示例#36
0
class TestDiffieHellman(unittest.TestCase):
    """Test `DiffieHellman` class."""
    def test_init(self):
        dh = DiffieHellman(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR)
        self.assertTrue(dh.usingDefaultValues())

    def test_init_int(self):
        dh = DiffieHellman(base64ToLong(DEFAULT_DH_MODULUS),
                           base64ToLong(DEFAULT_DH_GENERATOR))
        self.assertTrue(dh.usingDefaultValues())

    def test_modulus(self):
        dh = DiffieHellman.fromDefaults()
        modulus = int(
            '155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698'
            '188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681'
            '476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848'
            '253359305585439638443')
        warning_msg = "Modulus property will return base64 encoded string."
        with ShouldWarn(DeprecationWarning(warning_msg)):
            warnings.simplefilter('always')
            self.assertEqual(dh.modulus, modulus)

    def test_generator(self):
        dh = DiffieHellman.fromDefaults()
        warning_msg = "Generator property will return base64 encoded string."
        with ShouldWarn(DeprecationWarning(warning_msg)):
            warnings.simplefilter('always')
            self.assertEqual(dh.generator, 2)

    def test_parameters(self):
        dh = DiffieHellman.fromDefaults()
        self.assertEqual(dh.parameters,
                         (DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR))

    consumer_private_key = (
        'bVQh4Z81F5e57JCT1pmxADRktpYwIwhNjWkiIjg450sfYZOJ9Ntf4YHBhcBpkPyehdq/XL+yEWbZFig4wh2MdqES0X'
        'aOPRVl7ZzsjTNgztKUYE2mhiYQd4KMmB9uLExM72ntwcdZ3/vlb0Fq8DlIx3FhqeaYsKKTsdUW/KbJcS0='
    )
    consumer_public_key = (
        'ANMxIwAeRWw5mZD3+DkoX3G6n/tuBGsjfk6R+vBW2zwve0BSlh1F0EsXlQEUuXJ+s1DQ8nFQLPYOLO0mLexXH0bSscv'
        'zhBldH+L+fxJfoL9xoTAxk7qqT659QqErhEMtQpBy7hK5L7Qb8R2NAUZ++MPxUNB71IBd6vMG6M6MueXp'
    )
    server_private_key = (
        'ANxFaZXkCVNESkYKFclilsm7tVIO1CNYy621Y44w19OPk7xE7zEZdttX/KfRSImecPpn+AATLhRZMuXzaq3KDFFTu9Nu'
        'hSINYml2f7xZd1+lYg6YhWiojfP3YPqLIV9sj/26O1A7pTcq6jajj/8E5P+qkr6+bSQhZ0UlZiBQUyDr'
    )
    server_public_key = (
        'MSJTx7cMqUBAcpLCan75t+8OSf3SZUSwivlEUYxMaHbbueKp1u4/7Fdw9sTCN3gA0iFE2dTOJpRUT4TmFomHnyIfBExdc'
        'wbkXiQIhsSnBJkGmPuAPkKFFHtB0pKET6bWZolwP5fp4lZOgM+7FIRte5OZd5XEJIN9vBYxo6NaoRc='
    )
    shared_secret = (
        'FHWhX2v2g/twI8mO1HFiI9zgRP6/CBbJ0+13cgpDJvIUypDNcqLHlkGJtjaOJ1ciX+qk2Jf3Zdt5YJDgilVH+Xg7x7WaHXVxX'
        'Yxu5RTwEuPyFUjO62XT6u11qJ35PvveTDwwAsv6+OspK8FRbqMKIgNuEkmaFDVwr4dKyhZUtNg='
    )
    secret = toBase64(b'Rimmer ordered hot gazpacho soup')
    mac_key = 'hAYpHzbPvEHs0J2t8KYiqoxsLSmRzGfCQmwMg9taNf0='

    def setup_keys(self, dh_object, public_key, private_key):
        """Set up private and public key into DiffieHellman object."""
        public_numbers = DHPublicNumbers(base64ToLong(public_key),
                                         dh_object.parameter_numbers)
        private_numbers = DHPrivateNumbers(base64ToLong(private_key),
                                           public_numbers)
        dh_object.private_key = private_numbers.private_key(default_backend())

    def test_public(self):
        dh = DiffieHellman.fromDefaults()
        self.setup_keys(dh, self.server_public_key, self.server_private_key)
        warning_msg = "Attribute 'public' is deprecated. Use 'public_key' instead."
        with ShouldWarn(DeprecationWarning(warning_msg)):
            warnings.simplefilter('always')
            self.assertEqual(dh.public, base64ToLong(self.server_public_key))

    def test_public_key(self):
        dh = DiffieHellman.fromDefaults()
        self.setup_keys(dh, self.server_public_key, self.server_private_key)
        self.assertEqual(dh.public_key, self.server_public_key)

    def test_get_shared_secret_server(self):
        server_dh = DiffieHellman.fromDefaults()
        self.setup_keys(server_dh, self.server_public_key,
                        self.server_private_key)
        self.assertEqual(
            server_dh._get_shared_secret(self.consumer_public_key),
            base64.b64decode(self.shared_secret))

    def test_get_shared_secret_consumer(self):
        consumer_dh = DiffieHellman.fromDefaults()
        self.setup_keys(consumer_dh, self.consumer_public_key,
                        self.consumer_private_key)
        self.assertEqual(
            consumer_dh._get_shared_secret(self.server_public_key),
            base64.b64decode(self.shared_secret))

    def test_getSharedSecret(self):
        # Test the deprecated method
        consumer_dh = DiffieHellman.fromDefaults()
        self.setup_keys(consumer_dh, self.consumer_public_key,
                        self.consumer_private_key)
        warning_msg = "Method 'getSharedSecret' is deprecated in favor of '_get_shared_secret'."
        with ShouldWarn(DeprecationWarning(warning_msg)):
            warnings.simplefilter('always')
            self.assertEqual(
                consumer_dh.getSharedSecret(self.server_public_key),
                base64ToLong(self.shared_secret))

    def test_xorSecret(self):
        # Test key exchange - deprecated method
        server_dh = DiffieHellman.fromDefaults()
        self.setup_keys(server_dh, self.server_public_key,
                        self.server_private_key)

        def sha256(value):
            digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
            digest.update(value)
            return digest.finalize()

        warning_msg = "Method 'xorSecret' is deprecated, use 'xor_secret' instead."
        with ShouldWarn(DeprecationWarning(warning_msg)):
            warnings.simplefilter('always')
            secret = server_dh.xorSecret(
                base64ToLong(self.consumer_public_key),
                base64.b64decode(self.secret), sha256)
            self.assertEqual(secret, base64.b64decode(self.mac_key))

    def test_exchange_server_static(self):
        # Test key exchange - server part with static values
        server_dh = DiffieHellman.fromDefaults()
        self.setup_keys(server_dh, self.server_public_key,
                        self.server_private_key)

        self.assertEqual(
            server_dh.xor_secret(self.consumer_public_key, self.secret,
                                 hashes.SHA256()), self.mac_key)
        self.assertEqual(server_dh.public_key, self.server_public_key)

    def test_exchange_consumer_static(self):
        # Test key exchange - consumer part with static values
        consumer_dh = DiffieHellman.fromDefaults()
        self.setup_keys(consumer_dh, self.consumer_public_key,
                        self.consumer_private_key)

        shared_secret = consumer_dh.xor_secret(self.server_public_key,
                                               self.mac_key, hashes.SHA256())
        # Check secret was negotiated correctly
        self.assertEqual(shared_secret, self.secret)

    def test_exchange_dynamic(self):
        # Test complete key exchange with random values
        # Consumer part
        consumer_dh = DiffieHellman.fromDefaults()
        consumer_public_key = consumer_dh.public_key
        # Server part
        secret = toBase64(os.urandom(32))
        server_dh = DiffieHellman.fromDefaults()
        mac_key = server_dh.xor_secret(consumer_public_key, secret,
                                       hashes.SHA256())
        server_public_key = server_dh.public_key
        # Consumer part
        shared_secret = consumer_dh.xor_secret(server_public_key, mac_key,
                                               hashes.SHA256())
        # Check secret was negotiated correctly
        self.assertEqual(secret, shared_secret)
示例#37
0
def longToBase64(value):
    return toBase64(int_to_bytes(value))
示例#38
0
def _safe64(s):
    h64 = oidutil.toBase64(cryptutil.sha1(s))
    h64 = h64.replace('+', '_')
    h64 = h64.replace('/', '.')
    h64 = h64.replace('=', '')
    return h64
 def answer(self, secret):
     return {'mac_key': oidutil.toBase64(secret)}
 def answer(self, secret):
     mac_key = self.dh.xorSecret(self.consumer_pubkey, secret)
     return {
         'dh_server_public': cryptutil.longToBase64(self.dh.public),
         'enc_mac_key': oidutil.toBase64(mac_key),
         }
示例#41
0
def _safe64(s):
    h64 = oidutil.toBase64(cryptutil.sha1(s))
    h64 = h64.replace('+', '_')
    h64 = h64.replace('/', '.')
    h64 = h64.replace('=', '')
    return h64
 def answer(self, secret):
     return {'mac_key': oidutil.toBase64(secret)}
示例#43
0
def associate(services, url):
    '''Create an association (OpenID section 8) between RP and OP.
    Return response as a dictionary.'''
    req_data = {
        'openid.ns': "http://specs.openid.net/auth/2.0",
        'openid.mode': "associate",
        'openid.assoc_type': "HMAC-SHA1",
        'openid.session_type': "no-encryption",
    }
    if url.startswith('http:'):
        # Use DH exchange
        req_data['openid.session_type'] = "DH-SHA1"
        # Private key: random number between 1 and dh_prime-1
        priv = random.SystemRandom().randrange(1, dh_prime - 1)
        # Public key: 2^priv mod prime
        pubkey = pow(2L, priv, dh_prime)
        dh_public_base64 = base64.b64encode(btwoc(pubkey))
        # No need to send key and generator
        req_data['openid.dh_consumer_public'] = dh_public_base64
    if is_compat_1x(services):
        # 14.2.1: clear session_type in 1.1 compatibility mode
        if req_data['openid.session_type'] == "no-encryption":
            req_data['openid.session_type'] = ''
        del req_data['openid.ns']
    res = urllib.urlopen(url, b(urllib.urlencode(req_data)))
    try:
        if res.getcode() != 200:
            raise ValueError(
                "OpenID provider refuses connection with status %s" %
                res.getcode())
        data = parse_response(res.read())
    except ValueError:
        endpoint = OpenIDServiceEndpoint.fromOPEndpointURL(url)
        store = MemoryStore()
        consumer = GenericConsumer(store)
        try:
            assoc = consumer._requestAssociation(
                endpoint, req_data['openid.assoc_type'],
                req_data['openid.session_type'])
            data = {
                'assoc_handle': assoc.handle,
                'expires_in': assoc.lifetime,
                'mac_key': oidutil.toBase64(assoc.secret),
            }
        except ServerError:
            data = {
                'error':
                'Server %s refused its suggested association type: session_type=%s, assoc_type=%s'
                % (url, req_data['openid.assoc_type'],
                   req_data['openid.session_type']),
            }
    if 'error' in data:
        raise ValueError, "associate failed: " + data['error']
    if url.startswith('http:'):
        enc_mac_key = b(data.get('enc_mac_key'))
        if not enc_mac_key:
            raise ValueError, "Provider protocol error: not using DH-SHA1"
        enc_mac_key = base64.b64decode(enc_mac_key)
        dh_server_public = unbtwoc(
            base64.b64decode(b(data['dh_server_public'])))
        # shared secret: sha1(2^(server_priv*priv) mod prime) xor enc_mac_key
        shared_secret = btwoc(pow(dh_server_public, priv, dh_prime))
        shared_secret = hashlib.sha1(shared_secret).digest()
        if len(shared_secret) != len(enc_mac_key):
            raise ValueError, "incorrect DH key size"
        # Fake mac_key result
        data['mac_key'] = b(
            base64.b64encode(string_xor(enc_mac_key, shared_secret)))
    return data
 def answer(self, secret):
     mac_key = self.dh.xorSecret(self.consumer_pubkey, secret)
     return {
         'dh_server_public': cryptutil.longToBase64(self.dh.public),
         'enc_mac_key': oidutil.toBase64(mac_key),
     }