コード例 #1
0
    def __init__(self,
                 app_name,
                 cert=None,
                 key=None,
                 ca_bundle=None,
                 authserver="login.ancient-solutions.com"):
        """Set up the authentication client so it can be used lateron.

        Args:
        app_name: The name the login server shall display to the user.
        cert: Path to the certificate to use for signing the
        requests, or the contents of the certificate.
        key: Path to the private key to use for signing the
        requests, or the contents of the key.
        ca_bundle: path to a CA bundle file to use for authenticating
        the server.
        """

        if key is not None and type(key) == str and exists(key):
            self._rsa_key = rsa.UnwrapRSAKey(key)
        elif key is not None and isinstance(key, RSA._RSAobj):
            self._rsa_key = key
        elif key is not None:
            self._rsa_key = RSA.importKey(key)
        else:
            self._rsa_key = None

        if cert is not None and type(cert) == str and exists(cert):
            self._cert = x509.parse_certificate_file(cert)
            f = open(cert)
            self._plain_cert = f.read()
            f.close()
        elif cert is not None and isinstance(cert, x509.Certificate):
            self._cert = cert
            # TODO: We'll need the plaintext certificate here...
        elif cert is not None:
            self._cert = x509.parse_certificate(cert)
            self._plain_cert = cert
        else:
            self._cert = None
            self._plain_cert = None

        if ca_bundle is not None and type(ca_bundle) == str and exists(
                ca_bundle):
            self._ca = x509.parse_certificate_file(ca_bundle)
        elif ca_bundle is not None and isinstance(ca_bundle, x509.Certificate):
            self._ca = ca_bundle
        elif ca_bundle is not None:
            self._ca = x509.parse_certificate(ca_bundle)
        else:
            self._ca = None

        self._app_name = app_name
        self._authserver = authserver
コード例 #2
0
    def __init__(self, app_name, cert=None, key=None, ca_bundle=None,
                 authserver="login.ancient-solutions.com"):
        """Set up the authentication client so it can be used lateron.

        Args:
        app_name: The name the login server shall display to the user.
        cert: Path to the certificate to use for signing the
        requests, or the contents of the certificate.
        key: Path to the private key to use for signing the
        requests, or the contents of the key.
        ca_bundle: path to a CA bundle file to use for authenticating
        the server.
        """

        if key is not None and type(key) == str and exists(key):
            self._rsa_key = rsa.UnwrapRSAKey(key)
        elif key is not None and isinstance(key, RSA._RSAobj):
            self._rsa_key = key
        elif key is not None:
            self._rsa_key = RSA.importKey(key)
        else:
            self._rsa_key = None

        if cert is not None and type(cert) == str and exists(cert):
            self._cert = x509.parse_certificate_file(cert)
            f = open(cert)
            self._plain_cert = f.read()
            f.close()
        elif cert is not None and isinstance(cert, x509.Certificate):
            self._cert = cert
            # TODO: We'll need the plaintext certificate here...
        elif cert is not None:
            self._cert = x509.parse_certificate(cert)
            self._plain_cert = cert
        else:
            self._cert = None
            self._plain_cert = None

        if ca_bundle is not None and type(ca_bundle) == str and exists(ca_bundle):
            self._ca = x509.parse_certificate_file(ca_bundle)
        elif ca_bundle is not None and isinstance(ca_bundle, x509.Certificate):
            self._ca = ca_bundle
        elif ca_bundle is not None:
            self._ca = x509.parse_certificate(ca_bundle)
        else:
            self._ca = None

        self._app_name = app_name
        self._authserver = authserver
コード例 #3
0
    def test_request_authorization(self):
        """Test if we can request authorization correctly."""

        cert = x509.parse_certificate(_TEST_CERT)

        auth = authenticator.Authenticator("Unit Test",
                                           cert=_TEST_CERT,
                                           key=_TEST_KEY)
        dest = authenticator.urlparse(
            auth.request_authorization(
                'http://bazquux.foo/asdf/bsdf?q=x&r=x#asd'))

        self.assertEqual("https", dest.scheme)
        self.assertEqual("login.ancient-solutions.com", dest.hostname)
        self.assertEqual("/", dest.path)

        query = authenticator.parse_qs(dest.query)
        self.assertEqual(["token"], query["response_type"])
        self.assertEqual(["http://bazquux.foo/asdf/bsdf?q=x&r=x#asd"],
                         query["redirect_uri"])
        self.assertIn("client_id", query)

        atr = token_pb2.AuthTokenRequest()
        cdc = token_cookie.AuthTokenRequestCodec(atr,
                                                 pubkey=cert.get_pub_key())
        try:
            cdc.decode(query["client_id"][0])
        except token_cookie.SignatureException as e:
            self.fail("Cannot validate signature on auth token request")

        self.assertEqual("Unit Test", atr.app_name)
        self.assertEqual("http://bazquux.foo/asdf/bsdf?q=x&r=x#asd",
                         atr.original_uri)
        self.assertEqual("http://bazquux.foo/login", atr.return_uri)
コード例 #4
0
	def test_request_authorization(self):
		"""Test if we can request authorization correctly."""

		cert = x509.parse_certificate(_TEST_CERT)

		auth = authenticator.Authenticator("Unit Test", cert=_TEST_CERT,
			key=_TEST_KEY)
		dest = authenticator.urlparse(auth.request_authorization(
			'http://bazquux.foo/asdf/bsdf?q=x&r=x#asd'))

		self.assertEqual("https", dest.scheme)
		self.assertEqual("login.ancient-solutions.com", dest.hostname)
		self.assertEqual("/", dest.path)

		query = authenticator.parse_qs(dest.query)
		self.assertEqual(["token"], query["response_type"])
		self.assertEqual(["http://bazquux.foo/asdf/bsdf?q=x&r=x#asd"],
			query["redirect_uri"])
		self.assertIn("client_id", query)

		atr = token_pb2.AuthTokenRequest()
		cdc = token_cookie.AuthTokenRequestCodec(atr,
			pubkey=cert.get_pub_key())
		try:
			cdc.decode(query["client_id"][0])
		except token_cookie.SignatureException as e:
			self.fail("Cannot validate signature on auth token request")

		self.assertEqual("Unit Test", atr.app_name)
		self.assertEqual("http://bazquux.foo/asdf/bsdf?q=x&r=x#asd",
			atr.original_uri)
		self.assertEqual("http://bazquux.foo/login", atr.return_uri)
コード例 #5
0
	def test_verify_unknown_signer(self):
		"""Verify a wrong signature."""

		cert, key = gen_certificate()
		cacert = x509.parse_certificate(_TEST_CA)

		# Set up a token cookie with test data.
		atr = token_pb2.AuthTokenResponse()
		set_basic_creds(atr.basic_creds)
		atr.certificate = _TEST_CERT
		atr.original_uri = 'https://localhost/'
		atr.app_name = 'Test Application'
		atr.granted = calendar.timegm(datetime.now().timetuple())
		atr.random = 'A' * 42  # TODO(tonnerre): This should go away.

		# Create the codec and encode.
		atrc = token_cookie.AuthTokenResponseCodec(atr, privkey=key)

		data = atrc.encode()

		# Verify the signature.
		vatr = token_pb2.AuthTokenResponse()
		vatrc = token_cookie.AuthTokenResponseCodec(vatr,
			cacert=cacert)
		self.assertRaises(token_cookie.SignatureException, vatrc.decode, data)
コード例 #6
0
	def test_sign_and_decrypt(self):
		"""Encode and decode an authentication token request object."""

		# We need a CA signed certificate, so we use the one
		# from above.
		cert = x509.parse_certificate(_TEST_CERT)
		key = RSA.importKey(_TEST_KEY)
		cacert = x509.parse_certificate(_TEST_CA)

		# Sanity check for the above certificates.
		self.assertTrue(cert.check_signature(cacert))

		# Create an AuthTokenRequest with some correct-sounding data.
		atr = token_pb2.AuthTokenRequest()
		atr.certificate = _TEST_CERT
		atr.return_uri = 'https://localhost/login'
		atr.original_uri = 'https://localhost/'
		atr.app_name = 'Test Application'

		# Create the codec and encode.
		atrc = token_cookie.AuthTokenRequestCodec(atr, privkey=key)

		data = atrc.encode()

		# Verify the signature.
		vatr = token_pb2.AuthTokenRequest()
		vatrc = token_cookie.AuthTokenRequestCodec(vatr,
			pubkey=cert.get_pub_key())
		try:
			vatrc.decode(data)
		except token_cookie.SignatureException as e:
			# TODO(tonnerre): Reenable this test.
			self.fail("Can't verify signature using original certificate")

		self.assertEqual(atr, vatr)

		# Decode again, using the contained certificate.
		vatr.Clear()
		vatrc = token_cookie.AuthTokenRequestCodec(vatr, cacert=cacert)
		try:
			vatrc.decode(data)
		except token_cookie.SignatureException as e:
			# TODO(tonnerre): reenable this test.
			# self.fail("Can't verify signature using inband certificate")
			pass

		self.assertEqual(atr, vatr)
コード例 #7
0
	def test_sign_and_decrypt(self):
		"""Encode and decode an authentication token response object."""

		# We need a CA signed certificate, so we use the one
		# from above.
		cert = x509.parse_certificate(_TEST_CERT)
		key = RSA.importKey(_TEST_KEY)
		cacert = x509.parse_certificate(_TEST_CA)

		# Sanity check for the above certificates.
		self.assertTrue(cert.check_signature(cacert))

		# Create an AuthTokenRequest with some correct-sounding data.
		atr = token_pb2.AuthTokenResponse()
		set_basic_creds(atr.basic_creds)
		atr.certificate = _TEST_CERT
		atr.original_uri = 'https://localhost/'
		atr.app_name = 'Test Application'
		atr.granted = calendar.timegm(datetime.now().timetuple())
		atr.random = 'A' * 42  # TODO(tonnerre): This should go away.

		# Create the codec and encode.
		atrc = token_cookie.AuthTokenResponseCodec(atr, privkey=key)

		data = atrc.encode()

		# Verify the signature.
		vatr = token_pb2.AuthTokenResponse()
		vatrc = token_cookie.AuthTokenResponseCodec(vatr,
			pubkey=cert.get_pub_key())
		try:
			vatrc.decode(data)
		except token_cookie.SignatureException as e:
			self.fail("Can't verify signature using original certificate")

		self.assertEqual(atr, vatr)

		# Decode again, using the contained certificate.
		vatr.Clear()
		vatrc = token_cookie.AuthTokenResponseCodec(vatr, cacert=cacert)
		try:
			vatrc.decode(data)
		except token_cookie.SignatureException as e:
			self.fail("Can't verify signature using inband certificate: " +
				e.message)

		self.assertEqual(atr, vatr)
コード例 #8
0
    def test_sign_and_decrypt(self):
        """Encode and decode an authentication token response object."""

        # We need a CA signed certificate, so we use the one
        # from above.
        cert = x509.parse_certificate(_TEST_CERT)
        key = RSA.importKey(_TEST_KEY)
        cacert = x509.parse_certificate(_TEST_CA)

        # Sanity check for the above certificates.
        self.assertTrue(cert.check_signature(cacert))

        # Create an AuthTokenRequest with some correct-sounding data.
        atr = token_pb2.AuthTokenResponse()
        set_basic_creds(atr.basic_creds)
        atr.certificate = _TEST_CERT
        atr.original_uri = 'https://localhost/'
        atr.app_name = 'Test Application'
        atr.granted = calendar.timegm(datetime.now().timetuple())
        atr.random = 'A' * 42  # TODO(caoimhe): This should go away.

        # Create the codec and encode.
        atrc = token_cookie.AuthTokenResponseCodec(atr, privkey=key)

        data = atrc.encode()

        # Verify the signature.
        vatr = token_pb2.AuthTokenResponse()
        vatrc = token_cookie.AuthTokenResponseCodec(vatr,
                                                    pubkey=cert.get_pub_key())
        try:
            vatrc.decode(data)
        except token_cookie.SignatureException as e:
            self.fail("Can't verify signature using original certificate")

        self.assertEqual(atr, vatr)

        # Decode again, using the contained certificate.
        vatr.Clear()
        vatrc = token_cookie.AuthTokenResponseCodec(vatr, cacert=cacert)
        try:
            vatrc.decode(data)
        except token_cookie.SignatureException as e:
            self.fail("Can't verify signature using inband certificate: " +
                      e.message)

        self.assertEqual(atr, vatr)
コード例 #9
0
    def test_sign_and_decrypt(self):
        """Encode and decode an authentication token request object."""

        # We need a CA signed certificate, so we use the one
        # from above.
        cert = x509.parse_certificate(_TEST_CERT)
        key = RSA.importKey(_TEST_KEY)
        cacert = x509.parse_certificate(_TEST_CA)

        # Sanity check for the above certificates.
        self.assertTrue(cert.check_signature(cacert))

        # Create an AuthTokenRequest with some correct-sounding data.
        atr = token_pb2.AuthTokenRequest()
        atr.certificate = _TEST_CERT
        atr.return_uri = 'https://localhost/login'
        atr.original_uri = 'https://localhost/'
        atr.app_name = 'Test Application'

        # Create the codec and encode.
        atrc = token_cookie.AuthTokenRequestCodec(atr, privkey=key)

        data = atrc.encode()

        # Verify the signature.
        vatr = token_pb2.AuthTokenRequest()
        vatrc = token_cookie.AuthTokenRequestCodec(vatr,
                                                   pubkey=cert.get_pub_key())
        try:
            vatrc.decode(data)
        except token_cookie.SignatureException as e:
            # TODO(caoimhe): Reenable this test.
            self.fail("Can't verify signature using original certificate")

        self.assertEqual(atr, vatr)

        # Decode again, using the contained certificate.
        vatr.Clear()
        vatrc = token_cookie.AuthTokenRequestCodec(vatr, cacert=cacert)
        try:
            vatrc.decode(data)
        except token_cookie.SignatureException as e:
            # TODO(caoimhe): reenable this test.
            # self.fail("Can't verify signature using inband certificate")
            pass

        self.assertEqual(atr, vatr)
コード例 #10
0
    def test_login_handler(self):
        """Check whether an authentication token response is handled
		and decoded correctly by the authenticator implementation."""

        now = datetime.now()
        expires = now + timedelta(0, 300)
        pkey = importKey(_TEST_KEY)

        # We need a CA signed certificate, so we use the one
        # from above.
        cert = x509.parse_certificate(_TEST_CERT)
        cacert = x509.parse_certificate(_TEST_CA)

        # Sanity check for the above certificates.
        self.assertTrue(cert.check_signature(cacert))

        auth = authenticator.Authenticator("Unit Test",
                                           cert=_TEST_CERT,
                                           key=_TEST_KEY,
                                           ca_bundle=_TEST_CA)
        atres = token_pb2.AuthTokenResponse()
        atres.basic_creds.user_name = 'testosteronius'
        atres.basic_creds.scope.extend(['one', 'two'])
        atres.basic_creds.expires = calendar.timegm(expires.utctimetuple())

        atres.app_name = 'Unit Test'
        atres.original_uri = 'http://lolcathost:8080/foo/bar'
        atres.certificate = _TEST_CERT
        atres.granted = calendar.timegm(now.utctimetuple())

        # FIXME(caoimhe): this should go away.
        atres.random = 'A' * 64

        atrc = token_cookie.AuthTokenResponseCodec(atres, privkey=pkey)
        response = atrc.encode()

        data = auth.login_handler(response)
        self.assertEquals(2, len(data))
        cookiedata = data[0]
        nexturl = data[1]

        self.assertEquals('http://lolcathost:8080/foo/bar', nexturl)
コード例 #11
0
	def test_login_handler(self):
		"""Check whether an authentication token response is handled
		and decoded correctly by the authenticator implementation."""

		now = datetime.now()
		expires = now + timedelta(0, 300)
		pkey = importKey(_TEST_KEY)

		# We need a CA signed certificate, so we use the one
		# from above.
		cert = x509.parse_certificate(_TEST_CERT)
		cacert = x509.parse_certificate(_TEST_CA)

		# Sanity check for the above certificates.
		self.assertTrue(cert.check_signature(cacert))

		auth = authenticator.Authenticator("Unit Test", cert=_TEST_CERT,
			key=_TEST_KEY, ca_bundle=_TEST_CA)
		atres = token_pb2.AuthTokenResponse()
		atres.basic_creds.user_name = 'testosteronius'
		atres.basic_creds.scope.extend(['one', 'two'])
		atres.basic_creds.expires = calendar.timegm(expires.utctimetuple())

		atres.app_name = 'Unit Test'
		atres.original_uri = 'http://lolcathost:8080/foo/bar'
		atres.certificate = _TEST_CERT
		atres.granted = calendar.timegm(now.utctimetuple())

		# FIXME(tonnerre): this should go away.
		atres.random = 'A' * 64

		atrc = token_cookie.AuthTokenResponseCodec(atres, privkey=pkey)
		response = atrc.encode()

		data = auth.login_handler(response)
		self.assertEquals(2, len(data))
		cookiedata = data[0]
		nexturl = data[1]

		self.assertEquals('http://lolcathost:8080/foo/bar', nexturl)
コード例 #12
0
    def decode(self, src):
        """Verify the signature and decode the response.

        Decode the structure. Verifies the signature with the given
        public key, or with the key contained inside the message if
        None is passed.

        Args:
        src: string containing the base64 encoded cookie.

        Return:
        Integer value indicating the length of the data which was
        read; this is so it can be skipped if multiple records are
        returned. This length is after base64 decoding, so a
        multiplier must be applied.
        """
        data = base64.urlsafe_b64decode(src)
        self._atr.ParseFromString(data)

        if (datetime.utcfromtimestamp(self._atr.basic_creds.expires) <
                datetime.utcnow()):
            raise TokenExpiredException()

        # We'll need a copy of the data so we can verify it by
        # setting the signature to None.
        pb = token_pb2.AuthTokenResponse()
        pb.ParseFromString(data)
        pb.ClearField("signature")

        h = SHA256.new(pb.SerializeToString())
        if self._pub:
            verifier = PKCS1_v1_5.new(self._pub)
        else:
            # Attempt to extract the certificate from the request.
            cert = x509.parse_certificate(self._atr.certificate)

            if not self._ca:
                raise NoKeyException()
            if not cert.check_signature(self._ca):
                raise SignatureException("Certificate not signed by CA")

            verifier = PKCS1_v1_5.new(cert.get_pub_key())

        if verifier.verify(h, self._atr.signature):
            return len(data)
        else:
            raise SignatureException("Unable to verify data signature")
コード例 #13
0
    def test_verify_unknown_signer(self):
        """Verify a wrong signature."""

        cert, key = gen_certificate()
        cacert = x509.parse_certificate(_TEST_CA)

        # Set up a token cookie with test data.
        atr = token_pb2.AuthTokenRequest()
        atr.certificate = _TEST_CERT
        atr.return_uri = 'https://localhost/login'
        atr.original_uri = 'https://localhost/'
        atr.app_name = 'Test Application'

        # Create the codec and encode.
        atrc = token_cookie.AuthTokenRequestCodec(atr, privkey=key)
        data = atrc.encode()

        # Verify the signature.
        vatr = token_pb2.AuthTokenRequest()
        vatrc = token_cookie.AuthTokenRequestCodec(vatr, cacert=cacert)
        self.assertRaises(token_cookie.SignatureException, vatrc.decode, data)
コード例 #14
0
	def test_verify_unknown_signer(self):
		"""Verify a wrong signature."""

		cert, key = gen_certificate()
		cacert = x509.parse_certificate(_TEST_CA)

		# Set up a token cookie with test data.
		atr = token_pb2.AuthTokenRequest()
		atr.certificate = _TEST_CERT
		atr.return_uri = 'https://localhost/login'
		atr.original_uri = 'https://localhost/'
		atr.app_name = 'Test Application'

		# Create the codec and encode.
		atrc = token_cookie.AuthTokenRequestCodec(atr, privkey=key)
		data = atrc.encode()

		# Verify the signature.
		vatr = token_pb2.AuthTokenRequest()
		vatrc = token_cookie.AuthTokenRequestCodec(vatr,
			cacert=cacert)
		self.assertRaises(token_cookie.SignatureException, vatrc.decode, data)
コード例 #15
0
    def test_verify_unknown_signer(self):
        """Verify a wrong signature."""

        cert, key = gen_certificate()
        cacert = x509.parse_certificate(_TEST_CA)

        # Set up a token cookie with test data.
        atr = token_pb2.AuthTokenResponse()
        set_basic_creds(atr.basic_creds)
        atr.certificate = _TEST_CERT
        atr.original_uri = 'https://localhost/'
        atr.app_name = 'Test Application'
        atr.granted = calendar.timegm(datetime.now().timetuple())
        atr.random = 'A' * 42  # TODO(caoimhe): This should go away.

        # Create the codec and encode.
        atrc = token_cookie.AuthTokenResponseCodec(atr, privkey=key)

        data = atrc.encode()

        # Verify the signature.
        vatr = token_pb2.AuthTokenResponse()
        vatrc = token_cookie.AuthTokenResponseCodec(vatr, cacert=cacert)
        self.assertRaises(token_cookie.SignatureException, vatrc.decode, data)