Example #1
0
    def test_client_secret_jwt(self, client):
        _ci = client.client_info
        _ci.token_endpoint = "https://example.com/token"
        _ci.provider_info = {
            'issuer': 'https://example.com/',
            'token_endpoint': "https://example.com/token"
        }

        csj = ClientSecretJWT()
        request = AccessTokenRequest()

        csj.construct(request,
                      cli_info=client.client_info,
                      algorithm="HS256",
                      authn_endpoint='userinfo')
        assert request["client_assertion_type"] == JWT_BEARER
        assert "client_assertion" in request
        cas = request["client_assertion"]

        _skey = [SYMKey(k=b64e(as_bytes(_ci.client_secret)), use='sig')]
        jso = JWT(rec_keys={client.client_id: _skey}).unpack(cas)
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])

        _rj = JWS()
        info = _rj.verify_compact(
            cas, [SYMKey(k=b64e(as_bytes(_ci.client_secret)))])

        assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert info['aud'] == [_ci.provider_info['issuer']]
Example #2
0
def cookie_signature(key, *parts):
    """Generates a cookie signature.

       :param key: The HMAC key to use.
       :type key: bytes
       :param parts: List of parts to include in the MAC
       :type parts: list of bytes or strings
       :returns: hexdigest of the HMAC
    """

    sha1 = hmac.new(as_bytes(key), digestmod=hashlib.sha1)
    for part in parts:
        if part:
            sha1.update(as_bytes(part))
    return str(sha1.hexdigest())
Example #3
0
    def service_endpoint(self, name, **kwargs):
        logger.info(kwargs)
        logger.info('At the {} endpoint'.format(name))

        endpoint = self.endpoint_context.endpoint[name]

        try:
            authn = cherrypy.request.headers['Authorization']
        except KeyError:
            pr_args = {}
        else:
            pr_args = {'auth': authn}

        if endpoint.request_placement == 'body':
            if cherrypy.request.process_request_body is True:
                _request = cherrypy.request.body.read()
            else:
                raise cherrypy.HTTPError(400, 'Missing HTTP body')
            if not _request:
                _request = kwargs

            req_args = endpoint.parse_request(_request, **pr_args)
        else:
            req_args = endpoint.parse_request(kwargs, **pr_args)
        logger.info('request: {}'.format(req_args))

        if isinstance(req_args, ResponseMessage) and 'error' in req_args:
            return as_bytes(req_args.to_json())

        args = endpoint.process_request(req_args)
        return self.do_response(endpoint, req_args, **args)
Example #4
0
    def acb(self, op_hash='', **kwargs):
        logger.debug('Callback kwargs: {}'.format(kwargs))

        rp = self.get_rp(op_hash)

        try:
            session_info = self.rph.session_interface.get_state(
                kwargs['state'])
        except KeyError:
            raise cherrypy.HTTPError(400, 'Unknown state')

        logger.debug('Session info: {}'.format(session_info))
        # rp.service_context.provider_info['issuer'] != state_info['iss']:
        #   raise cherrypy.HTTPError(400, 'Wrong Issuer')
        res = self.rph.finalize(session_info['iss'], kwargs)

        if is_error_message(res):
            raise cherrypy.HTTPError(400, res['error'])
        else:
            fname = os.path.join(self.html_home, 'opresult.html')
            _pre_html = open(fname, 'r').read()
            _html = _pre_html.format(result=create_result_page(
                userinfo=res['userinfo'], access_token=res['token'],
                client=rp))
            return as_bytes(_html)
Example #5
0
def test_client_secret_basic():
    _token = '{}:{}'.format(client_id, client_secret)
    token = as_unicode(base64.b64encode(as_bytes(_token)))

    authz_token = 'Basic {}'.format(token)

    authn_info = ClientSecretBasic(endpoint_context).verify({}, authz_token)

    assert authn_info['client_id'] == client_id
Example #6
0
 def metadata(self):
     cherrypy.response.headers['Content-Type'] = 'application/jws'
     metadata_statement = MetadataStatement()
     fe = self.endpoint_context.federation_entity
     fe.add_signing_keys(metadata_statement)
     try:
         sms = fe.self_signer.sign(metadata_statement, aud=fe.fo_priority)
     except Exception as err:
         logger.exception(err)
         raise
     return as_bytes(sms)
Example #7
0
 def metadata(self):
     cherrypy.response.headers['Content-Type'] = 'application/jws'
     _info = self.rph.client_configs['']['client_preferences']
     metadata_statement = MetadataStatement(**_info)
     fe = self.rph.extra['federation_entity']
     fe.add_signing_keys(metadata_statement)
     try:
         sms = fe.self_signer.sign(metadata_statement, aud=fe.fo_priority)
     except Exception as err:
         logger.exception(err)
         raise
     return as_bytes(sms)
Example #8
0
    def encrypt(self, key, iv="", cek="", **kwargs):
        """
        Produces a JWE using RSA algorithms

        :param key: RSA key
        :param context:
        :param iv:
        :param cek:
        :return: A jwe
        """

        _msg = as_bytes(self.msg)
        if "zip" in self:
            if self["zip"] == "DEF":
                _msg = zlib.compress(_msg)
            else:
                raise ParameterError("Zip has unknown value: %s" % self["zip"])

        kwarg_cek = cek or None

        _enc = self["enc"]
        iv = self._generate_iv(_enc, iv)
        cek = self._generate_key(_enc, cek)
        self["cek"] = cek

        logger.debug("cek: %s, iv: %s" % ([c for c in cek], [c for c in iv]))

        _encrypt = RSAEncrypter(self.with_digest).encrypt

        _alg = self["alg"]
        if kwarg_cek:
            jwe_enc_key = ''
        elif _alg == "RSA-OAEP":
            jwe_enc_key = _encrypt(cek, key, 'pkcs1_oaep_padding')
        elif _alg == "RSA-OAEP-256":
            jwe_enc_key = _encrypt(cek, key, 'pkcs1_oaep_256_padding')
        elif _alg == "RSA1_5":
            jwe_enc_key = _encrypt(cek, key)
        else:
            raise NotSupportedAlgorithm(_alg)

        jwe = JWEnc(**self.headers())

        try:
            _auth_data = kwargs['auth_data']
        except KeyError:
            _auth_data = jwe.b64_encode_header()

        ctxt, tag, key = self.enc_setup(_enc, _msg, key=cek, iv=iv,
                                        auth_data=_auth_data)
        return jwe.pack(parts=[jwe_enc_key, iv, ctxt, tag])
Example #9
0
def _make_hashed_key(parts, hashfunc='sha256'):
    """
    Construct a key via hashing the parts

    If the parts do not have enough entropy of their
    own, this doesn't help.

    The size of the hash digest determines the size.
    """
    h = hashlib.new(hashfunc)
    for part in parts:
        if part:
            h.update(as_bytes(part))
    return h.digest()
Example #10
0
    def do_response(self, endpoint, req_args, **args):
        info = endpoint.do_response(request=req_args, **args)

        for key, value in info['http_headers']:
            cherrypy.response.headers[key] = value

        try:
            _response_placement = info['response_placement']
        except KeyError:
            _response_placement = endpoint.response_placement

        if _response_placement == 'body':
            logger.info('Response: {}'.format(info['response']))
            return as_bytes(info['response'])
        elif _response_placement == 'url':
            logger.info('Redirect to: {}'.format(info['response']))
            raise cherrypy.HTTPRedirect(info['response'])
    def repost_fragment(self, **kwargs):
        logger.debug('repost_fragment kwargs: {}'.format(kwargs))
        args = compact(parse_qs(kwargs['url_fragment']))
        op_hash = kwargs['op_hash']

        rp = self.get_rp(op_hash)

        x = rp.service_context.state_db[args['state']]
        logger.debug('State info: {}'.format(x))
        res = self.rph.finalize(x['as'], args)

        if res[0] is True:
            fname = os.path.join(self.html_home, 'opresult.html')
            _pre_html = open(fname, 'r').read()
            _html = _pre_html.format(result=create_result_page(*res[1:]))
            return as_bytes(_html)
        else:
            raise cherrypy.HTTPError(400, res[1])
 def __init__(self,
              kty="oct",
              alg="",
              use="",
              kid="",
              key=None,
              x5c=None,
              x5t="",
              x5u="",
              k="",
              mtrl="",
              **kwargs):
     Key.__init__(self, kty, alg, use, kid, as_bytes(key), x5c, x5t, x5u,
                  **kwargs)
     self.k = k
     if not self.key and self.k:
         if isinstance(self.k, str):
             self.k = self.k.encode("utf-8")
         self.key = b64d(bytes(self.k))
Example #13
0
    def create_callbacks(self, issuer):
        """
        To mitigate some security issues the redirect_uris should be OP/AS
        specific. This method creates a set of redirect_uris unique to the
        OP/AS.

        :param issuer: Issuer ID
        :return: A set of redirect_uris
        """
        _hash = hashlib.sha256()
        _hash.update(self.hash_seed)
        _hash.update(as_bytes(issuer))
        _hex = _hash.hexdigest()
        self.hash2issuer[_hex] = issuer
        return {
            'code': "{}/authz_cb/{}".format(self.base_url, _hex),
            'implicit': "{}/authz_im_cb/{}".format(self.base_url, _hex),
            'form_post': "{}/authz_fp_cb/{}".format(self.base_url, _hex),
            '__hex': _hex
        }
Example #14
0
    def index(self, uid='', iss=''):
        link = ''
        if iss:
            link = iss
        elif uid:
            pass
        else:
            fname = os.path.join(self.html_home, 'opbyuid.html')
            return as_bytes(open(fname, 'r').read())

        if link or uid:
            if uid:
                args = {'user_id': uid}
            else:
                args = {}
            try:
                result = self.rph.begin(link, **args)
            except Exception as err:
                raise cherrypy.HTTPError(err)
            else:
                raise cherrypy.HTTPRedirect(result['url'])
Example #15
0
    def __init__(self,
                 base_url='',
                 hash_seed="",
                 keyjar=None,
                 verify_ssl=True,
                 services=None,
                 service_factory=None,
                 client_configs=None,
                 client_authn_factory=None,
                 client_cls=None,
                 state_db=None,
                 **kwargs):
        self.base_url = base_url
        self.hash_seed = as_bytes(hash_seed)
        self.verify_ssl = verify_ssl
        self.keyjar = keyjar

        if state_db:
            self.state_db = state_db
        else:
            self.state_db = InMemoryStateDataBase()

        self.session_interface = StateInterface(self.state_db)

        try:
            self.jwks_uri = add_path(base_url, kwargs['jwks_path'])
        except KeyError:
            pass

        self.extra = kwargs

        self.client_cls = client_cls or oidc.RP
        self.services = services
        self.service_factory = service_factory or factory
        self.client_authn_factory = client_authn_factory
        self.client_configs = client_configs

        # keep track on which RP instance that serves with OP
        self.issuer2rp = {}
        self.hash2issuer = {}
Example #16
0
    def encrypt(self, iv="", cek="", **kwargs):

        _msg = as_bytes(self.msg)
        _args = self._dict
        try:
            _args["kid"] = kwargs["kid"]
        except KeyError:
            pass

        if 'params' in kwargs:
            if 'apu' in kwargs['params']:
                _args['apu'] = kwargs['params']['apu']
            if 'apv' in kwargs['params']:
                _args['apv'] = kwargs['params']['apv']
            if 'epk' in kwargs['params']:
                _args['epk'] = kwargs['params']['epk']

        jwe = JWEnc(**_args)
        ctxt, tag, cek = super(JWE_EC, self).enc_setup(self["enc"], _msg,
                                                       auth_data=jwe.b64_encode_header(),
                                                       key=cek, iv=iv)
        if 'encrypted_key' in kwargs:
            return jwe.pack(parts=[kwargs['encrypted_key'], iv, ctxt, tag])
        return jwe.pack(parts=[iv, ctxt, tag])
def sha512_digest(msg):
    return hashlib.sha512(as_bytes(msg)).digest()
Example #18
0
def get_client_id(cdb, req, authn):
    """
    Verify the client and return the client id

    :param req: The request
    :param authn: Authentication information from the HTTP header
    :return:
    """

    logger.debug("REQ: %s" % sanitize(req.to_dict()))
    if authn:
        if authn.startswith("Basic "):
            logger.debug("Basic auth")
            (_id, _secret) = base64.b64decode(
                authn[6:].encode("utf-8")).decode("utf-8").split(":")

            _bid = as_bytes(_id)
            _cinfo = None
            try:
                _cinfo = cdb[_id]
            except KeyError:
                try:
                    _cinfo[_bid]
                except AttributeError:
                    pass

            if not _cinfo:
                logger.debug("Unknown client_id")
                raise FailedAuthentication("Unknown client_id")
            else:
                if not valid_client_info(_cinfo):
                    logger.debug("Invalid Client info")
                    raise FailedAuthentication("Invalid Client")

                if _secret != _cinfo["client_secret"]:
                    logger.debug("Incorrect secret")
                    raise FailedAuthentication("Incorrect secret")
        else:
            if authn[:6].lower() == "bearer":
                logger.debug("Bearer auth")
                _token = authn[7:]
            else:
                raise FailedAuthentication("AuthZ type I don't know")

            try:
                _id = cdb[_token]
            except KeyError:
                logger.debug("Unknown access token")
                raise FailedAuthentication("Unknown access token")
    else:
        try:
            _id = str(req["client_id"])
            if _id not in cdb:
                logger.debug("Unknown client_id")
                raise FailedAuthentication("Unknown client_id")
            if not valid_client_info(cdb[_id]):
                raise FailedAuthentication("Invalid client_id")
        except KeyError:
            raise FailedAuthentication("Missing client_id")

    return _id
Example #19
0
 def hash(value):
     _hash = hashlib.sha256()
     _hash.update(as_bytes(value))
     return _hash.hexdigest()
def sha256_digest(msg):
    return hashlib.sha256(as_bytes(msg)).digest()
def sha384_digest(msg):
    return hashlib.sha384(as_bytes(msg)).digest()